236 Commits

Author SHA1 Message Date
Nic Limper
d2135a57bd bugfix 2024-01-09 21:35:42 +01:00
Jelmer
e77556ee9c Added M2 2.7 jig - updated Hanshow Jigs 2024-01-09 21:19:46 +01:00
Jonas Niesner
1aeea88696 Revert release file change 2024-01-09 20:33:51 +01:00
Nic Limper
837c5de1a8 minor fix in content 2024-01-09 17:58:29 +01:00
Jonas Niesner
d4f16f74e9 Update tagotaversions.json 2024-01-09 16:48:03 +01:00
Nic Limper
fdb4a3cbf1 weather forecast template 2.9" M3 and some minor fixes 2024-01-09 16:09:43 +01:00
Jelmer
5b7c96dcc0 Added 3 Hanshow Jigs 2024-01-09 13:25:16 +01:00
Jonas Niesner
c0a2bd01e5 CI cleanup (#195)
* Update release.yml

* Update platformio.ini

* Update build-test.yml
2024-01-09 08:59:06 +01:00
atc1441
bd8965174a Merge branch 'master' of https://github.com/jjwbruijn/OpenEPaperLink 2024-01-09 00:10:15 +01:00
atc1441
229962165a Added SubGHz Alpha 2024-01-09 00:10:11 +01:00
jjwbruijn
4dac6ab05c M2 v0026 firmware added 2024-01-08 21:59:51 +01:00
atc1441
f95e957361 Merge branch 'master' of https://github.com/jjwbruijn/OpenEPaperLink 2024-01-08 08:09:50 +01:00
atc1441
b8161f21fa Arduino ino file renaming 2024-01-08 07:40:07 +01:00
Nic Limper
950931b9a6 smaller UI improvements
- got rid of gamma correction during dithering for quality reasons
- smaller UI improvements and textual edits
- tag grouping in the interface is now sticky across sessions
- tag auto update now shows before/after version number
2024-01-08 01:01:06 +01:00
atc1441
af5e917cb3 Arduino port of the ESP32-C6 AP Firmware added (Not PlatformIO) 2024-01-08 00:36:34 +01:00
atc1441
8005ae71fc Create TLSR_HS_35_ALPHA.bin 2024-01-07 20:10:05 +01:00
atc1441
4965c68516 Added Telink TLSR Alpha release 2024-01-07 20:07:59 +01:00
Nic Limper
96e8fe8660 geocoding and other small improvements
- separated content types for 'not configured', 'static image', 'uploaded image' and 'home assistant' (which is all the same internally, but it confused the users to always see 'static image'
- changed channel reported by the AP to the ieee801.15.4 channel instead of the WiFi channel
- added geocoding to the 'location' fields (e.g. weather forecast). Now you can choose an ambiguous location from a dropdown.
- added 'firmware update rejected' wakeup reason
2024-01-07 19:32:56 +01:00
jjwbruijn
fcff10412d added wakeup-reason for failed OTA 2024-01-07 19:23:36 +01:00
Nic Limper
23c3611872 button to restore tagDB file from backup; cleanup 2024-01-07 02:40:55 +01:00
Nic Limper
7cb7eddc22 removed u8g2 library/fonts (+ automatic substitution for compatibilty) 2024-01-07 00:03:51 +01:00
Jonas Niesner
b68cd22eb1 Updated tag OTA (#193) 2024-01-06 21:16:48 +01:00
Nic Limper
b0cfa1b2b4 new week calendar added 2024-01-06 21:09:08 +01:00
Nic Limper
29589bc5b0 content template redesign / textbox / various
- Added Signika-SB.ttf and some small bitmap fonts
- Removed calibrib50/60/80/100/120/150 bitmap fonts, as they can be better rendered using truetype. Fallback is in place to auto translate to Signika-SB.ttf with the right size in case it is still used in a json template
- Renamed confusing tag type names to 'M2 + size' and 'M3 + size'. Because the universal firmware, there is no need to tell every subtile type change apart anymore.
- added `textbox` to json templates (https://github.com/jjwbruijn/OpenEPaperLink/wiki/Json-template#paragraph-text)
- redesign of count days/hours
- redesign of RSS feed
- designed Buienradar for more tag sizes
- on a scheduled or user initiated reboot, 'REBOOTING' is sent to the error channel of the websockets just before the connection is dropped
- phased out "hwtype": [] in content_cards.json (new location is in the tagtype json, which contains a list of valid content types)

In case of problems using this commit: keep in mind the heavy caching of the tagtypes in the browser. You might still unknowingly use the old contents.
2024-01-05 13:59:31 +01:00
Nic Limper
00ce785158 use latest version 6 of ArduinoJson, not 7 for now. 2024-01-04 20:07:15 +01:00
Pablo Gonzalez
9da9ac9395 Make WebSocket connection protocol dependent (#191)
Currently, the connection to WebSockets is hardcoded to the protocol "ws://".

If the server is put behind a proxy server (like Nginx) to support "https", the connection to websockets will fail (at least in Firefox) due to insecure protocol.

This change checks the current protocol and connects to "wss" if loaded via "https", which makes it work when loaded via proxy.
2024-01-04 19:18:14 +01:00
Jonas Niesner
022f72eee7 Add simple tag ota (#190)
and renamed files
2024-01-04 17:30:42 +01:00
Nic Limper
1d03eedfd6 bugfix in WiFi connection setup; + reset wifi settings using gpio0
- in rare cases, an AP didn't connect to a WiFi network due to some tight timing
- bringing GPIO0 to LOW for more than 5 seconds now resets the wifi settings, in case you're stuck with e.g. a wrong static ip configuration
2024-01-03 15:34:09 +01:00
Nic Limper
4f7a226312 last small fixes before release 2024-01-01 13:25:42 +01:00
Nic Limper
43fd751d1e moved language strings to json file
(don't forget to place languages.json in the file partition)
2023-12-31 17:26:17 +01:00
jjwbruijn
ab8cb3955a Fixed M2 0024 issue->0025 2023-12-31 15:07:26 +01:00
Jelmer
2694a0936f added universal M3 flasher jig 2023-12-31 14:52:28 +01:00
Jelmer
547d27e256 Better EEPROM handling (9.7") 2023-12-31 12:37:40 +01:00
Nic Limper
12f91fb293 fixed 9.7" image wrapping 2023-12-31 02:17:26 +01:00
Nic Limper
5973607ad7 firmware version in webinterface (for now, both dec and hex...) 2023-12-30 22:56:04 +01:00
Jonas Niesner
c4fb629ed4 Move content cards to tag types (#188) 2023-12-30 22:54:09 +01:00
Nic Limper
e14ec92d48 optional previewtype and previewlut parameters for /imgupload call
- optional previewtype and previewlut parameters for /imgupload call
- new 35.json for M3 6.0" (no template yet; coming up next)
- updated upload-demo.html
2023-12-30 22:25:04 +01:00
atc1441
b3887b6874 Added content IDs for 3.5" 2023-12-30 17:41:29 +01:00
Nic Limper
424cf2faf6 webinterface changes
- add tag resolution
- weather forecast card: enabled modify lat/lon coordinates
2023-12-30 15:41:22 +01:00
Nic Limper
0621dda3cc autosize QR code 2023-12-30 14:04:25 +01:00
Nic Limper
9f55d72f97 various small fixes
- prevent using html file for tag firmware update
- removed excessive logging
- fallback to .bak on tagDB load error
- scheduled reboot once at night around 4:00
2023-12-30 12:30:07 +01:00
Jelmer
3621d4b6e1 Merge branch 'master' of https://github.com/jjwbruijn/OpenEPaperLink 2023-12-30 11:50:42 +01:00
Jelmer
209f0f218a fixed M3 7.5 and 6.0 support in universal M3 fw 2023-12-30 11:50:30 +01:00
Nic Limper
9bb857329e re-rendered bitmap fonts for added languages 2023-12-30 00:38:45 +01:00
Miloš Krumpolc
b0d1e1da2c Add 4 new language: Czech, Slovak, Polish, Spanish (#162) 2023-12-29 23:57:55 +01:00
Nic Limper
d75a1d137f Fix automatic build for NRF 2023-12-29 23:42:22 +01:00
Vstudio LAB
19fc8c6594 Screen rotation in json (#173) 2023-12-29 23:35:47 +01:00
Nic Limper
bcd2a4618d bugfix deleting unknown tag / WIP locking
- bugfix: unable to delete unknown tag by right clicking
- work in progress: lock tag inventory, by rejecting new tags
2023-12-29 23:19:16 +01:00
Jelmer
a962828c4f Universal M3 binary 2023-12-29 19:32:40 +01:00
atc1441
45530085f9 Added S3_C6_NanoAP Gerbers 2023-12-28 09:15:57 +01:00
atc1441
ae4a5d5994 Added S3 C6 Nano AP 2023-12-27 23:09:06 +01:00
Jonas Niesner
bb11458167 M3 led control (#186)
Fixes led control for M3 based displays
2023-12-26 13:20:08 +01:00
atc1441
1f02a8288d Added 9.7" M3 Beta, still many bugs^^ 2023-12-23 13:53:43 +01:00
Jelmer
8065479557 Added 4.3" M3 definition 2023-12-22 00:30:37 +01:00
atc1441
ab65479917 Better Main Case for YellowAP 2023-12-20 18:38:54 +01:00
Jelmer
36596542c4 M3: Bugfix for buttons that would trigger multiple times on HA 2023-12-15 22:32:52 +01:00
Jelmer
eb66e4b7ec M3 v0024 - Slideshows and custom screens 2023-12-13 19:04:02 +01:00
Jelmer
8d15bb72fd Merge pull request #174 from VstudioLAB/M3_7.5BWR_support
Added M3 7.5" BWR EL075H3BRA tag to the AP
2023-12-13 15:10:29 +01:00
atc1441
4c43d76e09 Added YellowAP Case 2023-12-13 11:19:51 +01:00
Vstudio LAB
a1664daba4 Merge branch 'jjwbruijn:master' into M3_7.5BWR_support 2023-12-11 11:55:52 +01:00
jjwbruijn
60f9454bb2 M2 tag firmware v0024 2023-12-09 01:07:27 +01:00
VstudioLAB
db56860d26 Added M3 7.5" BWR EL075H3BRA tag to the AP 2023-12-09 00:54:17 +01:00
jjwbruijn
bb73069097 2.9 Slideshow builder 2023-12-09 00:31:03 +01:00
jjwbruijn
14e4d17b31 code cleanup, settings in eeprom, serial eeprom loader 2023-12-04 22:01:21 +01:00
Jelmer
a941cad902 Merge branch 'VstudioLAB-master' 2023-12-04 21:35:23 +01:00
Jelmer
80fc7997b7 remove content_cards.json.gz 2023-12-04 21:32:55 +01:00
Jelmer
ae0b44a424 Merge pull request #154 from skiphansen/master
Added scripts to build/use a local copy of sdcc version 4.2.0.
2023-12-04 19:56:35 +01:00
atc1441
372cb39c33 HS 3.5" BWY, BWR and BW Added 2023-12-02 13:43:52 +01:00
VstudioLAB
66c7ad6140 Added ST‐GM29XXF 2.9" Support
added ST‐GM29XXF 2.9" support
2023-11-29 00:26:15 +01:00
Skip Hansen
e95a1acae8 Merge branch 'jjwbruijn:master' into master 2023-11-26 18:41:35 -08:00
VstudioLAB
9410c47875 Added French
Added french langage as an option for tag content
2023-11-22 00:25:17 +01:00
Jelmer
220b4ae3e8 Restructured epd driver interface, support for UC-based tags 2023-11-12 10:24:36 +01:00
Skip Hansen
c64190709a Fix typos. 2023-11-04 09:48:40 -07:00
Skip Hansen
c446452b69 Added support for sdcc 4.0.7 used by https://dmitry.gr projects.
Make path's absolute, renamed scripts, added .gitignore
2023-11-04 08:20:51 -07:00
Skip Hansen
a24bccd1af Added scripts to build/use a local copy of sdcc version 4.2.0. 2023-11-03 16:21:02 -07:00
Nic Limper
246b234b22 small fix in follow redirects, and update of gzipped wwwroot 2023-10-29 22:07:58 +01:00
Milo Cesar
22c5bda4c5 Select currently configured files in tag editor (#152) 2023-10-29 22:04:18 +01:00
Sven-Ove Bjerkan
13f8dea68b Add support for Norwegian content (#149)
* Add support for Norwegian content
2023-10-23 19:06:00 +02:00
atc1441
696cb448fe Added Sub GHz YellowAP Gerber 2023-10-23 10:58:08 +02:00
Nic Limper
a4e19b19ab bugfixes: truetype rendering / fast luts / various
- no tag timeouts when tag is put to sleep
- small timing tweaks
- truetype render bugfix
- fix in fast lut setting
2023-10-22 13:20:54 +02:00
Sven-Ove Bjerkan
9d579e9515 Fix: Weather forecast showing yesterday as day 1 in some time zones (#146) (#148) 2023-10-19 16:27:15 +02:00
jjwbruijn
7faeb2eb54 slideshow builder for eeprom 2023-10-14 23:08:36 +02:00
Jelmer
5318f1fdc4 eeprom support OEPL-Flasher.py 2023-10-14 23:00:35 +02:00
Jelmer
4bf61c1dd0 added eeprom support for tag flasher 2023-10-14 22:59:11 +02:00
atc1441
c4beaa51c8 Model name typo 2023-10-13 11:07:31 +02:00
atc1441
26598fc408 Added NanoC6 Infos and Board definition 2023-10-12 17:20:42 +02:00
Nic Limper
06f3a5d524 small cosmetic changes 2023-10-12 17:06:57 +02:00
atc1441
0bed91ecc2 Update OpenEPaperLink_Yellow_AP_ESP32_C6_Gerber.zip 2023-10-12 13:26:40 +02:00
B0rax
1e76d690ec Add circle and rounded box to json template (#143) 2023-10-08 15:47:30 +02:00
Nic Limper
9c06cdf2d7 small fix for fw compile test 2023-10-08 15:44:02 +02:00
Nic Limper
7a0ca319e7 timing fix in getting version info for ota 2023-10-07 22:21:54 +02:00
Nic Limper
c095f4c881 created Python port for packagebinaries.php to create Tag_FW_Pack.bin 2023-10-06 22:30:09 +02:00
Nic Limper
c586c9f541 added negative sign to fonts; small improvements 2023-10-06 13:14:22 +02:00
Moritz Wirger
6c4f8ef35b Add ap_date and ap_time vars (#142)
* Add ap_date and ap_time vars
* Add convenience creation function for Timer
* Optimize timer
* Document timer
2023-10-04 21:43:28 +02:00
Nic Limper
c403c06b09 fix AP not responding + add more logs to investigate crashes 2023-10-04 15:33:22 +02:00
Nic Limper
ddd043f44f update esp32-C6 binaries 2023-10-02 15:09:29 +02:00
Nic Limper
81cc5ccc9a tiny oops 2023-10-02 13:51:11 +02:00
Nic Limper
be325b0e62 forgot to add gzipped files with previous commit 2023-10-02 13:45:03 +02:00
Nic Limper
3621c84cc4 various small fixes
- neopixel patterns optimized. The 'breathing' led state now is green colored if everything is okay, and blue if there are one or more tags timed out.
- time zone is now set before wifi connect to show correct time zone in the logs during startup
- concurrent image upload POST is now blocked. If an upload is in progress while you do a second http POST, http status 409 Conflict is returned.
- small synchronisation bug fix in web interface on loading tag type
- dialog window close bugfix in painter
- image upload is now logged in /log.txt
2023-10-02 13:43:53 +02:00
Nic Limper
ed82795e5f tweak timings 2023-10-02 11:54:36 +02:00
Marcel
5b9f8b324e New hardware profile: PoE AP (#141)
* New hardware profile: PoE AP

- added harware profiles for C6 firmware in menuconfig
- added free PSRAM stat in webinterface

* fix(fsfree): fixed var type of freesize of FS
2023-09-29 02:46:11 +02:00
Nic Limper
db80d23b52 several small improvements
- neopixel idle color now represents AP status
- option to invert colors (advanced options at tag card)
- filename dropdown in tag card when a filename is expected
- redrawing pending instead of raw, if previews are off and tag reboots
- tft brightness setting independent from neopixel brightness
2023-09-29 00:11:44 +02:00
jjwbruijn
125922f8e7 M2 2.2 - RFW for added RF Wake 2023-09-28 17:29:00 +02:00
Nic Limper
aa484575b8 update update screen to new design; ability to choose repo source for OTA 2023-09-28 11:40:29 +02:00
jjwbruijn
fa97daef3c M2 FW 2.2 - Preload and buttons 2023-09-28 01:03:29 +02:00
Jonas Niesner
0c591660bc Fix wrong domain
fixes #140
2023-09-27 20:33:54 +02:00
Jelmer
c8fb0ca4de ESP: Added feature to preload images 2023-09-27 14:04:48 +02:00
jjwbruijn
87ce823776 added new image type arguments for M3 2023-09-27 12:24:08 +02:00
Jonas Niesner
7fe4a1e6ad Rename bin files to the new standard (#139)
* Update release.yml
* Update genfilelist.py
* Rename files
* Create .gitignore
2023-09-27 08:33:32 +02:00
Nic Limper
29b8c9bc21 small fix in data parser 2023-09-26 22:53:59 +02:00
Moritz Wirger
2e44889b19 Add custom tag data parser (#132)
* Add formatString convenience function

* Use String& for wsLog, wsErr and wsSerial

* Add tag data parser and parse tag data

* Make logLine use String&

* Fix issue with formatString

* Reuse payloadLength in processTagReturnData

* Fix parsing of unsigned/signed inetegers and cleanup

* Use c++17 standard

* Cleanup logging
2023-09-26 22:51:57 +02:00
Nic Limper
4d08454fff Update README.md 2023-09-26 20:30:03 +02:00
Nic Limper
f131b5ce84 Update README.md 2023-09-26 20:29:23 +02:00
Nic Limper
33ba6a7aa7 updated web interface design 2023-09-26 10:27:57 +02:00
Nic Limper
75c6a6c0f9 previews now also show for tags connected to external AP; removed extra debug msg 2023-09-24 21:34:30 +02:00
Jonas Niesner
f7e2025487 M3 display led code fixes 2023-09-23 22:47:56 +02:00
Nic Limper
a91dd5c2a2 fix hangs on esp32-s2; refactor task runner; moved some json objects from the stack to the heap
temporary, there's some extra debug info on the terminal. Will be removed again in the near future.
2023-09-23 18:40:28 +02:00
Nic Limper
0ba287f734 mutex on file write; prevent other AP from stealing tag content; bigger heap for timeTask 2023-09-22 19:42:36 +02:00
Nic Limper
ad52c64b94 typo 2023-09-22 11:13:48 +02:00
Nic Limper
8c06bb04f3 typo 2023-09-22 11:13:15 +02:00
Nic Limper
07807afe08 add 4.2" mini stands design 2023-09-22 11:11:36 +02:00
onkelfunny
eb173e355f avoid loading *.raw files when preview is disabled (#136)
by @onkelfunny
2023-09-21 17:03:21 +02:00
onkelfunny
b792b71608 default configurable tag content (#134)
by @onkelfunny
2023-09-21 13:51:03 +02:00
Nic Limper
b0715fae97 cosmetic 2023-09-20 10:24:40 +02:00
Nic Limper
6e326009c3 finetuning C6 flashing, automatic retry on failing download 2023-09-20 10:15:55 +02:00
Jelmer
0a43c601fe M3 FW 0.1.6-beta3 2023-09-20 00:51:31 +02:00
Nic Limper
f92448992e remove debug info 2023-09-20 00:26:36 +02:00
Nic Limper
2d84583797 update button: download latest esp32-c6 firmware + flash from esp32-s3 2023-09-19 20:24:57 +02:00
atc1441
fac67eac7e Fixed Pull-up for C6 in YellowAP PCB for self flashing the C6 from ESP32-S3 2023-09-18 21:51:28 +02:00
Nic Limper
6cee005e92 esp32-c6 binaries for flashing by esp32-s3 2023-09-18 20:11:56 +02:00
Nic Limper
e68e549eaf bugfix, prevent duplicate dhcp hostnames 2023-09-15 09:50:56 +02:00
Jelmer
3eb4b94b06 Merge branch 'master' of https://github.com/jjwbruijn/OpenEPaperLink 2023-09-14 12:38:03 +02:00
Jelmer
9951dc5ce5 added and updated M3 jigs 2023-09-14 12:37:47 +02:00
Nic Limper
c53f33f8ec bugfix calculating expected next checkin 2023-09-11 20:40:05 +02:00
Nic Limper
abbc636948 custom partition table (with 3MB littlefs) for C6 2023-09-11 14:01:42 +02:00
Nic Limper
7e32a1a197 remove unused preview files from /current folder at startup 2023-09-11 13:50:37 +02:00
Nic Limper
95d0cf6804 esp-serial-flasher library (altered from the original) 2023-09-11 00:57:19 +02:00
Nic Limper
a92e0eb5e6 flashing ESP32-C6 from ESP32 via serial connection from webinterface
To flash the C6, place bootloader.bin, partition-table.bin and OpenEPaperLink_esp32_C6.bin in the file system root.
APconfig -> update -> advanced options -> update ESP32-C6
This should also work with a previous unconfigured C6.
Compatible with Yellow-AP.
2023-09-11 00:48:08 +02:00
Jelmer
c6c3c4f9f6 Update README.md 2023-09-10 22:45:48 +02:00
Nic Limper
2e64ed2f16 set dhcp hostname 2023-09-09 19:01:18 +02:00
Nic Limper
2780b7ce36 only send fast lut to capable tags 2023-09-08 23:58:52 +02:00
Nic Limper
9af2bd2a92 tagReturnData for C6 AP. It compiles, but other than that, untested 2023-09-08 20:27:18 +02:00
Nic Limper
92ff939adc bugfix gethwtype 2023-09-08 17:23:19 +02:00
Nic Limper
83ff8564a7 'flash led' command in context menu of webinterface 2023-09-08 17:07:48 +02:00
Jelmer
dc33ff5854 ESP32 return-data support 2023-09-08 11:19:33 +02:00
jjwbruijn
4176252b51 ZBS Tag Return-data support 2023-09-08 11:16:16 +02:00
Moritz Wirger
36c3c45510 Json url file template (#128)
json template url + file implementation. 
The file contains the json template, and can contain variables that will be extracted from the json in the url. The url is fetched at regular intervals.
2023-09-08 11:06:15 +02:00
jjwbruijn
abb9b195d3 updated oepl-wide definitions 2023-09-08 00:10:26 +02:00
Jonas Niesner
a3e30c549e Multiple 2.2" and build script improvements + housekeeping (#127)
* Update build-test.yml

* Update build-test.yml

* Update release.yml

* Create hextobin.py

* Update preparefiles.py

* Delete ARM_Tag_FW/nrf52811_Platformio_2.9 directory

* Delete ARM_Tag_FW/nrf52811_Platformio_7.4 directory

* Update release.yml

* Delete binaries/Tag_FW_M3_7.5.hex

* Delete binaries/Tag_FW_M3_2.9.hex

* Fix mac for 2.2"

* Fix bug in the release script and add comment about future plans

* fix 2.2" mac again
2023-09-04 22:26:52 +02:00
Jonas Niesner
02cd65d383 Add 2.2" to content cards 2023-09-04 19:44:52 +02:00
Jelmer
bc394e0d26 Added MD5 verification for nRF-based tags 2023-09-04 15:22:22 +02:00
Jelmer
22d3001996 added 6.0 jig 2023-09-04 12:54:21 +02:00
Jelmer
efb5a3cb55 added OTA for M3 tags 2023-09-04 01:18:33 +02:00
Jonas Niesner
8055de91f3 Merge pull request #125 from jonasniesner/master
Add multiple 2.2" M3 tag files
2023-09-03 20:09:56 +02:00
Jonas Niesner
0226f01ddb Add 2.2" tag type 2023-09-03 20:08:38 +02:00
Jonas Niesner
9cfadf1670 Add M3 2.2" to release scripts 2023-09-03 19:34:15 +02:00
Jonas Niesner
a1d06a2d34 Merge branch 'jjwbruijn:master' into master 2023-09-03 19:33:01 +02:00
Jonas Niesner
27665174b7 Merge branch 'master' of github.com:jonasniesner/OpenEPaperLink 2023-09-03 19:32:13 +02:00
Jonas Niesner
c23c3049bf 2.2" M3 config added 2023-09-03 19:31:38 +02:00
atc1441
55fe95903a Added C6 flasher, The S3 can flash the connected ESP32-C6 via UART 2023-09-03 10:47:16 +02:00
Jelmer
ea39ea0fc8 Merge pull request #124 from milo526/master
extend patch_mac script
2023-09-02 22:24:38 +02:00
Milo Cesar
f966bee5af extend patch_mac script 2023-09-02 22:19:46 +02:00
Jonas Niesner
8f9a9e44c2 Merge pull request #6 from jjwbruijn/master
Add NRF firmware building to release scripts
2023-09-02 18:59:30 +02:00
Jonas Niesner
214ddbf4e0 Merge branch 'master' into master 2023-09-02 18:59:17 +02:00
Jonas Niesner
65431e587e Update release.yml 2023-09-02 18:57:55 +02:00
Jonas Niesner
52fd9f1232 Update main.cpp 2023-09-02 18:38:42 +02:00
Jonas Niesner
76345fa794 Update release.yml 2023-09-02 17:59:30 +02:00
Jonas Niesner
12f5add21b Add files via upload 2023-09-02 17:57:12 +02:00
Jonas Niesner
eccd309a61 Add NRF firmware building to release scripts 2023-09-02 16:17:17 +02:00
Jonas Niesner
6a58d0143c Update release.yml 2023-09-02 15:20:46 +02:00
Jonas Niesner
70b4bd197c Update release.yml 2023-09-02 15:18:16 +02:00
jjwbruijn
aad5fe71eb updated beta 7.5" fw 2023-09-02 12:26:40 +02:00
Jelmer
8f7ec46f68 Merge pull request #122 from jonasniesner/master
M3 firmware improvements
2023-09-02 11:46:34 +02:00
Jonas Niesner
733078147d Merge branch 'jjwbruijn:master' into master 2023-09-02 11:40:58 +02:00
Jonas Niesner
ae8bc98619 Merge branch 'master' of github.com:jonasniesner/OpenEPaperLink 2023-09-02 11:38:48 +02:00
Jonas Niesner
bbe903bf90 Led LUT for M3 2023-09-02 11:36:07 +02:00
Nic Limper
73ecdd09b4 tiny bugfixes 2023-09-02 11:17:42 +02:00
Jonas Niesner
2674b733db Merge branch 'jjwbruijn:master' into master 2023-09-01 20:17:06 +02:00
Nic Limper
b919445ecc highspeed communication between S3<>C6 2023-08-31 21:10:36 +02:00
Nic Limper
eba0ea8a89 simple http call to test the led flasher 2023-08-31 20:12:49 +02:00
Nic Limper
15719126b8 render raw preview files within the file editor 2023-08-31 12:19:04 +02:00
Nic Limper
e45693bfe0 new version of 88MZ100 7.4" tag firmware + patch_mac.py for easy mac change
No need for HxD anymore for this firmware. See https://github.com/jjwbruijn/OpenEPaperLink/wiki/88MZ100-Programming-and-interfacing
2023-08-31 02:44:34 +02:00
Nic Limper
ab83cb03cc improvements for yellow ap / esp32-c6
- Wifi connection progress is now visible on the TFT
- passthrough serial logging from the C6 to the S3 terminal for easier debugging
- no checks on force_flash and APtag-firmware version when C6 is used
2023-08-31 02:13:45 +02:00
Nic Limper
714f7fffae clean up
- removed the custom printf function (inherited from the zbs code, but easier to just use the native printf)
- led flash timer
- proper HW_TYPE set, now reported as 0xC6
2023-08-30 22:20:08 +02:00
Nic Limper
9929d1646f small fixes
- fixed context menu position
- fixed free space sometimes displays 0
- added 12 byte payload to sendCommand
2023-08-29 22:11:05 +02:00
Jonas Niesner
b423ed4163 Update build-test.yml 2023-08-29 18:45:22 +02:00
Jonas Niesner
71d8aba77a NFC + button wake and LED 2023-08-28 15:41:19 +02:00
Jonas Niesner
81f5345237 Improved M3 firmware try 6 2023-08-28 13:54:59 +02:00
Jonas Niesner
bfe3561553 Improved M3 firmware try 5 2023-08-28 13:04:11 +02:00
Jonas Niesner
66a6a204c1 Improved M3 firmware try 2 2023-08-28 12:49:29 +02:00
Jonas Niesner
a6af0deaab Improved M3 firmware 2023-08-28 12:43:40 +02:00
Nic Limper
c9cc33f3d6 Update README.md 2023-08-27 22:34:40 +02:00
Jelmer
57c9962a67 fixed an especially dumb mistake in the tag flashr 2023-08-26 22:32:29 +02:00
Jelmer
c1e53e7c4f Merge branch 'master' of https://github.com/jjwbruijn/OpenEPaperLink 2023-08-26 22:21:10 +02:00
Jelmer
505e3d38af improved nRF flashing 2023-08-26 22:21:03 +02:00
Jelmer
00432bd9b5 Merge pull request #118 from kquinsland/bug/c6-include-path-fix
Make path to `soc/lp_uart_reg.{c,h}` consistent
2023-08-26 21:34:30 +02:00
karl
3a1c34f3a6 Make path to soc/lp_uart_reg.{c,h} consistent
Using _just_ the `/` character makes the paths "universal".

On *nix, `/` is the path separator and windows has support for `/` internally.
2023-08-26 12:32:24 -07:00
Jelmer
51087fa400 Merge pull request #116 from kquinsland/feat/add-m3-2.2-jig
Add my 2.2 inch pogo jig
2023-08-26 21:19:59 +02:00
Karl Quinsalnd
073972875a Add my 2.2 inch pogo jig 2023-08-26 12:10:05 -07:00
Jelmer
de38662a2a New clamp design 2.9 2023-08-26 20:48:26 +02:00
Jelmer
69bf4fe036 M3-2.2 Jig 2023-08-26 13:09:11 +02:00
Jelmer
fcedb8256a Merge branch 'master' of https://github.com/jjwbruijn/OpenEPaperLink 2023-08-24 22:57:06 +02:00
Jelmer
6252f81888 Added some M2 7.5 stuff 2023-08-24 22:57:02 +02:00
Jelmer
3223d7c861 Another update on the readme for tag flasher 2023-08-24 22:20:43 +02:00
Jelmer
99a36c4eb8 Updated Tag-Flasher README.md 2023-08-24 22:10:35 +02:00
Jelmer
3c77e375d9 Added the tag-flasher 2023-08-24 21:37:32 +02:00
Jelmer
891b7a83be Tag_Flasher README.md 2023-08-24 21:16:30 +02:00
Nic Limper
09f6f7b4b1 small fix in ota.js 2023-08-24 12:59:31 +02:00
Jelmer
ec7bac1f34 Moved flasher script, added support for 88mz100 2023-08-23 12:52:58 +02:00
Nic Limper
0df91096c2 little oops 2023-08-23 01:35:48 +02:00
Nic Limper
79efe473bf various small fixes
- clean up webproxy getExtUrl
- bugfix init multicast on wifi reconnect
- add ip address of remote AP that's taken over a tag
- renamed button 'edit contentFS' to 'file system'
2023-08-23 01:29:52 +02:00
Nic Limper
034521682c get rid of using eps32 as web proxy 2023-08-22 17:05:23 +02:00
Nic Limper
9ad847eb53 Update content_cards.json.gz 2023-08-22 13:15:03 +02:00
Nic Limper
f268c48717 add wifi events to log.txt 2023-08-22 13:06:42 +02:00
Nic Limper
a0ebf0d255 weather values in fahrenheit/mph 2023-08-21 01:05:43 +02:00
Nic Limper
6fcfe02b28 updated .gz-files for www folder 2023-08-20 20:18:58 +02:00
Nic Limper
2edbf27033 various fixes / sleep at night / resend image at tag boot
- apconfig: configure night time, where the system is not updating tags, and the tags are sleeping
- fixed bug calculating expected checkin
- throttle down apinfo update to once per minute
- fixed too many concurrent requests getting tagtypes
- resend current image when a tag reboots and the content type is 'static image' (all other content types were already regenerating the content)
- fixed timing of main loop
2023-08-20 20:16:34 +02:00
Nic Limper
46fb23b70f drop json files to a tagcard + small fixes 2023-08-19 20:31:25 +02:00
Moritz Wirger
fce6c16153 Optimize tagDB and reduce RAM usage (#113)
* Reduce code size by removing nullptr assignments

* Optimize tagDB for loops

* More tagDB optimizations

* Remove static from language arrays reducing RAM by 5128b

- Reduces Flash by 13060b

* Add missing extern in tag_db.h

* Fix deprecation warning of sntp.h

* Remove static from contentmanager, reduces RAM by 184b

* Use string reference in prepareDataAvail

- Remove some unneeded buffers
- Remove some gotos
2023-08-17 10:06:21 +02:00
atc1441
a31e1453d0 Now resending the Pending data on Reset of the Connected AP 2023-08-15 13:49:09 +02:00
Nic Limper
d17502cb63 contextmenu: right-click on a tagcard 2023-08-15 12:42:59 +02:00
atc1441
828679b6f3 Update README.md 2023-08-14 23:43:23 +02:00
atc1441
bff6794303 Added Yellow AP Gerber files 2023-08-14 21:40:34 +02:00
atc1441
2f86ea54d0 Precompiled ESP32-C6 AP 2023-08-14 21:28:03 +02:00
atc1441
80e0d9e5dd Added ESP32-C6 AP Release :) 2023-08-14 21:25:38 +02:00
atc1441
4d8cfeae63 Added nRF52811 AP Port 2023-08-14 12:12:44 +02:00
atc1441
3271f399c9 Auto template for AP Display disabled as currently to many refreshes break and reset the AP 2023-08-14 12:02:32 +02:00
atc1441
862c08c00b Set AP Info screen as default template on boot again to know IP of AP 2023-08-13 22:43:59 +02:00
Nic Limper
77cbf92281 bugfix getlocation 2023-08-13 01:48:32 +02:00
Moritz Wirger
c4022e45f9 Fix weather icons exception (#114) 2023-08-13 01:00:47 +02:00
atc1441
a13c220565 Fixed countdown via negative count value 2023-08-12 21:43:37 +02:00
Nic Limper
3989ecc3a3 bugfix date display 2023-08-12 21:17:08 +02:00
Nic Limper
cb0f029900 Update build-test.yml
don't build all small variations. Just the minor platforms, the rest will work.
2023-08-12 21:11:33 +02:00
Nic Limper
443714e9dc build fixes 2023-08-12 20:58:25 +02:00
Nic Limper
f3f163fa00 Revert "Ziped web files"
This reverts commit 8848cfc0f8.
2023-08-12 20:19:01 +02:00
Bot
8848cfc0f8 Ziped web files 2023-08-12 17:16:45 +00:00
22811 changed files with 435695 additions and 2621102 deletions

View File

@@ -19,7 +19,15 @@ jobs:
python-version: '3.9'
- name: Install PlatformIO Core
run: pip install --upgrade platformio
- name: Install intelhex
run: pip install --upgrade intelhex
- name: Build NRF firmware
run: |
cd ARM_Tag_FW/Newton_M3_nRF52811
pio run --environment Newton_M3_Universal
- name: Build Simple_AP
run: |
cd ESP32_AP-Flasher
@@ -31,12 +39,6 @@ jobs:
cd ESP32_AP-Flasher
pio run --environment OpenEPaperLink_Mini_AP
pio run --target buildfs --environment OpenEPaperLink_Mini_AP
- name: Build OpenEPaperLink_Nano_AP
run: |
cd ESP32_AP-Flasher
pio run --environment OpenEPaperLink_Nano_AP
pio run --target buildfs --environment OpenEPaperLink_Nano_AP
- name: Build OpenEPaperLink_AP_and_Flasher
run: |
@@ -44,38 +46,8 @@ jobs:
pio run --environment OpenEPaperLink_AP_and_Flasher
pio run --target buildfs --environment OpenEPaperLink_AP_and_Flasher
- name: Build Wemos_d1_mini32_AP
run: |
cd ESP32_AP-Flasher
pio run --environment Wemos_d1_mini32_AP
pio run --target buildfs --environment Wemos_d1_mini32_AP
- name: Build M5Stack_Core_ONE_AP
run: |
cd ESP32_AP-Flasher
pio run --environment M5Stack_Core_ONE_AP
pio run --target buildfs --environment M5Stack_Core_ONE_AP
- name: Build ESP32_S3_16_8_YELLOW_AP]
run: |
cd ESP32_AP-Flasher
pio run --environment ESP32_S3_16_8_YELLOW_AP
pio run --target buildfs --environment ESP32_S3_16_8_YELLOW_AP
- name: Build Sonoff_zb_bridge_P_AP
run: |
cd ESP32_AP-Flasher
pio run --environment Sonoff_zb_bridge_P_AP
pio run --target buildfs --environment Sonoff_zb_bridge_P_AP
- name: Build OpenEPaperLink_CC1352P
run: |
cd ESP32_AP-Flasher
pio run --environment OpenEPaperLink_CC1352P
pio run --target buildfs --environment OpenEPaperLink_CC1352P
- name: OutdoorAP
run: |
cd ESP32_AP-Flasher
pio run --environment OutdoorAP
pio run --target buildfs --environment OutdoorAP

View File

@@ -21,27 +21,30 @@ jobs:
with:
python-version: '3.9'
- name: Zip web files
run: |
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_AP-Flasher
python gzip_wwwfiles.py
- name: Commit zipped files
run: |
git config --global user.name 'Bot'
git config --global user.email "bot@openepaperlink.de"
git commit -am "Ziped web files"
git push origin HEAD:master
# - name: Commit zipped files
# run: |
# git config --global user.name 'Bot'
# git config --global user.email "bot@openepaperlink.de"
# git commit -am "Zipped web files"
# git push origin HEAD:master
- name: Install PlatformIO Core
run: pip install --upgrade platformio
- name: Install intelhex
run: pip install --upgrade intelhex
- name: Install esptool
run: pip install esptool
- name: create folders
run: |
mkdir espbinaries
# - name: Zip web files
# run: |
# cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_AP-Flasher
# python gzip_wwwfiles.py
- name: Build firmware for Simple_AP
run: |
@@ -61,42 +64,6 @@ jobs:
cp Simple_AP/firmware.bin espbinaries/Simple_AP.bin
cp Simple_AP/merged-firmware.bin espbinaries/Simple_AP_full.bin
- name: Build firmware for Wemos_d1_mini32_AP
run: |
cd ESP32_AP-Flasher
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
pio run --environment Wemos_d1_mini32_AP
pio run --target buildfs --environment Wemos_d1_mini32_AP
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP/boot_app0.bin
cp .pio/build/Wemos_d1_mini32_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP/firmware.bin
cp .pio/build/Wemos_d1_mini32_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP/bootloader.bin
cp .pio/build/Wemos_d1_mini32_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP/partitions.bin
cp .pio/build/Wemos_d1_mini32_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP/littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP
esptool.py --chip esp32 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin 0x290000 littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
cp Wemos_d1_mini32_AP/firmware.bin espbinaries/Wemos_d1_mini32_AP.bin
cp Wemos_d1_mini32_AP/merged-firmware.bin espbinaries/Wemos_d1_mini32_AP_full.bin
- name: Build firmware for M5Stack_Core_ONE_AP
run: |
cd ESP32_AP-Flasher
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
pio run --environment M5Stack_Core_ONE_AP
pio run --target buildfs --environment M5Stack_Core_ONE_AP
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP/boot_app0.bin
cp .pio/build/M5Stack_Core_ONE_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP/firmware.bin
cp .pio/build/M5Stack_Core_ONE_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP/bootloader.bin
cp .pio/build/M5Stack_Core_ONE_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP/partitions.bin
cp .pio/build/M5Stack_Core_ONE_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP/littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP
esptool.py --chip esp32 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin 0x2B0000 littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
cp M5Stack_Core_ONE_AP/firmware.bin espbinaries/M5Stack_Core_ONE_AP.bin
cp M5Stack_Core_ONE_AP/merged-firmware.bin espbinaries/M5Stack_Core_ONE_AP_full.bin
- name: Build firmware for OpenEPaperLink_Mini_AP
run: |
cd ESP32_AP-Flasher
@@ -132,6 +99,10 @@ jobs:
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
cp OpenEPaperLink_Nano_AP/firmware.bin espbinaries/OpenEPaperLink_Nano_AP.bin
cp OpenEPaperLink_Nano_AP/merged-firmware.bin espbinaries/OpenEPaperLink_Nano_AP_full.bin
# - name: move files for big APs
# run: |
# cp -a binaries/ESP32-C6/. ESP32_AP-Flasher/data/
- name: Build firmware for OpenEPaperLink_AP_and_Flasher
run: |
@@ -150,12 +121,66 @@ jobs:
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: Build firmware for ESP32_S3_16_8_YELLOW_AP
run: |
cd ESP32_AP-Flasher
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
pio run --environment ESP32_S3_16_8_YELLOW_AP
pio run --target buildfs --environment ESP32_S3_16_8_YELLOW_AP
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_YELLOW_AP
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_YELLOW_AP/boot_app0.bin
cp .pio/build/ESP32_S3_16_8_YELLOW_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_YELLOW_AP/firmware.bin
cp .pio/build/ESP32_S3_16_8_YELLOW_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_YELLOW_AP/bootloader.bin
cp .pio/build/ESP32_S3_16_8_YELLOW_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_YELLOW_AP/partitions.bin
cp .pio/build/ESP32_S3_16_8_YELLOW_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_YELLOW_AP/littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_YELLOW_AP
esptool.py --chip esp32-s3 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 80m --flash_size 16MB 0x0000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin 0x00910000 littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
cp ESP32_S3_16_8_YELLOW_AP/firmware.bin espbinaries/ESP32_S3_16_8_YELLOW_AP.bin
cp ESP32_S3_16_8_YELLOW_AP/merged-firmware.bin espbinaries/ESP32_S3_16_8_YELLOW_AP_full.bin
- name: Build firmware for ESP32_S3_C6_NANO_AP
run: |
cd ESP32_AP-Flasher
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
pio run --environment ESP32_S3_C6_NANO_AP
pio run --target buildfs --environment ESP32_S3_C6_NANO_AP
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP/boot_app0.bin
cp .pio/build/ESP32_S3_C6_NANO_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP/firmware.bin
cp .pio/build/ESP32_S3_C6_NANO_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP/bootloader.bin
cp .pio/build/ESP32_S3_C6_NANO_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP/partitions.bin
cp .pio/build/ESP32_S3_C6_NANO_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP/littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP
esptool.py --chip esp32-s3 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 80m --flash_size 16MB 0x0000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin 0x00910000 littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
cp ESP32_S3_C6_NANO_AP/firmware.bin espbinaries/ESP32_S3_C6_NANO_AP.bin
cp ESP32_S3_C6_NANO_AP/merged-firmware.bin espbinaries/ESP32_S3_C6_NANO_AP_full.bin
- name: Build firmware for OpenEPaperLink_PoE_AP
run: |
cd ESP32_AP-Flasher
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
pio run --environment OpenEPaperLink_PoE_AP
pio run --target buildfs --environment OpenEPaperLink_PoE_AP
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP/boot_app0.bin
cp .pio/build/OpenEPaperLink_PoE_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP/firmware.bin
cp .pio/build/OpenEPaperLink_PoE_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP/bootloader.bin
cp .pio/build/OpenEPaperLink_PoE_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP/partitions.bin
cp .pio/build/OpenEPaperLink_PoE_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP/littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP
esptool.py --chip esp32 merge_bin -o merged-firmware.bin --flash_mode qio --flash_freq 80m --flash_size 16MB 0x0000 bootloader.bin 0x8000 partitions.bin 0xD000 boot_app0.bin 0x10000 firmware.bin 0x410000 littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
cp OpenEPaperLink_PoE_AP/firmware.bin espbinaries/OpenEPaperLink_PoE_AP.bin
cp OpenEPaperLink_PoE_AP/merged-firmware.bin espbinaries/OpenEPaperLink_PoE_AP_full.bin
- name: generate release json file
run: |
mkdir jsonfiles
python genfilelist.py ${{ github.ref_name }} $GITHUB_REPOSITORY $GITHUB_SHA
- name: Add file lists to release
uses: svenstaro/upload-release-action@v2
with:
@@ -164,7 +189,27 @@ jobs:
tag: ${{ github.ref }}
file_glob: true
overwrite: true
# this is down here intentionally to be able to modify the binary folder before adding it to the Tag_Flasher later (ota binaries can be removed)
- name: Build firmware for Tag_Flasher
run: |
cd Tag_Flasher/ESP32_Flasher
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
pio run --environment S2_Tag_Flasher
pio run --target buildfs --environment S2_Tag_Flasher
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/S2_Tag_Flasher
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/S2_Tag_Flasher/boot_app0.bin
cp .pio/build/S2_Tag_Flasher/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/S2_Tag_Flasher/firmware.bin
cp .pio/build/S2_Tag_Flasher/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/S2_Tag_Flasher/bootloader.bin
cp .pio/build/S2_Tag_Flasher/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/S2_Tag_Flasher/partitions.bin
cp .pio/build/S2_Tag_Flasher/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/S2_Tag_Flasher/littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/S2_Tag_Flasher
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 S2_Tag_Flasher/firmware.bin espbinaries/S2_Tag_Flasher.bin
cp S2_Tag_Flasher/merged-firmware.bin espbinaries/S2_Tag_Flasher_full.bin
- name: Add esp bins to release
uses: svenstaro/upload-release-action@v2
with:
@@ -173,36 +218,3 @@ jobs:
tag: ${{ github.ref }}
file_glob: true
overwrite: true
- name: Add tag bins to release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: binaries/*
tag: ${{ github.ref }}
file_glob: true
overwrite: true
# - name: Add www folder to release
# uses: svenstaro/upload-release-action@v2
# with:
# repo_token: ${{ secrets.GITHUB_TOKEN }}
# file: ESP32_AP-Flasher/data/www/*
# tag: ${{ github.ref }}
# file_glob: true
# - name: Add fonts folder to release
# uses: svenstaro/upload-release-action@v2
# with:
# repo_token: ${{ secrets.GITHUB_TOKEN }}
# file: ESP32_AP-Flasher/data/fonts/*
# tag: ${{ github.ref }}
# file_glob: true
# - name: Add data folder to release
# uses: svenstaro/upload-release-action@v2
# with:
# repo_token: ${{ secrets.GITHUB_TOKEN }}
# file: ESP32_AP-Flasher/data/*
# tag: ${{ github.ref }}
# file_glob: true

3
.gitignore vendored
View File

@@ -23,3 +23,6 @@
*.bin
*.lk
*.o
sdcc/sdcc
ESP32_AP-Flasher/.vscode/extensions.json

View File

@@ -49,8 +49,8 @@ compile:
@$(CC) $(CC_FlAGS) -c mz100_aon_ram.c -o build/mz100_aon_ram.o
@$(CC) $(CC_FlAGS) -c printf.c -o build/printf.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c zigbee.c -o build/zigbee.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c ccm.c -o build/ccm.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c chars.c -o build/chars.o
# @$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c ccm.c -o build/ccm.o
# @$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c chars.c -o build/chars.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c drawing.c -o build/drawing.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c powermgt.c -o build/powermgt.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c syncedproto.c -o build/syncedproto.o
@@ -62,7 +62,7 @@ compile:
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c epd.c -o build/epd.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c userinterface.c -o build/userinterface.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c main.c -o build/main.o
@$(CC) $(CC_END_FLAGS) $(CC_WARNING_FLAGS) build/main.o build/userinterface.o build/printf.o build/mz100_aon_ram.o build/zigbee.o build/chars.o build/drawing.o build/powermgt.o build/syncedproto.o build/comms.o build/settings.o build/timer.o build/util.o build/gpio.o build/epd.o build/mz100_sleep.o build/core_cm3.o build/mz100_ssp.o build/mz100_wdt.o build/mz100_gpio.o build/mz100_driver.o build/mz100_adc.o build/mz100_flash.o build/mz100_clock.o build/mz100_rtc.o build/mz100_pinmux.o build/mz100_pmu.o build/mz100_qspi.o build/mz100_aes.o build/mz100_gpt.o build/mz100_uart.o build/startup.o -o main.axf
@$(CC) $(CC_END_FLAGS) $(CC_WARNING_FLAGS) build/main.o build/userinterface.o build/printf.o build/mz100_aon_ram.o build/zigbee.o build/drawing.o build/powermgt.o build/syncedproto.o build/comms.o build/settings.o build/timer.o build/util.o build/gpio.o build/epd.o build/mz100_sleep.o build/core_cm3.o build/mz100_ssp.o build/mz100_wdt.o build/mz100_gpio.o build/mz100_driver.o build/mz100_adc.o build/mz100_flash.o build/mz100_clock.o build/mz100_rtc.o build/mz100_pinmux.o build/mz100_pmu.o build/mz100_qspi.o build/mz100_aes.o build/mz100_gpt.o build/mz100_uart.o build/startup.o -o main.axf
@$(OBJCOPY) -v -O binary main.axf main.bin
clean:

379
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/bitmaps.h Normal file → Executable file
View File

@@ -6,293 +6,102 @@
#include "screen.h"
static const uint8_t oepli[] = {
128, 26,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1c, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x9f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x70, 0x01, 0xc0,
0x7f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x9f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x70, 0x01, 0xc0,
0x7f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x9f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x70, 0x01, 0xc0,
0xf7, 0x80, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0xc0,
0xe3, 0x80, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0xc0,
0xe3, 0x9d, 0xc1, 0xc7, 0x70, 0x1f, 0x9c, 0xe7, 0x73, 0xb8, 0x71, 0xd0, 0x38, 0x73, 0xb9, 0xc7,
0xe3, 0x9f, 0xe3, 0xe7, 0xf8, 0x1f, 0x9f, 0xef, 0xf3, 0xfc, 0xf9, 0xf0, 0x38, 0x73, 0xfd, 0xce,
0xe3, 0x9f, 0xe7, 0x77, 0xf8, 0x1f, 0x9f, 0xcf, 0xf3, 0xfd, 0xdd, 0xf0, 0x38, 0x73, 0xfd, 0xdc,
0xe3, 0x9c, 0xe7, 0xf7, 0x38, 0x1c, 0x1f, 0x8e, 0x73, 0x9d, 0xfd, 0xc0, 0x38, 0x73, 0x9d, 0xf8,
0xe3, 0x9c, 0xe7, 0xf7, 0x38, 0x1c, 0x1c, 0x0e, 0x73, 0x9d, 0xfd, 0xc0, 0x38, 0x73, 0x9d, 0xf8,
0xf7, 0x9c, 0xe7, 0x07, 0x38, 0x1c, 0x1c, 0x0e, 0x73, 0x9d, 0xc1, 0xc0, 0x38, 0x73, 0x9d, 0xdc,
0x7f, 0x1f, 0xe7, 0xf7, 0x38, 0x1f, 0x9c, 0x0f, 0xf3, 0xfd, 0xfd, 0xc0, 0x3f, 0x73, 0x9d, 0xdc,
0x7f, 0x1f, 0xe3, 0xe7, 0x38, 0x1f, 0x9c, 0x0f, 0xf3, 0xfc, 0xf9, 0xc0, 0x3f, 0x73, 0x9d, 0xce,
0x1e, 0x1d, 0xc1, 0xc7, 0x38, 0x1f, 0x9c, 0x07, 0x73, 0xb8, 0x71, 0xc0, 0x3f, 0x73, 0x9d, 0xc7,
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
const uint8_t norf[] = {
24,
24,
0x00,
0x00,
0x00,
0x70,
0xe0,
0x00,
0x79,
0xe0,
0x00,
0x7f,
0xe0,
0x00,
0x3f,
0xc0,
0x00,
0x1f,
0x80,
0x00,
0x1f,
0x80,
0x00,
0x3f,
0xc0,
0x00,
0x7f,
0xe0,
0x0e,
0x79,
0xe0,
0x0a,
0x70,
0xe0,
0x0a,
0x00,
0x00,
0xea,
0x00,
0x00,
0xaa,
0x00,
0x00,
0xaa,
0x00,
0x0e,
0xaa,
0x00,
0x0a,
0xaa,
0x00,
0x0a,
0xaa,
0x00,
0xea,
0xaa,
0x00,
0xaa,
0xaa,
0x00,
0xaa,
0xaa,
0x0e,
0xaa,
0xaa,
0x0a,
0xaa,
0xaa,
0x0e,
0xee,
0xee,
0x00,
0x00,
0x00,
};
static const uint8_t cloud[] = {
128, 50,
0x00, 0x08, 0x82, 0xa2, 0xab, 0x55, 0xbf, 0xff, 0xff, 0xff, 0x7d, 0xb4, 0x62, 0x28, 0x00, 0x00,
0x00, 0x10, 0x10, 0x11, 0x76, 0xff, 0x7b, 0xff, 0xff, 0x7f, 0xb7, 0xa9, 0x55, 0x50, 0x51, 0x00,
0x00, 0x29, 0x22, 0x96, 0x6f, 0xf7, 0xbf, 0xff, 0xff, 0xff, 0xea, 0xe6, 0x22, 0xaa, 0x08, 0x00,
0x00, 0x02, 0x54, 0x2a, 0xbf, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xfd, 0x59, 0xb4, 0x10, 0x20, 0x00,
0x00, 0x24, 0x23, 0xb5, 0xb5, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xae, 0x48, 0x55, 0x10, 0x00,
0x00, 0x88, 0x90, 0x54, 0x6a, 0xef, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xf5, 0xa3, 0x82, 0x00, 0x00,
0x00, 0x01, 0x2d, 0xa3, 0xb3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xbe, 0x4e, 0x52, 0x09, 0x00,
0x04, 0x90, 0x02, 0x0d, 0x55, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xdd, 0x68, 0xa9, 0x00, 0x10,
0x00, 0x49, 0x0c, 0xfb, 0xab, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xeb, 0x95, 0x5a, 0x00, 0x20,
0x00, 0x12, 0x91, 0x22, 0xbf, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, 0x65, 0x81, 0x40, 0x40,
0x00, 0x28, 0x12, 0x7d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xab, 0x28, 0x00, 0x00,
0x00, 0x42, 0x0a, 0x97, 0x75, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x4a, 0xc2, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x08, 0x02, 0x9c, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6a, 0x6a, 0x8d, 0x00, 0x20,
0x00, 0x04, 0x4d, 0x72, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0xd5, 0x74, 0x80, 0x00,
0x02, 0x40, 0x12, 0x8e, 0xdf, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xae, 0xaa, 0x0a, 0x11, 0x20,
0x00, 0x20, 0x52, 0x5f, 0xf5, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x72, 0x94, 0xaa, 0x24, 0x00,
0x00, 0x01, 0x0a, 0xab, 0x6f, 0x77, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xaf, 0x54, 0x54, 0x88, 0x00,
0x00, 0x04, 0x80, 0x4d, 0x95, 0xeb, 0xff, 0xff, 0xff, 0xff, 0x5b, 0x58, 0xb5, 0x51, 0x40, 0x00,
0x00, 0x08, 0x08, 0xa6, 0xb3, 0xf7, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xad, 0x4a, 0xa0, 0x10, 0x00,
0x00, 0x02, 0x96, 0x41, 0xdc, 0xae, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xbf, 0xea, 0x48, 0x02, 0x00,
0x00, 0x00, 0x09, 0x3e, 0xab, 0x75, 0xef, 0xff, 0xff, 0xff, 0xff, 0xd4, 0xb1, 0x21, 0x08, 0x00,
0x00, 0x00, 0x0a, 0xc3, 0x5d, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xef, 0xef, 0x44, 0x4a, 0x64, 0x80,
0x00, 0x00, 0xa1, 0x52, 0xa6, 0xef, 0xef, 0xff, 0xff, 0xff, 0xd6, 0xca, 0xf5, 0x10, 0x18, 0x00,
0x00, 0x00, 0x02, 0x15, 0x4b, 0xd5, 0xdf, 0xff, 0xff, 0xf7, 0xeb, 0xd4, 0xd8, 0x85, 0x00, 0x00,
static const uint8_t batlow[] = {
24,17,
0x00, 0x00, 0x00,
0x7f, 0xff, 0xf8,
0x40, 0x00, 0x08,
0x40, 0x00, 0x08,
0x40, 0x00, 0x0e,
0x40, 0x00, 0x0a,
0x48, 0x00, 0x0a,
0x48, 0x00, 0x0a,
0x48, 0x64, 0x4a,
0x48, 0x94, 0x4a,
0x48, 0x95, 0x4a,
0x4e, 0x62, 0x8a,
0x40, 0x00, 0x0e,
0x40, 0x00, 0x08,
0x40, 0x00, 0x08,
0x7f, 0xff, 0xf8,
0x00, 0x00, 0x00,
};
static const uint8_t receive[] = {
56, 56,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0,
0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0,
0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0,
0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0,
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xf0,
0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0,
0x00, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xc0, 0x00, 0x03, 0xe0,
0x00, 0x00, 0x7f, 0x80, 0x00, 0x7f, 0xf0,
0x00, 0x00, 0xfe, 0x00, 0x03, 0xff, 0xf0,
0x00, 0x01, 0xfc, 0x00, 0x0f, 0xff, 0xf0,
0x00, 0x01, 0xf8, 0x00, 0x3f, 0xff, 0xf0,
0x00, 0x03, 0xf8, 0x00, 0xff, 0xff, 0x80,
0x00, 0x07, 0xf0, 0x01, 0xff, 0xe0, 0x00,
0x00, 0x0f, 0xe0, 0x03, 0xff, 0x00, 0x00,
0x00, 0x0f, 0xc0, 0x0f, 0xf8, 0x00, 0x00,
0x00, 0x1f, 0x80, 0x1f, 0xf0, 0x00, 0x00,
0x00, 0x1f, 0x80, 0x3f, 0xc0, 0x00, 0x00,
0x00, 0x3f, 0x00, 0x3f, 0x80, 0x00, 0x00,
0x00, 0x3f, 0x00, 0x7f, 0x00, 0x00, 0x00,
0x00, 0x7e, 0x00, 0xfe, 0x00, 0x07, 0xe0,
0x00, 0x7e, 0x01, 0xfc, 0x00, 0x1f, 0xf0,
0x00, 0xfc, 0x01, 0xf8, 0x00, 0x7f, 0xf0,
0x00, 0xfc, 0x03, 0xf0, 0x01, 0xff, 0xf0,
0x00, 0xf8, 0x03, 0xf0, 0x03, 0xff, 0xf0,
0x01, 0xf8, 0x07, 0xe0, 0x07, 0xff, 0x00,
0x01, 0xf8, 0x07, 0xe0, 0x0f, 0xf0, 0x00,
0x01, 0xf0, 0x0f, 0xc0, 0x1f, 0xe0, 0x00,
0x01, 0xf0, 0x0f, 0xc0, 0x3f, 0x80, 0x00,
0x03, 0xf0, 0x0f, 0x80, 0x3f, 0x00, 0x00,
0x03, 0xf0, 0x1f, 0x80, 0x7e, 0x00, 0x00,
0x03, 0xe0, 0x1f, 0x80, 0x7e, 0x00, 0x00,
0x03, 0xe0, 0x1f, 0x00, 0xfc, 0x01, 0xe0,
0x03, 0xe0, 0x1f, 0x00, 0xfc, 0x07, 0xf8,
0x03, 0xe0, 0x1f, 0x00, 0xf8, 0x0f, 0xfc,
0x03, 0xe0, 0x3f, 0x00, 0xf8, 0x0f, 0xfc,
0x03, 0xe0, 0x3f, 0x01, 0xf8, 0x1f, 0xfe,
0x03, 0xe0, 0x3f, 0x01, 0xf8, 0x1f, 0xfe,
0x03, 0xe0, 0x3f, 0x01, 0xf8, 0x1f, 0xfe,
0x03, 0xc0, 0x3e, 0x01, 0xf0, 0x1f, 0xfe,
0x01, 0xc0, 0x1e, 0x00, 0xf0, 0x0f, 0xfc,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const uint8_t failed[] = {
48, 48,
0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x03, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x7f, 0xf0, 0x0f, 0xfe, 0x00,
0x00, 0xff, 0x80, 0x01, 0xff, 0x00,
0x01, 0xfe, 0x00, 0x00, 0x7f, 0x80,
0x03, 0xf8, 0x00, 0x00, 0x1f, 0xc0,
0x07, 0xf0, 0x00, 0x00, 0x3f, 0xe0,
0x0f, 0xe0, 0x00, 0x00, 0x7f, 0xf0,
0x0f, 0xc0, 0x00, 0x00, 0xff, 0xf0,
0x1f, 0x80, 0x00, 0x01, 0xff, 0xf8,
0x1f, 0x00, 0x00, 0x03, 0xff, 0xf8,
0x3f, 0x00, 0x00, 0x07, 0xfe, 0xfc,
0x3e, 0x00, 0x00, 0x0f, 0xfc, 0x7c,
0x7e, 0x00, 0x00, 0x1f, 0xf8, 0x7e,
0x7c, 0x00, 0x00, 0x3f, 0xf0, 0x3e,
0x7c, 0x00, 0x00, 0x7f, 0xe0, 0x3e,
0xfc, 0x00, 0x00, 0xff, 0xc0, 0x3f,
0xf8, 0x00, 0x01, 0xff, 0x80, 0x1f,
0xf8, 0x00, 0x03, 0xff, 0x00, 0x1f,
0xf8, 0x00, 0x07, 0xfe, 0x00, 0x1f,
0xf8, 0x00, 0x0f, 0xfc, 0x00, 0x1f,
0xf8, 0x00, 0x1f, 0xf8, 0x00, 0x1f,
0xf8, 0x00, 0x3f, 0xf0, 0x00, 0x1f,
0xf8, 0x00, 0x7f, 0xe0, 0x00, 0x1f,
0xf8, 0x00, 0xff, 0xc0, 0x00, 0x1f,
0xfc, 0x01, 0xff, 0x80, 0x00, 0x3f,
0x7c, 0x03, 0xff, 0x00, 0x00, 0x3e,
0x7c, 0x07, 0xfe, 0x00, 0x00, 0x3e,
0x7e, 0x0f, 0xfc, 0x00, 0x00, 0x7e,
0x3e, 0x1f, 0xf8, 0x00, 0x00, 0x7c,
0x3f, 0x3f, 0xf0, 0x00, 0x00, 0xfc,
0x3f, 0x7f, 0xe0, 0x00, 0x00, 0xfc,
0x1f, 0xff, 0xc0, 0x00, 0x01, 0xf8,
0x0f, 0xff, 0x80, 0x00, 0x03, 0xf0,
0x0f, 0xff, 0x00, 0x00, 0x07, 0xf0,
0x07, 0xfe, 0x00, 0x00, 0x0f, 0xe0,
0x03, 0xfc, 0x00, 0x00, 0x1f, 0xc0,
0x01, 0xfe, 0x00, 0x00, 0x7f, 0x80,
0x00, 0xff, 0x80, 0x01, 0xff, 0x00,
0x00, 0x7f, 0xf0, 0x0f, 0xfe, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x03, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00,
};
#if (SCREEN_WIDTH != 128)
static const uint8_t ant[] = {
16, 16,
0x00, 0x40,
0x02, 0x20,
0x01, 0x20,
0x11, 0x20,
0x11, 0x20,
0x12, 0x20,
0x28, 0x40,
0x28, 0x00,
0x28, 0x00,
0x44, 0x00,
0x44, 0x00,
0x44, 0x00,
0x44, 0x00,
0x82, 0x00,
0x82, 0x00,
0xfe, 0x00,
};
#else
static const uint8_t ant[] = {
// rotated 90 degrees
16,16,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x7c, 0x00,
0x82, 0x00,
0x00, 0x00,
0x38, 0x00,
0x44, 0x07,
0x00, 0x79,
0x03, 0x81,
0x1c, 0x01,
0x03, 0x81,
0x00, 0x79,
0x00, 0x07,
};
#endif
static const uint8_t cross[] = {
8,8,
0x00,
0x63,
0x77,
0x3e,
0x1c,
0x3e,
0x77,
0x63
};
#if (SCREEN_WIDTH != 128)
static const uint8_t battery[] = {
16,10,
0x00, 0x00,
0x7f, 0xfc,
0x40, 0x04,
0x58, 0x06,
0x58, 0x06,
0x58, 0x06,
0x58, 0x06,
0x40, 0x04,
0x7f, 0xfc,
0x00, 0x00,
};
#else
// this battery symbol is rotated 90'
static const uint8_t battery[] = {
16,16,
0x00, 0x00,
0x03, 0xc0,
0x0f, 0xf0,
0x08, 0x10,
0x08, 0x10,
0x08, 0x10,
0x08, 0x10,
0x08, 0x10,
0x08, 0x10,
0x08, 0x10,
0x08, 0x10,
0x0b, 0xd0,
0x0b, 0xd0,
0x08, 0x10,
0x0f, 0xf0,
0x00, 0x00,
};
#endif
#endif

View File

@@ -1,96 +0,0 @@
#include <string.h>
#include "mz100.h"
#include "mz100_aes.h"
#include "mz100_driver.h"
#include "ccm.h"
static bool aesCcmOp(void* dst, const void *src, uint16_t authSrcLen, uint16_t encSrcLen, const void *key, const void *nonce, bool dec)
{
uint32_t tempB, nBytesNoMic = authSrcLen + encSrcLen, nBytesIn, nBytesOut;
const uint32_t *inD = (const uint32_t*)src;
uint32_t *outD = (uint32_t*)dst;
uint_fast8_t i;
bool success;
if (dec) {
nBytesIn = nBytesNoMic + AES_CCM_MIC_SIZE;
nBytesOut = nBytesNoMic;
}
else {
nBytesIn = nBytesNoMic;
nBytesOut = nBytesNoMic + AES_CCM_MIC_SIZE;
}
do{
AES->CTRL1.WORDVAL |= 2;
} while (!(AES->STATUS.WORDVAL & 2));
AES->CTRL2.WORDVAL |= 1;
(void)AES->CTRL2.WORDVAL;
AES->CTRL2.WORDVAL &=~ 1;
AES->CTRL1.WORDVAL = 0x0005501e + (dec ? 0x8000 : 0);
AES->IMR.WORDVAL = 0xffffffff;
for(i = 0; i < 4; i++)
AES->KEY[7 - i].WORDVAL = ((uint32_t*)key)[i];
AES->MSTR_LEN.WORDVAL = encSrcLen;
AES->ASTR_LEN.WORDVAL = authSrcLen;
for(i = 0; i < 3; i++)
AES->IV[i].WORDVAL = ((uint32_t*)nonce)[i];
AES->IV[3].WORDVAL = ((uint8_t*)nonce)[12] + 0x200; //2 byte lengths
AES->CTRL1.WORDVAL |= 1;
while (nBytesIn || nBytesOut) {
if (!(AES->STATUS.WORDVAL & 0x10) && nBytesIn) {
if (nBytesIn >= 4) {
AES->STR_IN.WORDVAL = *inD++;
nBytesIn -= 4;
}
else {
memcpy(&tempB, inD, nBytesIn);
AES->STR_IN.WORDVAL = tempB;
nBytesIn = 0;
}
}
if ((AES->STATUS.WORDVAL & 0x40) && nBytesOut) {
if (nBytesOut >= 4) {
*outD++ = AES->STR_OUT.WORDVAL;
nBytesOut -= 4;
}
else {
tempB = AES->STR_OUT.WORDVAL;
memcpy(outD, &tempB, nBytesOut);
nBytesOut = 0;
}
}
}
success = !((AES->STATUS.WORDVAL >> 11) & 7);
AES->CTRL1.WORDVAL = 0;
return success;
}
void aesCcmEnc(void* dst, const void *src, uint16_t authSrcLen, uint16_t encSrcLen, const void *key, const void *nonce)
{
aesCcmOp(dst, src, authSrcLen, encSrcLen, key, nonce, false);
}
bool aesCcmDec(void* dst, const void *src, uint16_t authSrcLen, uint16_t encSrcLen, const void *key, const void *nonce)
{
return aesCcmOp(dst, src, authSrcLen, encSrcLen, key, nonce, true);
}

View File

@@ -1,20 +0,0 @@
#ifndef _CCM_H_
#define _CCM_H_
//CCM defined for T = 4 (mic is 4 bytes), Q = 2 (max data len 65536), N = 13( nonse is 13 bytes), 128-bit AES (16 bytes of key)
//no more than 0xff00 auth data bytes allowed
#include <stdbool.h>
#include <stdint.h>
#define AES_CCM_MIC_SIZE 4
#define AES_CCM_NONCE_SIZE 13
//encrypted data follows auth data. both in and out. 4 bytes of MIC appended on the encrypt path, checke don the decrypt path
void aesCcmEnc(void* dst, const void *src, uint16_t authSrcLen, uint16_t encSrcLen, const void *key, const void *nonce);
bool aesCcmDec(void* dst, const void *src, uint16_t authSrcLen, uint16_t encSrcLen, const void *key, const void *nonce);
#endif

View File

@@ -1,410 +0,0 @@
#include "eeprom.h"
#include "chars.h"
#include "mz100_flash.h"
#include "epd.h"
#define NUM_CHARS 256
#define CANVAS_FLIP_H 1
#define CANVAS_MSB_FIRST 1
const static uint8_t mCharsImgs[];
extern uint8_t mScreenRow[];
static void charsPrvDrawCharRow(uint8_t ch, int16_t x, uint8_t imgRow, uint8_t foreColor, uint8_t backColor, uint8_t mag)
{
uint8_t c, mc, charRow = imgRow / mag, bitMask = (1 << 4) - 1;
for (c = 0; c < CHAR_WIDTH; c++)
{ // iterate over the char's columns for this row
uint8_t imgCol = ((uint8_t)((uint8_t)CHAR_WIDTH * (uint8_t)ch) & 7) + c; // sort out where in the row our data begins
uint8_t color = ((mCharsImgs[(((CHAR_WIDTH * NUM_CHARS + 7) / 8 * charRow) + (CHAR_WIDTH * ch) / 8) + (imgCol >> 3)] >> (7 - (imgCol % 8))) & 1) ? foreColor : backColor; // get the color
if (color == CHAR_COLOR_TRANSPARENT)
continue;
for (mc = 0; mc < mag; mc++, x++)
{ // set the pixel
uint8_t *dst = mScreenRow;
uint8_t bitOfst;
uint16_t c = x;
if (x < 0)
continue;
if (x >= DISPLAY_WIDTH)
break;
#if CANVAS_FLIP_H
c = DISPLAY_WIDTH - c - 1;
#endif
dst += (c * 4) / 8;
bitOfst = (c * 4) % 8;
#if CANVAS_MSB_FIRST
bitOfst = 8 - bitOfst - 4;
#endif
*dst = ((*dst) & ~(bitMask << bitOfst)) | ((color & bitMask) << bitOfst);
}
}
}
void charsDrawString(const struct CharDrawingParams *params)
{
const char *s = params->str;
int16_t x = params->x;
uint8_t ch;
while ((ch = *s++) != 0)
{
charsPrvDrawCharRow(ch, x, params->imgRow, params->foreColor, params->backColor, params->magnify);
x += (uint16_t)(uint8_t)(CHAR_WIDTH * params->magnify);
}
}
const static uint8_t mCharsImgs[] = {
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0xf0, 0x0f, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x7e, 0x36,
0x3c, 0xd8, 0x38, 0x1c, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
0x1e, 0x0c, 0x3c, 0x3c, 0x30, 0x7e, 0x1c, 0x7e, 0x3c, 0x3c, 0x00, 0x00,
0x06, 0x00, 0x60, 0x3c, 0x7e, 0x18, 0x7c, 0x3c, 0x78, 0x7e, 0x7e, 0x3c,
0x66, 0x3c, 0x06, 0x66, 0x60, 0x63, 0x63, 0x3c, 0x7c, 0x3c, 0x7c, 0x3c,
0x7e, 0x66, 0x66, 0x63, 0x66, 0x66, 0x7e, 0x3c, 0x60, 0x3c, 0x66, 0x00,
0x0c, 0x00, 0x60, 0x00, 0x06, 0x00, 0x1e, 0x00, 0x60, 0x18, 0x0c, 0x60,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x30, 0x38, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3c, 0x7e, 0x36, 0x66, 0xda, 0x6c, 0x1c, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x06, 0x33, 0x1c, 0x66, 0x66, 0x30, 0x60, 0x18, 0x06,
0x66, 0x66, 0x00, 0x00, 0x0c, 0x00, 0x30, 0x66, 0xc3, 0x3c, 0x66, 0x66,
0x6c, 0x60, 0x60, 0x66, 0x66, 0x18, 0x06, 0x66, 0x60, 0x63, 0x63, 0x66,
0x66, 0x66, 0x66, 0x66, 0x18, 0x66, 0x66, 0x63, 0x66, 0x66, 0x06, 0x30,
0x60, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x06, 0x00, 0x30, 0x00,
0x60, 0x00, 0x00, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xdb, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x40,
0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7e, 0x7f, 0x60, 0x76, 0x6c, 0x0c,
0x18, 0x18, 0x36, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x37, 0x7c, 0x66, 0x66,
0x36, 0x60, 0x30, 0x0c, 0x66, 0x66, 0x1c, 0x1c, 0x18, 0x00, 0x18, 0x66,
0xc3, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x66, 0x66, 0x18, 0x06, 0x6c,
0x60, 0x77, 0x73, 0x66, 0x66, 0x66, 0x66, 0x60, 0x18, 0x66, 0x66, 0x63,
0x34, 0x66, 0x06, 0x30, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x3c, 0x7c, 0x3c,
0x3e, 0x3c, 0x30, 0x3e, 0x7c, 0x78, 0x3c, 0x66, 0x18, 0x7e, 0x7c, 0x3c,
0x7c, 0x3e, 0x66, 0x3e, 0x7e, 0x66, 0x66, 0x63, 0x66, 0x66, 0x7e, 0x18,
0x18, 0x18, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x87, 0xe1, 0x86, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7e, 0x36,
0x30, 0x0c, 0x38, 0x18, 0x30, 0x0c, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x0c,
0x37, 0x0c, 0x06, 0x06, 0x36, 0x60, 0x7c, 0x0c, 0x76, 0x66, 0x1c, 0x1c,
0x30, 0x7e, 0x0c, 0x0c, 0xcf, 0x66, 0x66, 0x60, 0x66, 0x60, 0x60, 0x60,
0x66, 0x18, 0x06, 0x6c, 0x60, 0x6b, 0x7b, 0x66, 0x66, 0x66, 0x66, 0x30,
0x18, 0x66, 0x66, 0x6b, 0x18, 0x66, 0x0c, 0x30, 0x30, 0x0c, 0x00, 0x00,
0x00, 0x06, 0x66, 0x66, 0x66, 0x66, 0x30, 0x66, 0x66, 0x18, 0x0c, 0x66,
0x18, 0x6b, 0x66, 0x66, 0x66, 0x66, 0x6e, 0x60, 0x30, 0x66, 0x66, 0x6b,
0x66, 0x66, 0x06, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x19, 0xd8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x7e, 0x36, 0x18, 0x18, 0x60, 0x00, 0x30, 0x0c, 0x7f, 0x7e,
0x00, 0x7e, 0x00, 0x18, 0x33, 0x0c, 0x0c, 0x1c, 0x36, 0x7c, 0x66, 0x18,
0x3c, 0x66, 0x00, 0x00, 0x60, 0x00, 0x06, 0x18, 0xdb, 0x66, 0x7c, 0x60,
0x66, 0x7c, 0x7c, 0x60, 0x7e, 0x18, 0x06, 0x78, 0x60, 0x6b, 0x6f, 0x66,
0x7c, 0x66, 0x7c, 0x18, 0x18, 0x66, 0x66, 0x6b, 0x18, 0x3c, 0x18, 0x30,
0x18, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x66, 0x60, 0x66, 0x66, 0x7e, 0x66,
0x66, 0x18, 0x0c, 0x6c, 0x18, 0x6b, 0x66, 0x66, 0x66, 0x66, 0x70, 0x60,
0x30, 0x66, 0x66, 0x6b, 0x3c, 0x66, 0x0c, 0x30, 0x18, 0x0c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x23,
0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x7e, 0x36, 0x0c, 0x30, 0x6f, 0x00,
0x30, 0x0c, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x18, 0x3b, 0x0c, 0x18, 0x06,
0x66, 0x06, 0x66, 0x18, 0x6e, 0x3e, 0x00, 0x00, 0x30, 0x7e, 0x0c, 0x18,
0xdb, 0x7e, 0x66, 0x60, 0x66, 0x60, 0x60, 0x6e, 0x66, 0x18, 0x06, 0x6c,
0x60, 0x6b, 0x67, 0x66, 0x60, 0x66, 0x6c, 0x0c, 0x18, 0x66, 0x66, 0x6b,
0x2c, 0x18, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x60,
0x66, 0x7e, 0x30, 0x66, 0x66, 0x18, 0x0c, 0x78, 0x18, 0x6b, 0x66, 0x66,
0x66, 0x66, 0x60, 0x3c, 0x30, 0x66, 0x66, 0x6b, 0x18, 0x66, 0x18, 0x60,
0x18, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x41, 0x82, 0x47, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7f,
0x06, 0x6e, 0x66, 0x00, 0x30, 0x0c, 0x36, 0x18, 0x00, 0x00, 0x00, 0x30,
0x3b, 0x0c, 0x30, 0x66, 0x7f, 0x06, 0x66, 0x30, 0x66, 0x0c, 0x00, 0x00,
0x18, 0x00, 0x18, 0x00, 0xcf, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x66,
0x66, 0x18, 0x66, 0x6c, 0x60, 0x63, 0x63, 0x66, 0x60, 0x66, 0x66, 0x06,
0x18, 0x66, 0x66, 0x36, 0x66, 0x18, 0x60, 0x30, 0x0c, 0x0c, 0x00, 0x00,
0x00, 0x66, 0x66, 0x60, 0x66, 0x60, 0x30, 0x66, 0x66, 0x18, 0x0c, 0x6c,
0x18, 0x6b, 0x66, 0x66, 0x66, 0x66, 0x60, 0x06, 0x30, 0x66, 0x66, 0x6b,
0x3c, 0x66, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x61, 0x8e, 0x61, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x7e, 0x36, 0x66, 0x5b, 0x66, 0x00, 0x30, 0x0c, 0x00, 0x00,
0x1c, 0x00, 0x1c, 0x30, 0x33, 0x0c, 0x60, 0x66, 0x06, 0x0c, 0x66, 0x30,
0x66, 0x18, 0x1c, 0x1c, 0x0c, 0x00, 0x30, 0x18, 0xc0, 0x66, 0x66, 0x66,
0x6c, 0x60, 0x60, 0x66, 0x66, 0x18, 0x66, 0x66, 0x60, 0x63, 0x63, 0x66,
0x60, 0x66, 0x66, 0x66, 0x18, 0x66, 0x3c, 0x36, 0x66, 0x18, 0x60, 0x30,
0x0c, 0x0c, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x60, 0x30, 0x66,
0x66, 0x18, 0x0c, 0x66, 0x18, 0x6b, 0x66, 0x66, 0x66, 0x66, 0x60, 0x06,
0x30, 0x66, 0x3c, 0x36, 0x66, 0x66, 0x60, 0x18, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x11, 0x9c,
0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x7e, 0x36, 0x3c, 0x1b, 0x3b, 0x00,
0x18, 0x18, 0x00, 0x00, 0x1c, 0x00, 0x1c, 0x60, 0x1e, 0x0c, 0x7e, 0x3c,
0x06, 0x78, 0x3c, 0x30, 0x3c, 0x38, 0x1c, 0x1c, 0x06, 0x00, 0x60, 0x18,
0x7f, 0x66, 0x7c, 0x3c, 0x78, 0x7e, 0x60, 0x3e, 0x66, 0x3c, 0x3c, 0x66,
0x7e, 0x63, 0x63, 0x3c, 0x60, 0x3c, 0x66, 0x3c, 0x18, 0x3c, 0x18, 0x36,
0x66, 0x18, 0x7e, 0x30, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x3e, 0x7c, 0x3c,
0x3e, 0x3c, 0x30, 0x3e, 0x66, 0x7e, 0x0c, 0x66, 0x7e, 0x63, 0x66, 0x3c,
0x7c, 0x3e, 0x60, 0x7c, 0x1e, 0x3e, 0x18, 0x36, 0x66, 0x3c, 0x7e, 0x18,
0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x08, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x0e, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x60,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x0c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0c, 0x00, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x88, 0x71, 0x88, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0xe3,
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0xc0, 0x43, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};

View File

@@ -1,31 +0,0 @@
#ifndef _CHARS_H_
#define _CHARS_H_
#include <stdbool.h>
#include <stdint.h>
#define CHAR_WIDTH 8
#define CHAR_HEIGHT 16
#define CHAR_COLOR_TRANSPARENT (0xff)
#define CHAR_SIGNAL_PT1 (1)
#define CHAR_SIGNAL_PT2 (2)
#define CHAR_NO_SIGNAL_PT1 (3)
#define CHAR_NO_SIGNAL_PT2 (4)
struct CharDrawingParams
{
const char *str;
int16_t x;
uint8_t imgRow;
uint8_t foreColor;
uint8_t backColor;
uint8_t magnify;
};
void charsDrawString(const struct CharDrawingParams *params);
#endif

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

@@ -1,10 +1,8 @@
#include "comms.h"
#include <stdint.h>
//#include <stdio.h>
#include <string.h>
#include "ccm.h"
#include <stdbool.h>
#include "proto.h"
extern uint8_t Zigbee_tx_buffer(uint8_t tx_buffer[], int len);

11
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/comms.h Normal file → Executable file
View File

@@ -2,28 +2,17 @@
#define _COMMS_H_
#include <stdint.h>
#include "ccm.h"
extern uint8_t mLastLqi;
extern int8_t mLastRSSI;
#define COMMS_MAX_RADIO_WAIT_MSEC 100
#define COMMS_IV_SIZE (4) //zeroes except these 4 counter bytes
#define COMMS_RX_ERR_NO_PACKETS (-1)
#define COMMS_RX_ERR_INVALID_PACKET (-2)
#define COMMS_RX_ERR_MIC_FAIL (-3)
#define COMMS_MAX_PACKET_SZ (127 /* max phy len */ - 21 /* max mac frame with panID compression */ - 2 /* FCS len */ - AES_CCM_MIC_SIZE - COMMS_IV_SIZE)
uint8_t commsGetLastPacketLQI(void);
int8_t commsGetLastPacketRSSI(void);
int32_t commsRxUnenc(void *data);
void commsTxNoCpy(uint8_t *packetp);
#endif

View File

@@ -1,116 +0,0 @@
#include "compression.h"
#include "uzlib/src/uzlib.h"
//#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "mz100_flash.h"
#include "mz100_wdt.h"
#include "util.h"
#include "eeprom.h"
#define OUT_CHUNK_SIZE 0x100
struct EepromImageHeader backup_header;
uint8_t out_buffer[OUT_CHUNK_SIZE];
uint8_t dict_buffer[32768];
uint32_t current_in_pos = 0;
int callback_read_more_data(TINF_DATA *d)
{
return FLASH_ByteRead(FLASH_NORMAL_READ, current_in_pos++);
}
uint32_t decompress_file(uint32_t address_in, uint32_t size_compressed, uint32_t address_temp, uint32_t max_len_temp, char error_reason[100])
{
FLASH_Read(0, address_in - sizeof(struct EepromImageHeader), (uint8_t *)&backup_header, sizeof(struct EepromImageHeader)); // Save the image header to write it back later
int res;
struct uzlib_uncomp d;
uint32_t decomp_len;
uint32_t decomp_left;
uint32_t current_out_pos = 0;
current_in_pos = address_in;
FLASH_Read(0, address_in + size_compressed - 4, (uint8_t *)&decomp_len, 4); // Read the expected decompressed len
printf("Compressed size is: %i\r\n", size_compressed);
printf("Decompressed size is: %i\r\n", decomp_len);
if (decomp_len + 1 > max_len_temp)
{
printf("Error decompiled file will get too big\r\n");
sprintf(error_reason, "Out too big %i of max %i bytes", decomp_len, max_len_temp);
return 0;
}
decomp_left = decomp_len + 1;
uzlib_init();
uzlib_uncompress_init(&d, dict_buffer, 32768);
d.source = NULL;
d.source_limit = 0;
d.source_read_cb = callback_read_more_data; // Read each byte in the callback to save RAM
res = uzlib_gzip_parse_header(&d);
if (res != TINF_OK)
{
printf("Error parsing header: %d\r\n", res);
sprintf(error_reason, "Error parsing header %i", res);
return 0;
}
printf("Header parsed !\r\n");
qspiEraseRange(address_temp, max_len_temp);
printf("OTA Area erased\r\n");
while (decomp_left)
{
WDT_RestartCounter();
unsigned int chunk_len = decomp_left < OUT_CHUNK_SIZE ? decomp_left : OUT_CHUNK_SIZE;
d.dest = out_buffer;
d.dest_start = d.dest;
d.dest_limit = d.dest + sizeof(out_buffer);
// printf("One round: %i\r\n", decomp_left);
// printf("chunk_len: %i\r\n", chunk_len);
res = uzlib_uncompress_chksum(&d);
// printf("res: %i\r\n", res);
decomp_left -= chunk_len;
FLASH_Write(false, address_temp + current_out_pos, out_buffer, chunk_len);
current_out_pos += chunk_len;
if (res == TINF_DONE)
{
break;
}
if (res != TINF_OK)
{
printf("Some error inner decomp %i\r\n", res);
sprintf(error_reason, "Inner decomp error %i", res);
return 0;
}
}
if (res != TINF_DONE)
{
printf("Some error in decomp %i\r\n", res);
sprintf(error_reason, "Decomp error %i", res);
return 0;
}
printf("Decompression done\r\n");
printf("Writing image to correct position\r\n");
qspiEraseRange(address_in, EEPROM_IMG_EACH);
uint32_t copy_left = decomp_len;
current_out_pos = 0;
while (copy_left)
{
WDT_RestartCounter();
unsigned int chunk_len = copy_left < OUT_CHUNK_SIZE ? copy_left : OUT_CHUNK_SIZE;
FLASH_Read(0, address_temp + current_out_pos, (uint8_t *)&out_buffer, chunk_len);
FLASH_Write(false, address_in + current_out_pos, out_buffer, chunk_len);
current_out_pos += chunk_len;
copy_left -= chunk_len;
}
backup_header.size = decomp_len;
// Writing back the header of an uncompressed image
FLASH_Write(false, address_in - sizeof(struct EepromImageHeader), (uint8_t *)&backup_header, sizeof(struct EepromImageHeader));
printf("Everything done\r\n");
return decomp_len;
}

View File

@@ -1,9 +0,0 @@
#pragma once
#include "uzlib/src/uzlib.h"
//#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
uint32_t decompress_file(uint32_t address_in, uint32_t size_compressed, uint32_t address_temp, uint32_t max_len_temp, char error_reason[100]);

110
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/drawing.c Normal file → Executable file
View File

@@ -1,95 +1,67 @@
#include "drawing.h"
#include <stdbool.h>
#include <stdbool.h>
#include "printf.h"
#include "board.h"
#include "eeprom.h"
#include "proto.h"
#include "timer.h"
#include "screen.h"
#include "util.h"
#include "epd.h"
#include "printf.h"
#include "proto.h"
#include "screen.h"
#include "timer.h"
#include "util.h"
struct BitmapClutEntry
{
struct BitmapClutEntry {
uint8_t b, g, r, x;
};
uint8_t mPassNo = 0;
static uint8_t mClutMap[256];
static uint8_t mClutMapRed[256];
void drawImageAtAddress(uint32_t addr, uint8_t lut)
{
void drawImageAtAddress(uint32_t addr, uint8_t lut) {
struct EepromImageHeader *eih = (struct EepromImageHeader *)mClutMap;
eepromRead(addr, mClutMap, sizeof(struct EepromImageHeader));
switch (eih->dataType)
{
case DATATYPE_IMG_RAW_1BPP:
printf("Doing raw 1bpp\n");
switch (eih->dataType) {
case DATATYPE_IMG_RAW_1BPP:
printf("Doing raw 1bpp\n");
init_epd();
display_send_start(1);
for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++)
{
if (c % 256 == 0)
{
eepromRead(addr + sizeof(struct EepromImageHeader) + c, mClutMap, 256);
init_epd();
display_send_start(1);
for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++) {
if (c % 256 == 0) {
eepromRead(addr + sizeof(struct EepromImageHeader) + c, mClutMap, 256);
}
uint8_t curr_byte = mClutMap[c % 256]; // this one holds 8 pixel, we will translate them to 4 sendings
interleaveColor(curr_byte, 0x00);
}
display_send_stop();
epd_refresh_and_sleep(lut);
break;
case DATATYPE_IMG_RAW_2BPP:
printf("Doing raw 2bpp\n");
init_epd();
display_send_start(1);
for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++) {
if (c % 256 == 0) {
eepromRead(addr + sizeof(struct EepromImageHeader) + c, mClutMap, 256);
eepromRead(addr + sizeof(struct EepromImageHeader) + (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)) + c, mClutMapRed, 256);
}
uint8_t curr_byte = mClutMap[c % 256]; // this one holds 8 pixel, we will translate them to 4 sendings
uint8_t curr_byte = mClutMap[c % 256]; // this one holds 8 pixel, we will translate them to 4 sendings
uint8_t curr_byteRed = mClutMapRed[c % 256]; // this one holds 8 pixel, we will translate them to 4 sendings
for (int pixI = 0; pixI < 4; pixI++)
{
uint8_t pixel1 = (curr_byte & 0x80) ? 0 : 3;
curr_byte <<= 1;
uint8_t pixel2 = (curr_byte & 0x80) ? 0 : 3;
curr_byte <<= 1;
display_tx_byte((pixel1 << 4) | pixel2);
interleaveColor(curr_byte, curr_byteRed);
}
}
display_send_stop();
epd_refresh_and_sleep();
break;
case DATATYPE_IMG_RAW_2BPP:
printf("Doing raw 2bpp\n");
init_epd();
display_send_start(1);
for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++)
{
if (c % 256 == 0)
{
eepromRead(addr + sizeof(struct EepromImageHeader) + c, mClutMap, 256);
eepromRead(addr + sizeof(struct EepromImageHeader) + (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)) + c, mClutMapRed, 256);
}
uint8_t curr_byte = mClutMap[c % 256]; // this one holds 8 pixel, we will translate them to 4 sendings
uint8_t curr_byteRed = mClutMapRed[c % 256]; // this one holds 8 pixel, we will translate them to 4 sendings
for (int pixI = 0; pixI < 4; pixI++)
{
uint8_t pixel1 = (curr_byte & 0x80) ? 0 : 3;
pixel1 = (curr_byteRed & 0x80) ? 4 : pixel1;
curr_byte <<= 1;
curr_byteRed <<= 1;
uint8_t pixel2 = (curr_byte & 0x80) ? 0 : 3;
pixel2 = (curr_byteRed & 0x80) ? 4 : pixel1;
curr_byte <<= 1;
curr_byteRed <<= 1;
display_tx_byte((pixel1 << 4) | pixel2);
}
}
display_send_stop();
epd_refresh_and_sleep();
break;
default: // prevent drawing from an unknown file image type
printf("Image with type 0x%02X was requested, but we don't know what to do with that currently...\n", eih->dataType);
return;
display_send_stop();
epd_refresh_and_sleep(lut);
break;
default: // prevent drawing from an unknown file image type
printf("Image with type 0x%02X was requested, but we don't know what to do with that currently...\n", eih->dataType);
return;
}
// addOverlay();
// drawWithSleep();

16
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/eeprom.h Normal file → Executable file
View File

@@ -7,8 +7,7 @@
#define EEPROM_ERZ_SECTOR_SZ 4096 //erase size and alignment
//pages are 4K in size
//an update can be stored in any 2 image slots
#define EEPROM_UPDATA_AREA_START (0x17000UL)
#define EEPROM_UPDATE_AREA_LEN (0x10000UL)
#define EEPROM_PAGE_SIZE (0x01000UL)
#define EEPROM_OS_START (0x00000UL)
@@ -32,18 +31,7 @@
#define EEPROM_IMG_VALID (0x494d4721)
#define EEPROM_PIECE_SZ (88)
struct EepromImageHeaderOld {
uint64_t version;
uint32_t validMarker;
uint32_t size;
uint32_t rfu[8]; //zero-filled for now
uint8_t piecesMissing[256]; //each bit represents a 64-byte piece
//image data here
//os update here possibly (EEPROM_OS_UPDATE_SZ_PER_IMG bytes each piece)
//we pre-erase so progress can be calculated by finding the first non-0xff byte
};
//#define EEPROM_PIECE_SZ (88)
struct EepromImageHeader { //each image space is 0x17000 bytes, we have space for ten of them
uint64_t version;

View File

@@ -2,8 +2,7 @@
#include <stdbool.h>
#include <stdint.h>
//#include <stdio.h>
#include "printf.h"
// #include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -16,6 +15,7 @@
#include "mz100_pinmux.h"
#include "mz100_ssp.h"
#include "mz100_wdt.h"
#include "printf.h"
#include "stdarg.h"
#include "util.h"
@@ -63,6 +63,17 @@
static uint8_t EPDtempBracket = 0;
#define CHAR_WIDTH_BYTES 2
#define CHAR_HEIGHT 20
#define CHAR_WIDTH 12
#define SCREEN_WIDTH 640
uint8_t buffer[CHAR_HEIGHT][640 / 8];
uint8_t charbuffer[CHAR_HEIGHT][CHAR_WIDTH_BYTES + 1];
#define CHAR_SPACING 1
#define EMPTY_SPACING 3
struct epd_colorlutpart {
uint8_t repeat;
uint8_t lvl0 : 4;
@@ -114,13 +125,39 @@ struct epd_xonlut {
struct epd_xonlutpart part[20];
} __packed;
void interleaveColor(uint8_t b) {
void interleaveBW(uint8_t b) {
b ^= 0xFF;
uint8_t b_out = 0;
for (uint8_t shift = 0; shift < 4; shift++) {
b_out = 0;
if ((b >> 2 * shift) & 0x01) b_out |= 0x30;
if ((b >> 2 * shift) & 0x02) b_out |= 0x03;
if ((b >> 2 * shift) & 0x01) b_out |= 0x30; // 0x30
if ((b >> 2 * shift) & 0x02) b_out |= 0x03; // 0x03
display_tx_byte(b_out);
}
}
void interleaveColor(uint8_t b, uint8_t r) {
b ^= 0xFF;
uint8_t b_out = 0;
for (int8_t shift = 3; shift >= 0; shift--) {
b_out = 0;
if (((b >> 2 * shift) & 0x01) && ((r >> 2 * shift) & 0x01)) {
b_out |= 0x04; // 0x30
} else if ((b >> 2 * shift) & 0x01) {
b_out |= 0x03; // 0x30
} else if ((r >> 2 * shift) & 0x01) { // 4 or 5
b_out |= 0x04; // 0x30
} else {
}
if (((b >> 2 * shift) & 0x02) && ((r >> 2 * shift) & 0x02)) {
b_out |= 0x40; // 0x30
} else if ((b >> 2 * shift) & 0x02) {
b_out |= 0x30; // 0x30
} else if ((r >> 2 * shift) & 0x02) {
b_out |= 0x40; // 0x30
} else {
}
display_tx_byte(b_out);
}
}
@@ -423,21 +460,9 @@ void shiftLeftByX(uint8_t *data, int X, int N) {
data[i] = (data[i] << X) | ((data[i - 1] >> (8 - X)) & ((1 << X) - 1));
}
}
#define CHAR_WIDTH_BYTES 2
#define CHAR_HEIGHT 20
#define CHAR_WIDTH 12
#define SCREEN_WIDTH 640
uint8_t buffer[CHAR_HEIGHT][640 / 8];
uint8_t charbuffer[CHAR_HEIGHT][CHAR_WIDTH_BYTES + 1];
// uint16_t curX = 0;
#define CHAR_SPACING 1
#define EMPTY_SPACING 3
uint16_t loadCharacter(uint8_t currentChar, uint16_t curX, bool first) {
currentChar-=0x20;
currentChar -= 0x20;
memset(charbuffer, 0, sizeof(charbuffer));
for (uint8_t d = 0; d < CHAR_HEIGHT; d++) {
@@ -507,19 +532,29 @@ void dumpBuffer(uint16_t xloc, uint16_t yloc, uint16_t width) {
display_send_start(0);
for (uint8_t curY = 0; curY < CHAR_HEIGHT; curY++) {
for (uint16_t curX = 0; curX < width; curX += 8) {
interleaveColor(buffer[curY][curX / 8]);
interleaveBW(buffer[curY][curX / 8]);
}
}
display_send_stop();
}
void loadLUTSfromEEPROM() {
uint8_t bracket = getTempBracket();
void loadLUTSfromEEPROM(uint8_t bracket) {
for (uint8_t c = EPD_LUT_B; c <= EPD_LUT_R3; c++) {
struct epd_colorlut *colorlut = (struct epd_colorlut *)loadLUT(c, bracket);
for (uint8_t part = 0; part < 20; part++) {
for (uint8_t d = 0; d < 8; d++) {
colorlut->part[1].length[d] = 1;
colorlut->part[0].length[d] = 1;
}
for (uint8_t part = 0; part < 4; part++) {
if (colorlut->part[part].repeat) colorlut->part[part].repeat = 1;
}
for (uint8_t part = 4; part < 20; part++) {
if (colorlut->part[part].repeat) colorlut->part[part].repeat = 0;
}
lutBeginTX(c);
for (uint16_t d = 0; d < 260; d++) {
display_tx_byte(((uint8_t *)colorlut)[d]);
@@ -529,8 +564,9 @@ void loadLUTSfromEEPROM() {
}
struct epd_vcomlut *vcomlut = (struct epd_vcomlut *)loadLUT(EPD_LUT_VCOM, bracket);
for (uint8_t part = 0; part < 20; part++) {
if (vcomlut->part[part].repeat) vcomlut->part[part].repeat = 1;
if (vcomlut->part[part].repeat) vcomlut->part[part].repeat = 0;
}
lutBeginTX(EPD_LUT_VCOM);
for (uint16_t d = 0; d < 220; d++) {
@@ -540,8 +576,12 @@ void loadLUTSfromEEPROM() {
if (vcomlut) free(vcomlut);
struct epd_xonlut *xonlut = (struct epd_xonlut *)loadLUT(EPD_LUT_XON, bracket);
// memset(&(xonlut->part[0].repeat), 0x00, sizeof(struct epd_xonlutpart));
// memset(&(xonlut->part[1].repeat), 0x00, sizeof(struct epd_xonlutpart));
for (uint8_t part = 0; part < 20; part++) {
if (xonlut->part[part].repeat) xonlut->part[part].repeat = 1;
if (xonlut->part[part].repeat) xonlut->part[part].repeat = 0;
}
lutBeginTX(EPD_LUT_XON);
for (uint16_t d = 0; d < 200; d++) {
@@ -595,31 +635,45 @@ void fillWindow(uint16_t x, uint16_t y, uint16_t xe, uint16_t ye, uint8_t color)
display_send_start(0);
for (uint32_t c = 0; c < (xe - x) * (ye - y) / 8; c++) {
interleaveColor(0x00);
interleaveBW(0x00);
}
display_send_stop();
}
void epd_refresh_and_sleep() {
loadLUTSfromEEPROM(EPDtempBracket);
void epd_refresh_and_sleep(uint8_t lut) {
if (lut) {
epdWrite(EPD_PANEL_SETTING, 2, 0xC3, 0x88); // 0xC3-0x88 // lut from register
loadLUTSfromEEPROM(EPDtempBracket);
} else {
epdWrite(EPD_PANEL_SETTING, 2, 0xC3, 0x08); // 0xC3-0x88 // lut from EEPROM
epdWrite(EPD_UNKNOWN_1, 1, 0x03); // load lut, probably
}
// epdPrintf(50,100,false,"Blaat! Dit is een test %d", 6);
EPD_cmd(EPD_REFRESH);
delay(100000);
unsigned int v2 = 0;
while (GPIO_ReadPinLevel(EPD_BUSY) == GPIO_IO_HIGH) {
WDT_RestartCounter();
delay(10000);
v2++;
if (v2 > 10)
break;
}
do_sleeped_epd_refresh();
init_GPIO_EPD();
epd_reset();
epd_reset();
// epd_reset();
EPD_cmd(EPD_POWER_SETTING);
EPD_data(2);
EPD_data(0);
EPD_data(0);
EPD_data(0);
delay_us(500000);
delay_us(50000);
EPD_cmd(EPD_POWER_OFF);
delay_us(1000000);
delay_us(100000);
BUSY_wait(0x32u);
EPD_cmd(EPD_SPI_FLASH_CONTROL);
EPD_data(1);
@@ -701,9 +755,9 @@ void init_epd(void) {
epdWrite(EPD_SPI_FLASH_CONTROL, 1, 0x00);
epdWrite(EPD_POWER_SETTING, 4, 0x37, 0x00, 0x05, 0x05); // 0x37 - 00- 05 05
epdWrite(EPD_PANEL_SETTING, 2, 0xC3, 0x88); // CB-88 // CB-08 // C3-reverse
// epdWrite(EPD_POWER_SETTING, 4, 0x07, 0x00, 0x05, 0x05); // 0x37 - 00- 05 05
// epdWrite(EPD_UNKNOWN_1, 1, 0x03);
epdWrite(EPD_PANEL_SETTING, 2, 0xC3, 0x08); // 0xC3-0x88 // lut from EEPROM
epdWrite(EPD_POWER_OFF_SEQUENCE, 1, 0x00);
epdWrite(EPD_BOOSTER_SOFT_START, 0x03, 199, 204, 45);
@@ -714,12 +768,9 @@ void init_epd(void) {
epdWrite(EPD_TCON_SET, 0x01, 34);
epdWrite(EPD_TRES, 0x04, 2, 128, 1, 128);
//setDisplayWindow(96, 32, 496, 332);
EPDtempBracket = getTempBracket();
loadFrameRatePLL(EPDtempBracket);
loadTempVCOMDC(EPDtempBracket);
printf("EPD Powerup complete\n");
}
void epdPrintf(uint16_t x, uint16_t y, bool color, const char *c, ...) {
@@ -731,7 +782,7 @@ void epdPrintf(uint16_t x, uint16_t y, bool color, const char *c, ...) {
memset(charbuffer, 0, sizeof(charbuffer));
va_list lst;
va_start(lst, c);
vsnprintf(out_buffer,256, c, lst);
vsnprintf(out_buffer, 256, c, lst);
va_end(lst);
curX = x % 8;
@@ -750,4 +801,18 @@ void epdPrintf(uint16_t x, uint16_t y, bool color, const char *c, ...) {
x /= 8;
x *= 8;
dumpBuffer(x, y, curX);
}
void drawImg(uint16_t x, uint16_t y, const uint8_t *img) {
uint16_t width = img[0];
uint16_t height = img[1];
img += 2;
setDisplayWindow(x, y, x + width, y + height);
display_send_start(0);
for (uint8_t curY = 0; curY < height; curY++) {
for (uint16_t curX = 0; curX < width; curX += 8) {
interleaveColor(*(img++), 0x00);
}
}
display_send_stop();
}

9
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/epd.h Normal file → Executable file
View File

@@ -32,7 +32,7 @@
void init_GPIO_EPD();
void display_send_buffer();
void epd_refresh_and_sleep();
void epd_refresh_and_sleep(uint8_t lut);
void display_tx_byte(uint8_t data);
void display_send_start(uint8_t inverted);
@@ -50,4 +50,9 @@ void epd_pin_enable(int a1);
void fillWindow(uint16_t x, uint16_t y, uint16_t xe, uint16_t ye, uint8_t color);
void epdPrintf(uint16_t x, uint16_t y, bool color, const char* c, ...);
void epdPrintf(uint16_t x, uint16_t y, bool color, const char* c, ...);
void interleaveColor(uint8_t b, uint8_t r);
void interleaveBW(uint8_t);
void drawImg(uint16_t x, uint16_t y, const uint8_t *img);

View File

@@ -2,11 +2,8 @@
#include <stdbool.h>
#include <stdint.h>
// #include <stdio.h>
#include <string.h>
#include "ccm.h"
#include "chars.h"
#include "comms.h"
#include "core_cm3.h"
#include "eeprom.h"
@@ -48,73 +45,24 @@ char macStr1[32];
__attribute__((section(".aon"))) uint8_t currentTagMode = TAG_MODE_CHANSEARCH;
__attribute__((section(".aon"))) volatile struct zigbeeCalibDataStruct zigbeeCalibData;
void prvApplyUpdateIfNeeded() {
uint32_t ofst, now, size, pieceSz = 0x2000;
uint8_t chunkStore[0x2000];
(*(volatile unsigned int *)0x130000) = 0; // Invalidate RAM in any case so the next boot will be a full one
(*(volatile unsigned int *)0x130400) = 0;
printf("Applying update\r\n");
qspiEraseRange(EEPROM_OS_START, EEPROM_OS_LEN);
size = EEPROM_OS_LEN;
for (ofst = 0; ofst < size; ofst += now) {
now = size - ofst;
if (now > pieceSz)
now = pieceSz;
printf("Cpy 0x%06x + 0x%04x to 0x%06x\r\n", EEPROM_UPDATE_START + ofst, now, EEPROM_OS_START + ofst);
FLASH_Read(0, EEPROM_UPDATE_START + ofst, chunkStore, now);
FLASH_Write(false, EEPROM_OS_START + ofst, chunkStore, now);
WDT_RestartCounter();
}
// printf("Erz IMAGES\r\n");
// qspiEraseRange(EEPROM_IMG_START, EEPROM_IMG_LEN);
// printf("Erz update\r\n");
// qspiEraseRange(EEPROM_UPDATE_START, EEPROM_UPDATE_LEN);
sleep_with_with_wakeup(1000);
}
void prvEepromIndex(struct EepromContentsInfo *eci) {
struct EepromImageHeader eih;
uint32_t addr;
for (addr = EEPROM_IMG_START; addr - EEPROM_IMG_START < EEPROM_IMG_LEN; addr += EEPROM_IMG_EACH) {
uint32_t *addrP, *szP = NULL;
uint64_t *verP = NULL;
FLASH_Read(0, addr, (uint8_t *)&eih, sizeof(struct EepromImageHeader));
printf("DATA slot 0x%06x: type 0x%08x ver 0x%08x%08x\r\n", addr, eih.validMarker, (uint32_t)(eih.version >> 32), (uint32_t)eih.version);
switch (eih.validMarker) {
case EEPROM_IMG_INPROGRESS:
verP = &eci->latestInprogressImgVer;
addrP = &eci->latestInprogressImgAddr;
break;
case EEPROM_IMG_VALID:
verP = &eci->latestCompleteImgVer;
addrP = &eci->latestCompleteImgAddr;
szP = &eci->latestCompleteImgSize;
break;
}
if (verP && eih.version >= *verP) {
*verP = eih.version;
*addrP = addr;
if (szP)
*szP = eih.size;
bool protectedFlashWrite(uint32_t address, uint8_t *buffer, uint32_t num) {
uint8_t attempt = 3;
uint8_t *buf2 = (uint8_t *)malloc(num);
while (attempt--) {
qspiEraseRange(address, num);
delay(50);
FLASH_Write(false, address, buffer, num);
FLASH_Read(0, address, buf2, num);
if (memcmp(buffer, buf2, num) == 0) {
printf("Flash block at %06X written successfully\n", address);
free(buf2);
return true;
}
printf("Failed attempt to write flash block at %lu\n", address);
}
}
void prvWriteNewHeader(struct EepromImageHeaderOld *eih, uint32_t addr, uint32_t eeSize, uint64_t ver, uint32_t size) {
qspiEraseRange(addr, eeSize);
// bzero(eih, sizeof(struct EepromImageHeaderOld));
eih->version = ver;
eih->validMarker = EEPROM_IMG_INPROGRESS;
eih->size = size;
memset(eih->piecesMissing, 0xff, sizeof(eih->piecesMissing));
FLASH_Write(false, addr, (uint8_t *)eih, sizeof(struct EepromImageHeaderOld));
free(buf2);
printf("Giving up on writing block at %lu\n", address);
return false;
}
static void prvGetSelfMac(void) {
@@ -158,6 +106,7 @@ uint8_t showChannelSelect() { // returns 0 if no accesspoints were found
}
uint8_t channelSelect() { // returns 0 if no accesspoints were found
printf("Doing chansearch...\n");
uint8_t result[16];
memset(result, 0, sizeof(result));
@@ -336,7 +285,6 @@ void TagAssociated() {
if ((lowBattery && !lowBatteryShown && tagSettings.enableLowBatSymbol) || (noAPShown && tagSettings.enableNoRFSymbol)) {
printf("For some reason, we're going to redraw the image. lowbat=%d, lowbatshown=%d, noAPShown=%d\n", lowBattery, lowBatteryShown, noAPShown);
// Check if we were already displaying an image
/*
if (curImgSlot != 0xFF) {
powerUp(INIT_EEPROM | INIT_EPD);
wdt60s();
@@ -347,7 +295,6 @@ void TagAssociated() {
showAPFound();
powerDown(INIT_EPD);
}
*/
}
powerUp(INIT_RADIO);
@@ -473,6 +420,8 @@ int main(void) {
printf("AON is not valid!\n");
setupRTC();
clearAonRam();
showSplashScreen();
currentChannel = 0;
zigbeeCalibData.isValid = false;
wakeUpReason = WAKEUP_REASON_FIRSTBOOT;
@@ -483,8 +432,6 @@ int main(void) {
loadDefaultSettings();
doVoltageReading();
qspiEraseRange(EEPROM_IMG_START, EEPROM_IMG_LEN);
qspiEraseRange(EEPROM_UPDATE_START, EEPROM_UPDATE_LEN);
qspiEraseRange(EEPROM_SETTINGS_AREA_START, EEPROM_SETTINGS_AREA_LEN);
sprintf(macStr, "(" MACFMT ")", MACCVT(mSelfMac));
@@ -498,6 +445,7 @@ int main(void) {
currentTagMode = TAG_MODE_ASSOCIATED;
} else {
printf("No AP found\r\n");
showNoAP();
sleep_with_with_wakeup(120000UL);
currentTagMode = TAG_MODE_CHANSEARCH;
}
@@ -511,8 +459,8 @@ int main(void) {
memset(curBlock.requestedParts, 0x00, BLOCK_REQ_PARTS_BYTES);
}
powerUp(INIT_UART);
while (1) {
powerUp(INIT_UART);
wdt10s();
switch (currentTagMode) {
case TAG_MODE_ASSOCIATED:
@@ -533,4 +481,29 @@ int _write(int file, char *ptr, int len) {
void _putchar(char c) {
_write(0, &c, 1);
}
}
void applyUpdate() {
uint32_t ofst, now, size, pieceSz = 0x2000;
uint8_t chunkStore[0x2000];
printf("Applying update\r\n");
// apparently, the flash process is more reliable if we do these two first
setupCLKCalib();
setupRTC();
showApplyUpdate();
size = EEPROM_OS_LEN;
for (ofst = 0; ofst < size; ofst += now) {
now = size - ofst;
if (now > pieceSz)
now = pieceSz;
printf("Cpy 0x%06x + 0x%04x to 0x%06x\r\n", EEPROM_UPDATE_START + ofst, now, EEPROM_OS_START + ofst);
FLASH_Read(0, EEPROM_UPDATE_START + ofst, chunkStore, now);
protectedFlashWrite(EEPROM_OS_START + ofst, chunkStore, now);
WDT_RestartCounter();
}
NVIC_SystemReset();
}

10
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/main.h Normal file → Executable file
View File

@@ -28,11 +28,7 @@
#define EPD_BUSY 27
#define EPD_HLT_CTRL 25
#define RADIO_FIRST_CHANNEL (11) //2.4-GHz channels start at 11
struct EepromContentsInfo
{
uint32_t latestCompleteImgAddr, latestInprogressImgAddr, latestCompleteImgSize;
uint64_t latestCompleteImgVer, latestInprogressImgVer;
};
void uiPrvFullscreenMsg(const char *str, const char *line2, const char *line3);
void prvApplyUpdateIfNeeded();
void applyUpdate();

2
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/powermgt.h Normal file → Executable file
View File

@@ -26,7 +26,7 @@
// power saving algorithm
#define INTERVAL_BASE 40 // interval (in seconds) (when 1 packet is sent/received) for target current (7.2µA)
#define INTERVAL_AT_MAX_ATTEMPTS 600 // interval (in seconds) (at max attempts) for target average current
#define INTERVAL_AT_MAX_ATTEMPTS 300 // interval (in seconds) (at max attempts) for target average current
#define DATA_REQ_RX_WINDOW_SIZE 5UL // How many milliseconds we should wait for a packet during the data_request.
// If the AP holds a long list of data for tags, it may need a little more time to lookup the mac address
#define DATA_REQ_MAX_ATTEMPTS 3 // How many attempts (at most) we should do to get something back from the AP

360
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/proto.h Normal file → Executable file
View File

@@ -3,364 +3,10 @@
#include <stdint.h>
/*
All communications are direct from tag to station, EXCEPT association (tag will broadcast).
All comms shall be encrypted and authenticated with AES-CCM. Shared key shall be burned into the firmware.
Master shall provision new key at association. All non-bcast packets shall have pan id compression.
Master may skip "from" field. Tag checking in confirms it got the master's provisioning reply.
Sadly filtering on MZ100 fails for long addr with no src addr. so short addr for src is used
T = tag, S = station
PACKET TYPE USE PAYLOAD STRUCT NOTES
ASSOC_REQ T2bcast TagInfo tag's info and assoc request (encrypted with shared key)
ASSOC_RESP S2T AssocInfo tag's association info (encrypted with shared key)
CHECKIN T2S CheckinInfo tag checking in occasionally
CHECKOUT S2T PendingInfo station's checkin reply telling tag what we have for it
CHUNK_REQ T2S ChunkReqInfo tag requesting a piece of data
CHUNK_RESP S2T ChunkInfo station provides chunk
*/
#define PROTO_PRESHARED_KEY \
{ 0x34D906D3, 0xE3E5298E, 0x3429BF58, 0xC1022081 }
#define PROTO_PAN_ID (0x4447) // PAN ID compression shall be used
#define PKT_ASSOC_REQ (0xF0)
#define PKT_ASSOC_RESP (0xF1)
#define PKT_CHECKIN (0xF2)
#define PKT_CHECKOUT (0xF3)
#define PKT_CHUNK_REQ (0xF4)
#define PKT_CHUNK_RESP (0xF5)
#define PROTO_VER_0 (0)
#define PROTO_VER_CURRENT (PROTO_VER_0)
#define PROTO_COMPR_TYPE_LZ (0x0001)
#define PROTO_COMPR_TYPE_BITPACK (0x0002)
#define PROTO_MAX_DL_LEN (88)
//////////////// NEW
#include "tag_types.h"
/*
// power saving algorithm
#define INTERVAL_BASE 40 // interval (in seconds) (when 1 packet is sent/received) for target current (7.2µA)
#define INTERVAL_AT_MAX_ATTEMPTS 600 // interval (in seconds) (at max attempts) for target average current
#define DATA_REQ_RX_WINDOW_SIZE 5UL // How many milliseconds we should wait for a packet during the data_request.
// If the AP holds a long list of data for tags, it may need a little more time to lookup the mac address
#define DATA_REQ_MAX_ATTEMPTS 14 // How many attempts (at most) we should do to get something back from the AP
#define POWER_SAVING_SMOOTHING 8 // How many samples we should use to smooth the data request interval
#define MINIMUM_INTERVAL 45 // IMPORTANT: Minimum interval for check-in; this determines overal battery life!
#define MAXIMUM_PING_ATTEMPTS 20 // How many attempts to discover an AP the tag should do
#define LONG_DATAREQ_INTERVAL 300 // How often (in seconds, approximately) the tag should do a long datareq (including temperature)
#define VOLTAGE_CHECK_INTERVAL 288 // How often the tag should do a battery voltage check (multiplied by LONG_DATAREQ_INTERVAL)
#define BATTERY_VOLTAGE_MINIMUM 2450 // 2600 or below is the best we can do on the EPD
// power saving when no AP's were found (scanning every X)
#define VOLTAGEREADING_DURING_SCAN_INTERVAL 2 // how often we should read voltages; this is done every scan attempt in interval bracket 3
#define INTERVAL_1_TIME 3600UL // Try every hour
#define INTERVAL_1_ATTEMPTS 24 // for 24 attempts (an entire day)
#define INTERVAL_2_TIME 7200UL // Try every 2 hours
#define INTERVAL_2_ATTEMPTS 12 // for 12 attempts (an additional day)
#define INTERVAL_3_TIME 86400UL // Finally, try every day
*/
#pragma pack(1)
enum TagScreenType {
TagScreenEink_BW_1bpp,
TagScreenEink_BW_2bpp,
TagScreenEink_BW_4bpp,
TagScreenEink_BWY_only, // 2bpp, but only 3 colors (BW?Y)
TagScreenEink_BWY_2bpp,
TagScreenEink_BWY_4bpp,
TagScreenEink_BWR_only, // 2bpp, but only 3 colors (BW?R)
TagScreenEink_BWR_2bpp,
TagScreenEink_BWR_4bpp,
TagScreenEink_BWY_3bpp,
TagScreenEink_BWR_3bpp,
TagScreenEink_BW_3bpp,
TagScreenPersistentLcd_1bpp,
TagScreenEink_BWY_5colors,
TagScreenEink_BWR_5colors,
TagScreenEink_BWY_6colors,
TagScreenEink_BWR_6colors,
TagScreenTypeOther = 0x7f,
};
#define RADIO_MAX_PACKET_LEN (125) // useful payload, not including the crc
#define ADDR_MODE_NONE (0)
#define ADDR_MODE_SHORT (2)
#define ADDR_MODE_LONG (3)
#define FRAME_TYPE_BEACON (0)
#define FRAME_TYPE_DATA (1)
#define FRAME_TYPE_ACK (2)
#define FRAME_TYPE_MAC_CMD (3)
#define SHORT_MAC_UNUSED (0x10000000UL) // for radioRxFilterCfg's myShortMac
struct MacFcs {
uint8_t frameType : 3;
uint8_t secure : 1;
uint8_t framePending : 1;
uint8_t ackReqd : 1;
uint8_t panIdCompressed : 1;
uint8_t rfu1 : 1;
uint8_t rfu2 : 2;
uint8_t destAddrType : 2;
uint8_t frameVer : 2;
uint8_t srcAddrType : 2;
};
struct MacFrameFromMaster {
struct MacFcs fcs;
uint8_t seq;
uint16_t pan;
uint8_t dst[8];
uint16_t from;
};
struct MacFrameNormal {
struct MacFcs fcs;
uint8_t seq;
uint16_t pan;
uint8_t dst[8];
uint8_t src[8];
};
struct MacFrameBcast {
struct MacFcs fcs;
uint8_t seq;
uint16_t dstPan;
uint16_t dstAddr;
uint16_t srcPan;
uint8_t src[8];
};
#define PKT_AVAIL_DATA_SHORTREQ 0xE3
#define PKT_AVAIL_DATA_REQ 0xE5
#define PKT_AVAIL_DATA_INFO 0xE6
#define PKT_BLOCK_PARTIAL_REQUEST 0xE7
#define PKT_BLOCK_REQUEST_ACK 0xE9
#define PKT_BLOCK_REQUEST 0xE4
#define PKT_BLOCK_PART 0xE8
#define PKT_XFER_COMPLETE 0xEA
#define PKT_XFER_COMPLETE_ACK 0xEB
#define PKT_CANCEL_XFER 0xEC
#define PKT_PING 0xED
#define PKT_PONG 0xEE
struct AvailDataReq {
uint8_t checksum;
uint8_t lastPacketLQI;
int8_t lastPacketRSSI;
int8_t temperature;
uint16_t batteryMv;
uint8_t hwType;
uint8_t wakeupReason;
uint8_t capabilities;
uint16_t tagSoftwareVersion;
uint8_t currentChannel;
uint8_t customMode;
uint8_t reserved[8];
};
struct oldAvailDataReq {
uint8_t checksum;
uint8_t lastPacketLQI;
int8_t lastPacketRSSI;
int8_t temperature;
uint16_t batteryMv;
uint8_t hwType;
uint8_t wakeupReason;
uint8_t capabilities;
};
struct AvailDataInfo {
uint8_t checksum;
uint64_t dataVer; // MD5 of potential traffic
uint32_t dataSize;
uint8_t dataType;
uint8_t dataTypeArgument; // extra specification or instruction for the tag (LUT to be used for drawing image)
uint16_t nextCheckIn; // when should the tag check-in again? Measured in minutes
} __attribute__((packed)) ;
struct pendingData {
struct AvailDataInfo availdatainfo;
uint16_t attemptsLeft;
uint8_t targetMac[8];
};
struct blockPart {
uint8_t checksum;
uint8_t blockId;
uint8_t blockPart;
uint8_t data[];
};
struct blockData {
uint16_t size;
uint16_t checksum;
uint8_t data[];
};
struct burstMacData {
uint16_t offset;
uint8_t targetMac[8];
};
#define BLOCK_PART_DATA_SIZE 99
#define BLOCK_MAX_PARTS 42
#define BLOCK_DATA_SIZE 4096UL
#define BLOCK_XFER_BUFFER_SIZE BLOCK_DATA_SIZE + sizeof(struct blockData)
#define BLOCK_REQ_PARTS_BYTES 6
struct blockRequest {
uint8_t checksum;
uint64_t ver;
uint8_t blockId;
uint8_t type;
uint8_t requestedParts[BLOCK_REQ_PARTS_BYTES];
} ;
struct blockRequestAck {
uint8_t checksum;
uint16_t pleaseWaitMs;
};
struct espBlockRequest {
uint8_t checksum;
uint64_t ver;
uint8_t blockId;
uint8_t src[8];
};
struct espXferComplete {
uint8_t checksum;
uint8_t src[8];
};
struct espAvailDataReq {
uint8_t checksum;
uint8_t src[8];
struct AvailDataReq adr;
};
struct espSetChannelPower {
uint8_t checksum;
uint8_t channel;
uint8_t power;
};
#pragma pack(0)
///////////////// NEW END
#ifndef __packed
#define __packed __attribute__((packed))
#endif
struct TagState {
uint64_t swVer;
uint16_t hwType;
uint16_t batteryMv;
} __packed;
struct TagInfo {
uint8_t protoVer; // PROTO_VER_*
struct TagState state;
uint8_t rfu1[1]; // shall be ignored for now
uint16_t screenPixWidth;
uint16_t screenPixHeight;
uint16_t screenMmWidth;
uint16_t screenMmHeight;
uint16_t compressionsSupported; // COMPR_TYPE_* bitfield
uint16_t maxWaitMsec; // how long tag will wait for packets before going to sleep
uint8_t screenType; // enum TagScreenType
uint8_t rfu[11]; // shall be zero for now
} __packed;
struct AssocInfo {
uint32_t checkinDelay; // space between checkins, in msec
uint32_t retryDelay; // if download fails mid-way wait thi smany msec to retry (IFF progress was made)
uint16_t failedCheckinsTillBlank; // how many fails till we go blank
uint16_t failedCheckinsTillDissoc; // how many fails till we dissociate
uint32_t newKey[4];
uint8_t rfu[8]; // shall be zero for now
} __packed;
#define CHECKIN_TEMP_OFFSET 0x7f
struct CheckinInfo {
struct TagState state;
uint8_t lastPacketLQI; // zero if not reported/not supported to be reported
int8_t lastPacketRSSI; // zero if not reported/not supported to be reported
uint8_t temperature; // zero if not reported/not supported to be reported. else, this minus CHECKIN_TEMP_OFFSET is temp in degrees C
uint8_t rfu[6]; // shall be zero for now
} __packed;
struct PendingInfo {
uint64_t imgUpdateVer;
uint32_t imgUpdateSize;
uint64_t osUpdateVer; // version of OS update avail
uint32_t osUpdateSize;
uint8_t rfu[8]; // shall be zero for now
} __packed;
struct ChunkReqInfo {
uint64_t versionRequested;
uint32_t offset;
uint8_t len;
uint8_t osUpdatePlz : 1;
uint8_t rfu[6]; // shall be zero for now
} __packed;
struct ChunkInfo {
uint32_t offset;
uint8_t osUpdatePlz : 1;
uint8_t rfu; // shall be zero for now
uint8_t data[]; // no data means request is out of bounds of this version no longer exists
} __packed;
#include "../../oepl-definitions.h"
#include "../../oepl-proto.h"
#define MACFMT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
#define MACCVT(x) ((const uint8_t*)(x))[7], ((const uint8_t*)(x))[6], ((const uint8_t*)(x))[5], ((const uint8_t*)(x))[4], ((const uint8_t*)(x))[3], ((const uint8_t*)(x))[2], ((const uint8_t*)(x))[1], ((const uint8_t*)(x))[0]
#define VERSION_SIGNIFICANT_MASK (0x0000ffffffffffffull)
#define HW_TYPE_42_INCH_SAMSUNG (1)
#define HW_TYPE_42_INCH_SAMSUNG_ROM_VER_OFST (0xEFF8)
#define HW_TYPE_74_INCH_DISPDATA (2)
#define HW_TYPE_74_INCH_DISPDATA_FRAME_MODE (3)
#define HW_TYPE_74_INCH_DISPDATA_ROM_VER_OFST (0x008b)
#define HW_TYPE_ZBD_EPOP50 (4)
#define HW_TYPE_ZBD_EPOP50_ROM_VER_OFST (0x008b)
#define HW_TYPE_ZBD_EPOP900 (5)
#define HW_TYPE_ZBD_EPOP900_ROM_VER_OFST (0x008b)
#define HW_TYPE_29_INCH_DISPDATA (6)
#define HW_TYPE_29_INCH_DISPDATA_FRAME_MODE (7)
#define HW_TYPE_29_INCH_DISPDATA_ROM_VER_OFST (0x008b)
#define HW_TYPE_29_INCH_ZBS_026 (8)
#define HW_TYPE_29_INCH_ZBS_026_FRAME_MODE (9)
#define HW_TYPE_29_INCH_ZBS_025 (10)
#define HW_TYPE_29_INCH_ZBS_025_FRAME_MODE (11)
#define HW_TYPE_29_INCH_ZBS_ROM_VER_OFST (0x008b)
#define HW_TYPE_74_INCH_BWR (40)
#define HW_TYPE_74_INCH_BWR_ROM_VER_OFST (0x0160)
#define HW_TYPE_58_INCH_BWR (41)
#define HW_TYPE_58_INCH_BWR_ROM_VER_OFST (0x0160)
#define HW_TYPE_42_INCH_BWR (42)
#define HW_TYPE_42_INCH_BWR_ROM_VER_OFST (0x0160)
#endif
#endif

2
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/settings.c Normal file → Executable file
View File

@@ -1,10 +1,12 @@
#include "settings.h"
#include "proto.h"
#include <string.h>
#include "eeprom.h"
#include "util.h"
#include "mz100_flash.h"
#include "powermgt.h"
__attribute__((section(".aonshadow"))) struct tagsettings tagSettings = {0};
extern uint8_t blockXferBuffer[];
uint8_t* infopageTempBuffer = 1024 + blockXferBuffer;

15
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/settings.h Normal file → Executable file
View File

@@ -17,21 +17,6 @@
#define DEFAULT_SETTING_LOWBATSYMBOL 1
#define DEFAULT_SETTING_NORFSYMBOL 1
struct tagsettings {
uint8_t settingsVer; // the version of the struct as written to the infopage
uint8_t enableFastBoot; // default 0; if set, it will skip splashscreen
uint8_t enableRFWake; // default 0; if set, it will enable RF wake. This will add about ~0.9µA idle power consumption
uint8_t enableTagRoaming; // default 0; if set, the tag will scan for an accesspoint every few check-ins. This will increase power consumption quite a bit
uint8_t enableScanForAPAfterTimeout; // default 1; if a the tag failed to check in, after a few attempts it will try to find a an AP on other channels
uint8_t enableLowBatSymbol; // default 1; tag will show 'low battery' icon on screen if the battery is depleted
uint8_t enableNoRFSymbol; // default 1; tag will show 'no signal' icon on screen if it failed to check in for a longer period of time
uint8_t fastBootCapabilities; // holds the byte with 'capabilities' as detected during a normal tag boot; allows the tag to skip detecting buttons and NFC chip
uint8_t customMode; // default 0; if anything else, tag will bootup in a different 'mode'
uint16_t batLowVoltage; // Low battery threshold voltage (2450 for 2.45v). defaults to BATTERY_VOLTAGE_MINIMUM from powermgt.h
uint16_t minimumCheckInTime; // defaults to BASE_INTERVAL from powermgt.h
uint8_t fixedChannel; // default 0; if set to a valid channel number, the tag will stick to that channel
} __attribute__((packed));
extern __attribute__((section(".aonshadow")))struct tagsettings tagSettings;
void loadDefaultSettings();

15
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/syncedproto.c Normal file → Executable file
View File

@@ -8,11 +8,11 @@
#include "main.h"
#include "mz100_sleep.h"
#include "powermgt.h"
#include "printf.h"
#include "proto.h"
#include "timer.h"
#include "util.h"
#include "zigbee.h"
#include "printf.h"
// download-stuff
uint8_t blockXferBuffer[BLOCK_XFER_BUFFER_SIZE] = {0};
@@ -438,11 +438,11 @@ static uint8_t findSlot(const uint8_t *ver) {
return 0xFF;
}
static void eraseUpdateBlock() {
eepromErase(EEPROM_UPDATA_AREA_START, (uint16_t)EEPROM_UPDATE_AREA_LEN);
qspiEraseRange(EEPROM_UPDATE_START, EEPROM_UPDATE_LEN);
}
static void saveUpdateBlockData(uint8_t blockId) {
printf("EEPROM writing UpdateBlock %i\n", blockId);
if (!eepromWrite(EEPROM_UPDATA_AREA_START + (blockId * BLOCK_DATA_SIZE), blockXferBuffer + sizeof(struct blockData), BLOCK_DATA_SIZE))
if (!eepromWrite(EEPROM_UPDATE_START + (blockId * BLOCK_DATA_SIZE), blockXferBuffer + sizeof(struct blockData), BLOCK_DATA_SIZE))
printf("EEPROM write failed\n");
}
static void saveImgBlockData(const uint8_t imgSlot, const uint8_t blockId) {
@@ -478,11 +478,9 @@ static uint32_t getHighSlotId() {
return temp;
}
static uint8_t partsThisBlock = 0;
static uint8_t 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.
static bool getDataBlock(const uint16_t blockSize) {
static uint8_t partsThisBlock = 0;
static uint8_t blockAttempts = 0;
blockAttempts = BLOCK_TRANSFER_ATTEMPTS;
if (blockSize == BLOCK_DATA_SIZE) {
partsThisBlock = BLOCK_MAX_PARTS;
@@ -587,6 +585,7 @@ static bool downloadFWUpdate(const struct AvailDataInfo *avail) {
curBlock.type = avail->dataType;
memcpy(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
eraseUpdateBlock();
delay(100);
}
while (curDataInfo.dataSize) {
@@ -767,7 +766,7 @@ bool processAvailDataInfo(struct AvailDataInfo *avail) {
powerUp(INIT_EEPROM);
wdt60s();
prvApplyUpdateIfNeeded();
applyUpdate();
} else {
return false;
}

View File

@@ -41,14 +41,13 @@ void addCapabilities() {
void addOverlay() {
if ((currentChannel == 0) && (tagSettings.enableNoRFSymbol)) {
// loadRawBitmap(ant, SCREEN_WIDTH - 24, 6, EPD_COLOR_BLACK);
// loadRawBitmap(cross, SCREEN_WIDTH - 16, 13, EPD_COLOR_RED);
drawImg(0, 3, norf);
noAPShown = true;
} else {
noAPShown = false;
}
if ((batteryVoltage < tagSettings.batLowVoltage) && (tagSettings.enableLowBatSymbol)) {
// loadRawBitmap(battery, SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, EPD_COLOR_BLACK);
drawImg(0, 366, batlow);
lowBatteryShown = true;
} else {
lowBatteryShown = false;
@@ -68,65 +67,39 @@ void afterFlashScreenSaver() {
}
void showSplashScreen() {
// selectLUT(EPD_LUT_NO_REPEATS);
// clearScreen();
#if (SCREEN_WIDTH == 400) // 4.2"
epdPrintBegin(3, 3, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("Starting");
epdPrintEnd();
epdPrintBegin(2, 252, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
addCapabilities();
epdPrintEnd();
epdPrintBegin(3, 268, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("zbs42v033 %d.%d.%d%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
epdPrintEnd();
epdPrintBegin(3, 284, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_RED);
epdpr("MAC: %02X:%02X", mSelfMac[7], mSelfMac[6]);
epdpr(":%02X:%02X", mSelfMac[5], mSelfMac[4]);
epdpr(":%02X:%02X", mSelfMac[3], mSelfMac[2]);
epdpr(":%02X:%02X", mSelfMac[1], mSelfMac[0]);
epdPrintEnd();
loadRawBitmap(oepli, 136, 22, EPD_COLOR_BLACK);
loadRawBitmap(cloud, 136, 10, EPD_COLOR_RED);
uint8_t __xdata buffer[17];
spr(buffer, "%02X%02X", mSelfMac[7], mSelfMac[6]);
spr(buffer + 4, "%02X%02X", mSelfMac[5], mSelfMac[4]);
spr(buffer + 8, "%02X%02X", mSelfMac[3], mSelfMac[2]);
spr(buffer + 12, "%02X%02X", mSelfMac[1], mSelfMac[0]);
printBarcode(buffer, 392, 264);
printBarcode(buffer, 384, 264);
#endif
// drawWithSleep();
init_epd();
fillWindow(0, 0, 640, 384, 1);
epdPrintf(10, 10, 1, "OpenEPaperLink starting!");
addOverlay();
epd_refresh_and_sleep(1);
}
void showApplyUpdate() {
// selectLUT(1);
// clearScreen();
#if (SCREEN_WIDTH == 400)
epdPrintBegin(136, 134, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
#endif
init_epd();
// epdpr("Updating!");
// epdPrintEnd();
// drawNoWait();
fillWindow(0, 0, 640, 384, 1);
epdPrintf(90, 170, 1, "Performing update... This shouldn't take too long!");
addOverlay();
epd_refresh_and_sleep(1);
}
void showAPFound() {
init_epd();
fillWindow(0, 0, 640, 384, 1);
epdPrintf(10, 10, 1, "OpenEPaperLink");
epdPrintf(10, 40, 1, "AP Found at channel %d", currentChannel);
epdPrintf(10, 60, 1, "AP MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
epdPrintf(10, 330, 1, "Battery: %d.%dV", batteryVoltage / 1000, batteryVoltage % 1000);
epdPrintf(10, 350, 1, "Tag MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
epd_refresh_and_sleep();
addOverlay();
epd_refresh_and_sleep(1);
}
void showNoAP() {
@@ -135,8 +108,8 @@ void showNoAP() {
epdPrintf(10, 10, 1, "OpenEPaperLink ");
epdPrintf(10, 40, 1, "No AP found... We'll try again in a little while though!");
epdPrintf(10, 350, 1, "Tag MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
epd_refresh_and_sleep();
addOverlay();
epd_refresh_and_sleep(1);
}
void showLongTermSleep() {

View File

@@ -1,67 +0,0 @@
name: "Close stale tickets"
on:
schedule:
- cron: "0 22 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
days-before-stale: 15
days-before-close: 15
exempt-issue-labels: triaged
exempt-pr-labels: triaged,contrib
stale-issue-message: |
Thanks for your submission. However there was no (further) activity
on it for some time. Below are possible reasons and/or means to
proceed further:
* Please make sure that your submission contains clear and complete
description of the issue and information required to understand and
reproduce it (exact version of all components involved, etc.). Please
refer to numerous guides on submitting helpful bugreports, e.g.
https://www.chiark.greenend.org.uk/~sgtatham/bugs.html
* Please make sure that your feature request/suggestion/change aligns
well with the project purpose, goals, and process.
* If you face the issue you report while working on a community-oriented
open-source project, feel free to provide additional context and
information - that may help to prioritize the issue better.
* As many open-source projects, this project is severely under-staffed
and under-resourced. If you don't run a community-oriented open-source
project, and would like to get additional support/maintenance, feel
free to request a support contract.
Thanks for your understanding!
stale-pr-message: |
Thanks for your submission. However there was no (further) activity
on it for some time. Below are possible reasons and/or means to
proceed further:
* Please make sure that your submission contains clear and complete
description of the issue and information required to understand and
reproduce it (exact version of all components involved, etc.). Please
refer to numerous guides on submitting helpful bugreports, e.g.
https://www.chiark.greenend.org.uk/~sgtatham/bugs.html
* Please make sure that your feature request/suggestion/change aligns
well with the project purpose, goals, and process.
* If you face the issue you report while working on a community-oriented
open-source project, feel free to provide additional context and
information - that may help to prioritize the issue better.
* As many open-source projects, this project is severely under-staffed
and under-resourced. If you don't run a community-oriented open-source
project, and would like to get additional support/maintenance, feel
free to request a support contract.
Thanks for your understanding!
close-issue-message: >
Closing due to inactivity.
close-pr-message: >
Closing due to inactivity.

View File

@@ -1,3 +0,0 @@
*.o
*.map
*.a

View File

@@ -1,65 +0,0 @@
Introduction
------------
uzlib as a whole is licensed under the terms of Zlib license, listed in
the next section. It consists of substantial works of individuals whose
copyrights listed in the next session. Some portions of the uzlib codebase
originally were licensed under different license(s), however compatible
with the Zlib license. Such license(s) are listed at the end of this file.
License
-------
uzlib - Deflate/Zlib-compatible LZ77 compression/decompression library
Copyright (c) 2003 Joergen Ibsen
Copyright (c) 1997-2014 Simon Tatham
Copyright (c) 2014-2020 Paul Sokolovsky
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
-------
Original license for src/defl_static.c:
PuTTY is copyright 1997-2014 Simon Tatham.
Portions copyright Robert de Bath, Joris van Rantwijk, Delian
Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
Kuhn, Colin Watson, and CORE SDI S.A.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,4 +0,0 @@
all clean:
$(MAKE) -C src $@
$(MAKE) -C examples/tgzip $@
$(MAKE) -C examples/tgunzip $@

View File

@@ -1,325 +0,0 @@
uzlib - Deflate/Zlib-compatible LZ77 compression/decompression library
======================================================================
uzlib is a library which can decompress any valid Deflate, Zlib, and Gzip
(further called just "Deflate") bitstream, and compress data to Deflate-
compatible bitstream, albeit with lower compression ratio than Zlib Deflate
algorithm (very basic LZ77 compression algorithm is used instead, static
Deflate Huffman tree encoding is used for bitstream).
uzlib aims for minimal code size and runtime memory requirements, and thus
suitable for (deeply) embedded systems.
uzlib is based on:
* tinf library by Joergen Ibsen (Deflate decompression)
* Deflate Static Huffman tree routines by Simon Tatham
* LZ77 compressor by Paul Sokolovsky
Library integrated and maintained by Paul Sokolovsky.
(c) 2014-2020 Paul Sokolovsky
uzlib library is licensed under Zlib license.
Decompressor features
---------------------
Handling of input (compressed) stream:
* Can reside (fully) in memory.
* Can be received, byte by byte, from an application-defined callback
function (which e.g. can read it from file or another I/O device).
* Combination of the above: a chunk of input is buffered in memory,
when buffer is exhausted, the application callback is called to refill
it.
Handling of output (decompressed) stream:
* In-memory decompression, where output stream fully resides in memory.
* Streaming decompression, which allows to process arbitrary-sized streams
(longer than available memory), but requires in-memory buffer for Deflate
dictionary window.
* Application specifies number of output bytes it wants to decompress,
which can be as high as UINT_MAX to decompress everything into memory
at once, or as low as 1 to decompress byte by byte, or any other value
to decompress a chunk of that size.
Note that in regard to input stream handling, uzlib employs callback-based,
"pull-style" design. The control flow looks as follows:
1. Application requests uzlib to decompress given number of bytes.
2. uzlib performs decompression.
3. If more input is needed to decompress given number of bytes, uzlib
calls back into application to provide more input bytes. (An
implication of this is that uzlib will always return given number of
output bytes, unless end of stream (or error) happens).
The original Zlib library instead features "push-style" design:
1. An application prepares arbitrary number of input bytes in a buffer,
and free space in output buffer, and calls Zlib with these buffers.
2. Zlib tries to decode as much as possible input and produce as much
as possible output. It returns back to the application if input
buffer is exhausted, or output buffer is full, whatever happens
first.
Currently, uzlib doesn't support push-style operation a-la Zlib.
Compressor features
-------------------
Compressor uses very basic implementation of LZ77 algorithm using hash
table to find repeating substrings. The size of the hash table (on which
compression efficiency depends), pointer to the hashtable memory, and
the size of LZ77 dictionary should be configured in `struct uzlib_comp`.
Currently, compressor doesn't support streaming operation, both input and
output must reside in memory. Neither it supports incremental operation,
entire input buffer is compressed at once with a single call to uzlib.
API and configuration
---------------------
The API is defined in the file [uzlib.h](src/uzlib.h) and should be largely
self-describing. There are also examples implementing gzip-compatible
compression and decompression applications in [examples/](examples/) for
further reference. (You may also refer to the original `tinf` README
below for additional information, but it's mostly provided for
historical reference, and `uzlib` largely evolved beyond it).
There are some compile-time options for the library, defined in
the file [uzlib_conf.h](src/uzlib_conf.h). They can be altered directly
in the file, or passed as the compiler options (`-DXXX=YYY`) when
building library.
Binary sizes
------------
To give an impression of code/data sizes of uzlib, the following figures
are provided. Numbers for *.o files are code sizes of individual
components (tinflate.o is decompressor, genlz77.o and defl_static.o -
compressor), and TINF_DATA is the size of the corresponding data
structure. These numbers are provided for different architectures,
with default uzlib configuration, and with compilers/their options
as specified.
```
gcc -m32 -Os
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
2891 src/tinflate.o
381 src/genlz77.o
1685 src/defl_static.o
1284 TINF_DATA
arm-none-eabi-gcc -mthumb -mcpu=cortex-m4 -Os
arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]
1620 src/tinflate.o
180 src/genlz77.o
1131 src/defl_static.o
1284 TINF_DATA
```
---
Original tinf library README
============================
*For historical reference and to provide proper credit, the original `tinf`
library README follows. NOTE: Many parts no longer apply to `uzlib`. In
particular, API is different, features supported are largely extended,
and during decompression, there are checks to avoid erroneous/undefined
behavior on incorrect Deflate bitstreams.*
tinf - tiny inflate library
===========================
Version 1.00
Copyright (c) 2003 Joergen Ibsen
<http://www.ibsensoftware.com/>
About
-----
tinf is a small library implementing the decompression algorithm for the
deflate compressed data format (called 'inflate'). Deflate compression is
used in e.g. zlib, gzip, zip and png.
I wrote it because I needed a small in-memory zlib decompressor for a self-
extracting archive, and the zlib library added 15k to my program. The tinf
code added only 2k.
Naturally the size difference is insignificant in most cases. Also, the
zlib library has many more features, is more secure, and mostly faster.
But if you have a project that calls for a small and simple deflate
decompressor, give it a try :-)
While the implementation should be fairly compliant, it does assume it is
given valid compressed data, and that there is sufficient space for the
decompressed data.
Simple wrappers for decompressing zlib streams and gzip'ed data in memory
are supplied.
tgunzip, an example command-line gzip decompressor in C, is included.
The inflate algorithm and data format are from 'DEFLATE Compressed Data
Format Specification version 1.3' ([RFC 1951][1]).
The zlib data format is from 'ZLIB Compressed Data Format Specification
version 3.3' ([RFC 1950][2]).
The gzip data format is from 'GZIP file format specification version 4.3'
([RFC 1952][3]).
Ideas for future versions:
- the fixed Huffman trees could be built by `tinf_decode_trees()`
using a small table
- memory for the `TINF_DATA` object should be passed, to avoid using
more than 1k of stack space
- wrappers for unpacking zip archives and png images
- implement more in x86 assembler
- more sanity checks
- in `tinf_uncompress`, the (entry value of) `destLen` and `sourceLen`
are not used
- blocking of some sort, so everything does not have to be in memory
- optional table-based huffman decoder
[1]: http://www.rfc-editor.org/rfc/rfc1951.txt
[2]: http://www.rfc-editor.org/rfc/rfc1950.txt
[3]: http://www.rfc-editor.org/rfc/rfc1952.txt
Functionality
-------------
void tinf_init();
Initialise the global uninitialised data used by the decompression code.
This function must be called once before any calls to the decompression
functions.
int tinf_uncompress(void *dest,
unsigned int *destLen,
const void *source,
unsigned int sourceLen);
Decompress data in deflate compressed format from `source[]` to `dest[]`.
`destLen` is set to the length of the decompressed data. Returns `TINF_OK`
on success, and `TINF_DATA_ERROR` on error.
int tinf_gzip_uncompress(void *dest,
unsigned int *destLen,
const void *source,
unsigned int sourceLen);
Decompress data in gzip compressed format from `source[]` to `dest[]`.
`destLen` is set to the length of the decompressed data. Returns `TINF_OK`
on success, and `TINF_DATA_ERROR` on error.
int tinf_zlib_uncompress(void *dest,
unsigned int *destLen,
const void *source,
unsigned int sourceLen);
Decompress data in zlib compressed format from `source[]` to `dest[]`.
`destLen` is set to the length of the decompressed data. Returns `TINF_OK`
on success, and `TINF_DATA_ERROR` on error.
unsigned int tinf_adler32(const void *data,
unsigned int length);
Computes the Adler-32 checksum of `length` bytes starting at `data`. Used by
`tinf_zlib_uncompress()`.
unsigned int tinf_crc32(const void *data,
unsigned int length);
Computes the CRC32 checksum of `length` bytes starting at `data`. Used by
`tinf_gzip_uncompress()`.
Source Code
-----------
The source code is ANSI C, and assumes that int is 32-bit. It has been
tested on the x86 platform under Windows and Linux.
The decompression functions should be endian-neutral, and also reentrant
and thread-safe (not tested).
In src/nasm there are 32-bit x86 assembler (386+) versions of some of the
files.
Makefiles (GNU Make style) for a number of compilers are included.
Frequently Asked Questions
--------------------------
Q: Is it really free? Can I use it in my commercial ExpenZip software?
A: It's open-source software, available under the zlib license (see
later), which means you can use it for free -- even in commercial
products. If you do, please be kind enough to add an acknowledgement.
Q: Did you just strip stuff from the zlib source to make it smaller?
A: No, tinf was written from scratch, using the RFC documentation of
the formats it supports.
Q: What do you mean by: 'the zlib library .. is more secure'?
A: The zlib decompression code checks the compressed data for validity
while decompressing, so even on corrupted data it will not crash.
The tinf code assumes it is given valid compressed data.
Q: I'm a Delphi programmer, can I use tinf?
A: Sure, the object files produced by both Borland C and Watcom C should
be linkable with Delphi.
Q: Will tinf work on UltraSTRANGE machines running WhackOS?
A: I have no idea .. please try it out and let me know!
Q: Why are all the makefiles in GNU Make style?
A: I'm used to GNU Make, and it has a number of features that are missing
in some of the other Make utilities.
Q: This is the first release, how can there be frequently asked questions?
A: Ok, ok .. I made the questions up ;-)
License
-------
tinf - tiny inflate library
Copyright (c) 2003 Joergen Ibsen
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.

View File

@@ -1,31 +0,0 @@
##
## tgunzip - gzip decompressor example
##
## GCC makefile (Linux, FreeBSD, BeOS and QNX)
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
## http://www.ibsensoftware.com/
##
target = tgunzip
objects = tgunzip.o
libs = ../../lib/libtinf.a
COPT = -Os
CFLAGS = -Wall -I../../src $(COPT)
LDFLAGS = $(CFLAGS) -s -Wl,-Map,ld.map
.PHONY: all clean
all: $(target)
$(target): $(objects) $(libs)
$(CC) $(LDFLAGS) -o $@ $^ $(libs)
%.o : %.c
$(CC) $(CFLAGS) -c $<
clean:
$(RM) $(objects) $(target)

View File

@@ -1,31 +0,0 @@
##
## tgunzip - gzip decompressor example
##
## Borland C/C++ makefile (GNU Make)
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
## http://www.ibsensoftware.com/
##
target = tgunzip.exe
objects = tgunzip.obj
libs = ..\..\lib\tinf.lib
temps = tgunzip.tds
cflags = -a16 -K -O2 -OS -I..\..\src
ldflags = -C -q -Gn -x -Gz -ap -Tpe
.PHONY: all clean
all: $(target)
$(target): $(objects)
ilink32 $(ldflags) c0x32 $(objects), $@ , , import32 cw32 $(libs) , ,
%.obj : %.c
bcc32 $(cflags) -c $<
clean:
$(RM) $(objects) $(target) $(temps)

View File

@@ -1,30 +0,0 @@
##
## tgunzip - gzip decompressor example
##
## DJGPP makefile
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
## http://www.ibsensoftware.com/
##
target = tgunzip.exe
objects = tgunzip.o
libs = ../../lib/libtinf.a
cflags = -s -Wall -Os -fomit-frame-pointer -I../../src
ldflags = $(cflags)
.PHONY: all clean
all: $(target)
$(target): $(objects)
gcc $(ldflags) -o $@ $^ $(libs)
%.o : %.c
gcc $(cflags) -o $@ -c $<
clean:
$(RM) $(objects) $(target)

View File

@@ -1,31 +0,0 @@
##
## tgunzip - gzip decompressor example
##
## Digital Mars C/C++ makefile (GNU Make)
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
## http://www.ibsensoftware.com/
##
target = tgunzip.exe
objects = tgunzip.obj
libs = ..\..\lib\tinf.lib
temps = tgunzip.map
cflags = -s -mn -o+all -I..\..\src
ldflags = $(cflags)
.PHONY: all clean
all: $(target)
$(target): $(objects)
dmc $(ldflags) -o$@ $^ $(libs)
%.obj : %.c
dmc $(cflags) -c $<
clean:
$(RM) $(objects) $(target) $(temps)

View File

@@ -1,28 +0,0 @@
##
## tgunzip - gzip decompressor example
##
## MinGW / Cygwin makefile
##
## Copyright (c) 1998-2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
target = tgunzip.exe
objects = tgunzip.o
libs = ../../lib/libtinf.a
cflags = -s -Wall -Os -fomit-frame-pointer -I../../src
ldflags = $(cflags)
.PHONY: all clean
all: $(target)
$(target): $(objects)
gcc $(ldflags) -o $@ $^ $(libs)
%.o : %.c
gcc $(cflags) -o $@ -c $<
clean:
$(RM) $(target) $(objects)

View File

@@ -1,28 +0,0 @@
##
## tgunzip - gzip decompressor example
##
## Visual C/C++ makefile (GNU Make)
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
target = tgunzip.exe
objects = tgunzip.obj
libs = ../../lib/tinf.lib
cflags = /nologo /W3 /O1 /G6 /W3 /Gy /GF /I..\..\src
ldflags = /nologo /release /opt:ref /opt:icf
.PHONY: all clean
all: $(target)
$(target): $(objects)
link $(ldflags) /out:$@ $^ $(libs)
%.obj : %.c
cl $(cflags) -c $<
clean:
$(RM) $(target) $(objects)

View File

@@ -1,31 +0,0 @@
##
## tgunzip - gzip decompressor example
##
## Watcom / OpenWatcom C/C++ makefile (GNU Make)
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
## http://www.ibsensoftware.com/
##
target = tgunzip.exe
objects = tgunzip.obj
libs = ../../lib/tinf.lib
system = nt
cflags = -bt=$(system) -d0 -ox -I..\..\src
ldflags = system $(system)
.PHONY: all clean
all: $(target)
$(target): $(objects)
wlink $(ldflags) name $@ file {$^} library {$(libs)}
%.obj : %.c
wcc386 $(cflags) $<
clean:
$(RM) $(objects) $(target)

View File

@@ -1,167 +0,0 @@
/*
* tgunzip - gzip decompressor example
*
* Copyright (c) 2003 by Joergen Ibsen / Jibz
* All Rights Reserved
*
* http://www.ibsensoftware.com/
*
* Copyright (c) 2014-2016 by Paul Sokolovsky
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
#include <stdlib.h>
#include <stdio.h>
#include "uzlib.h"
/* produce decompressed output in chunks of this size */
/* default is to decompress byte by byte; can be any other length */
#define OUT_CHUNK_SIZE 1
void exit_error(const char *what)
{
printf("ERROR: %s\n", what);
exit(1);
}
int main(int argc, char *argv[])
{
FILE *fin, *fout;
unsigned int len, dlen, outlen;
const unsigned char *source;
unsigned char *dest;
int res;
printf("tgunzip - example from the tiny inflate library (www.ibsensoftware.com)\n\n");
if (argc < 3)
{
printf(
"Syntax: tgunzip <source> <destination>\n\n"
"Both input and output are kept in memory, so do not use this on huge files.\n");
return 1;
}
uzlib_init();
/* -- open files -- */
if ((fin = fopen(argv[1], "rb")) == NULL) exit_error("source file");
if ((fout = fopen(argv[2], "wb")) == NULL) exit_error("destination file");
/* -- read source -- */
fseek(fin, 0, SEEK_END);
len = ftell(fin);
fseek(fin, 0, SEEK_SET);
source = (unsigned char *)malloc(len);
if (source == NULL) exit_error("memory");
if (fread((unsigned char*)source, 1, len, fin) != len) exit_error("read");
fclose(fin);
if (len < 4) exit_error("file too small");
/* -- get decompressed length -- */
dlen = source[len - 1];
dlen = 256*dlen + source[len - 2];
dlen = 256*dlen + source[len - 3];
dlen = 256*dlen + source[len - 4];
outlen = dlen;
/* there can be mismatch between length in the trailer and actual
data stream; to avoid buffer overruns on overlong streams, reserve
one extra byte */
dlen++;
dest = (unsigned char *)malloc(dlen);
if (dest == NULL) exit_error("memory");
/* -- decompress data -- */
struct uzlib_uncomp d;
// uzlib_uncompress_init(&d, malloc(32768), 32768);
uzlib_uncompress_init(&d, NULL, 0);
/* all 3 fields below must be initialized by user */
d.source = source;
d.source_limit = source + len - 4;
d.source_read_cb = NULL;
res = uzlib_gzip_parse_header(&d);
if (res != TINF_OK) {
printf("Error parsing header: %d\n", res);
exit(1);
}
d.dest_start = d.dest = dest;
while (dlen) {
unsigned int chunk_len = dlen < OUT_CHUNK_SIZE ? dlen : OUT_CHUNK_SIZE;
d.dest_limit = d.dest + chunk_len;
res = uzlib_uncompress_chksum(&d);
dlen -= chunk_len;
if (res != TINF_OK) {
break;
}
}
if (res != TINF_DONE) {
printf("Error during decompression: %d\n", res);
exit(-res);
}
printf("decompressed %lu bytes\n", d.dest - dest);
#if 0
if (d.dest - dest != gz.dlen) {
printf("Invalid decompressed length: %lu vs %u\n", d.dest - dest, gz.dlen);
}
if (tinf_crc32(dest, gz.dlen) != gz.crc32) {
printf("Invalid decompressed crc32\n");
}
#endif
/* -- write output -- */
fwrite(dest, 1, outlen, fout);
fclose(fout);
return 0;
}

View File

@@ -1,31 +0,0 @@
##
## tgzip - gzip compressor example
##
## GCC makefile (Linux, FreeBSD, BeOS and QNX)
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## Copyright (c) 2014 by Paul Sokolovsky
##
## http://www.ibsensoftware.com/
##
target = tgzip
objects = tgzip.o
libs = ../../lib/libtinf.a
COPT = -Os
CFLAGS = -Wall -I../../src $(COPT)
LDFLAGS = $(CFLAGS) -s -Wl,-Map,ld.map
.PHONY: all clean
all: $(target)
$(target): $(objects) $(libs)
$(CC) $(LDFLAGS) -o $@ $^ $(libs)
%.o : %.c
$(CC) $(CFLAGS) -c $<
clean:
$(RM) $(objects) $(target)

View File

@@ -1,120 +0,0 @@
/*
* tgzip - gzip compressor example
*
* Copyright (c) 2003 by Joergen Ibsen / Jibz
* Copyright (c) 2014-2018 by Paul Sokolovsky
*
* http://www.ibsensoftware.com/
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "uzlib.h"
void exit_error(const char *what)
{
printf("ERROR: %s\n", what);
exit(1);
}
int main(int argc, char *argv[])
{
FILE *fin, *fout;
unsigned int len;
unsigned char *source;
printf("tgzip - example from the uzlib library\n\n");
if (argc < 3)
{
printf(
"Syntax: tgunzip <source> <destination>\n\n"
"Both input and output are kept in memory, so do not use this on huge files.\n");
return 1;
}
/* -- open files -- */
if ((fin = fopen(argv[1], "rb")) == NULL) exit_error("source file");
if ((fout = fopen(argv[2], "wb")) == NULL) exit_error("destination file");
/* -- read source -- */
fseek(fin, 0, SEEK_END);
len = ftell(fin);
fseek(fin, 0, SEEK_SET);
source = (unsigned char *)malloc(len);
if (source == NULL) exit_error("memory");
if (fread(source, 1, len, fin) != len) exit_error("read");
fclose(fin);
/* -- compress data -- */
struct uzlib_comp comp = {0};
comp.dict_size = 32768;
comp.hash_bits = 12;
size_t hash_size = sizeof(uzlib_hash_entry_t) * (1 << comp.hash_bits);
comp.hash_table = malloc(hash_size);
memset(comp.hash_table, 0, hash_size);
zlib_start_block(&comp);
uzlib_compress(&comp, source, len);
zlib_finish_block(&comp);
printf("compressed to %u raw bytes\n", comp.outlen);
/* -- write output -- */
putc(0x1f, fout);
putc(0x8b, fout);
putc(0x08, fout);
putc(0x00, fout); // FLG
int mtime = 0;
fwrite(&mtime, sizeof(mtime), 1, fout);
putc(0x04, fout); // XFL
putc(0x03, fout); // OS
fwrite(comp.outbuf, 1, comp.outlen, fout);
unsigned crc = ~uzlib_crc32(source, len, ~0);
fwrite(&crc, sizeof(crc), 1, fout);
fwrite(&len, sizeof(len), 1, fout);
fclose(fout);
return 0;
}

View File

@@ -1 +0,0 @@
--- empty dir ---

View File

@@ -1,78 +0,0 @@
/*
* Adler-32 checksum
*
* Copyright (c) 2003 by Joergen Ibsen / Jibz
* All Rights Reserved
*
* http://www.ibsensoftware.com/
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
/*
* Adler-32 algorithm taken from the zlib source, which is
* Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
*/
#include "tinf.h"
#define A32_BASE 65521
#define A32_NMAX 5552
uint32_t uzlib_adler32(const void *data, unsigned int length, uint32_t prev_sum /* 1 */)
{
const unsigned char *buf = (const unsigned char *)data;
unsigned int s1 = prev_sum & 0xffff;
unsigned int s2 = prev_sum >> 16;
while (length > 0)
{
int k = length < A32_NMAX ? length : A32_NMAX;
int i;
for (i = k / 16; i; --i, buf += 16)
{
s1 += buf[0]; s2 += s1; s1 += buf[1]; s2 += s1;
s1 += buf[2]; s2 += s1; s1 += buf[3]; s2 += s1;
s1 += buf[4]; s2 += s1; s1 += buf[5]; s2 += s1;
s1 += buf[6]; s2 += s1; s1 += buf[7]; s2 += s1;
s1 += buf[8]; s2 += s1; s1 += buf[9]; s2 += s1;
s1 += buf[10]; s2 += s1; s1 += buf[11]; s2 += s1;
s1 += buf[12]; s2 += s1; s1 += buf[13]; s2 += s1;
s1 += buf[14]; s2 += s1; s1 += buf[15]; s2 += s1;
}
for (i = k % 16; i; --i) { s1 += *buf++; s2 += s1; }
s1 %= A32_BASE;
s2 %= A32_BASE;
length -= k;
}
return ((uint32_t)s2 << 16) | s1;
}

View File

@@ -1,63 +0,0 @@
/*
* CRC32 checksum
*
* Copyright (c) 1998-2003 by Joergen Ibsen / Jibz
* All Rights Reserved
*
* http://www.ibsensoftware.com/
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
/*
* CRC32 algorithm taken from the zlib source, which is
* Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
*/
#include "tinf.h"
static const uint32_t tinf_crc32tab[16] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190,
0x6b6b51f4, 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344,
0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278,
0xbdbdf21c
};
/* crc is previous value for incremental computation, 0xffffffff initially */
uint32_t uzlib_crc32(const void *data, unsigned int length, uint32_t crc)
{
const unsigned char *buf = (const unsigned char *)data;
unsigned int i;
for (i = 0; i < length; ++i)
{
crc ^= buf[i];
crc = tinf_crc32tab[crc & 0x0f] ^ (crc >> 4);
crc = tinf_crc32tab[crc & 0x0f] ^ (crc >> 4);
}
// return value suitable for passing in next time, for final value invert it
return crc/* ^ 0xffffffff*/;
}

View File

@@ -1,318 +0,0 @@
/*
Routines in this file are based on:
Zlib (RFC1950 / RFC1951) compression for PuTTY.
PuTTY is copyright 1997-2014 Simon Tatham.
Portions copyright Robert de Bath, Joris van Rantwijk, Delian
Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
Kuhn, Colin Watson, and CORE SDI S.A.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include "uzlib.h"
#include "defl_static.h"
#define snew(type) ( (type *) malloc(sizeof(type)) )
#define snewn(n, type) ( (type *) malloc((n) * sizeof(type)) )
#define sresize(x, n, type) ( (type *) realloc((x), (n) * sizeof(type)) )
#define sfree(x) ( free((x)) )
#ifndef FALSE
#define FALSE 0
#define TRUE (!FALSE)
#endif
/* ----------------------------------------------------------------------
* Zlib compression. We always use the static Huffman tree option.
* Mostly this is because it's hard to scan a block in advance to
* work out better trees; dynamic trees are great when you're
* compressing a large file under no significant time constraint,
* but when you're compressing little bits in real time, things get
* hairier.
*
* I suppose it's possible that I could compute Huffman trees based
* on the frequencies in the _previous_ block, as a sort of
* heuristic, but I'm not confident that the gain would balance out
* having to transmit the trees.
*/
void outbits(struct uzlib_comp *out, unsigned long bits, int nbits)
{
assert(out->noutbits + nbits <= 32);
out->outbits |= bits << out->noutbits;
out->noutbits += nbits;
while (out->noutbits >= 8) {
if (out->outlen >= out->outsize) {
out->outsize = out->outlen + 64;
out->outbuf = sresize(out->outbuf, out->outsize, unsigned char);
}
out->outbuf[out->outlen++] = (unsigned char) (out->outbits & 0xFF);
out->outbits >>= 8;
out->noutbits -= 8;
}
}
static const unsigned char mirrorbytes[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
};
typedef struct {
uint8_t extrabits;
uint8_t min, max;
} len_coderecord;
typedef struct {
uint8_t code, extrabits;
uint16_t min, max;
} dist_coderecord;
#define TO_LCODE(x, y) x - 3, y - 3
#define FROM_LCODE(x) (x + 3)
static const len_coderecord lencodes[] = {
{0, TO_LCODE(3, 3)},
{0, TO_LCODE(4, 4)},
{0, TO_LCODE(5, 5)},
{0, TO_LCODE(6, 6)},
{0, TO_LCODE(7, 7)},
{0, TO_LCODE(8, 8)},
{0, TO_LCODE(9, 9)},
{0, TO_LCODE(10, 10)},
{1, TO_LCODE(11, 12)},
{1, TO_LCODE(13, 14)},
{1, TO_LCODE(15, 16)},
{1, TO_LCODE(17, 18)},
{2, TO_LCODE(19, 22)},
{2, TO_LCODE(23, 26)},
{2, TO_LCODE(27, 30)},
{2, TO_LCODE(31, 34)},
{3, TO_LCODE(35, 42)},
{3, TO_LCODE(43, 50)},
{3, TO_LCODE(51, 58)},
{3, TO_LCODE(59, 66)},
{4, TO_LCODE(67, 82)},
{4, TO_LCODE(83, 98)},
{4, TO_LCODE(99, 114)},
{4, TO_LCODE(115, 130)},
{5, TO_LCODE(131, 162)},
{5, TO_LCODE(163, 194)},
{5, TO_LCODE(195, 226)},
{5, TO_LCODE(227, 257)},
{0, TO_LCODE(258, 258)},
};
static const dist_coderecord distcodes[] = {
{0, 0, 1, 1},
{1, 0, 2, 2},
{2, 0, 3, 3},
{3, 0, 4, 4},
{4, 1, 5, 6},
{5, 1, 7, 8},
{6, 2, 9, 12},
{7, 2, 13, 16},
{8, 3, 17, 24},
{9, 3, 25, 32},
{10, 4, 33, 48},
{11, 4, 49, 64},
{12, 5, 65, 96},
{13, 5, 97, 128},
{14, 6, 129, 192},
{15, 6, 193, 256},
{16, 7, 257, 384},
{17, 7, 385, 512},
{18, 8, 513, 768},
{19, 8, 769, 1024},
{20, 9, 1025, 1536},
{21, 9, 1537, 2048},
{22, 10, 2049, 3072},
{23, 10, 3073, 4096},
{24, 11, 4097, 6144},
{25, 11, 6145, 8192},
{26, 12, 8193, 12288},
{27, 12, 12289, 16384},
{28, 13, 16385, 24576},
{29, 13, 24577, 32768},
};
void zlib_literal(struct uzlib_comp *out, unsigned char c)
{
if (out->comp_disabled) {
/*
* We're in an uncompressed block, so just output the byte.
*/
outbits(out, c, 8);
return;
}
if (c <= 143) {
/* 0 through 143 are 8 bits long starting at 00110000. */
outbits(out, mirrorbytes[0x30 + c], 8);
} else {
/* 144 through 255 are 9 bits long starting at 110010000. */
outbits(out, 1 + 2 * mirrorbytes[0x90 - 144 + c], 9);
}
}
void zlib_match(struct uzlib_comp *out, int distance, int len)
{
const dist_coderecord *d;
const len_coderecord *l;
int i, j, k;
int lcode;
assert(!out->comp_disabled);
while (len > 0) {
int thislen;
/*
* We can transmit matches of lengths 3 through 258
* inclusive. So if len exceeds 258, we must transmit in
* several steps, with 258 or less in each step.
*
* Specifically: if len >= 261, we can transmit 258 and be
* sure of having at least 3 left for the next step. And if
* len <= 258, we can just transmit len. But if len == 259
* or 260, we must transmit len-3.
*/
thislen = (len > 260 ? 258 : len <= 258 ? len : len - 3);
len -= thislen;
/*
* Binary-search to find which length code we're
* transmitting.
*/
i = -1;
j = sizeof(lencodes) / sizeof(*lencodes);
while (1) {
assert(j - i >= 2);
k = (j + i) / 2;
if (thislen < FROM_LCODE(lencodes[k].min))
j = k;
else if (thislen > FROM_LCODE(lencodes[k].max))
i = k;
else {
l = &lencodes[k];
break; /* found it! */
}
}
lcode = l - lencodes + 257;
/*
* Transmit the length code. 256-279 are seven bits
* starting at 0000000; 280-287 are eight bits starting at
* 11000000.
*/
if (lcode <= 279) {
outbits(out, mirrorbytes[(lcode - 256) * 2], 7);
} else {
outbits(out, mirrorbytes[0xc0 - 280 + lcode], 8);
}
/*
* Transmit the extra bits.
*/
if (l->extrabits)
outbits(out, thislen - FROM_LCODE(l->min), l->extrabits);
/*
* Binary-search to find which distance code we're
* transmitting.
*/
i = -1;
j = sizeof(distcodes) / sizeof(*distcodes);
while (1) {
assert(j - i >= 2);
k = (j + i) / 2;
if (distance < distcodes[k].min)
j = k;
else if (distance > distcodes[k].max)
i = k;
else {
d = &distcodes[k];
break; /* found it! */
}
}
/*
* Transmit the distance code. Five bits starting at 00000.
*/
outbits(out, mirrorbytes[d->code * 8], 5);
/*
* Transmit the extra bits.
*/
if (d->extrabits)
outbits(out, distance - d->min, d->extrabits);
}
}
void zlib_start_block(struct uzlib_comp *out)
{
// outbits(out, 0x9C78, 16);
outbits(out, 1, 1); /* Final block */
outbits(out, 1, 2); /* Static huffman block */
}
void zlib_finish_block(struct uzlib_comp *out)
{
outbits(out, 0, 7); /* close block */
outbits(out, 0, 7); /* Make sure all bits are flushed */
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright (c) uzlib authors
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
/* This files contains type declaration and prototypes for defl_static.c.
They may be altered/distinct from the originals used in PuTTY source
code. */
void outbits(struct uzlib_comp *ctx, unsigned long bits, int nbits);
void zlib_start_block(struct uzlib_comp *ctx);
void zlib_finish_block(struct uzlib_comp *ctx);
void zlib_literal(struct uzlib_comp *ctx, unsigned char c);
void zlib_match(struct uzlib_comp *ctx, int distance, int len);

View File

@@ -1,124 +0,0 @@
/*
* genlz77 - Generic LZ77 compressor
*
* Copyright (c) 2014 by Paul Sokolovsky
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "uzlib.h"
#if 0
#define HASH_BITS 12
#else
#define HASH_BITS data->hash_bits
#endif
#define HASH_SIZE (1<<HASH_BITS)
/* Minimum and maximum length of matches to look for, inclusive */
#define MIN_MATCH 3
#define MAX_MATCH 258
/* Max offset of the match to look for, inclusive */
#if 0
#define MAX_OFFSET 32768
#else
#define MAX_OFFSET data->dict_size
#endif
/* Hash function can be defined as macro or as inline function */
/*#define HASH(p) (p[0] + p[1] + p[2])*/
/* This is hash function from liblzf */
static inline int HASH(struct uzlib_comp *data, const uint8_t *p) {
int v = (p[0] << 16) | (p[1] << 8) | p[2];
int hash = ((v >> (3*8 - HASH_BITS)) - v) & (HASH_SIZE - 1);
return hash;
}
#ifdef DUMP_LZTXT
/* Counter for approximate compressed length in LZTXT mode. */
/* Literal is counted as 1, copy as 2 bytes. */
unsigned approx_compressed_len;
void literal(void *data, uint8_t val)
{
printf("L%02x # %c\n", val, (val >= 0x20 && val <= 0x7e) ? val : '?');
approx_compressed_len++;
}
void copy(void *data, unsigned offset, unsigned len)
{
printf("C-%u,%u\n", offset, len);
approx_compressed_len += 2;
}
#else
static inline void literal(void *data, uint8_t val)
{
zlib_literal(data, val);
}
static inline void copy(void *data, unsigned offset, unsigned len)
{
zlib_match(data, offset, len);
}
#endif
void uzlib_compress(struct uzlib_comp *data, const uint8_t *src, unsigned slen)
{
const uint8_t *top = src + slen - MIN_MATCH;
while (src < top) {
int h = HASH(data, src);
const uint8_t **bucket = &data->hash_table[h & (HASH_SIZE - 1)];
const uint8_t *subs = *bucket;
*bucket = src;
if (subs && src > subs && (src - subs) <= MAX_OFFSET && !memcmp(src, subs, MIN_MATCH)) {
src += MIN_MATCH;
const uint8_t *m = subs + MIN_MATCH;
int len = MIN_MATCH;
while (*src == *m && len < MAX_MATCH && src < top) {
src++; m++; len++;
}
copy(data, src - len - subs, len);
} else {
literal(data, *src++);
}
}
// Process buffer tail, which is less than MIN_MATCH
// (and so it doesn't make sense to look for matches there)
top += MIN_MATCH;
while (src < top) {
literal(data, *src++);
}
}

View File

@@ -1,36 +0,0 @@
##
## tinflib - tiny inflate library (inflate, gzip, zlib)
##
## GCC makefile (Linux, FreeBSD, BeOS and QNX)
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
## http://www.ibsensoftware.com/
##
target = ../lib/libtinf.a
objects = tinflate.o tinfgzip.o tinfzlib.o adler32.o crc32.o \
defl_static.o genlz77.o
COPT = -Os
CFLAGS = -Wall $(COPT)
LDFLAGS = $(CFLAGS) -s
.PHONY: all clean
all: $(target)
$(target): $(objects)
$(RM) $@
ar -frs $@ $^
ranlib $@
%.o : %.c
$(CC) $(CFLAGS) -o $@ -c $<
%.o : %.nas
nasm -o $@ -f elf -D_ELF_ -O3 -Inasm/ $<
clean:
$(RM) $(objects) $(target)

View File

@@ -1,34 +0,0 @@
##
## tinflib - tiny inflate library (inflate, gzip, zlib)
##
## Borland C/C++ makefile (GNU Make)
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
## http://www.ibsensoftware.com/
##
target = ..\lib\tinf.lib
objects = tinflate.obj tinfgzip.obj tinfzlib.obj adler32.obj crc32.obj
cflags = -a16 -K -O2 -OS
.PHONY: all clean
all: $(target)
$(target): $(objects)
$(RM) $@
echo $(patsubst %,+%,$(objects)) >> lib.cmd
tlib $@ /C @lib.cmd
$(RM) lib.cmd
%.obj : %.c
bcc32 $(cflags) -c $<
%.obj : %.nas
nasm -o $@ -f obj -D_OBJ_ -O3 -Inasm/ $<
clean:
$(RM) $(objects) $(target) $(temps)

View File

@@ -1,33 +0,0 @@
##
## tinflib - tiny inflate library (inflate, gzip, zlib)
##
## DJGPP makefile
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
## http://www.ibsensoftware.com/
##
target = ../lib/libtinf.a
objects = tinflate.o tinfgzip.o tinfzlib.o adler32.o crc32.o
cflags = -s -Wall -Os -fomit-frame-pointer
.PHONY: all clean
all: $(target)
$(target): $(objects)
$(RM) $@
ar -frsv $@ $^
ranlib $@
%.o : %.c
gcc $(cflags) -o $@ -c $<
%.o : %.nas
nasm -o $@ -f coff -O3 -Inasm/ $<
clean:
$(RM) $(objects) $(target)

View File

@@ -1,32 +0,0 @@
##
## tinflib - tiny inflate library (inflate, gzip, zlib)
##
## Digital Mars C/C++ makefile (GNU Make)
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
## http://www.ibsensoftware.com/
##
target = ..\lib\tinf.lib
objects = tinflate.obj tinfgzip.obj tinfzlib.obj adler32.obj crc32.obj
cflags = -s -mn -o+all
.PHONY: all clean
all: $(target)
$(target): $(objects)
$(RM) $@
lib -c $@ $^
%.obj : %.c
dmc $(cflags) -c $<
%.obj : %.nas
nasm -o $@ -f obj -D_OBJ_ -O3 $<
clean:
$(RM) $(objects) $(target) $(temps)

View File

@@ -1,31 +0,0 @@
##
## tinflib - tiny inflate library (inflate, gzip, zlib)
##
## MinGW / Cygwin makefile
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
target = ../lib/libtinf.a
objects = tinflate.o tinfgzip.o tinfzlib.o adler32.o crc32.o
cflags = -s -Wall -Os -fomit-frame-pointer
.PHONY: all clean
all: $(target)
$(target): $(objects)
$(RM) $@
ar -frsv $@ $^
ranlib $@
%.o : %.c
gcc $(cflags) -o $@ -c $<
%.o : %.nas
nasm -o $@ -f win32 -O3 -Inasm/ $<
clean:
$(RM) $(target) $(objects)

View File

@@ -1,30 +0,0 @@
##
## tinflib - tiny inflate library (inflate, gzip, zlib)
##
## Visual C++ Makefile (GNU Make)
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
target = ../lib/tinf.lib
objects = tinflate.obj tinfgzip.obj tinfzlib.obj adler32.obj crc32.obj
cflags = /nologo /W3 /O1 /G6 /W3 /Gy /GF
.PHONY: all clean
all: $(target)
$(target): $(objects)
$(RM) $@
lib /OUT:$@ $^
%.obj : %.c
cl $(cflags) -c $<
%.obj : %.nas
nasm -o $@ -f win32 -O3 -Inasm/ $<
clean:
$(RM) $(target) $(objects)

View File

@@ -1,35 +0,0 @@
##
## tinflib - tiny inflate library (inflate, gzip, zlib)
##
## Watcom / OpenWatcom C/C++ makefile (GNU Make)
##
## Copyright (c) 2003 by Joergen Ibsen / Jibz
## All Rights Reserved
##
## http://www.ibsensoftware.com/
##
target = ..\lib\tinf.lib
objects = tinflate.obj tinfgzip.obj tinfzlib.obj adler32.obj crc32.obj
system = nt
cflags = -bt=$(system) -d0 -obmlrs -s -zl
.PHONY: all clean
all: $(target)
$(target): $(objects)
$(RM) $@
echo $(patsubst %,+%,$(objects)) >> lib.cmd
wlib -c -n -q -s -fo -io $@ @lib.cmd
$(RM) lib.cmd
%.obj : %.c
wcc386 $(cflags) $<
%.obj : %.nas
nasm -o $@ -f obj -D_OBJ_ -O3 -Inasm/ $<
clean:
$(RM) $(objects) $(target)

View File

@@ -1,118 +0,0 @@
;;
;; NASM assembler crc32
;;
;; Copyright (c) 1998-2003 by Joergen Ibsen / Jibz
;; All Rights Reserved
;;
;; http://www.ibsensoftware.com/
;;
;; This software is provided 'as-is', without any express
;; or implied warranty. In no event will the authors be
;; held liable for any damages arising from the use of
;; this software.
;;
;; Permission is granted to anyone to use this software
;; for any purpose, including commercial applications,
;; and to alter it and redistribute it freely, subject to
;; the following restrictions:
;;
;; 1. The origin of this software must not be
;; misrepresented; you must not claim that you
;; wrote the original software. If you use this
;; software in a product, an acknowledgment in
;; the product documentation would be appreciated
;; but is not required.
;;
;; 2. Altered source versions must be plainly marked
;; as such, and must not be misrepresented as
;; being the original software.
;;
;; 3. This notice may not be removed or altered from
;; any source distribution.
;;
; CRC32 algorithm taken from the zlib source, which is
; Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
cpu 386
bits 32
%include "nasmlcm.inc"
section lcmtext
lcmglobal tinf_crc32,8
lcmexport tinf_crc32,8
; =============================================================
lcmlabel tinf_crc32,8
; tinf_crc32(const void *data,
; unsigned int length);
.len$ equ 2*4 + 4 + 4
.dat$ equ 2*4 + 4
push esi
push edi
mov esi, [esp + .dat$] ; esi -> buffer
mov ecx, [esp + .len$] ; ecx = length
sub eax, eax ; crc = 0
test esi, esi
jz short .c_exit
test ecx, ecx
jz short .c_exit
dec eax ; crc = 0xffffffff
%ifdef _OBJ_
mov edi, tinf_crc32tab wrt FLAT ; edi -> crctab
%else
mov edi, tinf_crc32tab ; edi -> crctab
%endif
.c_next_byte:
xor al, [esi]
inc esi
mov edx, 0x0f
and edx, eax
shr eax, 4
xor eax, [edi + edx*4]
mov edx, 0x0f
and edx, eax
shr eax, 4
xor eax, [edi + edx*4]
dec ecx
jnz short .c_next_byte
not eax
.c_exit:
pop edi
pop esi
lcmret 8
; =============================================================
section lcmdata
tinf_crc32tab dd 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190
dd 0x6b6b51f4, 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344
dd 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278
dd 0xbdbdf21c
; =============================================================

View File

@@ -1,326 +0,0 @@
;;
;; NASM linker compatibility macros 2002.07.24
;;
;; Copyright (c) 2001-2003 by Joergen Ibsen / Jibz
;; All Rights Reserved
;;
;; http://www.ibsensoftware.com/
;;
; define _ELF_ for ELF32 object files
; define _OBJ_ for OMF object files
; define _OBJ_ and _DLL_ for OMF object files for a dll (stdcall)
; define _MSLIBS_ for MS style Win32 import libs (lcmwinextern)
; default is DJGPP/WIN32 COFF object files
; remember to do lcm*extern before lcmimport
; ====================================================================
;
; There are differences between how the object formats that NASM
; supports work, and what features they support. Similarly there
; are differences between how complete and standard compliant the
; support for these formats are in linkers.
;
; The NASM linker compatibility macros (nasmlcm) were put together
; to ease my work by allowing a single source file to be assembled
; for use with a number of compilers/linkers.
;
; Currently obj/omf, win32/coff, djgpp/coff and elf32 output formats
; are supported. The following macros are available:
;
; lcmtext - section name for the code section
; lcmdata - section name for the initialized data section
; lcmbss - section name for the uninitialized data section
;
; lcmglobal - declare a function (two arguments) or data (one
; argument) as global in the current format
; lcmcglobal - same as lcmglobal, but uses C name decoration
;
; lcmextern - declare a function (two arguments) or data (one
; argument) as extern in the current format
; lcmcextern - same as lcmextern, but uses C name decoration
; lcmdllextern - same as lcmextern, but uses dll name decoration
; lcmwinextern - same as lcmextern, but uses name decoration for
; calling Win32 Api functions (see _MSLIBS_)
;
; lcmimport - declares a function (two arguments) or data (one
; argument) as imported in the current format
; lcmexport - declares a function (two arguments) or data (one
; argument) as exported in the current format
;
; lcmlabel - start label for a function in the current format
; lcmclabel - start label for a function with C name decoration
; lcmadjust - adjust stack after a function call in the current
; format
; lcmret - return from a function in the current format
; lcmcret - return from a C function
;
; The following defines change the format and behaviour:
;
; _ELF_ - the lcm*global macro adds :function and :data type
; specifiers
;
; _OBJ_ - section names are similar to those produced by
; Borland tools to increase compatibility with
; various OMF compatible linkers
;
; _DLL_ - functions are exported and imported with added
; size specifiers (_SomeFunction@12), lcmret adjusts
; stack (stdcall)
;
; _MSLIBS_ - the lcmwinextern macro prepends an underscore and
; adds size specification for functions, allowing
; the object file to be linked with MS libraries.
;
; ====================================================================
%ifndef NASMLCM_INC_INCLUDED
%define NASMLCM_INC_INCLUDED
%ifdef _DLL_
%ifndef _OBJ_
%error "_DLL_ needs _OBJ_ defined!"
%endif
%endif
; --- define lcm- section names ---
;
; a number of linkers require omf objects where the section
; names are equal to those produces by tasm.
%ifdef _OBJ_
%define lcmtext _TEXT class=CODE public use32 align=4 FLAT
%define lcmdata _DATA class=DATA public use32 align=4
%define lcmbss _BSS class=BSS public use32 align=4 FLAT
group FLAT
group DGROUP _DATA
%else ; _OBJ_
%define lcmtext .text
%define lcmdata .data
%define lcmbss .bss
%endif ; _OBJ_
; --- define lcmglobal and lcm*extern macros ---
;
; special handling of functions and data for ELF32
%ifdef _ELF_
%macro lcmglobal 2
global %{1}:function
%endmacro
%macro lcmglobal 1
global %{1}:data
%endmacro
%define lcmcglobal lcmglobal
%macro lcmextern 1-2
extern %1
%endmacro
%macro lcmcextern 0
%error lcmcextern not supported in ELF format
%endmacro
%macro lcmdllextern 0
%error lcmdllextern not supported in ELF format
%endmacro
%else ; _ELF_
%ifdef _DLL_
%macro lcmglobal 2
global _%1
global _%1@%2
%endmacro
%macro lcmglobal 1
global _%1
%define %1 _%1
%endmacro
%macro lcmcglobal 2
global _%1
%endmacro
%macro lcmcglobal 1
global _%1
%define %1 _%1
%endmacro
%macro lcmextern 2
extern _%1@%2
%define %1 _%1@%2
%endmacro
%macro lcmextern 1
extern _%1
%define %1 _%1
%endmacro
%else
%macro lcmglobal 2
global _%1
%endmacro
%macro lcmglobal 1
global _%1
%define %1 _%1
%endmacro
%define lcmcglobal lcmglobal
%macro lcmextern 1-2
extern _%1
%define %1 _%1
%endmacro
%endif
%macro lcmcextern 1-2
extern _%1
%define %1 _%1
%endmacro
%macro lcmdllextern 2
extern _%1@%2
%define %1 _%1@%2
%endmacro
%macro lcmdllextern 1
extern _%1
%define %1 _%1
%endmacro
%macro lcmwinextern 2
%ifdef _MSLIBS_
extern _%1@%2
%define %1 _%1@%2
%else
extern %1
%endif
%endmacro
%endif ; _ELF_
; --- define lcmimport and lcmexport ---
;
%ifdef _OBJ_
%macro lcmimport 2-3
import %1 %2 %3
%rotate 1
%endmacro
%ifdef _DLL_
%macro lcmexport 2
export _%1
export _%1@%2
%endmacro
%macro lcmexport 1
export _%1
%endmacro
%else
%macro lcmexport 1-2
%endmacro
%endif
%else ; _OBJ_
%macro lcmimport 2-3
%endmacro
%macro lcmexport 1-2
%endmacro
%endif ; _OBJ_
; --- define lcmlabel, lcmadjust and lcmret macros ---
;
; we need special labels and stdcall calling convention when
; assembling for a dll
%ifdef _ELF_
%macro lcmlabel 2
%1:
%endmacro
%define lcmclabel lcmlabel
%macro lcmadjust 1
%if %1 < 128
add esp, byte %1
%else
add esp, %1
%endif
%endmacro
%macro lcmret 1
ret
%endmacro
%define lcmcret lcmret
%else ; _ELF_
%ifdef _DLL_
%macro lcmlabel 2
_%1:
_%1@%2:
%endmacro
%macro lcmclabel 2
_%1:
%endmacro
%macro lcmadjust 1
%endmacro
%macro lcmret 1
%if %1 > 0
ret %1
%else
ret
%endif
%endmacro
%macro lcmcret 1
ret
%endmacro
%else
%macro lcmlabel 2
_%1:
%endmacro
%define lcmclabel lcmlabel
%macro lcmadjust 1
%if %1 < 128
add esp, byte %1
%else
add esp, %1
%endif
%endmacro
%macro lcmret 1
ret
%endmacro
%define lcmcret lcmret
%endif
%endif ; _ELF_
%endif ; NASMLCM_INC_INCLUDED

View File

@@ -1,160 +0,0 @@
;;
;; tinfzlib - tiny zlib uncompress
;;
;; Copyright (c) 2003 by Joergen Ibsen / Jibz
;; All Rights Reserved
;;
;; http://www.ibsensoftware.com/
;;
;; This software is provided 'as-is', without any express
;; or implied warranty. In no event will the authors be
;; held liable for any damages arising from the use of
;; this software.
;;
;; Permission is granted to anyone to use this software
;; for any purpose, including commercial applications,
;; and to alter it and redistribute it freely, subject to
;; the following restrictions:
;;
;; 1. The origin of this software must not be
;; misrepresented; you must not claim that you
;; wrote the original software. If you use this
;; software in a product, an acknowledgment in
;; the product documentation would be appreciated
;; but is not required.
;;
;; 2. Altered source versions must be plainly marked
;; as such, and must not be misrepresented as
;; being the original software.
;;
;; 3. This notice may not be removed or altered from
;; any source distribution.
;;
TINF_OK equ 0
TINF_DATA_ERROR equ (-3)
cpu 386
bits 32
%include "nasmlcm.inc"
section lcmtext
lcmglobal tinf_zlib_uncompress,16
lcmexport tinf_zlib_uncompress,16
lcmextern tinf_uncompress,16
lcmextern tinf_adler32,8
; =============================================================
lcmlabel tinf_zlib_uncompress,16
; tinf_zlib_uncompress(void *dest,
; unsigned int *destLen,
; const void *source,
; unsigned int sourceLen)
.slen$ equ 2*4 + 4 + 12
.src$ equ 2*4 + 4 + 8
.dlen$ equ 2*4 + 4 + 4
.dst$ equ 2*4 + 4
push esi
push ebx
mov esi, [esp + .src$] ; esi -> source
; -- get header bytes --
movzx eax, word [esi] ; al = cmf, ah = flg,
; -- check format --
; check method is deflate
; if ((cmf & 0x0f) != 8) return TINF_DATA_ERROR;
mov cl, 0x0f
and cl, al
cmp cl, 8
jne short .return_error
; check window size is valid
; if ((cmf >> 4) > 7) return TINF_DATA_ERROR;
mov ch, al
shr ch, 4
cmp ch, cl ; cl = 8 from above
jae short .return_error
; check there is no preset dictionary
; if (flg & 0x20) return TINF_DATA_ERROR;
test ah, 0x20
jnz short .return_error
; check checksum
; if ((256*cmf + flg) % 31) return TINF_DATA_ERROR;
xchg al, ah
xor edx, edx
lea ebx, [edx + 31]
div ebx
test edx, edx
jnz short .return_error
; -- get adler32 checksum --
mov ecx, [esp + .slen$] ; ecx = sourceLen
mov ebx, [esi + ecx - 4]
%ifdef BSWAP_OK
bswap ebx
%else ; BSWAP_OK
xchg bl, bh
rol ebx, 16
xchg bl, bh
%endif ; BSWAP_OK
; -- inflate --
; res = tinf_uncompress(dst, destLen, src + 2, sourceLen - 6);
lea eax, [ecx - 6]
push eax
lea eax, [esi + 2]
push eax
push dword [esp + 8 + .dlen$]
push dword [esp + 12 + .dst$]
call tinf_uncompress
add esp, byte 16
; if (res != TINF_OK) return TINF_DATA_ERROR;
test eax, eax
jnz short .return_error
; -- check adler32 checksum --
; if (a32 != tinf_adler32(dst, *destLen)) return TINF_DATA_ERROR;
mov eax, [esp + .dlen$];
push dword [eax]
push dword [esp + 4 + .dst$]
call tinf_adler32
add esp, byte 8
sub eax, ebx
jz short .return_eax
.return_error:
mov eax, TINF_DATA_ERROR
.return_eax:
pop ebx
pop esi
lcmret 16
; =============================================================
%ifdef _OBJ_
section lcmdata
%endif
; =============================================================

View File

@@ -1,3 +0,0 @@
/* Compatibility header for the original tinf lib/older versions of uzlib.
Note: may be removed in the future, please migrate to uzlib.h. */
#include "uzlib.h"

View File

@@ -1,9 +0,0 @@
/* This header contains compatibility defines for the original tinf API
and uzlib 2.x and below API. These defines are deprecated and going
to be removed in the future, so applications should migrate to new
uzlib API. */
#define TINF_DATA struct uzlib_uncomp
#define destSize dest_size
#define destStart dest_start
#define readSource source_read_cb

View File

@@ -1,110 +0,0 @@
/*
* uzlib - tiny deflate/inflate library (deflate, gzip, zlib)
*
* Copyright (c) 2003 by Joergen Ibsen / Jibz
* All Rights Reserved
*
* http://www.ibsensoftware.com/
*
* Copyright (c) 2014-2018 by Paul Sokolovsky
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
#include "tinf.h"
#define FTEXT 1
#define FHCRC 2
#define FEXTRA 4
#define FNAME 8
#define FCOMMENT 16
void tinf_skip_bytes(TINF_DATA *d, int num);
uint16_t tinf_get_uint16(TINF_DATA *d);
void tinf_skip_bytes(TINF_DATA *d, int num)
{
while (num--) uzlib_get_byte(d);
}
uint16_t tinf_get_uint16(TINF_DATA *d)
{
unsigned int v = uzlib_get_byte(d);
v = (uzlib_get_byte(d) << 8) | v;
return v;
}
int uzlib_gzip_parse_header(TINF_DATA *d)
{
unsigned char flg;
/* -- check format -- */
/* check id bytes */
if (uzlib_get_byte(d) != 0x1f || uzlib_get_byte(d) != 0x8b) return TINF_DATA_ERROR;
/* check method is deflate */
if (uzlib_get_byte(d) != 8) return TINF_DATA_ERROR;
/* get flag byte */
flg = uzlib_get_byte(d);
/* check that reserved bits are zero */
if (flg & 0xe0) return TINF_DATA_ERROR;
/* -- find start of compressed data -- */
/* skip rest of base header of 10 bytes */
tinf_skip_bytes(d, 6);
/* skip extra data if present */
if (flg & FEXTRA)
{
unsigned int xlen = tinf_get_uint16(d);
tinf_skip_bytes(d, xlen);
}
/* skip file name if present */
if (flg & FNAME) { while (uzlib_get_byte(d)); }
/* skip file comment if present */
if (flg & FCOMMENT) { while (uzlib_get_byte(d)); }
/* check header crc if present */
if (flg & FHCRC)
{
/*unsigned int hcrc =*/ tinf_get_uint16(d);
// TODO: Check!
// if (hcrc != (tinf_crc32(src, start - src) & 0x0000ffff))
// return TINF_DATA_ERROR;
}
/* initialize for crc32 checksum */
d->checksum_type = TINF_CHKSUM_CRC;
d->checksum = ~0;
return TINF_OK;
}

View File

@@ -1,673 +0,0 @@
/*
* uzlib - tiny deflate/inflate library (deflate, gzip, zlib)
*
* Copyright (c) 2003 by Joergen Ibsen / Jibz
* All Rights Reserved
* http://www.ibsensoftware.com/
*
* Copyright (c) 2014-2018 by Paul Sokolovsky
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
#include <assert.h>
#include <string.h>
#include "tinf.h"
#define UZLIB_DUMP_ARRAY(heading, arr, size) \
{ \
printf("%s", heading); \
for (int i = 0; i < size; ++i) { \
printf(" %d", (arr)[i]); \
} \
printf("\n"); \
}
uint32_t tinf_get_le_uint32(TINF_DATA *d);
uint32_t tinf_get_be_uint32(TINF_DATA *d);
/* --------------------------------------------------- *
* -- uninitialized global data (static structures) -- *
* --------------------------------------------------- */
#ifdef RUNTIME_BITS_TABLES
/* extra bits and base tables for length codes */
unsigned char length_bits[30];
unsigned short length_base[30];
/* extra bits and base tables for distance codes */
unsigned char dist_bits[30];
unsigned short dist_base[30];
#else
const unsigned char length_bits[30] = {
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4,
5, 5, 5, 5
};
const unsigned short length_base[30] = {
3, 4, 5, 6, 7, 8, 9, 10,
11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115,
131, 163, 195, 227, 258
};
const unsigned char dist_bits[30] = {
0, 0, 0, 0, 1, 1, 2, 2,
3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10,
11, 11, 12, 12, 13, 13
};
const unsigned short dist_base[30] = {
1, 2, 3, 4, 5, 7, 9, 13,
17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073,
4097, 6145, 8193, 12289, 16385, 24577
};
#endif
/* special ordering of code length codes */
const unsigned char clcidx[] = {
16, 17, 18, 0, 8, 7, 9, 6,
10, 5, 11, 4, 12, 3, 13, 2,
14, 1, 15
};
/* ----------------------- *
* -- utility functions -- *
* ----------------------- */
#ifdef RUNTIME_BITS_TABLES
/* build extra bits and base tables */
static void tinf_build_bits_base(unsigned char *bits, unsigned short *base, int delta, int first)
{
int i, sum;
/* build bits table */
for (i = 0; i < delta; ++i) bits[i] = 0;
for (i = 0; i < 30 - delta; ++i) bits[i + delta] = i / delta;
/* build base table */
for (sum = first, i = 0; i < 30; ++i)
{
base[i] = sum;
sum += 1 << bits[i];
}
}
#endif
/* build the fixed huffman trees */
static void tinf_build_fixed_trees(TINF_TREE *lt, TINF_TREE *dt)
{
int i;
/* build fixed length tree */
for (i = 0; i < 7; ++i) lt->table[i] = 0;
lt->table[7] = 24;
lt->table[8] = 152;
lt->table[9] = 112;
for (i = 0; i < 24; ++i) lt->trans[i] = 256 + i;
for (i = 0; i < 144; ++i) lt->trans[24 + i] = i;
for (i = 0; i < 8; ++i) lt->trans[24 + 144 + i] = 280 + i;
for (i = 0; i < 112; ++i) lt->trans[24 + 144 + 8 + i] = 144 + i;
/* build fixed distance tree */
for (i = 0; i < 5; ++i) dt->table[i] = 0;
dt->table[5] = 32;
for (i = 0; i < 32; ++i) dt->trans[i] = i;
}
/* given an array of code lengths, build a tree */
static void tinf_build_tree(TINF_TREE *t, const unsigned char *lengths, unsigned int num)
{
unsigned short offs[16];
unsigned int i, sum;
/* clear code length count table */
for (i = 0; i < 16; ++i) t->table[i] = 0;
/* scan symbol lengths, and sum code length counts */
for (i = 0; i < num; ++i) t->table[lengths[i]]++;
#if UZLIB_CONF_DEBUG_LOG >= 2
UZLIB_DUMP_ARRAY("codelen counts:", t->table, TINF_ARRAY_SIZE(t->table));
#endif
/* In the lengths array, 0 means unused code. So, t->table[0] now contains
number of unused codes. But table's purpose is to contain # of codes of
particular length, and there're 0 codes of length 0. */
t->table[0] = 0;
/* compute offset table for distribution sort */
for (sum = 0, i = 0; i < 16; ++i)
{
offs[i] = sum;
sum += t->table[i];
}
#if UZLIB_CONF_DEBUG_LOG >= 2
UZLIB_DUMP_ARRAY("codelen offsets:", offs, TINF_ARRAY_SIZE(offs));
#endif
/* create code->symbol translation table (symbols sorted by code) */
for (i = 0; i < num; ++i)
{
if (lengths[i]) t->trans[offs[lengths[i]]++] = i;
}
}
/* ---------------------- *
* -- decode functions -- *
* ---------------------- */
unsigned char uzlib_get_byte(TINF_DATA *d)
{
/* If end of source buffer is not reached, return next byte from source
buffer. */
if (d->source < d->source_limit) {
return *d->source++;
}
/* Otherwise if there's callback and we haven't seen EOF yet, try to
read next byte using it. (Note: the callback can also update ->source
and ->source_limit). */
if (d->readSource && !d->eof) {
int val = d->readSource(d);
if (val >= 0) {
return (unsigned char)val;
}
}
/* Otherwise, we hit EOF (either from ->readSource() or from exhaustion
of the buffer), and it will be "sticky", i.e. further calls to this
function will end up here too. */
d->eof = true;
return 0;
}
uint32_t tinf_get_le_uint32(TINF_DATA *d)
{
uint32_t val = 0;
int i;
for (i = 4; i--;) {
val = val >> 8 | ((uint32_t)uzlib_get_byte(d)) << 24;
}
return val;
}
uint32_t tinf_get_be_uint32(TINF_DATA *d)
{
uint32_t val = 0;
int i;
for (i = 4; i--;) {
val = val << 8 | uzlib_get_byte(d);
}
return val;
}
/* get one bit from source stream */
static int tinf_getbit(TINF_DATA *d)
{
unsigned int bit;
/* check if tag is empty */
if (!d->bitcount--)
{
/* load next tag */
d->tag = uzlib_get_byte(d);
d->bitcount = 7;
}
/* shift bit out of tag */
bit = d->tag & 0x01;
d->tag >>= 1;
return bit;
}
/* read a num bit value from a stream and add base */
static unsigned int tinf_read_bits(TINF_DATA *d, int num, int base)
{
unsigned int val = 0;
/* read num bits */
if (num)
{
unsigned int limit = 1 << (num);
unsigned int mask;
for (mask = 1; mask < limit; mask *= 2)
if (tinf_getbit(d)) val += mask;
}
return val + base;
}
/* given a data stream and a tree, decode a symbol */
static int tinf_decode_symbol(TINF_DATA *d, TINF_TREE *t)
{
int sum = 0, cur = 0, len = 0;
/* get more bits while code value is above sum */
do {
cur = 2*cur + tinf_getbit(d);
if (++len == TINF_ARRAY_SIZE(t->table)) {
return TINF_DATA_ERROR;
}
sum += t->table[len];
cur -= t->table[len];
} while (cur >= 0);
sum += cur;
#if UZLIB_CONF_PARANOID_CHECKS
if (sum < 0 || sum >= TINF_ARRAY_SIZE(t->trans)) {
return TINF_DATA_ERROR;
}
#endif
return t->trans[sum];
}
/* given a data stream, decode dynamic trees from it */
static int tinf_decode_trees(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
{
/* code lengths for 288 literal/len symbols and 32 dist symbols */
unsigned char lengths[288+32];
unsigned int hlit, hdist, hclen, hlimit;
unsigned int i, num, length;
/* get 5 bits HLIT (257-286) */
hlit = tinf_read_bits(d, 5, 257);
/* get 5 bits HDIST (1-32) */
hdist = tinf_read_bits(d, 5, 1);
/* get 4 bits HCLEN (4-19) */
hclen = tinf_read_bits(d, 4, 4);
for (i = 0; i < 19; ++i) lengths[i] = 0;
/* read code lengths for code length alphabet */
for (i = 0; i < hclen; ++i)
{
/* get 3 bits code length (0-7) */
unsigned int clen = tinf_read_bits(d, 3, 0);
lengths[clcidx[i]] = clen;
}
/* build code length tree, temporarily use length tree */
tinf_build_tree(lt, lengths, 19);
/* decode code lengths for the dynamic trees */
hlimit = hlit + hdist;
for (num = 0; num < hlimit; )
{
int sym = tinf_decode_symbol(d, lt);
unsigned char fill_value = 0;
int lbits, lbase = 3;
/* error decoding */
if (sym < 0) return sym;
switch (sym)
{
case 16:
/* copy previous code length 3-6 times (read 2 bits) */
if (num == 0) return TINF_DATA_ERROR;
fill_value = lengths[num - 1];
lbits = 2;
break;
case 17:
/* repeat code length 0 for 3-10 times (read 3 bits) */
lbits = 3;
break;
case 18:
/* repeat code length 0 for 11-138 times (read 7 bits) */
lbits = 7;
lbase = 11;
break;
default:
/* values 0-15 represent the actual code lengths */
lengths[num++] = sym;
/* continue the for loop */
continue;
}
/* special code length 16-18 are handled here */
length = tinf_read_bits(d, lbits, lbase);
if (num + length > hlimit) return TINF_DATA_ERROR;
for (; length; --length)
{
lengths[num++] = fill_value;
}
}
#if UZLIB_CONF_DEBUG_LOG >= 2
printf("lit code lengths (%d):", hlit);
UZLIB_DUMP_ARRAY("", lengths, hlit);
printf("dist code lengths (%d):", hdist);
UZLIB_DUMP_ARRAY("", lengths + hlit, hdist);
#endif
#if UZLIB_CONF_PARANOID_CHECKS
/* Check that there's "end of block" symbol */
if (lengths[256] == 0) {
return TINF_DATA_ERROR;
}
#endif
/* build dynamic trees */
tinf_build_tree(lt, lengths, hlit);
tinf_build_tree(dt, lengths + hlit, hdist);
return TINF_OK;
}
/* ----------------------------- *
* -- block inflate functions -- *
* ----------------------------- */
/* given a stream and two trees, inflate next chunk of output (a byte or more) */
static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
{
if (d->curlen == 0) {
unsigned int offs;
int dist;
int sym = tinf_decode_symbol(d, lt);
//printf("huff sym: %02x\n", sym);
if (d->eof) {
return TINF_DATA_ERROR;
}
/* literal byte */
if (sym < 256) {
TINF_PUT(d, sym);
return TINF_OK;
}
/* end of block */
if (sym == 256) {
return TINF_DONE;
}
/* substring from sliding dictionary */
sym -= 257;
if (sym >= 29) {
return TINF_DATA_ERROR;
}
/* possibly get more bits from length code */
d->curlen = tinf_read_bits(d, length_bits[sym], length_base[sym]);
dist = tinf_decode_symbol(d, dt);
if (dist >= 30) {
return TINF_DATA_ERROR;
}
/* possibly get more bits from distance code */
offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
/* calculate and validate actual LZ offset to use */
if (d->dict_ring) {
if (offs > d->dict_size) {
return TINF_DICT_ERROR;
}
/* Note: unlike full-dest-in-memory case below, we don't
try to catch offset which points to not yet filled
part of the dictionary here. Doing so would require
keeping another variable to track "filled in" size
of the dictionary. Appearance of such an offset cannot
lead to accessing memory outside of the dictionary
buffer, and clients which don't want to leak unrelated
information, should explicitly initialize dictionary
buffer passed to uzlib. */
d->lzOff = d->dict_idx - offs;
if (d->lzOff < 0) {
d->lzOff += d->dict_size;
}
} else {
/* catch trying to point before the start of dest buffer */
if (offs > d->dest - d->destStart) {
return TINF_DATA_ERROR;
}
d->lzOff = -offs;
}
}
/* copy next byte from dict substring */
if (d->dict_ring) {
TINF_PUT(d, d->dict_ring[d->lzOff]);
if ((unsigned)++d->lzOff == d->dict_size) {
d->lzOff = 0;
}
} else {
#if UZLIB_CONF_USE_MEMCPY
/* copy as much as possible, in one memcpy() call */
unsigned int to_copy = d->curlen, dest_len = d->dest_limit - d->dest;
if (to_copy > dest_len) {
to_copy = dest_len;
}
memcpy(d->dest, d->dest + d->lzOff, to_copy);
d->dest += to_copy;
d->curlen -= to_copy;
return TINF_OK;
#else
d->dest[0] = d->dest[d->lzOff];
d->dest++;
#endif
}
d->curlen--;
return TINF_OK;
}
/* inflate next byte from uncompressed block of data */
static int tinf_inflate_uncompressed_block(TINF_DATA *d)
{
if (d->curlen == 0) {
unsigned int length, invlength;
/* get length */
length = uzlib_get_byte(d);
length += 256 * uzlib_get_byte(d);
/* get one's complement of length */
invlength = uzlib_get_byte(d);
invlength += 256 * uzlib_get_byte(d);
/* check length */
if (length != (~invlength & 0x0000ffff)) return TINF_DATA_ERROR;
/* increment length to properly return TINF_DONE below, without
producing data at the same time */
d->curlen = length + 1;
/* make sure we start next block on a byte boundary */
d->bitcount = 0;
}
if (--d->curlen == 0) {
return TINF_DONE;
}
unsigned char c = uzlib_get_byte(d);
TINF_PUT(d, c);
return TINF_OK;
}
/* ---------------------- *
* -- public functions -- *
* ---------------------- */
/* initialize global (static) data */
void uzlib_init(void)
{
#ifdef RUNTIME_BITS_TABLES
/* build extra bits and base tables */
tinf_build_bits_base(length_bits, length_base, 4, 3);
tinf_build_bits_base(dist_bits, dist_base, 2, 1);
/* fix a special case */
length_bits[28] = 0;
length_base[28] = 258;
#endif
}
/* initialize decompression structure */
void uzlib_uncompress_init(TINF_DATA *d, void *dict, unsigned int dictLen)
{
d->eof = 0;
d->bitcount = 0;
d->bfinal = 0;
d->btype = -1;
d->dict_size = dictLen;
d->dict_ring = dict;
d->dict_idx = 0;
d->curlen = 0;
}
/* inflate next output bytes from compressed stream */
int uzlib_uncompress(TINF_DATA *d)
{
do {
int res;
/* start a new block */
if (d->btype == -1) {
int old_btype;
next_blk:
old_btype = d->btype;
/* read final block flag */
d->bfinal = tinf_getbit(d);
/* read block type (2 bits) */
d->btype = tinf_read_bits(d, 2, 0);
#if UZLIB_CONF_DEBUG_LOG >= 1
printf("Started new block: type=%d final=%d\n", d->btype, d->bfinal);
#endif
if (d->btype == 1 && old_btype != 1) {
/* build fixed huffman trees */
tinf_build_fixed_trees(&d->ltree, &d->dtree);
} else if (d->btype == 2) {
/* decode trees from stream */
res = tinf_decode_trees(d, &d->ltree, &d->dtree);
if (res != TINF_OK) {
return res;
}
}
}
/* process current block */
switch (d->btype)
{
case 0:
/* decompress uncompressed block */
res = tinf_inflate_uncompressed_block(d);
break;
case 1:
case 2:
/* decompress block with fixed/dynamic huffman trees */
/* trees were decoded previously, so it's the same routine for both */
res = tinf_inflate_block_data(d, &d->ltree, &d->dtree);
break;
default:
return TINF_DATA_ERROR;
}
if (res == TINF_DONE && !d->bfinal) {
/* the block has ended (without producing more data), but we
can't return without data, so start procesing next block */
goto next_blk;
}
if (res != TINF_OK) {
return res;
}
} while (d->dest < d->dest_limit);
return TINF_OK;
}
/* inflate next output bytes from compressed stream, updating
checksum, and at the end of stream, verify it */
int uzlib_uncompress_chksum(TINF_DATA *d)
{
int res;
unsigned char *data = d->dest;
res = uzlib_uncompress(d);
if (res < 0) return res;
switch (d->checksum_type) {
case TINF_CHKSUM_ADLER:
d->checksum = uzlib_adler32(data, d->dest - data, d->checksum);
break;
case TINF_CHKSUM_CRC:
d->checksum = uzlib_crc32(data, d->dest - data, d->checksum);
break;
}
if (res == TINF_DONE) {
unsigned int val;
switch (d->checksum_type) {
case TINF_CHKSUM_ADLER:
val = tinf_get_be_uint32(d);
if (d->checksum != val) {
return TINF_CHKSUM_ERROR;
}
break;
case TINF_CHKSUM_CRC:
val = tinf_get_le_uint32(d);
if (~d->checksum != val) {
return TINF_CHKSUM_ERROR;
}
// Uncompressed size. TODO: Check
val = tinf_get_le_uint32(d);
break;
}
}
return res;
}

View File

@@ -1,66 +0,0 @@
/*
* uzlib - tiny deflate/inflate library (deflate, gzip, zlib)
*
* Copyright (c) 2003 by Joergen Ibsen / Jibz
* All Rights Reserved
*
* http://www.ibsensoftware.com/
*
* Copyright (c) 2014-2018 by Paul Sokolovsky
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
#include "tinf.h"
int uzlib_zlib_parse_header(TINF_DATA *d)
{
unsigned char cmf, flg;
/* -- get header bytes -- */
cmf = uzlib_get_byte(d);
flg = uzlib_get_byte(d);
/* -- check format -- */
/* check checksum */
if ((256*cmf + flg) % 31) return TINF_DATA_ERROR;
/* check method is deflate */
if ((cmf & 0x0f) != 8) return TINF_DATA_ERROR;
/* check window size is valid */
if ((cmf >> 4) > 7) return TINF_DATA_ERROR;
/* check there is no preset dictionary */
if (flg & 0x20) return TINF_DATA_ERROR;
/* initialize for adler32 checksum */
d->checksum_type = TINF_CHKSUM_ADLER;
d->checksum = 1;
return cmf >> 4;
}

View File

@@ -1,173 +0,0 @@
/*
* uzlib - tiny deflate/inflate library (deflate, gzip, zlib)
*
* Copyright (c) 2003 by Joergen Ibsen / Jibz
* All Rights Reserved
* http://www.ibsensoftware.com/
*
* Copyright (c) 2014-2018 by Paul Sokolovsky
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
#ifndef UZLIB_H_INCLUDED
#define UZLIB_H_INCLUDED
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "uzlib_conf.h"
#if UZLIB_CONF_DEBUG_LOG
#include <stdio.h>
#endif
/* calling convention */
#ifndef TINFCC
#ifdef __WATCOMC__
#define TINFCC __cdecl
#else
#define TINFCC
#endif
#endif
/* ok status, more data produced */
#define TINF_OK 0
/* end of compressed stream reached */
#define TINF_DONE 1
#define TINF_DATA_ERROR (-3)
#define TINF_CHKSUM_ERROR (-4)
#define TINF_DICT_ERROR (-5)
/* checksum types */
#define TINF_CHKSUM_NONE 0
#define TINF_CHKSUM_ADLER 1
#define TINF_CHKSUM_CRC 2
/* helper macros */
#define TINF_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(*(arr)))
/* data structures */
typedef struct {
unsigned short table[16]; /* table of code length counts */
unsigned short trans[288]; /* code -> symbol translation table */
} TINF_TREE;
struct uzlib_uncomp {
/* Pointer to the next byte in the input buffer */
const unsigned char *source;
/* Pointer to the next byte past the input buffer (source_limit = source + len) */
const unsigned char *source_limit;
/* If source_limit == NULL, or source >= source_limit, this function
will be used to read next byte from source stream. The function may
also return -1 in case of EOF (or irrecoverable error). Note that
besides returning the next byte, it may also update source and
source_limit fields, thus allowing for buffered operation. */
int (*source_read_cb)(struct uzlib_uncomp *uncomp);
unsigned int tag;
unsigned int bitcount;
/* Destination (output) buffer start */
unsigned char *dest_start;
/* Current pointer in dest buffer */
unsigned char *dest;
/* Pointer past the end of the dest buffer, similar to source_limit */
unsigned char *dest_limit;
/* Accumulating checksum */
unsigned int checksum;
char checksum_type;
bool eof;
int btype;
int bfinal;
unsigned int curlen;
int lzOff;
unsigned char *dict_ring;
unsigned int dict_size;
unsigned int dict_idx;
TINF_TREE ltree; /* dynamic length/symbol tree */
TINF_TREE dtree; /* dynamic distance tree */
};
#include "tinf_compat.h"
#define TINF_PUT(d, c) \
{ \
*d->dest++ = c; \
if (d->dict_ring) { d->dict_ring[d->dict_idx++] = c; if (d->dict_idx == d->dict_size) d->dict_idx = 0; } \
}
unsigned char TINFCC uzlib_get_byte(TINF_DATA *d);
/* Decompression API */
void TINFCC uzlib_init(void);
void TINFCC uzlib_uncompress_init(TINF_DATA *d, void *dict, unsigned int dictLen);
int TINFCC uzlib_uncompress(TINF_DATA *d);
int TINFCC uzlib_uncompress_chksum(TINF_DATA *d);
int TINFCC uzlib_zlib_parse_header(TINF_DATA *d);
int TINFCC uzlib_gzip_parse_header(TINF_DATA *d);
/* Compression API */
typedef const uint8_t *uzlib_hash_entry_t;
struct uzlib_comp {
unsigned char *outbuf;
int outlen, outsize;
unsigned long outbits;
int noutbits;
int comp_disabled;
uzlib_hash_entry_t *hash_table;
unsigned int hash_bits;
unsigned int dict_size;
};
void TINFCC uzlib_compress(struct uzlib_comp *c, const uint8_t *src, unsigned slen);
#include "defl_static.h"
/* Checksum API */
/* prev_sum is previous value for incremental computation, 1 initially */
uint32_t TINFCC uzlib_adler32(const void *data, unsigned int length, uint32_t prev_sum);
/* crc is previous value for incremental computation, 0xffffffff initially */
uint32_t TINFCC uzlib_crc32(const void *data, unsigned int length, uint32_t crc);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UZLIB_H_INCLUDED */

View File

@@ -1,32 +0,0 @@
/*
* uzlib - tiny deflate/inflate library (deflate, gzip, zlib)
*
* Copyright (c) 2014-2018 by Paul Sokolovsky
*/
#ifndef UZLIB_CONF_H_INCLUDED
#define UZLIB_CONF_H_INCLUDED
#ifndef UZLIB_CONF_DEBUG_LOG
/* Debug logging level 0, 1, 2, etc. */
#define UZLIB_CONF_DEBUG_LOG 0
#endif
#ifndef UZLIB_CONF_PARANOID_CHECKS
/* Perform extra checks on the input stream, even if they aren't proven
to be strictly required (== lack of them wasn't proven to lead to
crashes). */
#define UZLIB_CONF_PARANOID_CHECKS 0
#endif
#ifndef UZLIB_CONF_USE_MEMCPY
/* Use memcpy() for copying data out of LZ window or uncompressed blocks,
instead of doing this byte by byte. For well-compressed data, this
may noticeably increase decompression speed. But for less compressed,
it can actually deteriorate it (due to the fact that many memcpy()
implementations are optimized for large blocks of data, and have
too much overhead for short strings of just a few bytes). */
#define UZLIB_CONF_USE_MEMCPY 0
#endif
#endif /* UZLIB_CONF_H_INCLUDED */

View File

@@ -0,0 +1,799 @@
// Ported to ESP32-C6 Arduino By ATC1441(ATCnetz.de) for OpenEPaperLink at ~01.2024
#include "led.h"
#include "proto.h"
#include "radio.h"
#include "subGhz.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#include "esp_err.h"
#include "esp_event.h"
#include "esp_ieee802154.h"
#include "esp_phy_init.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "sdkconfig.h"
#include "second_uart.h"
#include "soc/lp_uart_reg.h"
#include "soc/uart_struct.h"
#include <esp_mac.h>
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
const uint8_t channelList[6] = { 11, 15, 20, 25, 26, 27 };
#define DATATYPE_NOUPDATE 0
#define HW_TYPE 0xC6
#define MAX_PENDING_MACS 250
#define HOUSEKEEPING_INTERVAL 60UL
struct pendingData pendingDataArr[MAX_PENDING_MACS];
// VERSION GOES HERE!
uint16_t version = 0x0019;
#define RAW_PKT_PADDING 2
uint8_t radiotxbuffer[135];
uint8_t radiorxbuffer[135];
static uint32_t housekeepingTimer;
struct blockRequest requestedData = { 0 }; // holds which data was requested by the tag
uint8_t dstMac[8]; // target for the block transfer
uint16_t dstPan; //
static uint32_t blockStartTimer = 0; // reference that holds when the AP sends the next block
uint32_t nextBlockAttempt = 0; // reference time for when the AP can request a new block from the ESP32
uint8_t seq = 0; // holds current sequence number for transmission
uint8_t blockbuffer[BLOCK_XFER_BUFFER_SIZE + 5]; // block transfer buffer
uint8_t lastAckMac[8] = { 0 };
// these variables hold the current mac were talking to
#define CONCURRENT_REQUEST_DELAY 1200UL
uint32_t lastBlockRequest = 0;
uint8_t lastBlockMac[8];
uint8_t lastTagReturn[8];
uint8_t curChannel = 25;
uint8_t curPower = 10;
uint8_t curPendingData = 0;
uint8_t curNoUpdate = 0;
bool highspeedSerial = false;
void sendXferCompleteAck(uint8_t *dst, bool isSubGHz);
void sendCancelXfer(uint8_t *dst, bool isSubGHz);
void espNotifyAPInfo();
// tools
void addCRC(void *p, uint8_t len) {
uint8_t total = 0;
for (uint8_t c = 1; c < len; c++) {
total += ((uint8_t *)p)[c];
}
((uint8_t *)p)[0] = total;
}
bool checkCRC(void *p, uint8_t len) {
uint8_t total = 0;
for (uint8_t c = 1; c < len; c++) {
total += ((uint8_t *)p)[c];
}
return ((uint8_t *)p)[0] == total;
}
uint8_t getPacketType(void *buffer) {
struct MacFcs *fcs = (MacFcs *)buffer;
if ((fcs->frameType == 1) && (fcs->destAddrType == 2) && (fcs->srcAddrType == 3) && (fcs->panIdCompressed == 0)) {
// broadcast frame
uint8_t type = ((uint8_t *)buffer)[sizeof(struct MacFrameBcast)];
return type;
} else if ((fcs->frameType == 1) && (fcs->destAddrType == 3) && (fcs->srcAddrType == 3) && (fcs->panIdCompressed == 1)) {
// normal frame
uint8_t type = ((uint8_t *)buffer)[sizeof(struct MacFrameNormal)];
return type;
}
return 0;
}
uint8_t getBlockDataLength() {
uint8_t partNo = 0;
for (uint8_t c = 0; c < BLOCK_MAX_PARTS; c++) {
if (requestedData.requestedParts[c / 8] & (1 << (c % 8))) {
partNo++;
}
}
return partNo;
}
// pendingdata slot stuff
int8_t findSlotForMac(const uint8_t *mac) {
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
if (memcmp(mac, ((uint8_t *) & (pendingDataArr[c].targetMac)), 8) == 0) {
if (pendingDataArr[c].attemptsLeft != 0) {
return c;
}
}
}
return -1;
}
int8_t findFreeSlot() {
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
if (pendingDataArr[c].attemptsLeft == 0) {
return c;
}
}
return -1;
}
int8_t findSlotForVer(const uint8_t *ver) {
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
if (memcmp(ver, ((uint8_t *) & (pendingDataArr[c].availdatainfo.dataVer)), 8) == 0) {
if (pendingDataArr[c].attemptsLeft != 0) return c;
}
}
return -1;
}
void deleteAllPendingDataForVer(const uint8_t *ver) {
int8_t slot = -1;
do {
slot = findSlotForVer(ver);
if (slot != -1) pendingDataArr[slot].attemptsLeft = 0;
} while (slot != -1);
}
void deleteAllPendingDataForMac(const uint8_t *mac) {
int8_t slot = -1;
do {
slot = findSlotForMac(mac);
if (slot != -1) pendingDataArr[slot].attemptsLeft = 0;
} while (slot != -1);
}
void countSlots() {
curPendingData = 0;
curNoUpdate = 0;
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
if (pendingDataArr[c].attemptsLeft != 0) {
if (pendingDataArr[c].availdatainfo.dataType != 0) {
curPendingData++;
} else {
curNoUpdate++;
}
}
}
}
// processing serial data
#define ZBS_RX_WAIT_HEADER 0
#define ZBS_RX_WAIT_SDA 1 // send data avail
#define ZBS_RX_WAIT_CANCEL 2 // cancel traffic for mac
#define ZBS_RX_WAIT_SCP 3 // set channel power
#define ZBS_RX_WAIT_BLOCKDATA 4
bool isSame(uint8_t *in1, char *in2, int len) {
bool flag = 1;
for (int i = 0; i < len; i++) {
if (in1[i] != in2[i]) flag = 0;
}
return flag;
}
int blockPosition = 0;
void processSerial(uint8_t lastchar) {
static uint8_t cmdbuffer[4];
static uint8_t RXState = 0;
static uint8_t serialbuffer[48];
static uint8_t *serialbufferp;
static uint8_t bytesRemain = 0;
static uint32_t lastSerial = 0;
static uint32_t blockStartTime = 0;
if ((RXState != ZBS_RX_WAIT_HEADER) && ((millis() - lastSerial) > 1000)) {
RXState = ZBS_RX_WAIT_HEADER;
Serial.printf("UART Timeout\r\n");
}
lastSerial = millis();
switch (RXState) {
case ZBS_RX_WAIT_HEADER:
// shift characters in
for (uint8_t c = 0; c < 3; c++) {
cmdbuffer[c] = cmdbuffer[c + 1];
}
cmdbuffer[3] = lastchar;
if (isSame(cmdbuffer + 1, ">D>", 3)) {
pr("ACK>");
blockStartTime = millis();
Serial.printf("Starting BlkData, %lu ms after request\r\n", blockStartTime - nextBlockAttempt);
blockPosition = 0;
RXState = ZBS_RX_WAIT_BLOCKDATA;
}
if (isSame(cmdbuffer, "SDA>", 4)) {
Serial.printf("SDA In\r\n");
RXState = ZBS_RX_WAIT_SDA;
bytesRemain = sizeof(struct pendingData);
serialbufferp = serialbuffer;
break;
}
if (isSame(cmdbuffer, "CXD>", 4)) {
Serial.printf("CXD In\r\n");
RXState = ZBS_RX_WAIT_CANCEL;
bytesRemain = sizeof(struct pendingData);
serialbufferp = serialbuffer;
break;
}
if (isSame(cmdbuffer, "SCP>", 4)) {
Serial.printf("SCP In\r\n");
RXState = ZBS_RX_WAIT_SCP;
bytesRemain = sizeof(struct espSetChannelPower);
serialbufferp = serialbuffer;
break;
}
if (isSame(cmdbuffer, "NFO?", 4)) {
pr("ACK>");
Serial.printf("NFO? In\r\n");
espNotifyAPInfo();
RXState = ZBS_RX_WAIT_HEADER;
}
if (isSame(cmdbuffer, "RDY?", 4)) {
pr("ACK>");
Serial.printf("RDY? In\r\n");
RXState = ZBS_RX_WAIT_HEADER;
}
if (isSame(cmdbuffer, "RSET", 4)) {
pr("ACK>");
Serial.printf("RSET In\r\n");
delay(100);
// TODO RESET US HERE
RXState = ZBS_RX_WAIT_HEADER;
}
if (isSame(cmdbuffer, "HSPD", 4)) {
pr("ACK>");
Serial.printf("HSPD In, switching to 2000000\r\n");
delay(100);
uart_switch_speed(2000000);
delay(100);
highspeedSerial = true;
pr("ACK>");
RXState = ZBS_RX_WAIT_HEADER;
}
break;
case ZBS_RX_WAIT_BLOCKDATA:
blockbuffer[blockPosition++] = 0xAA ^ lastchar;
if (blockPosition >= 4100) {
Serial.printf("Blockdata fully received in %lu ms, %lu ms after the request\r\n", millis() - blockStartTime, millis() - nextBlockAttempt);
RXState = ZBS_RX_WAIT_HEADER;
}
break;
case ZBS_RX_WAIT_SDA:
*serialbufferp = lastchar;
serialbufferp++;
bytesRemain--;
if (bytesRemain == 0) {
if (checkCRC(serialbuffer, sizeof(struct pendingData))) {
struct pendingData *pd = (struct pendingData *)serialbuffer;
int8_t slot = findSlotForMac(pd->targetMac);
if (slot == -1) slot = findFreeSlot();
if (slot != -1) {
memcpy(&(pendingDataArr[slot]), serialbuffer, sizeof(struct pendingData));
pr("ACK>");
} else {
pr("NOQ>");
}
} else {
pr("NOK>");
}
RXState = ZBS_RX_WAIT_HEADER;
}
break;
case ZBS_RX_WAIT_CANCEL:
*serialbufferp = lastchar;
serialbufferp++;
bytesRemain--;
if (bytesRemain == 0) {
if (checkCRC(serialbuffer, sizeof(struct pendingData))) {
struct pendingData *pd = (struct pendingData *)serialbuffer;
deleteAllPendingDataForMac((uint8_t *)&pd->targetMac);
pr("ACK>");
} else {
pr("NOK>");
}
RXState = ZBS_RX_WAIT_HEADER;
}
break;
case ZBS_RX_WAIT_SCP:
*serialbufferp = lastchar;
serialbufferp++;
bytesRemain--;
if (bytesRemain == 0) {
if (checkCRC(serialbuffer, sizeof(struct espSetChannelPower))) {
struct espSetChannelPower *scp = (struct espSetChannelPower *)serialbuffer;
for (uint8_t c = 0; c < sizeof(channelList); c++) {
if (channelList[c] == scp->channel) goto SCPchannelFound;
}
goto SCPfailed;
SCPchannelFound:
pr("ACK>");
if (curChannel != scp->channel) {
radioSetChannel(scp->channel);
curChannel = scp->channel;
}
curPower = scp->power;
radioSetTxPower(scp->power);
Serial.printf("Set channel: %d power: %d\r\n", curChannel, curPower);
} else {
SCPfailed:
pr("NOK>");
}
RXState = ZBS_RX_WAIT_HEADER;
}
break;
}
}
// sending data to the ESP
void espBlockRequest(const struct blockRequest *br, uint8_t *src) {
struct espBlockRequest *ebr = (struct espBlockRequest *)blockbuffer;
uartTx('R');
uartTx('Q');
uartTx('B');
uartTx('>');
memcpy(&(ebr->ver), &(br->ver), 8);
memcpy(&(ebr->src), src, 8);
ebr->blockId = br->blockId;
addCRC(ebr, sizeof(struct espBlockRequest));
for (uint8_t c = 0; c < sizeof(struct espBlockRequest); c++) {
uartTx(((uint8_t *)ebr)[c]);
}
}
void espNotifyAvailDataReq(const struct AvailDataReq *adr, const uint8_t *src) {
uartTx('A');
uartTx('D');
uartTx('R');
uartTx('>');
struct espAvailDataReq eadr = { 0 };
memcpy((void *)eadr.src, (void *)src, 8);
memcpy((void *)&eadr.adr, (void *)adr, sizeof(struct AvailDataReq));
addCRC(&eadr, sizeof(struct espAvailDataReq));
for (uint8_t c = 0; c < sizeof(struct espAvailDataReq); c++) {
uartTx(((uint8_t *)&eadr)[c]);
}
}
void espNotifyXferComplete(const uint8_t *src) {
struct espXferComplete exfc;
memcpy(&exfc.src, src, 8);
uartTx('X');
uartTx('F');
uartTx('C');
uartTx('>');
addCRC(&exfc, sizeof(exfc));
for (uint8_t c = 0; c < sizeof(exfc); c++) {
uartTx(((uint8_t *)&exfc)[c]);
}
}
void espNotifyTimeOut(const uint8_t *src) {
struct espXferComplete exfc;
memcpy(&exfc.src, src, 8);
uartTx('X');
uartTx('T');
uartTx('O');
uartTx('>');
addCRC(&exfc, sizeof(exfc));
for (uint8_t c = 0; c < sizeof(exfc); c++) {
uartTx(((uint8_t *)&exfc)[c]);
}
}
void espNotifyAPInfo() {
pr("TYP>%02X", HW_TYPE);
pr("VER>%04X", version);
pr("MAC>%02X%02X", mSelfMac[0], mSelfMac[1]);
pr("%02X%02X", mSelfMac[2], mSelfMac[3]);
pr("%02X%02X", mSelfMac[4], mSelfMac[5]);
pr("%02X%02X", mSelfMac[6], mSelfMac[7]);
pr("ZCH>%02X", curChannel);
pr("ZPW>%02X", curPower);
countSlots();
pr("PEN>%02X", curPendingData);
pr("NOP>%02X", curNoUpdate);
}
void espNotifyTagReturnData(uint8_t *src, uint8_t len) {
struct tagReturnData *trd = (struct tagReturnData *)(radiorxbuffer + sizeof(struct MacFrameBcast) + 1); // oh how I'd love to pass this as an argument, but sdcc won't let me
struct espTagReturnData *etrd = (struct espTagReturnData *)radiotxbuffer;
if (memcmp((void *)&trd->dataVer, lastTagReturn, 8) == 0) {
return;
} else {
memcpy(lastTagReturn, &trd->dataVer, 8);
}
memcpy(etrd->src, src, 8);
etrd->len = len;
memcpy(&etrd->returnData, trd, len);
addCRC(etrd, len + 10);
uartTx('T');
uartTx('R');
uartTx('D');
uartTx('>');
for (uint8_t c = 0; c < len + 10; c++) {
uartTx(((uint8_t *)etrd)[c]);
}
}
// process data from tag
void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload, bool isSubGHz) {
struct MacFrameNormal *rxHeader = (struct MacFrameNormal *)buffer;
struct blockRequest *blockReq = (struct blockRequest *)(buffer + sizeof(struct MacFrameNormal) + 1);
if (!checkCRC(blockReq, sizeof(struct blockRequest))) return;
// check if we're already talking to this mac
if (memcmp(rxHeader->src, lastBlockMac, 8) == 0) {
lastBlockRequest = millis();
} else {
// we weren't talking to this mac, see if there was a transfer in progress from another mac, recently
if ((millis() - lastBlockRequest) > CONCURRENT_REQUEST_DELAY) {
// mark this mac as the new current mac we're talking to
memcpy((void *)lastBlockMac, (void *)rxHeader->src, 8);
lastBlockRequest = millis();
} else {
// we're talking to another mac, let this mac know we can't accomodate another request right now
pr("BUSY!\n");
sendCancelXfer(rxHeader->src, isSubGHz);
return;
}
}
// check if we have data for this mac
if (findSlotForMac(rxHeader->src) == -1) {
// no data for this mac, politely tell it to fuck off
sendCancelXfer(rxHeader->src, isSubGHz);
return;
}
bool requestDataDownload = false;
if ((blockReq->blockId != requestedData.blockId) || (blockReq->ver != requestedData.ver)) {
// requested block isn't already in the buffer
requestDataDownload = true;
} else {
// requested block is already in the buffer
if (forceBlockDownload) {
if ((millis() - nextBlockAttempt) > 380) {
requestDataDownload = true;
pr("FORCED\n");
} else {
pr("IGNORED\n");
}
}
}
// copy blockrequest into requested data
memcpy(&requestedData, blockReq, sizeof(struct blockRequest));
struct MacFrameNormal *txHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
struct blockRequestAck *blockRequestAck = (struct blockRequestAck *)(radiotxbuffer + sizeof(struct MacFrameNormal) + 2);
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + sizeof(struct blockRequestAck) + RAW_PKT_PADDING;
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_BLOCK_REQUEST_ACK;
if (blockStartTimer == 0) {
if (requestDataDownload) {
if (highspeedSerial == true) {
blockRequestAck->pleaseWaitMs = 140;
} else {
blockRequestAck->pleaseWaitMs = 550;
}
} else {
// block is already in buffer
blockRequestAck->pleaseWaitMs = 30;
}
} else {
blockRequestAck->pleaseWaitMs = 30;
}
blockStartTimer = millis() + blockRequestAck->pleaseWaitMs;
memcpy(txHeader->src, mSelfMac, 8);
memcpy(txHeader->dst, rxHeader->src, 8);
txHeader->pan = rxHeader->pan;
txHeader->fcs.frameType = 1;
txHeader->fcs.panIdCompressed = 1;
txHeader->fcs.destAddrType = 3;
txHeader->fcs.srcAddrType = 3;
txHeader->seq = seq++;
addCRC((void *)blockRequestAck, sizeof(struct blockRequestAck));
radioTx(radiotxbuffer, isSubGHz);
// save the target for the blockdata
memcpy(dstMac, rxHeader->src, 8);
dstPan = rxHeader->pan;
if (requestDataDownload) {
blockPosition = 0;
espBlockRequest(&requestedData, rxHeader->src);
nextBlockAttempt = millis();
}
}
void processAvailDataReq(uint8_t *buffer, bool isSubGHz) {
struct MacFrameBcast *rxHeader = (struct MacFrameBcast *)buffer;
struct AvailDataReq *availDataReq = (struct AvailDataReq *)(buffer + sizeof(struct MacFrameBcast) + 1);
if (!checkCRC(availDataReq, sizeof(struct AvailDataReq))) return;
// prepare tx buffer to send a response
memset(radiotxbuffer, 0, sizeof(struct MacFrameNormal) + sizeof(struct AvailDataInfo) + 2); // 120);
struct MacFrameNormal *txHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
struct AvailDataInfo *availDataInfo = (struct AvailDataInfo *)(radiotxbuffer + sizeof(struct MacFrameNormal) + 2);
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + sizeof(struct AvailDataInfo) + RAW_PKT_PADDING;
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_AVAIL_DATA_INFO;
// check to see if we have data available for this mac
bool haveData = false;
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
if (pendingDataArr[c].attemptsLeft) {
if (memcmp(pendingDataArr[c].targetMac, rxHeader->src, 8) == 0) {
haveData = true;
memcpy((void *)availDataInfo, &(pendingDataArr[c].availdatainfo), sizeof(struct AvailDataInfo));
break;
}
}
}
// couldn't find data for this mac
if (!haveData) availDataInfo->dataType = DATATYPE_NOUPDATE;
memcpy(txHeader->src, mSelfMac, 8);
memcpy(txHeader->dst, rxHeader->src, 8);
txHeader->pan = rxHeader->dstPan;
txHeader->fcs.frameType = 1;
txHeader->fcs.panIdCompressed = 1;
txHeader->fcs.destAddrType = 3;
txHeader->fcs.srcAddrType = 3;
txHeader->seq = seq++;
addCRC(availDataInfo, sizeof(struct AvailDataInfo));
radioTx(radiotxbuffer, isSubGHz);
memset(lastAckMac, 0, 8); // reset lastAckMac, so we can record if we've received exactly one ack packet
espNotifyAvailDataReq(availDataReq, rxHeader->src);
}
void processXferComplete(uint8_t *buffer, bool isSubGHz) {
struct MacFrameNormal *rxHeader = (struct MacFrameNormal *)buffer;
sendXferCompleteAck(rxHeader->src, isSubGHz);
if (memcmp(lastAckMac, rxHeader->src, 8) != 0) {
memcpy((void *)lastAckMac, (void *)rxHeader->src, 8);
espNotifyXferComplete(rxHeader->src);
int8_t slot = findSlotForMac(rxHeader->src);
if (slot != -1) pendingDataArr[slot].attemptsLeft = 0;
}
}
void processTagReturnData(uint8_t *buffer, uint8_t len, bool isSubGHz) {
struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buffer;
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
if (!checkCRC((buffer + sizeof(struct MacFrameBcast) + 1), len - (sizeof(struct MacFrameBcast) + 1))) {
return;
}
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_TAG_RETURN_DATA_ACK;
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + RAW_PKT_PADDING;
memcpy(frameHeader->src, mSelfMac, 8);
memcpy(frameHeader->dst, rxframe->src, 8);
radiotxbuffer[1] = 0x41; // fast way to set the appropriate bits
radiotxbuffer[2] = 0xCC; // normal frame
frameHeader->seq = seq++;
frameHeader->pan = rxframe->srcPan;
radioTx(radiotxbuffer, isSubGHz);
espNotifyTagReturnData(rxframe->src, len - (sizeof(struct MacFrameBcast) + 1));
}
// send block data to the tag
void sendPart(uint8_t partNo, bool isSubGHz) {
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
struct blockPart *blockPart = (struct blockPart *)(radiotxbuffer + sizeof(struct MacFrameNormal) + 2);
memset(radiotxbuffer + 1, 0, sizeof(struct blockPart) + sizeof(struct MacFrameNormal));
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_BLOCK_PART;
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + sizeof(struct blockPart) + BLOCK_PART_DATA_SIZE + 1 + RAW_PKT_PADDING;
memcpy(frameHeader->src, mSelfMac, 8);
memcpy(frameHeader->dst, dstMac, 8);
blockPart->blockId = requestedData.blockId;
blockPart->blockPart = partNo;
memcpy(&(blockPart->data), blockbuffer + (partNo * BLOCK_PART_DATA_SIZE), BLOCK_PART_DATA_SIZE);
addCRC(blockPart, sizeof(struct blockPart) + BLOCK_PART_DATA_SIZE);
frameHeader->fcs.frameType = 1;
frameHeader->fcs.panIdCompressed = 1;
frameHeader->fcs.destAddrType = 3;
frameHeader->fcs.srcAddrType = 3;
frameHeader->seq = seq++;
frameHeader->pan = dstPan;
radioTx(radiotxbuffer, isSubGHz);
}
void sendBlockData(bool isSubGHz) {
if (getBlockDataLength() == 0) {
pr("Invalid block request received, 0 parts..\n");
requestedData.requestedParts[0] |= 0x01;
}
pr("Sending parts:");
for (uint8_t c = 0; (c < BLOCK_MAX_PARTS); c++) {
if (c % 10 == 0) pr(" ");
if (requestedData.requestedParts[c / 8] & (1 << (c % 8))) {
pr("X");
} else {
pr(".");
}
}
pr("\n");
uint8_t partNo = 0;
while (partNo < BLOCK_MAX_PARTS) {
for (uint8_t c = 0; (c < BLOCK_MAX_PARTS) && (partNo < BLOCK_MAX_PARTS); c++) {
if (requestedData.requestedParts[c / 8] & (1 << (c % 8))) {
sendPart(c, isSubGHz);
partNo++;
}
}
}
}
void sendXferCompleteAck(uint8_t *dst, bool isSubGHz) {
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
memset(radiotxbuffer + 1, 0, sizeof(struct blockPart) + sizeof(struct MacFrameNormal));
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_XFER_COMPLETE_ACK;
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + RAW_PKT_PADDING;
memcpy(frameHeader->src, mSelfMac, 8);
memcpy(frameHeader->dst, dst, 8);
frameHeader->fcs.frameType = 1;
frameHeader->fcs.panIdCompressed = 1;
frameHeader->fcs.destAddrType = 3;
frameHeader->fcs.srcAddrType = 3;
frameHeader->seq = seq++;
frameHeader->pan = dstPan;
radioTx(radiotxbuffer, isSubGHz);
}
void sendCancelXfer(uint8_t *dst, bool isSubGHz) {
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
memset(radiotxbuffer + 1, 0, sizeof(struct blockPart) + sizeof(struct MacFrameNormal));
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_CANCEL_XFER;
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + RAW_PKT_PADDING;
memcpy(frameHeader->src, mSelfMac, 8);
memcpy(frameHeader->dst, dst, 8);
frameHeader->fcs.frameType = 1;
frameHeader->fcs.panIdCompressed = 1;
frameHeader->fcs.destAddrType = 3;
frameHeader->fcs.srcAddrType = 3;
frameHeader->seq = seq++;
frameHeader->pan = dstPan;
radioTx(radiotxbuffer, isSubGHz);
}
void sendPong(void *buf, bool isSubGHz) {
struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buf;
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_PONG;
radiotxbuffer[sizeof(struct MacFrameNormal) + 2] = curChannel;
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + 1 + RAW_PKT_PADDING;
memcpy(frameHeader->src, mSelfMac, 8);
memcpy(frameHeader->dst, rxframe->src, 8);
radiotxbuffer[1] = 0x41; // fast way to set the appropriate bits
radiotxbuffer[2] = 0xCC; // normal frame
frameHeader->seq = seq++;
frameHeader->pan = rxframe->srcPan;
radioTx(radiotxbuffer, isSubGHz);
}
extern uint8_t mSelfMac[8];
void setup() {
Serial.begin(115200);
init_led();
init_second_uart();
requestedData.blockId = 0xFF;
// clear the array with pending information
memset(pendingDataArr, 0, sizeof(pendingDataArr));
radio_init(curChannel);
radioSetTxPower(10);
pr("RES>");
pr("RDY>");
Serial.printf("C6 ready!\r\n");
housekeepingTimer = millis();
}
bool isSubGhzRx = false;
void loop() {
while ((millis() - housekeepingTimer) < ((1000 * HOUSEKEEPING_INTERVAL) - 100)) {
int8_t ret = commsRxUnencrypted(radiorxbuffer, &isSubGhzRx);
if (ret > 1) {
if (0)
{
Serial.printf("RXed packet len %u :", ret);
for (int t = 0; t < ret; t++) {
Serial.printf(" %02x", radiorxbuffer[t]);
}
Serial.printf("\n");
}
led_flash(0);
// received a packet, lets see what it is
switch (getPacketType(radiorxbuffer)) {
case PKT_AVAIL_DATA_REQ:
if (ret == 28) {
// old version of the AvailDataReq struct, set all the new fields to zero, so it will pass the CRC
memset(radiorxbuffer + 1 + sizeof(struct MacFrameBcast) + sizeof(struct oldAvailDataReq), 0,
sizeof(struct AvailDataReq) - sizeof(struct oldAvailDataReq) + 2);
processAvailDataReq(radiorxbuffer, isSubGhzRx);
} else if (ret == 40) {
// new version of the AvailDataReq struct
processAvailDataReq(radiorxbuffer, isSubGhzRx);
}
break;
case PKT_BLOCK_REQUEST:
processBlockRequest(radiorxbuffer, 1, isSubGhzRx);
break;
case PKT_BLOCK_PARTIAL_REQUEST:
processBlockRequest(radiorxbuffer, 0, isSubGhzRx);
break;
case PKT_XFER_COMPLETE:
processXferComplete(radiorxbuffer, isSubGhzRx);
break;
case PKT_PING:
sendPong(radiorxbuffer, isSubGhzRx);
break;
case PKT_AVAIL_DATA_SHORTREQ:
// a short AvailDataReq is basically a very short (1 byte payload) packet that requires little preparation on the tx side, for optimal
// battery use bytes of the struct are set 0, so it passes the checksum test, and the ESP32 can detect that no interesting payload is
// sent
if (ret == 18) {
memset(radiorxbuffer + 1 + sizeof(struct MacFrameBcast), 0, sizeof(struct AvailDataReq) + 2);
processAvailDataReq(radiorxbuffer, isSubGhzRx);
}
break;
case PKT_TAG_RETURN_DATA:
processTagReturnData(radiorxbuffer, ret, isSubGhzRx);
break;
default:
Serial.printf("t=%02X\r\n", getPacketType(radiorxbuffer));
break;
}
} else if (blockStartTimer == 0) {
delay(10);
}
uint8_t curr_char;
while (getRxCharSecond(&curr_char)) processSerial(curr_char);
if (blockStartTimer) {
if (millis() > blockStartTimer) {
sendBlockData(isSubGhzRx);
blockStartTimer = 0;
}
}
}
memset(&lastTagReturn, 0, 8);
for (uint8_t cCount = 0; cCount < MAX_PENDING_MACS; cCount++) {
if (pendingDataArr[cCount].attemptsLeft == 1) {
if (pendingDataArr[cCount].availdatainfo.dataType != DATATYPE_NOUPDATE) {
espNotifyTimeOut(pendingDataArr[cCount].targetMac);
}
pendingDataArr[cCount].attemptsLeft = 0;
} else if (pendingDataArr[cCount].attemptsLeft > 1) {
pendingDataArr[cCount].attemptsLeft--;
if (pendingDataArr[cCount].availdatainfo.nextCheckIn) pendingDataArr[cCount].availdatainfo.nextCheckIn--;
}
}
housekeepingTimer = millis();
}

View File

@@ -0,0 +1,44 @@
#include "led.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "proto.h"
#include <Arduino.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_LEDS 2
const uint8_t led_pins[NUM_LEDS] = { LED1, LED2 };
TimerHandle_t led_timers[NUM_LEDS] = { 0 };
void led_timer_callback(TimerHandle_t xTimer) {
int led_index = (int)pvTimerGetTimerID(xTimer);
if (led_index >= 0 && led_index < NUM_LEDS) {
digitalWrite(led_pins[led_index], 0);
}
}
void init_led() {
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
for (int i = 0; i < NUM_LEDS; i++) {
led_timers[i] = xTimerCreate("led_timer", pdMS_TO_TICKS(50), pdFALSE, (void *)i, led_timer_callback);
}
}
void led_flash(int nr) {
digitalWrite(led_pins[nr], 1);
if (nr >= 0 && nr < NUM_LEDS) {
xTimerStart(led_timers[nr], 0);
}
}
void led_set(int nr, bool state) {
digitalWrite(nr, state);
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include <stdbool.h>
void init_led();
void led_set(int nr, bool state);
void led_flash(int nr);

View File

@@ -0,0 +1,190 @@
#ifndef _PROTO_H_
#define _PROTO_H_
#include <stdint.h>
#define LED1 22
#define LED2 23
#define PROTO_PAN_ID (0x4447) // PAN ID compression shall be used
#define RADIO_MAX_PACKET_LEN (125) // useful payload, not including the crc
#define ADDR_MODE_NONE (0)
#define ADDR_MODE_SHORT (2)
#define ADDR_MODE_LONG (3)
#define FRAME_TYPE_BEACON (0)
#define FRAME_TYPE_DATA (1)
#define FRAME_TYPE_ACK (2)
#define FRAME_TYPE_MAC_CMD (3)
#define SHORT_MAC_UNUSED (0x10000000UL) // for radioRxFilterCfg's myShortMac
struct MacFcs {
uint8_t frameType : 3;
uint8_t secure : 1;
uint8_t framePending : 1;
uint8_t ackReqd : 1;
uint8_t panIdCompressed : 1;
uint8_t rfu1 : 1;
uint8_t rfu2 : 2;
uint8_t destAddrType : 2;
uint8_t frameVer : 2;
uint8_t srcAddrType : 2;
} __attribute__((packed, aligned(1)));
struct MacFrameFromMaster {
struct MacFcs fcs;
uint8_t seq;
uint16_t pan;
uint8_t dst[8];
uint16_t from;
} __attribute__((packed, aligned(1)));
struct MacFrameNormal {
struct MacFcs fcs;
uint8_t seq;
uint16_t pan;
uint8_t dst[8];
uint8_t src[8];
} __attribute__((packed, aligned(1)));
struct MacFrameBcast {
struct MacFcs fcs;
uint8_t seq;
uint16_t dstPan;
uint16_t dstAddr;
uint16_t srcPan;
uint8_t src[8];
} __attribute__((packed, aligned(1)));
#define PKT_TAG_RETURN_DATA 0xE1
#define PKT_TAG_RETURN_DATA_ACK 0xE2
#define PKT_AVAIL_DATA_SHORTREQ 0xE3
#define PKT_AVAIL_DATA_REQ 0xE5
#define PKT_AVAIL_DATA_INFO 0xE6
#define PKT_BLOCK_PARTIAL_REQUEST 0xE7
#define PKT_BLOCK_REQUEST_ACK 0xE9
#define PKT_BLOCK_REQUEST 0xE4
#define PKT_BLOCK_PART 0xE8
#define PKT_XFER_COMPLETE 0xEA
#define PKT_XFER_COMPLETE_ACK 0xEB
#define PKT_CANCEL_XFER 0xEC
#define PKT_PING 0xED
#define PKT_PONG 0xEE
struct AvailDataReq {
uint8_t checksum;
uint8_t lastPacketLQI;
int8_t lastPacketRSSI;
int8_t temperature;
uint16_t batteryMv;
uint8_t hwType;
uint8_t wakeupReason;
uint8_t capabilities;
uint16_t tagSoftwareVersion;
uint8_t currentChannel;
uint8_t customMode;
uint8_t reserved[8];
} __attribute__((packed, aligned(1)));
struct oldAvailDataReq {
uint8_t checksum;
uint8_t lastPacketLQI;
int8_t lastPacketRSSI;
int8_t temperature;
uint16_t batteryMv;
uint8_t hwType;
uint8_t wakeupReason;
uint8_t capabilities;
} __attribute__((packed, aligned(1)));
struct AvailDataInfo {
uint8_t checksum;
uint64_t dataVer; // MD5 of potential traffic
uint32_t dataSize;
uint8_t dataType;
uint8_t dataTypeArgument; // extra specification or instruction for the tag (LUT to be used for drawing image)
uint16_t nextCheckIn; // when should the tag check-in again? Measured in minutes
} __attribute__((packed, aligned(1)));
struct pendingData {
struct AvailDataInfo availdatainfo;
uint16_t attemptsLeft;
uint8_t targetMac[8];
} __attribute__((packed, aligned(1)));
struct blockPart {
uint8_t checksum;
uint8_t blockId;
uint8_t blockPart;
uint8_t data[];
} __attribute__((packed, aligned(1)));
struct blockData {
uint16_t size;
uint16_t checksum;
uint8_t data[];
} __attribute__((packed, aligned(1)));
#define TAG_RETURN_DATA_SIZE 90
struct tagReturnData {
uint8_t checksum;
uint8_t partId;
uint64_t dataVer;
uint8_t dataType;
uint8_t data[TAG_RETURN_DATA_SIZE];
} __attribute__((packed, aligned(1)));
#define BLOCK_PART_DATA_SIZE 99
#define BLOCK_MAX_PARTS 42
#define BLOCK_DATA_SIZE 4096UL
#define BLOCK_XFER_BUFFER_SIZE BLOCK_DATA_SIZE + sizeof(struct blockData)
#define BLOCK_REQ_PARTS_BYTES 6
struct blockRequest {
uint8_t checksum;
uint64_t ver;
uint8_t blockId;
uint8_t type;
uint8_t requestedParts[BLOCK_REQ_PARTS_BYTES];
} __attribute__((packed, aligned(1)));
struct blockRequestAck {
uint8_t checksum;
uint16_t pleaseWaitMs;
} __attribute__((packed, aligned(1)));
struct espBlockRequest {
uint8_t checksum;
uint64_t ver;
uint8_t blockId;
uint8_t src[8];
} __attribute__((packed, aligned(1)));
struct espXferComplete {
uint8_t checksum;
uint8_t src[8];
} __attribute__((packed, aligned(1)));
struct espAvailDataReq {
uint8_t checksum;
uint8_t src[8];
struct AvailDataReq adr;
} __attribute__((packed, aligned(1)));
struct espSetChannelPower {
uint8_t checksum;
uint8_t channel;
uint8_t power;
} __attribute__((packed, aligned(1)));
struct espTagReturnData {
uint8_t checksum;
uint8_t src[8];
uint8_t len;
struct tagReturnData returnData;
} __attribute__((packed, aligned(1)));
#endif

View File

@@ -0,0 +1,155 @@
#include "radio.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#include "esp_err.h"
#include "esp_event.h"
#include "esp_ieee802154.h"
#include "esp_phy_init.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "led.h"
#include "subGhz.h"
#include "proto.h"
#include "sdkconfig.h"
// if you get an error about soc/lp_uart_reg.h not being found,
// you didn't choose the right build target. :-)
#include "soc/lp_uart_reg.h"
#include "soc/uart_struct.h"
#include <esp_mac.h>
#include <math.h>
#include <stdarg.h>
#include <string.h>
#include <Arduino.h>
bool has_sub_ghz = false;
uint8_t mSelfMac[8];
volatile uint8_t isInTransmit = 0;
QueueHandle_t packet_buffer = NULL;
void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info) {
Serial.printf("RADIO info RX %d\r\n", frame[0]);
BaseType_t xHigherPriorityTaskWoken;
static uint8_t inner_rxPKT[130];
memcpy(inner_rxPKT, &frame[0], frame[0] + 1);
xQueueSendFromISR(packet_buffer, (void *)&inner_rxPKT, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR_ARG(xHigherPriorityTaskWoken);
}
void esp_ieee802154_transmit_failed(const uint8_t *frame, esp_ieee802154_tx_error_t error) {
isInTransmit = 0;
Serial.printf("RADIO err TX Err: %d\r\n", error);
}
void esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_ieee802154_frame_info_t *ack_frame_info) {
isInTransmit = 0;
Serial.printf("RADIO info TX %d\r\n", frame[0]);
}
void radio_init(uint8_t ch) {
if (packet_buffer == NULL) packet_buffer = xQueueCreate(32, 130);
// this will trigger a "IEEE802154 MAC sleep init failed" when called a second time, but it works
esp_ieee802154_enable();
esp_ieee802154_set_channel(ch);
// esp_ieee802154_set_txpower(int8_t power);
esp_ieee802154_set_panid(PROTO_PAN_ID);
esp_ieee802154_set_promiscuous(false);
esp_ieee802154_set_coordinator(false);
esp_ieee802154_set_pending_mode(ESP_IEEE802154_AUTO_PENDING_ZIGBEE);
// esp_ieee802154_set_extended_address needs the MAC in reversed byte order
esp_read_mac(mSelfMac, ESP_MAC_IEEE802154);
uint8_t eui64_rev[8] = { 0 };
for (int i = 0; i < 8; i++) {
eui64_rev[7 - i] = mSelfMac[i];
}
esp_ieee802154_set_extended_address(eui64_rev);
esp_ieee802154_get_extended_address(mSelfMac);
esp_ieee802154_set_short_address(0xFFFE);
esp_ieee802154_set_rx_when_idle(true);
esp_ieee802154_receive();
led_flash(1);
delay(100);
led_flash(0);
delay(100);
led_flash(1);
delay(100);
led_flash(0);
Serial.printf("RADIO Receiver ready, panId=0x%04x, channel=%d, long=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, short=%04x\r\n",
esp_ieee802154_get_panid(), esp_ieee802154_get_channel(),
mSelfMac[0], mSelfMac[1], mSelfMac[2], mSelfMac[3],
mSelfMac[4], mSelfMac[5], mSelfMac[6], mSelfMac[7],
esp_ieee802154_get_short_address());
// Lets here take care of the SubGhz Init
if (!init_subGhz())
Serial.printf("Sub-GHz radio init failed\r\n");
else if (!tiRadioSetChannel(ch))
Serial.printf("SubGHz radio channel fail\r\n");
else
has_sub_ghz = true;
Serial.printf("SubGhz %s\r\n", has_sub_ghz ? "Active" : "Not Found");
if (has_sub_ghz) {
tiRadioRxFilterCfg(mSelfMac, SHORT_MAC_UNUSED, PROTO_PAN_ID, true);
tiRadioTxConfigure(mSelfMac, SHORT_MAC_UNUSED, PROTO_PAN_ID);
tiRadioRxEnable(true, false);
}
}
// uint32_t lastZbTx = 0;
bool radioTx(uint8_t *packet, bool subGhz) {
led_flash(1);
if (has_sub_ghz && subGhz) {
tiRadioTxLL(packet);
} else {
static uint8_t txPKT[130];
while (isInTransmit) {
}
// while (millis() - lastZbTx < 6) {
// }
// lastZbTx = millis();
memcpy(txPKT, packet, packet[0]);
isInTransmit = 1;
esp_ieee802154_transmit(txPKT, false);
return true;
}
}
void radioSetChannel(uint8_t ch) {
radio_init(ch);
if (has_sub_ghz)
tiRadioSetChannel(ch);
}
void radioSetTxPower(uint8_t power) {}
int8_t commsRxUnencrypted(uint8_t *data, bool *subGhzRx) {
int8_t rssi_sub_rx = 0;
uint8_t lqi_sub_rx = 0;
static uint8_t inner_rxPKT_out[135];
if (xQueueReceive(packet_buffer, (void *)&inner_rxPKT_out, pdMS_TO_TICKS(100)) == pdTRUE) {
memcpy(data, &inner_rxPKT_out[1], inner_rxPKT_out[0] + 1);
*subGhzRx = false; // This is Normal data
return inner_rxPKT_out[0] - 2;
}
if (has_sub_ghz) {
int32_t ret_sub_rx_len = tiRadioRxDequeuePkt(inner_rxPKT_out, sizeof(inner_rxPKT_out), &rssi_sub_rx, &lqi_sub_rx);
if (ret_sub_rx_len > 0)
{
//Serial.printf("Got Sub Ghz Len %i data: %i %u\r\n", ret_sub_rx, rssi_sub_rx, lqi_sub_rx);
memcpy(data, inner_rxPKT_out, ret_sub_rx_len);
*subGhzRx = true; // This is SubGHz data
return ret_sub_rx_len;
}
}
return 0;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
extern uint8_t mSelfMac[8];
void radio_init(uint8_t ch);
bool radioTx(uint8_t *packet, bool subGhz);
void radioSetChannel(uint8_t ch);
void radioSetTxPower(uint8_t power);
int8_t commsRxUnencrypted(uint8_t *data, bool *subGhzRx);

View File

@@ -0,0 +1,125 @@
#include <esp_mac.h>
#include <math.h>
#include <stdarg.h>
#include <string.h>
#include <Arduino.h>
#include "driver/gpio.h"
#include "driver/uart.h"
#include "esp_err.h"
#include "esp_event.h"
#include "esp_ieee802154.h"
#include "esp_phy_init.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "proto.h"
#include "sdkconfig.h"
#include "soc/uart_struct.h"
#include "soc/lp_uart_reg.h"
#include "second_uart.h"
#if defined(CONFIG_OEPL_HARDWARE_PROFILE_POE_AP)
#define CONFIG_OEPL_HARDWARE_UART_TX 5
#define CONFIG_OEPL_HARDWARE_UART_RX 18
#else
#if !defined(CONFIG_OEPL_HARDWARE_UART_TX) || !defined(CONFIG_OEPL_HARDWARE_UART_RX)
#define CONFIG_OEPL_HARDWARE_UART_TX 3
#define CONFIG_OEPL_HARDWARE_UART_RX 2
#endif
#endif
#define BUF_SIZE (1024)
#define RD_BUF_SIZE (BUF_SIZE)
static QueueHandle_t uart0_queue;
#define MAX_BUFF_POS 8000
volatile int curr_buff_pos = 0;
volatile int worked_buff_pos = 0;
volatile uint8_t buff_pos[MAX_BUFF_POS + 5];
static void uart_event_task(void *pvParameters);
void init_second_uart() {
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
};
ESP_ERROR_CHECK(uart_driver_install(1, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart0_queue, 0));
ESP_ERROR_CHECK(uart_param_config(1, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(1, CONFIG_OEPL_HARDWARE_UART_TX, CONFIG_OEPL_HARDWARE_UART_RX, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
xTaskCreate(uart_event_task, "uart_event_task", 16384, NULL, 12, NULL);
}
void uart_switch_speed(int baudrate) {
uart_config_t uart_config = {
.baud_rate = baudrate,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
};
ESP_ERROR_CHECK(uart_param_config(1, &uart_config));
}
void uartTx(uint8_t data) {
uart_write_bytes(1, (const char *)&data, 1);
}
bool getRxCharSecond(uint8_t *newChar) {
if (curr_buff_pos != worked_buff_pos) {
*newChar = buff_pos[worked_buff_pos];
worked_buff_pos++;
worked_buff_pos %= MAX_BUFF_POS;
return true;
}
return false;
}
static void uart_event_task(void *pvParameters) {
uart_event_t event;
uint8_t *dtmp = (uint8_t *)malloc(RD_BUF_SIZE);
for (;;) {
if (xQueueReceive(uart0_queue, (void *)&event, (TickType_t)portMAX_DELAY)) {
bzero(dtmp, RD_BUF_SIZE);
switch (event.type) {
case UART_DATA:
uart_read_bytes(1, dtmp, event.size, portMAX_DELAY);
for (int i = 0; i < event.size; i++) {
buff_pos[curr_buff_pos] = dtmp[i];
curr_buff_pos++;
curr_buff_pos %= MAX_BUFF_POS;
}
break;
default:
Serial.printf("Second UART uart event type: %d\r\n", event.type);
break;
}
}
}
free(dtmp);
dtmp = NULL;
vTaskDelete(NULL);
}
void uart_printf(const char *format, ...) {
va_list args;
va_start(args, format);
char buffer[128];
int len = vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
if (len > 0) {
uart_write_bytes(1, buffer, len);
}
}

View File

@@ -0,0 +1,13 @@
#pragma once
#include <inttypes.h>
void init_second_uart();
void uart_switch_speed(int baudrate);
void uartTx(uint8_t data);
bool getRxCharSecond(uint8_t *newChar);
void uart_printf(const char *format, ...);
#define pr uart_printf

View File

@@ -0,0 +1,609 @@
// This code is heavily depending on Dmitrys wonderful Work !
// https://dmitry.gr/?r=05.Projects&proj=29.%20eInk%20Price%20Tags
// Ported and modified to fit the OpenEPaperLink Project by ATC1441 (ATCnetz.de) ~01.2024
#include "subGhz.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "proto.h"
#include <Arduino.h>
#include <SPI.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SUB_GHZ_CH_OFST 11
#define SUB_GHZ_NUM_CHANNELS 25
/*
//we configure GDO_2 is for TX.has_fifo_space
//we configure GDO_0 is for RX.has_data
WIRING:
*/
#define sub_CS 4
#define sub_GD0 5
#define sub_GD2 6
#define sub_MISO 7
#define sub_CLK 0
#define sub_MOSI 1
#define CMD_SRES 0x30
#define CMD_SFSTXON 0x31
#define CMD_SXOFF 0x32
#define CMD_SCAL 0x33
#define CMD_SRX 0x34
#define CMD_STX 0x35
#define CMD_SIDLE 0x36
#define CMD_SWOR 0x38
#define CMD_SPWD 0x39
#define CMD_SFRX 0x3a
#define CMD_SFTX 0x3b
#define CMD_SWORRST 0x3c
#define CMD_SNOP 0x3d
#define REG_IOCFG2 0x00
#define REG_IOCFG1 0x01
#define REG_IOCFG0 0x02
#define REG_FIFOTHR 0x03
#define REG_SYNC1 0x04
#define REG_SYNC0 0x05
#define REG_PKTLEN 0x06
#define REG_PKTCTRL1 0x07
#define REG_PKTCTRL0 0x08
#define REG_ADDR 0x09
#define REG_CHANNR 0x0a
#define REG_FSCTRL1 0x0b
#define REG_FSCTRL0 0x0c
#define REG_FREQ2 0x0d
#define REG_FREQ1 0x0e
#define REG_FREQ0 0x0f
#define REG_MDMCFG4 0x10
#define REG_MDMCFG3 0x11
#define REG_MDMCFG2 0x12
#define REG_MDMCFG1 0x13
#define REG_MDMCFG0 0x14
#define REG_DEVIATN 0x15
#define REG_MCSM2 0x16
#define REG_MCSM1 0x17
#define REG_MCSM0 0x18
#define REG_FOCCFG 0x19
#define REG_BSCFG 0x1a
#define REG_AGCTRL2 0x1b
#define REG_AGCTRL1 0x1c
#define REG_AGCTRL0 0x1d
#define REG_WOREVT1 0x1e
#define REG_WOREVT0 0x1f
#define REG_WORCTRL 0x20
#define REG_FREND1 0x21
#define REG_FREND0 0x22
#define REG_FSCAL3 0x23
#define REG_FSCAL2 0x24
#define REG_FSCAL1 0x25
#define REG_FSCAL0 0x26
#define REG_RCCTRL1 0x27
#define REG_RCCTRL0 0x28
#define REG_FSTEST 0x29
#define REG_PTEST 0x2a
#define REG_AGCTEST 0x2b
#define REG_TEST2 0x2c
#define REG_TEST1 0x2d
#define REG_TEST0 0x2e
#define REG_PATABLE 0x3e
#define REG_FIFO 0x3f
#define REG_PARTNUM 0xf0
#define REG_VERSION 0xf1
#define REG_FREQEST 0xf2
#define REG_LQI 0xf3
#define REG_RSSI 0xf4
#define REG_MARCSTATE 0xf5
#define REG_WORTIME1 0xf6
#define REG_WORTIME0 0xf7
#define REG_PKTSTATUS 0xf8
#define REG_VCO_VC_DAC 0xf9
#define REG_TXBYTES 0xfa
#define REG_RXBYTES 0xfb
#define REG_RCCTRL1_STA 0xfc
#define REG_RCCTRL0_STA 0xfd
#define MAX_RX_PKTS 80
static volatile uint8_t mRxBufs[MAX_RX_PKTS][RADIO_MAX_PACKET_LEN + 1 /* length */ + 2 /* RSSI, LQI/STA */];
static volatile uint8_t mRxNextWrite, mRxNextRead, mRxNumFree, mRxNumGot;
static uint8_t mRxFilterLongMac[8], mTxLongMac[8];
static uint32_t mRxFilterShortMac, mTxShortMac;
static bool mRxEnabled, mAutoAck, mPromisc;
static uint16_t mRxFilterPan, mTxPan;
static volatile int16_t mLastAck;
struct MacHeaderGenericAddr {
struct MacFcs fixed;
uint8_t seq;
} __attribute__((packed));
struct MacHeaderShortAddr {
struct MacFcs fixed;
uint8_t seq;
uint16_t pan;
uint16_t shortDstAddr;
} __attribute__((packed));
struct MacHeaderLongAddr {
struct MacFcs fixed;
uint8_t seq;
uint16_t pan;
uint8_t longDstAddr[8];
} __attribute__((packed));
void tiRadioTxConfigure(const uint8_t *myLongMac, uint32_t myShortMac, uint16_t pan) {
memcpy(mTxLongMac, myLongMac, sizeof(mTxLongMac));
mTxShortMac = myShortMac;
mTxPan = pan;
}
void tiRadioRxFilterCfg(const uint8_t *myMac, uint32_t myShortMac, uint16_t myPan, bool promisc) {
mPromisc = promisc;
mRxFilterShortMac = myShortMac;
mRxFilterPan = myPan;
memcpy(mRxFilterLongMac, myMac, sizeof(mRxFilterLongMac));
}
static bool tiRadioPrvSelect(void) {
digitalWrite(sub_CS, LOW);
SPI.beginTransaction(SPISettings(6000000, MSBFIRST, SPI_MODE0));
asm volatile("nop \n nop \n nop \n");
return true;
}
static void tiRadioPrvDeselect(void) {
asm volatile("nop \n nop \n nop \n");
SPI.endTransaction();
digitalWrite(sub_CS, HIGH);
asm volatile("nop \n nop \n nop \n");
}
static void read_multiple(uint8_t *dst, uint_fast8_t rxLen) {
for (int i = 0; i < rxLen; i++) {
dst[i] = SPI.transfer(0xff);
}
}
static int_fast16_t tiRadioPrvStrobe(uint8_t cmd) //negative on error
{
if (!tiRadioPrvSelect())
return -1;
cmd = SPI.transfer(cmd);
tiRadioPrvDeselect();
return (uint_fast16_t)cmd;
}
static bool tiRadioPrvRegWrite(uint_fast8_t reg, uint_fast8_t val) {
if (!tiRadioPrvSelect())
return false;
SPI.transfer(reg);
SPI.transfer(val);
tiRadioPrvDeselect();
return true;
}
static int_fast16_t tiRadioPrvRegRead(uint_fast8_t reg) {
uint8_t read_data = 0x00;
if (!tiRadioPrvSelect())
return -1;
SPI.transfer(reg | 0x80);
read_data = SPI.transfer(0xff);
tiRadioPrvDeselect();
return (uint_fast16_t)read_data;
}
static bool tiRadioPrvRegWriteLong(uint8_t reg, const uint8_t *valP, uint8_t len) {
if (!tiRadioPrvSelect())
return false;
SPI.transfer(reg | 0x40);
for (int i = 0; i < len; i++) {
SPI.transfer(valP[i]);
}
tiRadioPrvDeselect();
return true;
}
bool tiRadioRxEnable(bool on, bool autoAck) {
bool ret = false;
if (on) {
mAutoAck = autoAck;
if (mRxEnabled) {
ret = true;
goto out;
}
if (!tiRadioPrvStrobe(CMD_SRX))
goto out;
mRxEnabled = true;
} else if (mRxEnabled) {
if (!tiRadioPrvStrobe(CMD_SIDLE))
goto out;
mRxEnabled = false;
}
ret = true;
out:
return ret;
}
static bool radioPrvMacsEqual(const uint8_t *macA, const uint8_t *macB) {
const uint32_t *a = (const uint32_t *)(const char *)macA;
const uint32_t *b = (const uint32_t *)(const char *)macB;
return a[0] == b[0] && a[1] == b[1];
}
static uint_fast8_t tiRadioPrvGetState(void) {
uint_fast8_t state;
do {
state = tiRadioPrvRegRead(REG_MARCSTATE);
} while (tiRadioPrvRegRead(REG_MARCSTATE) != state);
return state;
}
static void tiRadioPrvPacketRx(void) {
uint8_t *rxedPkt = (uint8_t *)mRxBufs[mRxNextWrite];
const struct MacHeaderShortAddr *withShortDst = (const struct MacHeaderShortAddr *)(rxedPkt + 1);
const struct MacHeaderGenericAddr *generic = (const struct MacHeaderGenericAddr *)(rxedPkt + 1);
const struct MacHeaderLongAddr *withLongDst = (const struct MacHeaderLongAddr *)(rxedPkt + 1);
bool crcOk, acceptPacket, sendAck = false;
int32_t t, lenNoCrc, lenNoMacFixed;
uint32_t nWaitCycles = 10000;
uint_fast8_t spiLen, now;
t = tiRadioPrvRegRead(REG_FIFO);
if (t < 0)
goto fail;
if (!mRxNumFree)
goto fail;
spiLen = t;
if (spiLen > RADIO_MAX_PACKET_LEN)
goto fail;
t = 0;
rxedPkt[t++] = lenNoCrc = spiLen;
now = 31; //we just read one so 31 left for sure in the FIFO
spiLen += 2; //we expect 2 more bytes
while (spiLen) {
uint8_t reg;
if (!tiRadioPrvSelect()) {
tiRadioPrvDeselect();
goto fail;
}
reg = 0xc0 | REG_FIFO; //burst read
reg = SPI.transfer(reg);
now = reg & 0x0f;
if (now > spiLen)
now = spiLen;
if (!now && !--nWaitCycles) {
tiRadioPrvDeselect();
//Serial.printf(" !!! RX timeout !!! \r\n");
goto fail;
}
read_multiple(rxedPkt + t, now);
t += now;
spiLen -= now;
tiRadioPrvDeselect();
}
rxedPkt++; //skip len;
crcOk = !!(rxedPkt[lenNoCrc + 1] & 0x80);
lenNoMacFixed = lenNoCrc - sizeof(struct MacFcs) - sizeof(uint8_t);
if (mPromisc)
acceptPacket = true;
//otherwise, we need a valid crc
else if (!crcOk) {
acceptPacket = false;
}
//packet should be big enough to contain a header
else if (lenNoMacFixed < 0)
acceptPacket = false;
else switch (generic->fixed.frameType) {
case FRAME_TYPE_ACK:
mLastAck = (uint16_t)generic->seq;
acceptPacket = false; //no need to save it as a packet
break;
case FRAME_TYPE_DATA: //we are not the coordinator, so we demand to see our address as destination...
switch (generic->fixed.destAddrType) {
case ADDR_MODE_SHORT:
acceptPacket = (withShortDst->pan == 0xffff && withShortDst->shortDstAddr == 0xffff) || (withShortDst->pan == mRxFilterPan && (withShortDst->shortDstAddr == 0xffff || ((uint32_t)withShortDst->shortDstAddr) == mRxFilterShortMac));
break;
case ADDR_MODE_LONG:
acceptPacket = withLongDst->pan == mRxFilterPan && radioPrvMacsEqual(withLongDst->longDstAddr, mRxFilterLongMac);
break;
default:
acceptPacket = false;
break;
}
sendAck = generic->fixed.ackReqd && mAutoAck;
break;
default:
//no riff-raff please
acceptPacket = false;
break;
}
if (acceptPacket) { //other checks here too plz
if (sendAck) {
static struct {
uint8_t len;
struct MacFcs mac;
uint8_t seq;
} __attribute__((packed)) ack = {
.len = sizeof(ack) + sizeof(uint16_t) - sizeof(ack.len),
.mac = {
.frameType = FRAME_TYPE_ACK,
},
};
ack.seq = generic->seq;
tiRadioTxLL(&ack);
}
mRxNumFree--;
if (++mRxNextWrite == MAX_RX_PKTS)
mRxNextWrite = 0;
mRxNumGot++;
}
out:
if (mRxEnabled && !sendAck) { //if ack is being TXed, TX irq will restart rx later
uint32_t maxWait = 100000;
uint8_t state;
(void)tiRadioPrvStrobe(CMD_SRX);
do {
state = tiRadioPrvGetState();
if (!--maxWait) {
//Serial.printf("too long wait for rx state. state is %d\n", state);
break;
}
} while (state != 13 && state != 14 && state != 15);
}
return;
fail:
(void)tiRadioPrvStrobe(CMD_SFRX);
goto out;
}
void tiRadioRxAckReset(void) {
mLastAck = -1;
}
int16_t tiRadioRxAckGetLast(void) {
return mLastAck;
}
int32_t tiRadioRxDequeuePkt(void *dstBuf, uint32_t maxLen, int8_t *rssiP, uint8_t *lqiP) {
uint32_t len, copyLen = maxLen;
if (!mRxNumGot)
return -1;
len = mRxBufs[mRxNextRead][0];
if (copyLen > len)
copyLen = len;
memcpy(dstBuf, (const void *)(mRxBufs[mRxNextRead] + 1), copyLen);
if (lqiP) {
uint32_t lqi = 296 - ((mRxBufs[mRxNextRead][len + 2] & 0x7f) * 2);
//LQI: lower is better. 48 is very good (no lower value seen), 127 is very bad (max value possible)
//we want LQI 0..255 so we scale as SATURATE(296 - 2 * val)
if (lqi > 255)
lqi = 255;
*lqiP = lqi;
}
if (rssiP)
*rssiP = ((int8_t)mRxBufs[mRxNextRead][len + 1]) / 2 - 77;
if (++mRxNextRead == MAX_RX_PKTS)
mRxNextRead = 0;
noInterrupts();
mRxNumFree++;
mRxNumGot--;
interrupts();
//ti radio never stalls RX state machine so nothing to do even if we just freed up a buffer
return len;
}
void data_input_interrupt(void) {
while (digitalRead(sub_GD0)) //while there is data (packets)
tiRadioPrvPacketRx();
}
static void tiRadioPrvIfInit(void) {
//configure pins
pinMode(sub_CS, OUTPUT);
pinMode(sub_GD0, INPUT_PULLUP);
pinMode(sub_GD2, INPUT_PULLUP);
SPI.begin(sub_CLK, sub_MISO, sub_MOSI);
tiRadioPrvDeselect();
mRxNumFree = MAX_RX_PKTS;
}
static void tiRadioPrvIrqInit(void) {
attachInterrupt(sub_GD0, data_input_interrupt, RISING);
}
bool tiRadioSetChannel(uint_fast8_t channel) {
channel -= SUB_GHZ_CH_OFST;
if (channel >= SUB_GHZ_NUM_CHANNELS)
return false;
return tiRadioPrvRegWrite(REG_CHANNR, channel * 3);
}
bool tiRadioTxLL(const void *pkt) {
const uint8_t *data = (const uint8_t *)pkt;
uint32_t len = 1 + *data, now;
bool ret = false;
if (0) {
Serial.printf("TX packet len %u :", len);
for (int t = 0; t < len; t++) {
Serial.printf(" %02x", data[1 + t]);
}
Serial.printf("\n");
}
if (tiRadioPrvStrobe(CMD_SIDLE) < 0)
goto out;
if (tiRadioPrvStrobe(CMD_SFTX) < 0)
goto out;
now = (len > 64 ? 64 : len);
if (!tiRadioPrvRegWriteLong(REG_FIFO, data, now))
goto out;
len -= now;
data += now;
if (tiRadioPrvStrobe(CMD_STX) < 0)
goto out;
while (len) {
now = 8;
if (now > len)
now = len;
while (digitalRead(sub_GD2))
; //wait till there is space
if (!tiRadioPrvRegWriteLong(REG_FIFO, data, now))
goto out;
data += now;
len -= now;
}
while (tiRadioPrvGetState() != 1)
;
if (!tiRadioPrvStrobe(mRxEnabled ? CMD_SRX : CMD_SIDLE))
goto out;
ret = true;
out:
return ret;
}
bool init_subGhz(void) {
uint8_t regsCfg[] = {
/* 0x00 */ 0x02, 0x2e, 0x01, 0x07, 0xd3, 0x91, 0x7f, 0x04,
/* 0x08 */ 0x45, 0x22, 0x00, 0x0e, 0x00, 0x22, 0xbb, 0x13,
/* 0x10 */ 0x1d, 0x3b, 0x13, 0x43, 0xa4, 0x65, 0x07, 0x30,
/* 0x18 */ 0x1d, 0x1e, 0x1c, 0xc7, 0x00, 0xb0, 0x87, 0x6b,
/* 0x20 */ 0xfb, 0xb6, 0x10, 0xea, 0x2a, 0x00, 0x1f, 0x41,
/* 0x28 */ 0x00,
};
uint8_t paTab[] = { 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0 };
tiRadioPrvIfInit();
if (tiRadioPrvRegRead(REG_PARTNUM) != 0x00) {
Serial.printf("partnum is wrong\n");
return false;
}
if (tiRadioPrvStrobe(CMD_SRES) < 0) {
Serial.printf("res reply\n");
return false;
}
delayMicroseconds(300);
if (tiRadioPrvStrobe(CMD_SIDLE) != 0x0f) {
Serial.printf("idle reply\n");
return false;
}
if (!tiRadioPrvRegWriteLong(0, regsCfg, sizeof(regsCfg))) {
Serial.printf("config issue\n");
return false;
}
if (!tiRadioPrvRegWriteLong(REG_PATABLE, paTab, sizeof(paTab))) {
Serial.printf("PAtable issue\n");
return false;
}
tiRadioPrvIrqInit();
Serial.printf("Sub-GHz radio inited\n");
tiRadioRxEnable(true, false);
Serial.printf("Sub-GHz rx is on\n");
return true;
}

View File

@@ -0,0 +1,32 @@
// This code is heavily depending on Dmitrys wonderful Work !
// https://dmitry.gr/?r=05.Projects&proj=29.%20eInk%20Price%20Tags
// Ported and modified to fit the OpenEPaperLink Project by ATC1441 (ATCnetz.de) ~01.2024
#pragma once
#include <Arduino.h>
#include <stdbool.h>
void tiRadioTxConfigure(const uint8_t *myLongMac, uint32_t myShortMac, uint16_t pan);
void tiRadioRxFilterCfg(const uint8_t *myMac, uint32_t myShortMac, uint16_t myPan, bool promisc);
static bool tiRadioPrvSelect(void);
static void tiRadioPrvDeselect(void);
static void read_multiple(uint8_t *dst, uint_fast8_t rxLen);
static int_fast16_t tiRadioPrvStrobe(uint8_t cmd);
static bool tiRadioPrvRegWrite(uint_fast8_t reg, uint_fast8_t val);
static int_fast16_t tiRadioPrvRegRead(uint_fast8_t reg);
static bool tiRadioPrvRegWriteLong(uint8_t reg, const uint8_t *valP, uint8_t len);
bool tiRadioRxEnable(bool on, bool autoAck);
static bool radioPrvMacsEqual(const uint8_t *macA, const uint8_t *macB);
static uint_fast8_t tiRadioPrvGetState(void);
static void tiRadioPrvPacketRx(void);
void tiRadioRxAckReset(void);
int16_t tiRadioRxAckGetLast(void);
int32_t tiRadioRxDequeuePkt(void* dstBuf, uint32_t maxLen, int8_t *rssiP, uint8_t *lqiP);
void data_input_interrupt(void);
static void tiRadioPrvIfInit(void);
static void tiRadioPrvIrqInit(void);
bool tiRadioSetChannel(uint_fast8_t channel);
bool tiRadioTxLL(const void* pkt);
bool init_subGhz(void);

View File

@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

View File

@@ -0,0 +1,47 @@
name: Bug report
description: Report a problem with esp-serial-flasher operation
labels: ['Type: Bug']
body:
- type: markdown
attributes:
value: |
* Please ensure you are using the latest version of `esp-serial-flasher`.
* Try using one of the examples from the `examples` directory and following the example documentation.
* If your board is a custom design, consider using our [free-of-charge schematic and PCB review service](https://www.espressif.com/en/contact-us/circuit-schematic-pcb-design-review).
* If still experiencing issues, please provide as many details as possible below about your hardware and software setup.
- type: input
id: port
attributes:
label: Port
description: Which port are you experiencing the issue with?
placeholder: ex. ESP, STM32
validations:
required: true
- type: input
id: target
attributes:
label: Target chip
description: Which chip are you trying to flash?
placeholder: ex. ESP8266, ESP32, ESP32-C3
validations:
required: true
- type: textarea
id: other-hw
attributes:
label: Hardware Configuration
description: What dev boards/custom PCB are you using, how are the chips connected, which baudrate are you trying to flash with?
validations:
required: true
id: output
- type: textarea
attributes:
label: Log output
description: Enable tracing with SERIAL_FLASHER_DEBUG_TRACE and provide the full log.
render: plain
validations:
required: true
- type: textarea
id: more-info
attributes:
label: More Information
description: Provide any additional information relevant to the issue.

View File

@@ -0,0 +1,34 @@
name: Feature request
description: Suggest an idea for this project
labels: ['Type: Feature Request']
body:
- type: markdown
attributes:
value: |
* We welcome any ideas or feature requests! It's helpful if you can explain exactly why the feature would be useful.
* Please check if the feature has already been suggested in [existing issues](https://github.com/espressif/esp-serial-flasher/issues) or [pull requests](https://github.com/espressif/esp-serial-flasher/pulls).
* Please provide enough context so that the reasoning behind the suggestion can be understood.
- type: textarea
id: problem-related
attributes:
label: Is your feature request related to a problem?
description: Please provide a clear and concise description of what the problem is.
validations:
required: true
- type: textarea
id: solution
attributes:
label: Describe the solution you'd like
description: Please provide a clear and concise description of a solution of the described problem or usecase.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered
description: Please provide a clear and concise description of any alternative solutions or features you've considered.
- type: textarea
id: context
attributes:
label: Additional context
description: Please add any other context here.

View File

@@ -0,0 +1,20 @@
name: Sync issue comments to JIRA
# This workflow will be triggered when new issue comment is created (including PR comments)
on: issue_comment
jobs:
sync_issue_comments_to_jira:
name: Sync Issue Comments to Jira
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Sync issue comments to JIRA
uses: espressif/github-actions/sync_issues_to_jira@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JIRA_PASS: ${{ secrets.JIRA_PASS }}
JIRA_PROJECT: ESF
JIRA_COMPONENT: GitHub
JIRA_URL: ${{ secrets.JIRA_URL }}
JIRA_USER: ${{ secrets.JIRA_USER }}

View File

@@ -0,0 +1,20 @@
name: Sync issues to Jira
# This workflow will be triggered when a new issue is opened
on: issues
jobs:
sync_issues_to_jira:
name: Sync issues to Jira
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Sync GitHub issues to Jira project
uses: espressif/github-actions/sync_issues_to_jira@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JIRA_PASS: ${{ secrets.JIRA_PASS }}
JIRA_PROJECT: ESF
JIRA_COMPONENT: GitHub
JIRA_URL: ${{ secrets.JIRA_URL }}
JIRA_USER: ${{ secrets.JIRA_USER }}

View File

@@ -0,0 +1,25 @@
name: Sync remain PRs to Jira
# This workflow will be triggered every hour, to sync remaining PRs (i.e. PRs with zero comment) to Jira project
# Note that, PRs can also get synced when new PR comment is created
on:
schedule:
- cron: "0 * * * *"
jobs:
sync_prs_to_jira:
name: Sync PRs to Jira
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Sync PRs to Jira project
uses: espressif/github-actions/sync_issues_to_jira@master
with:
cron_job: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JIRA_PASS: ${{ secrets.JIRA_PASS }}
JIRA_PROJECT: ESF
JIRA_COMPONENT: GitHub
JIRA_URL: ${{ secrets.JIRA_URL }}
JIRA_USER: ${{ secrets.JIRA_USER }}

View File

@@ -0,0 +1,6 @@
build
sdkconfig
sdkconfig.old
empty_file.bin
binaries.c
*.lock

View File

@@ -0,0 +1,139 @@
stages:
- build
- test
- deploy
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
when: never
- if: "$CI_COMMIT_BRANCH"
variables:
STM32_CUBE_F4_REPO: https://github.com/STMicroelectronics/STM32CubeF4
STM32_CUBE_F4_REPO_TAG: v1.26.2
ARM_TOOLCHAIN_URL: https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2?revision=05382cca-1721-44e1-ae19-1e7c3dc96118&la=en&hash=D7C9D18FCA2DD9F894FD9F3C3DC9228498FA281A
QEMU_PATH: /opt/qemu/bin/qemu-system-xtensa
ZEPHYR_REPO: https://github.com/zephyrproject-rtos/zephyr.git
ZEPHYR_REPO_REV: v3.2.0
ZEPHYR_TOOLCHAIN: https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.15.2/toolchain_linux-x86_64_xtensa-espressif_esp32_zephyr-elf.tar.gz
ZEPHYR_SDK: https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.15.2/zephyr-sdk-0.15.2_linux-aarch64_minimal.tar.gz
.build_idf_template:
stage: build
image: espressif/idf:latest
tags:
- build
- internet
variables:
PEDANTIC_FLAGS: "-Werror=all -Werror=extra"
EXTRA_CFLAGS: "${PEDANTIC_FLAGS}"
EXTRA_CXXFLAGS: "${PEDANTIC_FLAGS}"
script:
- cd $CI_PROJECT_DIR/examples/esp32_example
- idf.py build -DMD5_ENABLED=1
- idf.py build -DMD5_ENABLED=0
- cd $CI_PROJECT_DIR/examples/esp32_load_ram_example
- idf.py build
- cd $CI_PROJECT_DIR/examples/esp32_spi_load_ram_example
- idf.py build
build_idf_v4.2:
extends: .build_idf_template
image: espressif/idf:release-v4.2
build_idf_v4.3:
extends: .build_idf_template
image: espressif/idf:release-v4.3
build_idf_v4.4:
extends: .build_idf_template
image: espressif/idf:release-v4.4
build_idf_v5.0:
extends: .build_idf_template
image: espressif/idf:release-v5.0
build_idf_v5.1:
extends: .build_idf_template
image: espressif/idf:release-v5.1
build_idf_master:
extends: .build_idf_template
image: espressif/idf:latest
build_stm32:
stage: build
# IDF is not necessary for STM32 build, but this image is already used in another job
# and it comes with a recent enough CMake version.
image: espressif/idf:latest
tags:
- build
- internet
script:
- cd $CI_PROJECT_DIR
- git submodule update --init
- git clone --depth=1 -b ${STM32_CUBE_F4_REPO_TAG} ${STM32_CUBE_F4_REPO}
- wget --no-verbose -O gcc-arm-none-eabi.tar.bz2 ${ARM_TOOLCHAIN_URL}
- tar -xjf gcc-arm-none-eabi.tar.bz2
- mv gcc-arm-none-eabi-* gcc-arm-none-eabi
- mkdir $CI_PROJECT_DIR/examples/stm32_example/build
- cd $CI_PROJECT_DIR/examples/stm32_example/build
- cmake -DTOOLCHAIN_PREFIX=$CI_PROJECT_DIR/gcc-arm-none-eabi -DSTM32Cube_DIR=$CI_PROJECT_DIR/STM32CubeF4 -G Ninja ..
- cmake --build .
build_zephyr:
stage: build
image: espressif/idf:latest
tags:
- build
- internet
script:
- mkdir $CI_PROJECT_DIR/zephyrproject-rtos
- cd $CI_PROJECT_DIR/zephyrproject-rtos
- git clone --single-branch --depth=1 -b ${ZEPHYR_REPO_REV} ${ZEPHYR_REPO}
- mkdir $CI_PROJECT_DIR/zephyrproject-rtos/zephyr-sdk
- cd $CI_PROJECT_DIR/zephyrproject-rtos/zephyr-sdk
- wget --no-verbose -O zephyr_sdk.tar.gz ${ZEPHYR_SDK}
- tar xvf zephyr_sdk.tar.gz --strip-components=1
- wget --no-verbose -O esp32_toolchain.tar.gz ${ZEPHYR_TOOLCHAIN}
- tar xvf esp32_toolchain.tar.gz
- export ZEPHYR_SDK_INSTALL_DIR=$(pwd)
- export ZEPHYR_TOOLCHAIN_VARIANT="zephyr"
- cd $CI_PROJECT_DIR/zephyrproject-rtos/zephyr
- export ZEPHYR_BASE=$(pwd)
- pip install -r scripts/requirements.txt
- pip install wheel
- if [[ ! -d "$CI_PROJECT_DIR/zephyrproject-rtos/.west" ]]; then
- west init -l .
- fi
- unset IDF_PATH
- west zephyr-export
- west update hal_espressif
- west build -p -b esp32 $CI_PROJECT_DIR/examples/zephyr_example -DZEPHYR_EXTRA_MODULES=$CI_PROJECT_DIR
run_tests:
stage: test
image: ${CI_DOCKER_REGISTRY}/qemu:esp-develop-20191124
tags:
- build
- internet
script:
- cd $CI_PROJECT_DIR/test
- export QEMU_PATH=/opt/qemu/bin/qemu-system-xtensa
- ./run_test.sh qemu
- ./run_test.sh host
push_to_the_components_registry:
stage: deploy
image: python:3.10-alpine
tags:
- build
- internet
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
- if: '$FORCE_PUSH_COMPONENT == "1"'
script:
- pip install idf-component-manager
- python -m idf_component_manager upload-component --allow-existing --name=esp-serial-flasher --namespace=espressif

View File

@@ -0,0 +1,3 @@
[submodule "submodules/stm32-cmake"]
path = submodules/stm32-cmake
url = https://github.com/ObKo/stm32-cmake.git

View File

@@ -0,0 +1,119 @@
cmake_minimum_required(VERSION 3.5)
set(srcs
src/esp_targets.c
src/md5_hash.c
src/esp_loader.c
src/protocol_common.c
)
if (DEFINED ESP_PLATFORM)
if (${CONFIG_SERIAL_FLASHER_INTERFACE_UART})
list(APPEND srcs
src/protocol_uart.c
src/slip.c
port/esp32_port.c
)
elseif (${CONFIG_SERIAL_FLASHER_INTERFACE_SPI})
list(APPEND srcs
src/protocol_spi.c
port/esp32_spi_port.c
)
endif()
# Register component to esp-idf build system
if ("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER "4.0")
# esp_timer component was introduced in v4.2
set(priv_requires driver)
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER "4.1")
list(APPEND priv_requires esp_timer)
endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS include port
PRIV_INCLUDE_DIRS private_include
PRIV_REQUIRES ${priv_requires})
set(target ${COMPONENT_LIB})
component_compile_options(-Wstrict-prototypes)
else()
# Remove when dropping support for IDF 3.3
set(COMPONENT_SRCS ${srcs})
set(COMPONENT_ADD_INCLUDEDIRS include port)
set(COMPONENT_PRIV_INCLUDEDIRS private_include)
register_component()
set(target ${COMPONENT_TARGET})
endif()
else()
if (NOT DEFINED SERIAL_FLASHER_INTERFACE_UART AND NOT DEFINED SERIAL_FLASHER_INTERFACE_SPI)
set(SERIAL_FLASHER_INTERFACE_UART true)
endif()
if (DEFINED SERIAL_FLASHER_INTERFACE_UART)
list(APPEND srcs
src/protocol_uart.c
src/slip.c
)
elseif (DEFINED SERIAL_FLASHER_INTERFACE_SPI)
list(APPEND srcs src/protocol_spi.c)
endif()
# Create traditional CMake target
add_library(flasher ${srcs})
target_include_directories(flasher PUBLIC include port PRIVATE private_include)
if(PORT STREQUAL "STM32")
target_link_libraries(flasher PUBLIC stm_cube)
target_sources(flasher PRIVATE port/stm32_port.c)
elseif(PORT STREQUAL "RASPBERRY_PI")
find_library(pigpio_LIB pigpio)
target_link_libraries(flasher PUBLIC ${pigpio_LIB})
target_sources(flasher PRIVATE port/raspberry_port.c)
else()
message(FATAL_ERROR "Selected port is not supported")
endif()
set(target flasher)
endif()
if (DEFINED SERIAL_FLASHER_INTERFACE_UART OR CONFIG_SERIAL_FLASHER_INTERFACE_UART STREQUAL "y")
target_compile_definitions(${target}
PUBLIC
SERIAL_FLASHER_INTERFACE_UART
)
if (DEFINED MD5_ENABLED OR CONFIG_SERIAL_FLASHER_MD5_ENABLED)
target_compile_definitions(${target} PUBLIC MD5_ENABLED=1)
endif()
elseif (DEFINED SERIAL_FLASHER_INTERFACE_SPI OR CONFIG_SERIAL_FLASHER_INTERFACE_SPI STREQUAL "y")
target_compile_definitions(${target}
PUBLIC
SERIAL_FLASHER_INTERFACE_SPI
)
endif()
if(DEFINED SERIAL_FLASHER_DEBUG_TRACE OR CONFIG_SERIAL_FLASHER_DEBUG_TRACE)
target_compile_definitions(${target} PUBLIC SERIAL_FLASHER_DEBUG_TRACE)
endif()
if(DEFINED CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS AND DEFINED CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS)
target_compile_definitions(${target}
PUBLIC
SERIAL_FLASHER_RESET_HOLD_TIME_MS=${CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS}
SERIAL_FLASHER_BOOT_HOLD_TIME_MS=${CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS}
)
else()
if(NOT DEFINED SERIAL_FLASHER_RESET_HOLD_TIME_MS)
target_compile_definitions(${target}
PUBLIC
SERIAL_FLASHER_RESET_HOLD_TIME_MS=100
)
endif()
if(NOT DEFINED SERIAL_FLASHER_BOOT_HOLD_TIME_MS)
target_compile_definitions(${target}
PUBLIC
SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50
)
endif()
endif()

View File

@@ -0,0 +1,34 @@
menu "ESP serial flasher"
config SERIAL_FLASHER_MD5_ENABLED
bool "Enable MD5 check"
default y
help
Select this option to enable MD5 hashsum check after flashing.
choice SERIAL_FLASHER_INTERFACE
prompt "Hardware interface to use for firmware download"
default SERIAL_FLASHER_INTERFACE_UART
help
esp-serial-flasher can work with UART and SPI interfaces.
config SERIAL_FLASHER_INTERFACE_UART
bool "UART"
config SERIAL_FLASHER_INTERFACE_SPI
bool "SPI (Only supports downloading to RAM, experimental)"
endchoice
config SERIAL_FLASHER_RESET_HOLD_TIME_MS
int "Time for which the reset pin is asserted when doing a hard reset"
default 100
config SERIAL_FLASHER_BOOT_HOLD_TIME_MS
int "Time for which the boot pin is asserted when doing a hard reset"
default 50
config SERIAL_FLASHER_DEBUG_TRACE
bool "Enable debug tracing output (only transfer data tracing is supported at the time)"
default n
endmenu

View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,155 @@
# esp-serial-flasher
`esp-serial-flasher` is a portable C library for flashing or loading apps to RAM of Espressif SoCs from other host microcontrollers.
## Using the library
Espressif SoCs are normally programmed via serial interface (UART). The port layer for the given host microcontroller has to be implemented if not available. Details can be found in section below.
Supported **host** microcontrollers:
- STM32
- Raspberry Pi SBC
- ESP32
- Any MCU running Zephyr OS
Supported **target** microcontrollers:
- ESP32
- ESP8266
- ESP32-S2
- ESP32-S3
- ESP32-C3
- ESP32-C2
- ESP32-H2
- ESP32-C6
Supported hardware interfaces:
- UART
- SPI (only for RAM download, experimental)
For example usage check the `examples` directory.
## Supporting a new host target
In order to support a new target, following functions have to be implemented by user:
- `loader_port_read()`
- `loader_port_write()`
- `loader_port_enter_bootloader()`
- `loader_port_delay_ms()`
- `loader_port_start_timer()`
- `loader_port_remaining_time()`
For the SPI interface ports
- `loader_port_spi_set_cs()`
needs to be implemented as well.
The following functions are part of the [io.h](include/io.h) header for convenience, however, the user does not have to strictly follow function signatures, as there are not called directly from library.
- `loader_port_change_transmission_rate()`
- `loader_port_reset_target()`
- `loader_port_debug_print()`
Prototypes of all functions mentioned above can be found in [io.h](include/io.h).
## Configuration
These are the configuration toggles available to the user:
* `SERIAL_FLASHER_INTERFACE_UART/SERIAL_FLASHER_INTERFACE_SPI`
This defines the hardware interface to use. SPI interface only supports RAM download mode and is in experimental stage and can undergo changes.
Default: SERIAL_FLASHER_INTERFACE_UART
* `MD5_ENABLED`
If enabled, `esp-serial-flasher` is capable of verifying flash integrity after writing to flash.
Default: Enabled
> Warning: As ROM bootloader of the ESP8266 does not support MD5_CHECK, this option has to be disabled!
* `SERIAL_FLASHER_RESET_HOLD_TIME_MS`
This is the time for which the reset pin is asserted when doing a hard reset in milliseconds.
Default: 100
* `SERIAL_FLASHER_BOOT_HOLD_TIME_MS`
This is the time for which the boot pin is asserted when doing a hard reset in milliseconds.
Default: 50
Configuration can be passed to `cmake` via command line:
```
cmake -DMD5_ENABLED=1 .. && cmake --build .
```
### STM32 support
The STM32 port makes use of STM32 HAL libraries, and these do not come with CMake support. In order to compile the project, `stm32-cmake` (a `CMake` support package) has to be pulled as submodule.
```
git clone --recursive https://github.com/espressif/esp-serial-flasher.git
```
If you have cloned this repository without the `--recursive` flag, you can initialize the submodule using the following command:
```
git submodule update --init
```
In addition to configuration parameters mentioned above, following definitions has to be set:
- TOOLCHAIN_PREFIX: path to arm toolchain (i.e /home/user/gcc-arm-none-eabi-9-2019-q4-major)
- STM32Cube_DIR: path to STM32 Cube libraries (i.e /home/user/STM32Cube/Repository/STM32Cube_FW_F4_V1.25.0)
- STM32_CHIP: name of STM32 for which project should be compiled (i.e STM32F407VG)
- PORT: STM32
This can be achieved by passing definitions to the command line, such as:
```
cmake -DTOOLCHAIN_PREFIX="/path_to_toolchain" -DSTM32Cube_DIR="path_to_stm32Cube" -DSTM32_CHIP="STM32F407VG" -DPORT="STM32" .. && cmake --build .
```
Alternatively, those variables can be set in the top level `cmake` directory:
```
set(TOOLCHAIN_PREFIX path_to_toolchain)
set(STM32Cube_DIR path_to_stm32_HAL)
set(STM32_CHIP STM32F407VG)
set(PORT STM32)
```
### Zephyr support
The Zephyr port is ready to be integrated into Zephyr apps as a Zephyr module. In the manifest file (west.yml), add:
```
- name: esp-flasher
url: https://github.com/espressif/esp-serial-flasher
revision: master
path: modules/lib/esp_flasher
```
And add
```
CONFIG_ESP_SERIAL_FLASHER=y
CONFIG_CONSOLE_GETCHAR=y
CONFIG_SERIAL_FLASHER_MD5_ENABLED=y
```
to the project configuration `prj.conf`.
For the C/C++ source code, the example code provided in `examples/zephyr_example` can be used as a starting point.
## Licence
Code is distributed under Apache 2.0 license.
## Known limitations
Size of new binary image has to be known before flashing.

View File

@@ -0,0 +1,15 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
# Here we remove all unecessary components from the build to make the binary smaller
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(hello_world)
# This generates a binary file from the elf, as the RAM build doesn't do that automatically
add_custom_command(TARGET ${PROJECT_NAME}.elf
POST_BUILD
COMMAND esptool.py --chip ${IDF_TARGET} elf2image --output app.bin ${PROJECT_NAME}.elf
)

View File

@@ -0,0 +1,2 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS "")

View File

@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void app_main(void)
{
while (true) {
esp_rom_printf("Hello world!\n");
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}

View File

@@ -0,0 +1,11 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
CONFIG_APP_BUILD_TYPE_ELF_RAM=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_APP_NO_BLOBS=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
# CONFIG_ESP_ERR_TO_NAME_LOOKUP is not set
CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT=y
CONFIG_LOG_DEFAULT_LEVEL_NONE=y

View File

@@ -0,0 +1,20 @@
# Creates C resources file from files in given directory recursively
function(create_resources dir output)
# Create empty output file
file(WRITE ${output} "#include <stdint.h>\n\n")
# Collect input files
file(GLOB bin_paths ${dir}/ESP*/*)
# Iterate through input files
foreach(bin ${bin_paths})
# Get short filenames, by discarding relative path
file(GLOB name RELATIVE ${dir} ${bin})
# Replace filename spaces & extension separator for C compatibility
string(REGEX REPLACE "[\\./-]" "_" filename ${name})
# Read hex data from file
file(READ ${bin} filedata HEX)
# Convert hex data for C compatibility
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata})
# Append data to output file
file(APPEND ${output} "const uint8_t ${filename}[] = {${filedata}};\nconst uint32_t ${filename}_size = sizeof(${filename});\n")
endforeach()
endfunction()

View File

@@ -0,0 +1,7 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
set(EXTRA_COMPONENT_DIRS ../../)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(esp-serial-flasher)

Some files were not shown because too many files have changed in this diff Show More