From d7b6f106a993c0cf06a8511c3e520aa687331f76 Mon Sep 17 00:00:00 2001 From: Manfred Steiner Date: Thu, 31 Oct 2024 18:14:13 +0100 Subject: [PATCH] test-software vv2024-10-31, Inbetriebnahme abgeschlossen --- kicad/dist/v2a/README.md | 9 +- .../.~lock.BOM-nano-x-base.csv# | 1 + .../test_2024-07-23/.gdb_history | 9 - .../arduino-nano-5v/test_2024-07-23/.gdbinit | 2 - .../test_2024-07-23/.gitignore | 4 - .../.vscode/c_cpp_properties.json | 18 - .../test_2024-07-23/.vscode/launch.json | 37 - .../test_2024-07-23/.vscode/settings.json | 26 - .../test_2024-07-23/.vscode/tasks.json | 23 - .../arduino-nano-5v/test_2024-07-23/Makefile | 125 - .../arduino-nano-5v/test_2024-07-23/README.md | 1 - .../test_2024-07-23_nano-5v.elf | Bin 53568 -> 0 bytes software/arduino-nano-5v/test_2024-07-23/src | 1 - .../nano-1284/test_2024-07-23/.gdb_history | 9 - software/nano-1284/test_2024-07-23/.gdbinit | 2 - software/nano-1284/test_2024-07-23/.gitignore | 4 - .../.vscode/c_cpp_properties.json | 18 - .../test_2024-07-23/.vscode/launch.json | 37 - .../test_2024-07-23/.vscode/settings.json | 29 - .../test_2024-07-23/.vscode/tasks.json | 23 - software/nano-1284/test_2024-07-23/Makefile | 124 - software/nano-1284/test_2024-07-23/README.md | 1 - .../test_2024-07-23_nano-1284p.elf | Bin 73348 -> 0 bytes software/nano-1284/test_2024-07-23/src | 1 - .../nano-644/test_2024-07-23/.gdb_history | 9 - software/nano-644/test_2024-07-23/.gdbinit | 2 - software/nano-644/test_2024-07-23/.gitignore | 4 - .../.vscode/c_cpp_properties.json | 18 - .../test_2024-07-23/.vscode/launch.json | 37 - .../test_2024-07-23/.vscode/settings.json | 29 - .../test_2024-07-23/.vscode/tasks.json | 23 - software/nano-644/test_2024-07-23/Makefile | 138 - software/nano-644/test_2024-07-23/README.md | 1 - .../test_2024-07-23_nano-644.elf | Bin 71992 -> 0 bytes .../test_2024-07-23/src/adafruit/bme280.cpp | 512 ---- .../test_2024-07-23/src/adafruit/bme280.h | 373 --- .../test_2024-07-23/src/adafruit/ens160.cpp | 374 --- .../test_2024-07-23/src/adafruit/ens160.h | 188 -- .../test_2024-07-23/src/adafruit/sensor.h | 224 -- .../test_2024-07-23/src/i2cmaster.cpp | 155 -- .../test_2024-07-23/src/i2cmaster.hpp | 30 - .../nano-644/test_2024-07-23/src/i2cslave.cpp | 92 - .../nano-644/test_2024-07-23/src/i2cslave.hpp | 32 - .../nano-644/test_2024-07-23/src/main.cpp | 412 --- .../nano-644/test_2024-07-23/src/main.hpp | 38 - .../test_2024-07-23/src/units/cc1101.cpp | 753 ------ .../test_2024-07-23/src/units/cc1101.hpp | 281 -- .../test_2024-07-23/src/units/encoder.cpp | 138 - .../test_2024-07-23/src/units/encoder.hpp | 28 - .../test_2024-07-23/src/units/i2c.cpp | 216 -- .../test_2024-07-23/src/units/i2c.hpp | 43 - .../test_2024-07-23/src/units/ieee485.cpp | 111 - .../test_2024-07-23/src/units/ieee485.hpp | 22 - .../test_2024-07-23/src/units/lcd.cpp | 443 ---- .../test_2024-07-23/src/units/lcd.hpp | 48 - .../test_2024-07-23/src/units/led.cpp | 139 - .../test_2024-07-23/src/units/led.hpp | 25 - .../test_2024-07-23/src/units/modbus.cpp | 160 -- .../test_2024-07-23/src/units/modbus.hpp | 24 - .../test_2024-07-23/src/units/motor.cpp | 221 -- .../test_2024-07-23/src/units/motor.hpp | 30 - .../test_2024-07-23/src/units/portexp.cpp | 195 -- .../test_2024-07-23/src/units/portexp.hpp | 24 - .../test_2024-07-23/src/units/poti.cpp | 34 - .../test_2024-07-23/src/units/poti.hpp | 17 - .../test_2024-07-23/src/units/r2r.cpp | 48 - .../test_2024-07-23/src/units/r2r.hpp | 17 - .../test_2024-07-23/src/units/rgb.cpp | 152 -- .../test_2024-07-23/src/units/rgb.hpp | 25 - .../test_2024-07-23/src/units/rtc8563.cpp | 253 -- .../test_2024-07-23/src/units/rtc8563.hpp | 70 - .../test_2024-07-23/src/units/seg7.cpp | 283 -- .../test_2024-07-23/src/units/seg7.hpp | 25 - .../test_2024-07-23/src/units/switch.cpp | 100 - .../test_2024-07-23/src/units/switch.hpp | 20 - .../test_2024-07-23/src/units/uart1.cpp | 65 - .../test_2024-07-23/src/units/uart1.hpp | 21 - software/test-software/Makefile | 15 +- software/test-software/README.md | 21 +- software/test-software/create-release | 94 +- software/test-software/create-release.old | 86 + software/test-software/nano-1284/Makefile | 216 +- .../test-software_nano-1284p_12mhz.elf | Bin 75868 -> 0 bytes ...x-base_test-software_nano-m1284p_12mhz.bin | Bin 0 -> 36968 bytes ...x-base_test-software_nano-m1284p_12mhz.elf | Bin 0 -> 74516 bytes ...x-base_test-software_nano-m1284p_12mhz.hex | 2313 +++++++++++++++++ software/test-software/nano-328/Makefile | 217 +- .../test-software_nano-328p_16mhz.elf | Bin 56356 -> 0 bytes ...-x-base_test-software_nano-m328p_16mhz.bin | Bin 0 -> 26652 bytes ...-x-base_test-software_nano-m328p_16mhz.elf | Bin 0 -> 55004 bytes ...-x-base_test-software_nano-m328p_16mhz.hex | 1667 ++++++++++++ software/test-software/nano-644/Makefile | 215 +- .../test-software_nano-644_12mhz.elf | Bin 74504 -> 0 bytes ...-x-base_test-software_nano-m644p_12mhz.bin | Bin 0 -> 36670 bytes ...-x-base_test-software_nano-m644p_12mhz.elf | Bin 0 -> 73144 bytes ...-x-base_test-software_nano-m644p_12mhz.hex | 2294 ++++++++++++++++ .../test_2024-07-23_nano-644.elf | Bin 71992 -> 0 bytes software/test-software/src/main.cpp | 43 +- 98 files changed, 7022 insertions(+), 7385 deletions(-) create mode 100644 kicad/dist/v2a/production_files/.~lock.BOM-nano-x-base.csv# delete mode 100644 software/arduino-nano-5v/test_2024-07-23/.gdb_history delete mode 100644 software/arduino-nano-5v/test_2024-07-23/.gdbinit delete mode 100644 software/arduino-nano-5v/test_2024-07-23/.gitignore delete mode 100644 software/arduino-nano-5v/test_2024-07-23/.vscode/c_cpp_properties.json delete mode 100644 software/arduino-nano-5v/test_2024-07-23/.vscode/launch.json delete mode 100644 software/arduino-nano-5v/test_2024-07-23/.vscode/settings.json delete mode 100644 software/arduino-nano-5v/test_2024-07-23/.vscode/tasks.json delete mode 100644 software/arduino-nano-5v/test_2024-07-23/Makefile delete mode 100644 software/arduino-nano-5v/test_2024-07-23/README.md delete mode 100755 software/arduino-nano-5v/test_2024-07-23/release/v2024-08-18_1113/test_2024-07-23_nano-5v.elf delete mode 120000 software/arduino-nano-5v/test_2024-07-23/src delete mode 100644 software/nano-1284/test_2024-07-23/.gdb_history delete mode 100644 software/nano-1284/test_2024-07-23/.gdbinit delete mode 100644 software/nano-1284/test_2024-07-23/.gitignore delete mode 100644 software/nano-1284/test_2024-07-23/.vscode/c_cpp_properties.json delete mode 100644 software/nano-1284/test_2024-07-23/.vscode/launch.json delete mode 100644 software/nano-1284/test_2024-07-23/.vscode/settings.json delete mode 100644 software/nano-1284/test_2024-07-23/.vscode/tasks.json delete mode 100644 software/nano-1284/test_2024-07-23/Makefile delete mode 100644 software/nano-1284/test_2024-07-23/README.md delete mode 100755 software/nano-1284/test_2024-07-23/release/v2024-08-18_1118/test_2024-07-23_nano-1284p.elf delete mode 120000 software/nano-1284/test_2024-07-23/src delete mode 100644 software/nano-644/test_2024-07-23/.gdb_history delete mode 100644 software/nano-644/test_2024-07-23/.gdbinit delete mode 100644 software/nano-644/test_2024-07-23/.gitignore delete mode 100644 software/nano-644/test_2024-07-23/.vscode/c_cpp_properties.json delete mode 100644 software/nano-644/test_2024-07-23/.vscode/launch.json delete mode 100644 software/nano-644/test_2024-07-23/.vscode/settings.json delete mode 100644 software/nano-644/test_2024-07-23/.vscode/tasks.json delete mode 100644 software/nano-644/test_2024-07-23/Makefile delete mode 100644 software/nano-644/test_2024-07-23/README.md delete mode 100755 software/nano-644/test_2024-07-23/release/v2024-08-18_1103/test_2024-07-23_nano-644.elf delete mode 100644 software/nano-644/test_2024-07-23/src/adafruit/bme280.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/adafruit/bme280.h delete mode 100644 software/nano-644/test_2024-07-23/src/adafruit/ens160.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/adafruit/ens160.h delete mode 100644 software/nano-644/test_2024-07-23/src/adafruit/sensor.h delete mode 100644 software/nano-644/test_2024-07-23/src/i2cmaster.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/i2cmaster.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/i2cslave.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/i2cslave.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/main.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/main.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/cc1101.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/cc1101.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/encoder.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/encoder.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/i2c.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/i2c.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/ieee485.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/ieee485.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/lcd.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/lcd.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/led.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/led.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/modbus.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/modbus.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/motor.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/motor.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/portexp.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/portexp.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/poti.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/poti.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/r2r.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/r2r.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/rgb.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/rgb.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/rtc8563.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/rtc8563.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/seg7.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/seg7.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/switch.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/switch.hpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/uart1.cpp delete mode 100644 software/nano-644/test_2024-07-23/src/units/uart1.hpp create mode 100755 software/test-software/create-release.old delete mode 100755 software/test-software/nano-1284/release/v2024-10-28_141638/test-software_nano-1284p_12mhz.elf create mode 100755 software/test-software/nano-1284/release/v2024-10-31_172633/nano-x-base_test-software_nano-m1284p_12mhz.bin create mode 100755 software/test-software/nano-1284/release/v2024-10-31_172633/nano-x-base_test-software_nano-m1284p_12mhz.elf create mode 100644 software/test-software/nano-1284/release/v2024-10-31_172633/nano-x-base_test-software_nano-m1284p_12mhz.hex delete mode 100755 software/test-software/nano-328/release/v2024-10-28_141640/test-software_nano-328p_16mhz.elf create mode 100755 software/test-software/nano-328/release/v2024-10-31_172629/nano-x-base_test-software_nano-m328p_16mhz.bin create mode 100755 software/test-software/nano-328/release/v2024-10-31_172629/nano-x-base_test-software_nano-m328p_16mhz.elf create mode 100644 software/test-software/nano-328/release/v2024-10-31_172629/nano-x-base_test-software_nano-m328p_16mhz.hex delete mode 100755 software/test-software/nano-644/release/v2024-10-28_141636/test-software_nano-644_12mhz.elf create mode 100755 software/test-software/nano-644/release/v2024-10-31_172630/nano-x-base_test-software_nano-m644p_12mhz.bin create mode 100755 software/test-software/nano-644/release/v2024-10-31_172630/nano-x-base_test-software_nano-m644p_12mhz.elf create mode 100644 software/test-software/nano-644/release/v2024-10-31_172630/nano-x-base_test-software_nano-m644p_12mhz.hex delete mode 100755 software/test-software/release/v2024-08-18_1103/test_2024-07-23_nano-644.elf diff --git a/kicad/dist/v2a/README.md b/kicad/dist/v2a/README.md index 5bc74e5..d99aebf 100644 --- a/kicad/dist/v2a/README.md +++ b/kicad/dist/v2a/README.md @@ -117,23 +117,24 @@ Gesamtpreis (V1a + V2a): ## Verbesserungen V2a - ### Schaltung V2a | Reference | Beschreibung | | -------------- | ---------------------------------------------------------- | +| | Zusätzliche SS34 Schottkydiode (3A) antiparallel zu D7 würde zusätzlich Stromversorgung Raspberry PI via USB UART1 J1 ermöglichen | ### Bestückung V2a | Reference | Beschreibung | | -------------- | ---------------------------------------------------------- | +| CN1X6 | Fehlerhafte JLCPCB Nummer in Bestückungsdaten, C5116529 (Buchse) -> C6332196 (Header) | -### Funktion / Software +### Funktion -Keine +Keine Fehler gefunden. ---------------------------------------------------- ## Inbetriebnahme / Test -Noch nicht erfolgt. +Erfolgt. Siehe [software/test-software/README.md](../../../software/test-software/README.md) diff --git a/kicad/dist/v2a/production_files/.~lock.BOM-nano-x-base.csv# b/kicad/dist/v2a/production_files/.~lock.BOM-nano-x-base.csv# new file mode 100644 index 0000000..ad5da4d --- /dev/null +++ b/kicad/dist/v2a/production_files/.~lock.BOM-nano-x-base.csv# @@ -0,0 +1 @@ +,steiner,hpe,31.10.2024 18:07,file:///home/steiner/.config/libreoffice/4; \ No newline at end of file diff --git a/software/arduino-nano-5v/test_2024-07-23/.gdb_history b/software/arduino-nano-5v/test_2024-07-23/.gdb_history deleted file mode 100644 index 3339046..0000000 --- a/software/arduino-nano-5v/test_2024-07-23/.gdb_history +++ /dev/null @@ -1,9 +0,0 @@ -target remote :1234 -layout split -stepi -quit -target remote :1234 -layout split -stepi -b *main+9 -quit diff --git a/software/arduino-nano-5v/test_2024-07-23/.gdbinit b/software/arduino-nano-5v/test_2024-07-23/.gdbinit deleted file mode 100644 index 139597f..0000000 --- a/software/arduino-nano-5v/test_2024-07-23/.gdbinit +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/software/arduino-nano-5v/test_2024-07-23/.gitignore b/software/arduino-nano-5v/test_2024-07-23/.gitignore deleted file mode 100644 index a959910..0000000 --- a/software/arduino-nano-5v/test_2024-07-23/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.depend -**/build -**/dist -**/sim diff --git a/software/arduino-nano-5v/test_2024-07-23/.vscode/c_cpp_properties.json b/software/arduino-nano-5v/test_2024-07-23/.vscode/c_cpp_properties.json deleted file mode 100644 index 93c17af..0000000 --- a/software/arduino-nano-5v/test_2024-07-23/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "configurations": [ - { - "name": "Linux AVR", - "includePath": [ - "/usr/lib/avr/include/**", - "/usr/lib/gcc/avr/**" - ], - "defines": [], - "compilerPath": "/usr/bin/avr-gcc", - "compilerArgs": [ "-mmcu=atmega328p", "-DF_CPU=16000000", "-Os" ], - "cStandard": "gnu11", - "cppStandard": "gnu++11", - "intelliSenseMode": "linux-gcc-x64" - } - ], - "version": 4 -} diff --git a/software/arduino-nano-5v/test_2024-07-23/.vscode/launch.json b/software/arduino-nano-5v/test_2024-07-23/.vscode/launch.json deleted file mode 100644 index f29cf2e..0000000 --- a/software/arduino-nano-5v/test_2024-07-23/.vscode/launch.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Build", - // "request": "launch", - "type": "node-terminal", - "preLaunchTask": "build" - },{ - "name": "Flash", - // "request": "launch", - "type": "node-terminal", - "preLaunchTask": "flash" - },{ - "name": "Clean", - // "request": "launch", - "type": "node-terminal", - "preLaunchTask": "clean" - },{ - // es muss mit simuc --board arduino dist/programm.elf der Simulator - // gestartet werden. Dessen gdb-stub öffnet auf localhost:1234 einen Port - "name": "Debug (simuc)", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceFolder}/sim/atmega328p.elf", - "cwd": "${workspaceFolder}", - "externalConsole": false, - "MIMode": "gdb", - "miDebuggerPath": "/usr/bin/avr-gdb", - "miDebuggerServerAddress": ":1234", - "preLaunchTask": "build" - } - ] -} diff --git a/software/arduino-nano-5v/test_2024-07-23/.vscode/settings.json b/software/arduino-nano-5v/test_2024-07-23/.vscode/settings.json deleted file mode 100644 index b2e94c9..0000000 --- a/software/arduino-nano-5v/test_2024-07-23/.vscode/settings.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "[c]": { - "editor.insertSpaces": true, - "editor.tabSize": 3, - "editor.detectIndentation": false - }, - "[cpp]": { - "editor.insertSpaces": true, - "editor.tabSize": 3, - "editor.detectIndentation": false - }, - "[h]": { - "editor.insertSpaces": true, - "editor.tabSize": 3, - "editor.detectIndentation": false - }, - "[hpp]": { - "editor.insertSpaces": true, - "editor.tabSize": 3, - "editor.detectIndentation": false - }, - "cSpell.words": [], - "cSpell.ignorePaths": [ - "**/*.json", "**/*.c", "**/*.h", "**/*.cpp", "**/*.hpp", "**/Makefile" - ] -} diff --git a/software/arduino-nano-5v/test_2024-07-23/.vscode/tasks.json b/software/arduino-nano-5v/test_2024-07-23/.vscode/tasks.json deleted file mode 100644 index 74fb1c7..0000000 --- a/software/arduino-nano-5v/test_2024-07-23/.vscode/tasks.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [{ - "label": "build", - "type": "shell", - "command": "make", - "problemMatcher":[ - "$gcc" - ] - },{ - "label": "clean", - "type": "shell", - "command": "make", - "args": [ "clean" ], - },{ - "label": "flash", - "type": "shell", - "command": "make", - "args": [ "flash" ], - }] -} \ No newline at end of file diff --git a/software/arduino-nano-5v/test_2024-07-23/Makefile b/software/arduino-nano-5v/test_2024-07-23/Makefile deleted file mode 100644 index eb17024..0000000 --- a/software/arduino-nano-5v/test_2024-07-23/Makefile +++ /dev/null @@ -1,125 +0,0 @@ -.PHONY: all info flash picocom clean -$(shell mkdir -p dist >/dev/null) -$(shell mkdir -p build >/dev/null) -$(shell mkdir -p sim >/dev/null) -$(shell mkdir -p sim/build >/dev/null) - -NAME="test_2024-07-23_nano-5v" -SRC= $(wildcard src/*.c src/*.cpp src/*/*.c src/*/*.cpp) -HDR= $(wildcard src/*.h src/*.hpp src/*/*.h src/*/*.hpp) -OBJ_CPP = $(SRC:src/%.cpp=build/%.o) -OBJ = $(OBJ_CPP:src/%.c=build/%.o) -OBJ_SIM_CPP = $(SRC:src/%.cpp=sim/build/%.o) -OBJ_SIM = $(OBJ_SIM_CPP:src/%.c=sim/build/%.o) - -DEVICE=atmega328p - -CC= avr-g++ -CFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=16000000 -c -LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=16000000 -Wl,-u,vfprintf -lprintf_flt -lm - -CFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=16000000 -g -c -c -LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=16000000 -g -Wl,-u,vfprintf -lprintf_flt -lm - - -all: dist/$(NAME).elf dist/$(NAME).s dist/$(NAME).hex sim/$(NAME).elf sim/$(NAME).s info - - -info: - @avr-size --mcu=$(DEVICE) --format=avr dist/$(NAME).elf - -.depend: $(SRC) $(HDR) - $(CC) -mmcu=$(DEVICE) -MM $(SRC) | sed --regexp-extended 's/^(.*\.o)\: src\/(.*)(\.cpp|\.c) (.*)/build\/\2\.o\: src\/\2\3 \4/g' > .depend - --include .depend - -# .depend solte auch auf Header Files achten! - -dist/$(NAME).elf: .depend $(OBJ) - $(CC) $(LFLAGS) -o $@ $(OBJ) - -dist/%.s: dist/%.elf - avr-objdump -d $< > $@ - -dist/%.hex: dist/%.elf - avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ - -sim/$(NAME).elf: .depend $(OBJ_SIM) - $(CC) $(LFLAGS_SIM) -o $@ $(OBJ_SIM) - -# ensure that __DATE__ and __TIME__ macros are up to date -build/main.o: src/main.cpp $(SRC) $(HDR) - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -o $@ $< - -build/%.o: src/%.c - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -o $@ $< - -build/%.o: src/%.cpp - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -o $@ $< - -sim/build/%.o: src/%.c - @mkdir -p $(dir $@) - $(CC) $(CFLAGS_SIM) -o $@ $< - -sim/build/%.o: src/%.cpp - @mkdir -p $(dir $@) - $(CC) $(CFLAGS_SIM) -o $@ $< - -sim/%.s: sim/%.elf - avr-objdump -d $< > $@ - -simuc: sim/$(NAME).elf - simuc --board arduino $< - -gdb: sim/$(NAME).elf - avr-gdb $< - - -flash: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB0 -p m328p -e -U flash:w:$< - -flash0: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB0 -p m328p -e -U flash:w:$< - -flash1: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB1 -p m328p -e -U flash:w:$< - -flash2: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB2 -p m328p -e -U flash:w:$< - -picocom: - # picocom sends CR for ENTER -> convert cr (\r) to lf (\n) - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0 - -picocom0: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0 - -picocom1: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB1 - -picocom2: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB2 - - -isp-328p: - avrdude -c usbasp -p m328p - -isp-flash-328p: dist/$(NAME).elf all - avrdude -c usbasp -p m328p -e -U flash:w:$< - -flash-328pp: dist/$(NAME).elf all - avrdude -c arduino -p m328p -P /dev/ttyUSB0 -b 115200 -e -U flash:w:$< - - -isp-fuse-328p: - avrdude -c usbasp -p m328p -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xFF:m -U lock:w:0xFF:m - -clean: - @rm -r dist - @rm -r build - @rm -r sim - @find . -type f -name ".depend" -exec rm {} \; - @echo "clean done" diff --git a/software/arduino-nano-5v/test_2024-07-23/README.md b/software/arduino-nano-5v/test_2024-07-23/README.md deleted file mode 100644 index c4d5e14..0000000 --- a/software/arduino-nano-5v/test_2024-07-23/README.md +++ /dev/null @@ -1 +0,0 @@ -# Testprogramm diff --git a/software/arduino-nano-5v/test_2024-07-23/release/v2024-08-18_1113/test_2024-07-23_nano-5v.elf b/software/arduino-nano-5v/test_2024-07-23/release/v2024-08-18_1113/test_2024-07-23_nano-5v.elf deleted file mode 100755 index 2f20bd1e08d61e9f52599166e56bf895dd00f06f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53568 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 v/dev/null) -$(shell mkdir -p build >/dev/null) -$(shell mkdir -p sim >/dev/null) -$(shell mkdir -p sim/build >/dev/null) - -NAME=test_2024-07-23_nano-1284p -SRC= $(wildcard src/*.c src/*.cpp src/*/*.c src/*/*.cpp) -HDR= $(wildcard src/*.h src/*.hpp src/*/*.h src/*/*.hpp) -OBJ_CPP = $(SRC:src/%.cpp=build/%.o) -OBJ = $(OBJ_CPP:src/%.c=build/%.o) -OBJ_SIM_CPP = $(SRC:src/%.cpp=sim/build/%.o) -OBJ_SIM = $(OBJ_SIM_CPP:src/%.c=sim/build/%.o) - -DEVICE=atmega1284p -AVRDUDE_DEVICE=m1284p - -CC= avr-g++ -CFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=12000000 -c -LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=12000000 -Wl,-u,vfprintf -lprintf_flt -lm - -CFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=12000000 -g -c -c -LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=12000000 -g -Wl,-u,vfprintf -lprintf_flt -lm - - -all: dist/$(NAME).elf dist/$(NAME).s dist/$(NAME).hex sim/$(NAME).elf sim/$(NAME).s info - -info: - @avr-size --mcu=$(DEVICE) --format=avr dist/$(NAME).elf - -.depend: $(SRC) $(HDR) - $(CC) -mmcu=$(DEVICE) -MM $(SRC) | sed --regexp-extended 's/^(.*\.o)\: src\/(.*)(\.cpp|\.c) (.*)/build\/\2\.o\: src\/\2\3 \4/g' > .depend - --include .depend - -# .depend solte auch auf Header Files achten! - -dist/$(NAME).elf: .depend $(OBJ) - $(CC) $(LFLAGS) -o $@ $(OBJ) - -dist/%.s: dist/%.elf - avr-objdump -d $< > $@ - -dist/%.hex: dist/%.elf - avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ - -sim/$(NAME).elf: .depend $(OBJ_SIM) - $(CC) $(LFLAGS_SIM) -o $@ $(OBJ_SIM) - -# ensure that __DATE__ and __TIME__ macros are up to date -build/main.o: src/main.cpp $(SRC) $(HDR) - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -o $@ $< - -build/%.o: src/%.c - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -o $@ $< - -build/%.o: src/%.cpp - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -o $@ $< - -sim/build/%.o: src/%.c - @mkdir -p $(dir $@) - $(CC) $(CFLAGS_SIM) -o $@ $< - -sim/build/%.o: src/%.cpp - @mkdir -p $(dir $@) - $(CC) $(CFLAGS_SIM) -o $@ $< - -sim/%.s: sim/%.elf - avr-objdump -d $< > $@ - -simuc: sim/$(NAME).elf - simuc --board nano-1284 $< - -gdb: sim/$(NAME).elf - avr-gdb $< - - -flash: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB0 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< - -flash0: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB0 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< - -flash1: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB1 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< - -flash2: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB2 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< - -picocom: - # picocom sends CR for ENTER -> convert cr (\r) to lf (\n) - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0 - -picocom0: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0 - -picocom1: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB1 - -picocom2: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB2 - - -isp-1284p: - avrdude -c usbasp -p $(AVRDUDE_DEVICE) - -isp-flash-1284p: dist/$(NAME).elf all - avrdude -c usbasp -p $(AVRDUDE_DEVICE) -e -U flash:w:$< - -flash-1284p: dist/$(NAME).elf all - avrdude -c arduino -p $(AVRDUDE_DEVICE) -P /dev/ttyUSB0 -b 115200 -e -U flash:w:$< - -isp-fuse-1284p: - avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xFF:m -U lock:w:0xFF:m - -clean: - @rm -r dist - @rm -r build - @rm -r sim - @find . -type f -name ".depend" -exec rm {} \; - @echo "clean done" diff --git a/software/nano-1284/test_2024-07-23/README.md b/software/nano-1284/test_2024-07-23/README.md deleted file mode 100644 index 65a0866..0000000 --- a/software/nano-1284/test_2024-07-23/README.md +++ /dev/null @@ -1 +0,0 @@ -# Testprogramm für Nano-1284 diff --git a/software/nano-1284/test_2024-07-23/release/v2024-08-18_1118/test_2024-07-23_nano-1284p.elf b/software/nano-1284/test_2024-07-23/release/v2024-08-18_1118/test_2024-07-23_nano-1284p.elf deleted file mode 100755 index 8c3e0079fcd0571582ffc364699db16fb6653096..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73348 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 diff --git a/software/nano-1284/test_2024-07-23/src b/software/nano-1284/test_2024-07-23/src deleted file mode 120000 index 38a7ae1..0000000 --- a/software/nano-1284/test_2024-07-23/src +++ /dev/null @@ -1 +0,0 @@ -../../nano-644/test_2024-07-23/src \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/.gdb_history b/software/nano-644/test_2024-07-23/.gdb_history deleted file mode 100644 index 3339046..0000000 --- a/software/nano-644/test_2024-07-23/.gdb_history +++ /dev/null @@ -1,9 +0,0 @@ -target remote :1234 -layout split -stepi -quit -target remote :1234 -layout split -stepi -b *main+9 -quit diff --git a/software/nano-644/test_2024-07-23/.gdbinit b/software/nano-644/test_2024-07-23/.gdbinit deleted file mode 100644 index 139597f..0000000 --- a/software/nano-644/test_2024-07-23/.gdbinit +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/software/nano-644/test_2024-07-23/.gitignore b/software/nano-644/test_2024-07-23/.gitignore deleted file mode 100644 index a959910..0000000 --- a/software/nano-644/test_2024-07-23/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.depend -**/build -**/dist -**/sim diff --git a/software/nano-644/test_2024-07-23/.vscode/c_cpp_properties.json b/software/nano-644/test_2024-07-23/.vscode/c_cpp_properties.json deleted file mode 100644 index 3a57c79..0000000 --- a/software/nano-644/test_2024-07-23/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "configurations": [ - { - "name": "Linux AVR", - "includePath": [ - "/usr/lib/avr/include/**", - "/usr/lib/gcc/avr/**" - ], - "defines": [], - "compilerPath": "/usr/bin/avr-gcc", - "compilerArgs": [ "-mmcu=atmega644p", "-DF_CPU=12000000", "-Os" ], - "cStandard": "gnu11", - "cppStandard": "gnu++11", - "intelliSenseMode": "linux-gcc-x64" - } - ], - "version": 4 -} diff --git a/software/nano-644/test_2024-07-23/.vscode/launch.json b/software/nano-644/test_2024-07-23/.vscode/launch.json deleted file mode 100644 index f29cf2e..0000000 --- a/software/nano-644/test_2024-07-23/.vscode/launch.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Build", - // "request": "launch", - "type": "node-terminal", - "preLaunchTask": "build" - },{ - "name": "Flash", - // "request": "launch", - "type": "node-terminal", - "preLaunchTask": "flash" - },{ - "name": "Clean", - // "request": "launch", - "type": "node-terminal", - "preLaunchTask": "clean" - },{ - // es muss mit simuc --board arduino dist/programm.elf der Simulator - // gestartet werden. Dessen gdb-stub öffnet auf localhost:1234 einen Port - "name": "Debug (simuc)", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceFolder}/sim/atmega328p.elf", - "cwd": "${workspaceFolder}", - "externalConsole": false, - "MIMode": "gdb", - "miDebuggerPath": "/usr/bin/avr-gdb", - "miDebuggerServerAddress": ":1234", - "preLaunchTask": "build" - } - ] -} diff --git a/software/nano-644/test_2024-07-23/.vscode/settings.json b/software/nano-644/test_2024-07-23/.vscode/settings.json deleted file mode 100644 index 58539af..0000000 --- a/software/nano-644/test_2024-07-23/.vscode/settings.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "[c]": { - "editor.insertSpaces": true, - "editor.tabSize": 3, - "editor.detectIndentation": false - }, - "[cpp]": { - "editor.insertSpaces": true, - "editor.tabSize": 3, - "editor.detectIndentation": false - }, - "[h]": { - "editor.insertSpaces": true, - "editor.tabSize": 3, - "editor.detectIndentation": false - }, - "[hpp]": { - "editor.insertSpaces": true, - "editor.tabSize": 3, - "editor.detectIndentation": false - }, - "cSpell.words": [], - "cSpell.ignorePaths": [ - "**/*.json", "**/*.c", "**/*.h", "**/*.cpp", "**/*.hpp", "**/Makefile" - ], - "java.project.sourcePaths": [ - "src/units" - ] -} diff --git a/software/nano-644/test_2024-07-23/.vscode/tasks.json b/software/nano-644/test_2024-07-23/.vscode/tasks.json deleted file mode 100644 index 74fb1c7..0000000 --- a/software/nano-644/test_2024-07-23/.vscode/tasks.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [{ - "label": "build", - "type": "shell", - "command": "make", - "problemMatcher":[ - "$gcc" - ] - },{ - "label": "clean", - "type": "shell", - "command": "make", - "args": [ "clean" ], - },{ - "label": "flash", - "type": "shell", - "command": "make", - "args": [ "flash" ], - }] -} \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/Makefile b/software/nano-644/test_2024-07-23/Makefile deleted file mode 100644 index 4ceec53..0000000 --- a/software/nano-644/test_2024-07-23/Makefile +++ /dev/null @@ -1,138 +0,0 @@ -.PHONY: all info flash picocom clean -$(shell mkdir -p dist >/dev/null) -$(shell mkdir -p build >/dev/null) -$(shell mkdir -p sim >/dev/null) -$(shell mkdir -p sim/build >/dev/null) - -NAME=test_2024-07-23_nano-644 -SRC= $(wildcard src/*.c src/*.cpp src/*/*.c src/*/*.cpp) -HDR= $(wildcard src/*.h src/*.hpp src/*/*.h src/*/*.hpp) -OBJ_CPP = $(SRC:src/%.cpp=build/%.o) -OBJ = $(OBJ_CPP:src/%.c=build/%.o) -OBJ_SIM_CPP = $(SRC:src/%.cpp=sim/build/%.o) -OBJ_SIM = $(OBJ_SIM_CPP:src/%.c=sim/build/%.o) - -DEVICE=atmega644p - -CC= avr-g++ -CFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=12000000 -c -LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=12000000 -Wl,-u,vfprintf -lprintf_flt -lm - -CFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=12000000 -g -c -c -LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=12000000 -g -Wl,-u,vfprintf -lprintf_flt -lm - - -all: dist/$(NAME).elf dist/$(NAME).s dist/$(NAME).hex sim/$(NAME).elf sim/$(NAME).s info - -dbg: - @echo --HDR--------------------------------- - @echo $(HDR) - @echo --SRC--------------------------------- - @echo $(SRC) - @echo --OBJ--------------------------------- - @echo $(OBJ) - @echo --OBJ_CPP----------------------------- - @echo $(OBJ_CPP) - @echo --OBJ--------------------------------- - @echo $(OBJ) - @echo =================================== - @echo - -info: - @avr-size --mcu=$(DEVICE) --format=avr dist/$(NAME).elf - -.depend: $(SRC) $(HDR) - $(CC) -mmcu=$(DEVICE) -MM $(SRC) | sed --regexp-extended 's/^(.*\.o)\: src\/(.*)(\.cpp|\.c) (.*)/build\/\2\.o\: src\/\2\3 \4/g' > .depend - --include .depend - -# .depend solte auch auf Header Files achten! - -dist/$(NAME).elf: .depend $(OBJ) - $(CC) $(LFLAGS) -o $@ $(OBJ) - -dist/%.s: dist/%.elf - avr-objdump -d $< > $@ - -dist/%.hex: dist/%.elf - avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ - -sim/$(NAME).elf: .depend $(OBJ_SIM) - $(CC) $(LFLAGS_SIM) -o $@ $(OBJ_SIM) - -# ensure that __DATE__ and __TIME__ macros are up to date -build/main.o: src/main.cpp $(SRC) $(HDR) - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -o $@ $< - -build/%.o: src/%.c - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -o $@ $< - -build/%.o: src/%.cpp - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -o $@ $< - -sim/build/%.o: src/%.c - @mkdir -p $(dir $@) - $(CC) $(CFLAGS_SIM) -o $@ $< - -sim/build/%.o: src/%.cpp - @mkdir -p $(dir $@) - $(CC) $(CFLAGS_SIM) -o $@ $< - -sim/%.s: sim/%.elf - avr-objdump -d $< > $@ - -simuc: sim/$(NAME).elf - simuc --board arduino $< - -gdb: sim/$(NAME).elf - avr-gdb $< - - -flash: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB0 -p m644p -e -U flash:w:$< - -flash0: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB0 -p m644p -e -U flash:w:$< - -flash1: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB1 -p m644p -e -U flash:w:$< - -flash2: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB2 -p m644p -e -U flash:w:$< - -picocom: - # picocom sends CR for ENTER -> convert cr (\r) to lf (\n) - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0 - -picocom0: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0 - -picocom1: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB1 - -picocom2: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB2 - - -isp-644p: - avrdude -c usbasp -p m644p - -isp-flash-644p: dist/$(NAME).elf all - avrdude -c usbasp -p m644p -e -U flash:w:$< - -flash-644p: dist/$(NAME).elf all - avrdude -c arduino -p m644p -P /dev/ttyUSB0 -b 115200 -e -U flash:w:$< - - -isp-fuse-644p: - avrdude -c usbasp -p m644p -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xFF:m -U lock:w:0xFF:m - -clean: - @rm -r dist - @rm -r build - @rm -r sim - @find . -type f -name ".depend" -exec rm {} \; - @echo "clean done" diff --git a/software/nano-644/test_2024-07-23/README.md b/software/nano-644/test_2024-07-23/README.md deleted file mode 100644 index c4d5e14..0000000 --- a/software/nano-644/test_2024-07-23/README.md +++ /dev/null @@ -1 +0,0 @@ -# Testprogramm diff --git a/software/nano-644/test_2024-07-23/release/v2024-08-18_1103/test_2024-07-23_nano-644.elf b/software/nano-644/test_2024-07-23/release/v2024-08-18_1103/test_2024-07-23_nano-644.elf deleted file mode 100755 index 56055784ae148ab1eda6e966397a3f8c7f2126d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71992 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 diff --git a/software/nano-644/test_2024-07-23/src/adafruit/bme280.cpp b/software/nano-644/test_2024-07-23/src/adafruit/bme280.cpp deleted file mode 100644 index 1836c56..0000000 --- a/software/nano-644/test_2024-07-23/src/adafruit/bme280.cpp +++ /dev/null @@ -1,512 +0,0 @@ -#include "bme280.h" -#include -#include - -Adafruit_BME280 theBME280; -Adafruit_BME280_Temp bm280TempSensor; -Adafruit_BME280_Pressure bm280PressureSensor; -Adafruit_BME280_Humidity bm280HumiditySensor; - -Adafruit_BME280::Adafruit_BME280() { - static I2cMaster i2cDevice; - t_fine_adjust = 0; - temp_sensor = &bm280TempSensor; - pressure_sensor = &bm280PressureSensor; - humidity_sensor = &bm280HumiditySensor; - i2c_dev = &i2cDevice; -} - -bool Adafruit_BME280::begin (uint8_t addr) { - if (!i2c_dev->begin(addr)) { - return false; - } - return init(); -} - -bool Adafruit_BME280::init() { - _sensorID = read8(BME280_REGISTER_CHIPID); - if (_sensorID != 0x60) { - return false; - } - write8(BME280_REGISTER_SOFTRESET, 0xB6); - _delay_ms(10); // wait for chip to wake up. - - // if chip is still reading calibration, delay - while (isReadingCalibration()) { - _delay_ms(10); - } - - readCoefficients(); // read trimming parameters, see DS 4.2.2 - setSampling(); // use defaults - _delay_ms(100); - - return true; -} - -/*! - * @brief setup sensor with given parameters / settings - * - * This is simply a overload to the normal begin()-function, so SPI users - * don't get confused about the library requiring an address. - * @param mode the power mode to use for the sensor - * @param tempSampling the temp samping rate to use - * @param pressSampling the pressure sampling rate to use - * @param humSampling the humidity sampling rate to use - * @param filter the filter mode to use - * @param duration the standby duration to use - */ -void Adafruit_BME280::setSampling(sensor_mode mode, - sensor_sampling tempSampling, - sensor_sampling pressSampling, - sensor_sampling humSampling, - sensor_filter filter, - standby_duration duration) { - _measReg.mode = mode; - _measReg.osrs_t = tempSampling; - _measReg.osrs_p = pressSampling; - - _humReg.osrs_h = humSampling; - _configReg.filter = filter; - _configReg.t_sb = duration; - _configReg.spi3w_en = 0; - - // making sure sensor is in sleep mode before setting configuration - // as it otherwise may be ignored - write8(BME280_REGISTER_CONTROL, MODE_SLEEP); - - // you must make sure to also set REGISTER_CONTROL after setting the - // CONTROLHUMID register, otherwise the values won't be applied (see - // DS 5.4.3) - write8(BME280_REGISTER_CONTROLHUMID, _humReg.get()); - write8(BME280_REGISTER_CONFIG, _configReg.get()); - write8(BME280_REGISTER_CONTROL, _measReg.get()); -} - -/*! - * @brief Writes an 8 bit value over I2C or SPI - * @param reg the register address to write to - * @param value the value to write to the register - */ -void Adafruit_BME280::write8(uint8_t reg, uint8_t value) { - uint8_t buffer[2]; - buffer[1] = value; - if (i2c_dev) { - buffer[0] = reg; - i2c_dev->write(buffer, 2); - } -} - -/*! - * @brief Reads an 8 bit value over I2C or SPI - * @param reg the register address to read from - * @returns the data byte read from the device - */ -uint8_t Adafruit_BME280::read8(uint8_t reg) { - uint8_t buffer[1]; - if (i2c_dev) { - buffer[0] = uint8_t(reg); - i2c_dev->write_then_read(buffer, 1, buffer, 1); - } - return buffer[0]; -} - -/*! - * @brief Reads a 16 bit value over I2C or SPI - * @param reg the register address to read from - * @returns the 16 bit data value read from the device - */ -uint16_t Adafruit_BME280::read16(uint8_t reg) { - uint8_t buffer[2]; - - if (i2c_dev) { - buffer[0] = uint8_t(reg); - i2c_dev->write_then_read(buffer, 1, buffer, 2); - } - return uint16_t(buffer[0]) << 8 | uint16_t(buffer[1]); -} - -/*! - * @brief Reads a signed 16 bit little endian value over I2C or SPI - * @param reg the register address to read from - * @returns the 16 bit data value read from the device - */ -uint16_t Adafruit_BME280::read16_LE(uint8_t reg) { - uint16_t temp = read16(reg); - return (temp >> 8) | (temp << 8); -} - -/*! - * @brief Reads a signed 16 bit value over I2C or SPI - * @param reg the register address to read from - * @returns the 16 bit data value read from the device - */ -int16_t Adafruit_BME280::readS16(uint8_t reg) { return (int16_t)read16(reg); } - -/*! - * @brief Reads a signed little endian 16 bit value over I2C or SPI - * @param reg the register address to read from - * @returns the 16 bit data value read from the device - */ -int16_t Adafruit_BME280::readS16_LE(uint8_t reg) { - return (int16_t)read16_LE(reg); -} - -/*! - * @brief Reads a 24 bit value over I2C - * @param reg the register address to read from - * @returns the 24 bit data value read from the device - */ -uint32_t Adafruit_BME280::read24(uint8_t reg) { - uint8_t buffer[3]; - - if (i2c_dev) { - buffer[0] = uint8_t(reg); - i2c_dev->write_then_read(buffer, 1, buffer, 3); - } - return uint32_t(buffer[0]) << 16 | uint32_t(buffer[1]) << 8 | - uint32_t(buffer[2]); -} - -/*! - * @brief Take a new measurement (only possible in forced mode) - @returns true in case of success else false - */ -bool Adafruit_BME280::takeForcedMeasurement(void) { - bool return_value = false; - // If we are in forced mode, the BME sensor goes back to sleep after each - // measurement and we need to set it to forced mode once at this point, so - // it will take the next measurement and then return to sleep again. - // In normal mode simply does new measurements periodically. - if (_measReg.mode == MODE_FORCED) { - return_value = true; - // set to forced mode, i.e. "take next measurement" - write8(BME280_REGISTER_CONTROL, _measReg.get()); - // Store current time to measure the timeout - uint32_t timeout_start = millis(); - // wait until measurement has been completed, otherwise we would read the - // the values from the last measurement or the timeout occurred after 2 sec. - while (read8(BME280_REGISTER_STATUS) & 0x08) { - // In case of a timeout, stop the while loop - if ((millis() - timeout_start) > 2000) { - return_value = false; - break; - } - _delay_ms(1); - } - } - return return_value; -} - -/*! - * @brief Reads the factory-set coefficients - */ -void Adafruit_BME280::readCoefficients(void) { - _bme280_calib.dig_T1 = read16_LE(BME280_REGISTER_DIG_T1); - _bme280_calib.dig_T2 = readS16_LE(BME280_REGISTER_DIG_T2); - _bme280_calib.dig_T3 = readS16_LE(BME280_REGISTER_DIG_T3); - - _bme280_calib.dig_P1 = read16_LE(BME280_REGISTER_DIG_P1); - _bme280_calib.dig_P2 = readS16_LE(BME280_REGISTER_DIG_P2); - _bme280_calib.dig_P3 = readS16_LE(BME280_REGISTER_DIG_P3); - _bme280_calib.dig_P4 = readS16_LE(BME280_REGISTER_DIG_P4); - _bme280_calib.dig_P5 = readS16_LE(BME280_REGISTER_DIG_P5); - _bme280_calib.dig_P6 = readS16_LE(BME280_REGISTER_DIG_P6); - _bme280_calib.dig_P7 = readS16_LE(BME280_REGISTER_DIG_P7); - _bme280_calib.dig_P8 = readS16_LE(BME280_REGISTER_DIG_P8); - _bme280_calib.dig_P9 = readS16_LE(BME280_REGISTER_DIG_P9); - - _bme280_calib.dig_H1 = read8(BME280_REGISTER_DIG_H1); - _bme280_calib.dig_H2 = readS16_LE(BME280_REGISTER_DIG_H2); - _bme280_calib.dig_H3 = read8(BME280_REGISTER_DIG_H3); - _bme280_calib.dig_H4 = ((int8_t)read8(BME280_REGISTER_DIG_H4) << 4) | - (read8(BME280_REGISTER_DIG_H4 + 1) & 0xF); - _bme280_calib.dig_H5 = ((int8_t)read8(BME280_REGISTER_DIG_H5 + 1) << 4) | - (read8(BME280_REGISTER_DIG_H5) >> 4); - _bme280_calib.dig_H6 = (int8_t)read8(BME280_REGISTER_DIG_H6); -} - -/*! - * @brief return true if chip is busy reading cal data - * @returns true if reading calibration, false otherwise - */ -bool Adafruit_BME280::isReadingCalibration(void) { - uint8_t const rStatus = read8(BME280_REGISTER_STATUS); - - return (rStatus & (1 << 0)) != 0; -} - -/*! - * @brief Returns the temperature from the sensor - * @returns the temperature read from the device - */ -float Adafruit_BME280::readTemperature(void) { - int32_t var1, var2; - - int32_t adc_T = read24(BME280_REGISTER_TEMPDATA); - if (adc_T == 0x800000) // value in case temp measurement was disabled - return NAN; - adc_T >>= 4; - - var1 = (int32_t)((adc_T / 8) - ((int32_t)_bme280_calib.dig_T1 * 2)); - var1 = (var1 * ((int32_t)_bme280_calib.dig_T2)) / 2048; - var2 = (int32_t)((adc_T / 16) - ((int32_t)_bme280_calib.dig_T1)); - var2 = (((var2 * var2) / 4096) * ((int32_t)_bme280_calib.dig_T3)) / 16384; - - t_fine = var1 + var2 + t_fine_adjust; - - int32_t T = (t_fine * 5 + 128) / 256; - - return (float)T / 100; -} - -/*! - * @brief Returns the pressure from the sensor - * @returns the pressure value (in Pascal) read from the device - */ -float Adafruit_BME280::readPressure(void) { - int64_t var1, var2, var3, var4; - - readTemperature(); // must be done first to get t_fine - - int32_t adc_P = read24(BME280_REGISTER_PRESSUREDATA); - if (adc_P == 0x800000) // value in case pressure measurement was disabled - return NAN; - adc_P >>= 4; - - var1 = ((int64_t)t_fine) - 128000; - var2 = var1 * var1 * (int64_t)_bme280_calib.dig_P6; - var2 = var2 + ((var1 * (int64_t)_bme280_calib.dig_P5) * 131072); - var2 = var2 + (((int64_t)_bme280_calib.dig_P4) * 34359738368); - var1 = ((var1 * var1 * (int64_t)_bme280_calib.dig_P3) / 256) + - ((var1 * ((int64_t)_bme280_calib.dig_P2) * 4096)); - var3 = ((int64_t)1) * 140737488355328; - var1 = (var3 + var1) * ((int64_t)_bme280_calib.dig_P1) / 8589934592; - - if (var1 == 0) { - return 0; // avoid exception caused by division by zero - } - - var4 = 1048576 - adc_P; - var4 = (((var4 * 2147483648UL) - var2) * 3125) / var1; - var1 = (((int64_t)_bme280_calib.dig_P9) * (var4 / 8192) * (var4 / 8192)) / - 33554432; - var2 = (((int64_t)_bme280_calib.dig_P8) * var4) / 524288; - var4 = ((var4 + var1 + var2) / 256) + (((int64_t)_bme280_calib.dig_P7) * 16); - - float P = var4 / 256.0; - - return P; -} - -/*! - * @brief Returns the humidity from the sensor - * @returns the humidity value read from the device - */ -float Adafruit_BME280::readHumidity(void) { - int32_t var1, var2, var3, var4, var5; - - readTemperature(); // must be done first to get t_fine - - int32_t adc_H = read16(BME280_REGISTER_HUMIDDATA); - if (adc_H == 0x8000) // value in case humidity measurement was disabled - return NAN; - - var1 = t_fine - ((int32_t)76800); - var2 = (int32_t)(adc_H * 16384); - var3 = (int32_t)(((int32_t)_bme280_calib.dig_H4) * 1048576); - var4 = ((int32_t)_bme280_calib.dig_H5) * var1; - var5 = (((var2 - var3) - var4) + (int32_t)16384) / 32768; - var2 = (var1 * ((int32_t)_bme280_calib.dig_H6)) / 1024; - var3 = (var1 * ((int32_t)_bme280_calib.dig_H3)) / 2048; - var4 = ((var2 * (var3 + (int32_t)32768)) / 1024) + (int32_t)2097152; - var2 = ((var4 * ((int32_t)_bme280_calib.dig_H2)) + 8192) / 16384; - var3 = var5 * var2; - var4 = ((var3 / 32768) * (var3 / 32768)) / 128; - var5 = var3 - ((var4 * ((int32_t)_bme280_calib.dig_H1)) / 16); - var5 = (var5 < 0 ? 0 : var5); - var5 = (var5 > 419430400 ? 419430400 : var5); - uint32_t H = (uint32_t)(var5 / 4096); - - return (float)H / 1024.0; -} - -/*! - * Calculates the altitude (in meters) from the specified atmospheric - * pressure (in hPa), and sea-level pressure (in hPa). - * @param seaLevel Sea-level pressure in hPa - * @returns the altitude value read from the device - */ -float Adafruit_BME280::readAltitude(float seaLevel) { - // Equation taken from BMP180 datasheet (page 16): - // http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf - - // Note that using the equation from wikipedia can give bad results - // at high altitude. See this thread for more information: - // http://forums.adafruit.com/viewtopic.php?f=22&t=58064 - - float atmospheric = readPressure() / 100.0F; - return 44330.0 * (1.0 - pow(atmospheric / seaLevel, 0.1903)); -} - -/*! - * Calculates the pressure at sea level (in hPa) from the specified - * altitude (in meters), and atmospheric pressure (in hPa). - * @param altitude Altitude in meters - * @param atmospheric Atmospheric pressure in hPa - * @returns the pressure at sea level (in hPa) from the specified altitude - */ -float Adafruit_BME280::seaLevelForAltitude(float altitude, float atmospheric) { - // Equation taken from BMP180 datasheet (page 17): - // http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf - - // Note that using the equation from wikipedia can give bad results - // at high altitude. See this thread for more information: - // http://forums.adafruit.com/viewtopic.php?f=22&t=58064 - - return atmospheric / pow(1.0 - (altitude / 44330.0), 5.255); -} - -/*! - * Returns Sensor ID found by init() for diagnostics - * @returns Sensor ID 0x60 for BME280, 0x56, 0x57, 0x58 BMP280 - */ -uint32_t Adafruit_BME280::sensorID(void) { return _sensorID; } - -/*! - * Returns the current temperature compensation value in degrees Celsius - * @returns the current temperature compensation value in degrees Celsius - */ -float Adafruit_BME280::getTemperatureCompensation(void) { - return float((t_fine_adjust * 5) >> 8) / 100.0; -}; - -/*! - * Sets a value to be added to each temperature reading. This adjusted - * temperature is used in pressure and humidity readings. - * @param adjustment Value to be added to each temperature reading in Celsius - */ -void Adafruit_BME280::setTemperatureCompensation(float adjustment) { - // convert the value in C into and adjustment to t_fine - t_fine_adjust = ((int32_t(adjustment * 100) << 8)) / 5; -}; - - -/**************************************************************************/ -/*! - @brief Gets the sensor_t data for the BME280's temperature sensor -*/ -/**************************************************************************/ -void Adafruit_BME280_Temp::getSensor(sensor_t *sensor) { - /* Clear the sensor_t object */ - memset(sensor, 0, sizeof(sensor_t)); - - /* Insert the sensor name in the fixed length char array */ - strncpy(sensor->name, "BME280", sizeof(sensor->name) - 1); - sensor->name[sizeof(sensor->name) - 1] = 0; - sensor->version = 1; - sensor->sensor_id = _sensorID; - sensor->type = SENSOR_TYPE_AMBIENT_TEMPERATURE; - sensor->min_delay = 0; - sensor->min_value = -40.0; /* Temperature range -40 ~ +85 C */ - sensor->max_value = +85.0; - sensor->resolution = 0.01; /* 0.01 C */ -} - -/**************************************************************************/ -/*! - @brief Gets the temperature as a standard sensor event - @param event Sensor event object that will be populated - @returns True -*/ -/**************************************************************************/ -bool Adafruit_BME280_Temp::getEvent(sensors_event_t *event) { - /* Clear the event */ - memset(event, 0, sizeof(sensors_event_t)); - - event->version = sizeof(sensors_event_t); - event->sensor_id = _sensorID; - event->type = SENSOR_TYPE_AMBIENT_TEMPERATURE; - event->timestamp = millis(); - event->temperature = theBME280.readTemperature(); - return true; -} - -/**************************************************************************/ -/*! - @brief Gets the sensor_t data for the BME280's pressure sensor -*/ -/**************************************************************************/ -void Adafruit_BME280_Pressure::getSensor(sensor_t *sensor) { - /* Clear the sensor_t object */ - memset(sensor, 0, sizeof(sensor_t)); - - /* Insert the sensor name in the fixed length char array */ - strncpy(sensor->name, "BME280", sizeof(sensor->name) - 1); - sensor->name[sizeof(sensor->name) - 1] = 0; - sensor->version = 1; - sensor->sensor_id = _sensorID; - sensor->type = SENSOR_TYPE_PRESSURE; - sensor->min_delay = 0; - sensor->min_value = 300.0; /* 300 ~ 1100 hPa */ - sensor->max_value = 1100.0; - sensor->resolution = 0.012; /* 0.12 hPa relative */ -} - -/**************************************************************************/ -/*! - @brief Gets the pressure as a standard sensor event - @param event Sensor event object that will be populated - @returns True -*/ -/**************************************************************************/ -bool Adafruit_BME280_Pressure::getEvent(sensors_event_t *event) { - /* Clear the event */ - memset(event, 0, sizeof(sensors_event_t)); - - event->version = sizeof(sensors_event_t); - event->sensor_id = _sensorID; - event->type = SENSOR_TYPE_PRESSURE; - event->timestamp = millis(); - event->pressure = theBME280.readPressure() / 100; // convert Pa to hPa - return true; -} - -/**************************************************************************/ -/*! - @brief Gets the sensor_t data for the BME280's humidity sensor -*/ -/**************************************************************************/ -void Adafruit_BME280_Humidity::getSensor(sensor_t *sensor) { - /* Clear the sensor_t object */ - memset(sensor, 0, sizeof(sensor_t)); - - /* Insert the sensor name in the fixed length char array */ - strncpy(sensor->name, "BME280", sizeof(sensor->name) - 1); - sensor->name[sizeof(sensor->name) - 1] = 0; - sensor->version = 1; - sensor->sensor_id = _sensorID; - sensor->type = SENSOR_TYPE_RELATIVE_HUMIDITY; - sensor->min_delay = 0; - sensor->min_value = 0; - sensor->max_value = 100; /* 0 - 100 % */ - sensor->resolution = 3; /* 3% accuracy */ -} - -/**************************************************************************/ -/*! - @brief Gets the humidity as a standard sensor event - @param event Sensor event object that will be populated - @returns True -*/ -/**************************************************************************/ -bool Adafruit_BME280_Humidity::getEvent(sensors_event_t *event) { - /* Clear the event */ - memset(event, 0, sizeof(sensors_event_t)); - - event->version = sizeof(sensors_event_t); - event->sensor_id = _sensorID; - event->type = SENSOR_TYPE_RELATIVE_HUMIDITY; - event->timestamp = millis(); - event->relative_humidity = theBME280.readHumidity(); - return true; -} diff --git a/software/nano-644/test_2024-07-23/src/adafruit/bme280.h b/software/nano-644/test_2024-07-23/src/adafruit/bme280.h deleted file mode 100644 index aa5aa72..0000000 --- a/software/nano-644/test_2024-07-23/src/adafruit/bme280.h +++ /dev/null @@ -1,373 +0,0 @@ -// https://github.com/adafruit/Adafruit_BME280_Library - -/*! - * @file Adafruit_BME280.h - * - * Designed specifically to work with the Adafruit BME280 Breakout - * ----> http://www.adafruit.com/products/2650 - * - * These sensors use I2C or SPI to communicate, 2 or 4 pins are required - * to interface. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Written by Kevin "KTOWN" Townsend for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * See the LICENSE file for details. - * - */ - -#ifndef __BME280_H__ -#define __BME280_H__ - -// #include "Arduino.h" - -// #include -// #include -// #include - - -#include "../i2cmaster.hpp" -#include "../main.hpp" -// #define byte uint8_t - - - -#include -#include -#include "sensor.h" - -/*! - * @brief default I2C address - */ -#define BME280_ADDRESS (0x77) // Primary I2C Address - /*! - * @brief alternate I2C address - */ -#define BME280_ADDRESS_ALTERNATE (0x76) // Alternate Address - -/*! - * @brief Register addresses - */ -enum { - BME280_REGISTER_DIG_T1 = 0x88, - BME280_REGISTER_DIG_T2 = 0x8A, - BME280_REGISTER_DIG_T3 = 0x8C, - - BME280_REGISTER_DIG_P1 = 0x8E, - BME280_REGISTER_DIG_P2 = 0x90, - BME280_REGISTER_DIG_P3 = 0x92, - BME280_REGISTER_DIG_P4 = 0x94, - BME280_REGISTER_DIG_P5 = 0x96, - BME280_REGISTER_DIG_P6 = 0x98, - BME280_REGISTER_DIG_P7 = 0x9A, - BME280_REGISTER_DIG_P8 = 0x9C, - BME280_REGISTER_DIG_P9 = 0x9E, - - BME280_REGISTER_DIG_H1 = 0xA1, - BME280_REGISTER_DIG_H2 = 0xE1, - BME280_REGISTER_DIG_H3 = 0xE3, - BME280_REGISTER_DIG_H4 = 0xE4, - BME280_REGISTER_DIG_H5 = 0xE5, - BME280_REGISTER_DIG_H6 = 0xE7, - - BME280_REGISTER_CHIPID = 0xD0, - BME280_REGISTER_VERSION = 0xD1, - BME280_REGISTER_SOFTRESET = 0xE0, - - BME280_REGISTER_CAL26 = 0xE1, // R calibration stored in 0xE1-0xF0 - - BME280_REGISTER_CONTROLHUMID = 0xF2, - BME280_REGISTER_STATUS = 0XF3, - BME280_REGISTER_CONTROL = 0xF4, - BME280_REGISTER_CONFIG = 0xF5, - BME280_REGISTER_PRESSUREDATA = 0xF7, - BME280_REGISTER_TEMPDATA = 0xFA, - BME280_REGISTER_HUMIDDATA = 0xFD -}; - -/**************************************************************************/ -/*! - @brief calibration data -*/ -/**************************************************************************/ -typedef struct { - uint16_t dig_T1; ///< temperature compensation value - int16_t dig_T2; ///< temperature compensation value - int16_t dig_T3; ///< temperature compensation value - - uint16_t dig_P1; ///< pressure compensation value - int16_t dig_P2; ///< pressure compensation value - int16_t dig_P3; ///< pressure compensation value - int16_t dig_P4; ///< pressure compensation value - int16_t dig_P5; ///< pressure compensation value - int16_t dig_P6; ///< pressure compensation value - int16_t dig_P7; ///< pressure compensation value - int16_t dig_P8; ///< pressure compensation value - int16_t dig_P9; ///< pressure compensation value - - uint8_t dig_H1; ///< humidity compensation value - int16_t dig_H2; ///< humidity compensation value - uint8_t dig_H3; ///< humidity compensation value - int16_t dig_H4; ///< humidity compensation value - int16_t dig_H5; ///< humidity compensation value - int8_t dig_H6; ///< humidity compensation value -} bme280_calib_data; -/*=========================================================================*/ - -class Adafruit_BME280; - -/** Adafruit Unified Sensor interface for temperature component of BME280 */ -class Adafruit_BME280_Temp : public Adafruit_Sensor { -public: - /** @brief Create an Adafruit_Sensor compatible object for the temp sensor - @param parent A pointer to the BME280 class */ - Adafruit_BME280_Temp() { _sensorID = 280; } - bool getEvent(sensors_event_t *); - void getSensor(sensor_t *); - -private: - int _sensorID; -}; - -/** Adafruit Unified Sensor interface for pressure component of BME280 */ -class Adafruit_BME280_Pressure : public Adafruit_Sensor { -public: - /** @brief Create an Adafruit_Sensor compatible object for the pressure sensor - @param parent A pointer to the BME280 class */ - Adafruit_BME280_Pressure() { _sensorID = 280; } - bool getEvent(sensors_event_t *); - void getSensor(sensor_t *); - -private: - int _sensorID; -}; - -/** Adafruit Unified Sensor interface for humidity component of BME280 */ -class Adafruit_BME280_Humidity : public Adafruit_Sensor { -public: - /** @brief Create an Adafruit_Sensor compatible object for the humidity sensor - @param parent A pointer to the BME280 class */ - Adafruit_BME280_Humidity() { _sensorID = 280;} - bool getEvent(sensors_event_t *); - void getSensor(sensor_t *); - -private: - int _sensorID; -}; - -/**************************************************************************/ -/*! - @brief Class that stores state and functions for interacting with BME280 IC -*/ -/**************************************************************************/ -class Adafruit_BME280 { -public: - /**************************************************************************/ - /*! - @brief sampling rates - */ - /**************************************************************************/ - enum sensor_sampling { - SAMPLING_NONE = 0b000, - SAMPLING_X1 = 0b001, - SAMPLING_X2 = 0b010, - SAMPLING_X4 = 0b011, - SAMPLING_X8 = 0b100, - SAMPLING_X16 = 0b101 - }; - - /**************************************************************************/ - /*! - @brief power modes - */ - /**************************************************************************/ - enum sensor_mode { - MODE_SLEEP = 0b00, - MODE_FORCED = 0b01, - MODE_NORMAL = 0b11 - }; - - /**************************************************************************/ - /*! - @brief filter values - */ - /**************************************************************************/ - enum sensor_filter { - FILTER_OFF = 0b000, - FILTER_X2 = 0b001, - FILTER_X4 = 0b010, - FILTER_X8 = 0b011, - FILTER_X16 = 0b100 - }; - - /**************************************************************************/ - /*! - @brief standby duration in ms - */ - /**************************************************************************/ - enum standby_duration { - STANDBY_MS_0_5 = 0b000, - STANDBY_MS_10 = 0b110, - STANDBY_MS_20 = 0b111, - STANDBY_MS_62_5 = 0b001, - STANDBY_MS_125 = 0b010, - STANDBY_MS_250 = 0b011, - STANDBY_MS_500 = 0b100, - STANDBY_MS_1000 = 0b101 - }; - - // constructors - Adafruit_BME280(); - - bool begin(uint8_t addr = BME280_ADDRESS); - bool init(); - - void setSampling(sensor_mode mode = MODE_NORMAL, - sensor_sampling tempSampling = SAMPLING_X16, - sensor_sampling pressSampling = SAMPLING_X16, - sensor_sampling humSampling = SAMPLING_X16, - sensor_filter filter = FILTER_OFF, - standby_duration duration = STANDBY_MS_0_5); - - bool takeForcedMeasurement(void); - float readTemperature(void); - float readPressure(void); - float readHumidity(void); - - float readAltitude(float seaLevel); - float seaLevelForAltitude(float altitude, float pressure); - uint32_t sensorID(void); - - float getTemperatureCompensation(void); - void setTemperatureCompensation(float); - -protected: - I2cMaster *i2c_dev = NULL; ///< Pointer to I2C bus interface - // Adafruit_SPIDevice *spi_dev = NULL; ///< Pointer to SPI bus interface - - Adafruit_BME280_Temp *temp_sensor; - Adafruit_BME280_Pressure *pressure_sensor; - Adafruit_BME280_Humidity *humidity_sensor; - - void readCoefficients(void); - bool isReadingCalibration(void); - - void write8(uint8_t reg, uint8_t value); - uint8_t read8(uint8_t reg); - uint16_t read16(uint8_t reg); - uint32_t read24(uint8_t reg); - int16_t readS16(uint8_t reg); - uint16_t read16_LE(uint8_t reg); // little endian - int16_t readS16_LE(uint8_t reg); // little endian - - uint8_t _i2caddr; //!< I2C addr for the TwoWire interface - int32_t _sensorID; //!< ID of the BME Sensor - int32_t t_fine; //!< temperature with high resolution, stored as an attribute - //!< as this is used for temperature compensation reading - //!< humidity and pressure - - int32_t t_fine_adjust; //!< add to compensate temp readings and in turn - //!< to pressure and humidity readings - - bme280_calib_data _bme280_calib; //!< here calibration data is stored - - /**************************************************************************/ - /*! - @brief config register - */ - /**************************************************************************/ - struct config { - // inactive duration (standby time) in normal mode - // 000 = 0.5 ms - // 001 = 62.5 ms - // 010 = 125 ms - // 011 = 250 ms - // 100 = 500 ms - // 101 = 1000 ms - // 110 = 10 ms - // 111 = 20 ms - unsigned int t_sb : 3; ///< inactive duration (standby time) in normal mode - - // filter settings - // 000 = filter off - // 001 = 2x filter - // 010 = 4x filter - // 011 = 8x filter - // 100 and above = 16x filter - unsigned int filter : 3; ///< filter settings - - // unused - don't set - unsigned int none : 1; ///< unused - don't set - unsigned int spi3w_en : 1; ///< unused - don't set - - /// @return combined config register - unsigned int get() { return (t_sb << 5) | (filter << 2) | spi3w_en; } - }; - config _configReg; //!< config register object - - /**************************************************************************/ - /*! - @brief ctrl_meas register - */ - /**************************************************************************/ - struct ctrl_meas { - // temperature oversampling - // 000 = skipped - // 001 = x1 - // 010 = x2 - // 011 = x4 - // 100 = x8 - // 101 and above = x16 - unsigned int osrs_t : 3; ///< temperature oversampling - - // pressure oversampling - // 000 = skipped - // 001 = x1 - // 010 = x2 - // 011 = x4 - // 100 = x8 - // 101 and above = x16 - unsigned int osrs_p : 3; ///< pressure oversampling - - // device mode - // 00 = sleep - // 01 or 10 = forced - // 11 = normal - unsigned int mode : 2; ///< device mode - - /// @return combined ctrl register - unsigned int get() { return (osrs_t << 5) | (osrs_p << 2) | mode; } - }; - ctrl_meas _measReg; //!< measurement register object - - /**************************************************************************/ - /*! - @brief ctrl_hum register - */ - /**************************************************************************/ - struct ctrl_hum { - /// unused - don't set - unsigned int none : 5; - - // pressure oversampling - // 000 = skipped - // 001 = x1 - // 010 = x2 - // 011 = x4 - // 100 = x8 - // 101 and above = x16 - unsigned int osrs_h : 3; ///< pressure oversampling - - /// @return combined ctrl hum register - unsigned int get() { return (osrs_h); } - }; - ctrl_hum _humReg; //!< hum register object -}; - -extern Adafruit_BME280 theBME280; - -#endif diff --git a/software/nano-644/test_2024-07-23/src/adafruit/ens160.cpp b/software/nano-644/test_2024-07-23/src/adafruit/ens160.cpp deleted file mode 100644 index 29e3704..0000000 --- a/software/nano-644/test_2024-07-23/src/adafruit/ens160.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/* - ScioSense_ENS160.h - Library for the ENS160 sensor with I2C interface from ScioSense - 2023 Mar 23 v6 Christoph Friese Bugfix measurement routine, prepare next release - 2021 Nov 25 v5 Martin Herold Custom mode timing fixed - 2021 Feb 04 v4 Giuseppe de Pinto Custom mode fixed - 2020 Apr 06 v3 Christoph Friese Changed nomenclature to ScioSense as product shifted from ams - 2020 Feb 15 v2 Giuseppe Pasetti Corrected firmware flash option - 2019 May 05 v1 Christoph Friese Created - based on application note "ENS160 Software Integration.pdf" rev 0.01 -*/ - -#include "ens160.h" -#include "math.h" -#include -#include -#include - -ScioSense_ENS160::ScioSense_ENS160 () { - _revENS16x = 0; - - //Isotherm, HP0 252°C / HP1 350°C / HP2 250°C / HP3 324°C / measure every 1008ms - _seq_steps[0][0] = 0x7c; - _seq_steps[0][1] = 0x0a; - _seq_steps[0][2] = 0x7e; - _seq_steps[0][3] = 0xaf; - _seq_steps[0][4] = 0xaf; - _seq_steps[0][5] = 0xa2; - _seq_steps[0][6] = 0x00; - _seq_steps[0][7] = 0x80; -} - -bool ScioSense_ENS160::begin () { - i2cDevice.begin(ENS160_I2CADDR_1); - _delay_ms(ENS160_BOOTING); - if (reset()) { - if (checkPartID()) { - if (setMode(ENS160_OPMODE_IDLE)) { - if (clearCommand()) { - if (getFirmware()) { - return true; - } - } - } - } - } - return false; - -} - -bool ScioSense_ENS160::write8 (uint8_t reg, uint8_t value) { - uint8_t buffer[2]; - buffer[1] = value; - buffer[0] = reg; - return i2cDevice.write(buffer, 2); -} - -bool ScioSense_ENS160::read8 (uint8_t reg, uint8_t *value) { - uint8_t buffer[1]; - buffer[0] = uint8_t(reg); - return i2cDevice.write_then_read(buffer, 1, value, 1); -} - -bool ScioSense_ENS160::read16 (uint8_t reg, uint16_t *value) { - uint8_t buffer[1]; - buffer[0] = uint8_t(reg); - return i2cDevice.write_then_read(buffer, 1, (uint8_t *)value, 2); -} - -bool ScioSense_ENS160::read16LE (uint8_t reg, uint16_t *value) { - uint16_t tmp; - if (read16(reg, &tmp)) { - *value = ((tmp & 0xff) << 8) | (tmp >> 8); - return true; - } - return false; -} - -bool ScioSense_ENS160::readBytes (uint8_t reg, uint8_t *bytes, uint8_t len) { - uint8_t buffer[1]; - buffer[0] = uint8_t(reg); - return i2cDevice.write_then_read(buffer, 1, buffer, len); -} - - -// Sends a reset to the ENS160. Returns false on I2C problems. -bool ScioSense_ENS160::reset () { - if (write8(ENS160_REG_OPMODE, ENS160_OPMODE_RESET)) { - _delay_ms(ENS160_BOOTING); - return true; - } - _delay_ms(ENS160_BOOTING); - return false; -} - -// Reads the part ID and confirms valid sensor -bool ScioSense_ENS160::checkPartID () { - uint16_t part_id; - - read16(ENS160_REG_PART_ID, &part_id); - _delay_ms(ENS160_BOOTING); - - if (part_id == ENS160_PARTID) { - _revENS16x = 0; - return true; - - } else if (part_id == ENS161_PARTID) { - _revENS16x = 1; - return true; - } - - return false; -} - -// Initialize idle mode and confirms -bool ScioSense_ENS160::clearCommand () { - uint8_t status; - - if (write8(ENS160_REG_COMMAND, ENS160_COMMAND_NOP)) { - if (write8(ENS160_REG_COMMAND, ENS160_COMMAND_CLRGPR)) { - _delay_ms(ENS160_BOOTING); - if (read8(ENS160_REG_DATA_STATUS, &status)) { - return true; - } - } - } - _delay_ms(ENS160_BOOTING); - return false; -} - -// Read firmware revisions -bool ScioSense_ENS160::getFirmware () { - uint8_t i2cbuf[3]; - - if (clearCommand()) { - _delay_ms(ENS160_BOOTING); - if (write8(ENS160_REG_COMMAND, ENS160_COMMAND_GET_APPVER)) { - if (readBytes(ENS160_REG_GPR_READ_4, i2cbuf, 3)) { - _fw_ver_major = i2cbuf[0]; - _fw_ver_minor = i2cbuf[1]; - _fw_ver_build = i2cbuf[2]; - _revENS16x = this->_fw_ver_major > 6 ? 1 : 0; - _delay_ms(ENS160_BOOTING); - return true; - } - } - } - _delay_ms(ENS160_BOOTING); - return false; -} - -// Set operation mode of sensor -bool ScioSense_ENS160::setMode (uint8_t mode) { - //LP only valid for rev>0 - if ((mode == ENS160_OPMODE_LP) and (_revENS16x == 0)) { - return false; - } - if (write8(ENS160_REG_OPMODE, mode)) { - _delay_ms(ENS160_BOOTING); - return true; - } - _delay_ms(ENS160_BOOTING); - return false; -} - -// Initialize definition of custom mode with steps -bool ScioSense_ENS160::initCustomMode (uint16_t stepNum) { - if (stepNum > 0) { - _stepCount = stepNum; - if (setMode(ENS160_OPMODE_IDLE)) { - if (clearCommand()) { - if (write8(ENS160_REG_COMMAND, ENS160_COMMAND_SETSEQ)) { - _delay_ms(ENS160_BOOTING); - return true; - } - } - } - } - _delay_ms(ENS160_BOOTING); - return false; -} - -// Add a step to custom measurement profile with definition of duration, enabled data acquisition and temperature for each hotplate -bool ScioSense_ENS160::addCustomStep (uint16_t time, bool measureHP0, bool measureHP1, bool measureHP2, bool measureHP3, uint16_t tempHP0, uint16_t tempHP1, uint16_t tempHP2, uint16_t tempHP3) { - uint8_t seq_ack; - uint8_t temp; - - _delay_ms(ENS160_BOOTING); - - temp = (uint8_t)(((time / 24) - 1) << 6); - if (measureHP0) { - temp = temp | 0x20; - } - if (measureHP1) { - temp = temp | 0x10; - } - if (measureHP2) { - temp = temp | 0x08; - } - if (measureHP3) { - temp = temp | 0x04; - } - if (!write8(ENS160_REG_GPR_WRITE_0, temp)) { - return false; - } - temp = (uint8_t)(((time / 24) - 1) >> 2); - if (!write8(ENS160_REG_GPR_WRITE_1, temp)) { - return false; - } - if (!write8(ENS160_REG_GPR_WRITE_2, (uint8_t)(tempHP0 / 2))) { - return false; - } - if (!write8(ENS160_REG_GPR_WRITE_3, (uint8_t)(tempHP1 / 2))) { - return false; - } - if (write8(ENS160_REG_GPR_WRITE_4, (uint8_t)(tempHP2 / 2))) { - return false; - } - if (write8(ENS160_REG_GPR_WRITE_5, (uint8_t)(tempHP3 / 2))) { - return false; - } - - if (write8(ENS160_REG_GPR_WRITE_6, (uint8_t)(_stepCount - 1))) { - return false; - } - - if (_stepCount == 1) { - if (!write8(ENS160_REG_GPR_WRITE_7, 128)) { - return false; - } - } else { - if (!write8(ENS160_REG_GPR_WRITE_7, 0)) { - return false; - } - } - _delay_ms(ENS160_BOOTING); - - if (!read8(ENS160_REG_GPR_READ_7, &seq_ack)) { - return false; - } - _delay_ms(ENS160_BOOTING); - - if ((ENS160_SEQ_ACK_COMPLETE | _stepCount) != seq_ack) { - _stepCount++; - return false; - } - - return true; -} - -bool ScioSense_ENS160::readStatus (uint8_t *status) { - return read8(ENS160_REG_DATA_STATUS, status); -} - -bool ScioSense_ENS160::readData (ENS160_DATA *data) { - uint8_t buffer[1] = { 0x21 }; - return i2cDevice.write_then_read(buffer, 1, (uint8_t *)data, sizeof(ENS160_DATA)); -} - -// Perform prediction measurement and stores result in internal variables -bool ScioSense_ENS160::measure (bool waitForNew) { - uint8_t i2cbuf[8]; - uint8_t status; - - // Set default status for early bail out - if (waitForNew) { - do { - if (!read8(ENS160_REG_DATA_STATUS, &status)) { - return false; - } - _delay_ms(1); - } while (!IS_NEWDAT(status)); - } else { - if (!read8(ENS160_REG_DATA_STATUS, &status)) { - return false; - } - } - - - // Read predictions - if (IS_NEWDAT(status)) { - if (!readBytes(ENS160_REG_DATA_AQI, i2cbuf, 7)) { - return false; - } - return false; - _data_aqi = i2cbuf[0]; - _data_tvoc = i2cbuf[1] | ((uint16_t)i2cbuf[2] << 8); - _data_eco2 = i2cbuf[3] | ((uint16_t)i2cbuf[4] << 8); - if (_revENS16x > 0) { - _data_aqi500 = ((uint16_t)i2cbuf[5]) | ((uint16_t)i2cbuf[6] << 8); - } else { - _data_aqi500 = 0; - } - return true; - } - - return false; -} - -// Perfrom raw measurement and stores result in internal variables -bool ScioSense_ENS160::measureRaw (bool waitForNew) { - uint8_t i2cbuf[8]; - uint8_t status; - - // Set default status for early bail out - if (waitForNew) { - do { - _delay_ms(1); - if (!read8(ENS160_REG_DATA_STATUS, &status)) { - return false; - } - } while (!IS_NEWGPR(status)); - } else { - if (!read8(ENS160_REG_DATA_STATUS, &status)) { - return false; - } - } - - if (IS_NEWGPR(status)) { - - // Read raw resistance values - if (!readBytes(ENS160_REG_GPR_READ_0, i2cbuf, 8)) { - return false; - } - _hp0_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[0] | ((uint16_t)i2cbuf[1] << 8))); - _hp1_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[2] | ((uint16_t)i2cbuf[3] << 8))); - _hp2_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[4] | ((uint16_t)i2cbuf[5] << 8))); - _hp3_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[6] | ((uint16_t)i2cbuf[7] << 8))); - - // Read baselines - if (!readBytes(ENS160_REG_DATA_BL, i2cbuf, 8)) { - return false; - } - _hp0_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[0] | ((uint16_t)i2cbuf[1] << 8))); - _hp1_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[2] | ((uint16_t)i2cbuf[3] << 8))); - _hp2_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[4] | ((uint16_t)i2cbuf[5] << 8))); - _hp3_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[6] | ((uint16_t)i2cbuf[7] << 8))); - - if (!read8(ENS160_REG_DATA_MISR, i2cbuf)) { - return false; - } - _misr = i2cbuf[0]; - return true; - } - - return false; -} - - -// Writes t (degC) and h (%rh) to ENV_DATA. Returns false on I2C problems. -bool ScioSense_ENS160::set_envdata (float t, float h) { - uint16_t t_data = (uint16_t)((t + 273.15f) * 64.0f); - uint16_t rh_data = (uint16_t)(h * 512.0f); - return this->set_envdata210(t_data, rh_data); -} - -// Writes t and h (in ENS210 format) to ENV_DATA. Returns false on I2C problems. -bool ScioSense_ENS160::set_envdata210 (uint16_t t, uint16_t h) { - //uint16_t temp; - uint8_t trh_in[4]; - - //temp = (uint16_t)((t + 273.15f) * 64.0f); - trh_in[0] = t & 0xff; - trh_in[1] = (t >> 8) & 0xff; - - //temp = (uint16_t)(h * 512.0f); - trh_in[2] = h & 0xff; - trh_in[3] = (h >> 8) & 0xff; - - if (!i2cDevice.writeByteAndBuffer(ENS160_REG_TEMP_IN, trh_in, 4)) { - return false; - } - - return true; -} diff --git a/software/nano-644/test_2024-07-23/src/adafruit/ens160.h b/software/nano-644/test_2024-07-23/src/adafruit/ens160.h deleted file mode 100644 index 7f26ba1..0000000 --- a/software/nano-644/test_2024-07-23/src/adafruit/ens160.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - ScioSense_ENS160.h - Library for the ENS160 sensor with I2C interface from ScioSense - 2023 Mar 23 v6 Christoph Friese Bugfix measurement routine, prepare next release - 2021 July 29 v4 Christoph Friese Changed nomenclature to ScioSense as product shifted from ams - 2020 Apr 06 v3 Christoph Friese Changed nomenclature to ScioSense as product shifted from ams - 2020 Feb 15 v2 Giuseppe Pasetti Corrected firmware flash option - 2019 May 05 v1 Christoph Friese Created - based on application note "ENS160 Software Integration.pdf" rev 0.01 -*/ - -#ifndef __SCIOSENSE_ENS160_H_ -#define __SCIOSENSE_ENS160_H_ - -#include "../i2cmaster.hpp" -#include -// #define byte uint8_t - -// #if (ARDUINO >= 100) -// #include "Arduino.h" -// #else -// #include "WProgram.h" -// #endif - -// #include - -// Chip constants -#define ENS160_PARTID 0x0160 -#define ENS161_PARTID 0x0161 -#define ENS160_BOOTING 10 - -// 7-bit I2C slave address of the ENS160 -#define ENS160_I2CADDR_0 0x52 //ADDR low -#define ENS160_I2CADDR_1 0x53 //ADDR high - -// ENS160 registers for version V0 -#define ENS160_REG_PART_ID 0x00 // 2 byte register -#define ENS160_REG_OPMODE 0x10 -#define ENS160_REG_CONFIG 0x11 -#define ENS160_REG_COMMAND 0x12 -#define ENS160_REG_TEMP_IN 0x13 -#define ENS160_REG_RH_IN 0x15 -#define ENS160_REG_DATA_STATUS 0x20 -#define ENS160_REG_DATA_AQI 0x21 -#define ENS160_REG_DATA_TVOC 0x22 -#define ENS160_REG_DATA_ECO2 0x24 -#define ENS160_REG_DATA_BL 0x28 -#define ENS160_REG_DATA_T 0x30 -#define ENS160_REG_DATA_RH 0x32 -#define ENS160_REG_DATA_MISR 0x38 -#define ENS160_REG_GPR_WRITE_0 0x40 -#define ENS160_REG_GPR_WRITE_1 ENS160_REG_GPR_WRITE_0 + 1 -#define ENS160_REG_GPR_WRITE_2 ENS160_REG_GPR_WRITE_0 + 2 -#define ENS160_REG_GPR_WRITE_3 ENS160_REG_GPR_WRITE_0 + 3 -#define ENS160_REG_GPR_WRITE_4 ENS160_REG_GPR_WRITE_0 + 4 -#define ENS160_REG_GPR_WRITE_5 ENS160_REG_GPR_WRITE_0 + 5 -#define ENS160_REG_GPR_WRITE_6 ENS160_REG_GPR_WRITE_0 + 6 -#define ENS160_REG_GPR_WRITE_7 ENS160_REG_GPR_WRITE_0 + 7 -#define ENS160_REG_GPR_READ_0 0x48 -#define ENS160_REG_GPR_READ_4 ENS160_REG_GPR_READ_0 + 4 -#define ENS160_REG_GPR_READ_6 ENS160_REG_GPR_READ_0 + 6 -#define ENS160_REG_GPR_READ_7 ENS160_REG_GPR_READ_0 + 7 - -//ENS160 data register fields -#define ENS160_COMMAND_NOP 0x00 -#define ENS160_COMMAND_CLRGPR 0xCC -#define ENS160_COMMAND_GET_APPVER 0x0E -#define ENS160_COMMAND_SETTH 0x02 -#define ENS160_COMMAND_SETSEQ 0xC2 - -#define ENS160_OPMODE_RESET 0xF0 -#define ENS160_OPMODE_DEP_SLEEP 0x00 -#define ENS160_OPMODE_IDLE 0x01 -#define ENS160_OPMODE_STD 0x02 -#define ENS160_OPMODE_LP 0x03 -#define ENS160_OPMODE_CUSTOM 0xC0 - -#define ENS160_BL_CMD_START 0x02 -#define ENS160_BL_CMD_ERASE_APP 0x04 -#define ENS160_BL_CMD_ERASE_BLINE 0x06 -#define ENS160_BL_CMD_WRITE 0x08 -#define ENS160_BL_CMD_VERIFY 0x0A -#define ENS160_BL_CMD_GET_BLVER 0x0C -#define ENS160_BL_CMD_GET_APPVER 0x0E -#define ENS160_BL_CMD_EXITBL 0x12 - -#define ENS160_SEQ_ACK_NOTCOMPLETE 0x80 -#define ENS160_SEQ_ACK_COMPLETE 0xC0 - -#define IS_ENS160_SEQ_ACK_NOT_COMPLETE(x) (ENS160_SEQ_ACK_NOTCOMPLETE == (ENS160_SEQ_ACK_NOTCOMPLETE & (x))) -#define IS_ENS160_SEQ_ACK_COMPLETE(x) (ENS160_SEQ_ACK_COMPLETE == (ENS160_SEQ_ACK_COMPLETE & (x))) - -#define ENS160_DATA_STATUS_NEWDAT 0x02 -#define ENS160_DATA_STATUS_NEWGPR 0x01 - -#define IS_NEWDAT(x) (ENS160_DATA_STATUS_NEWDAT == (ENS160_DATA_STATUS_NEWDAT & (x))) -#define IS_NEWGPR(x) (ENS160_DATA_STATUS_NEWGPR == (ENS160_DATA_STATUS_NEWGPR & (x))) -#define IS_NEW_DATA_AVAILABLE(x) (0 != ((ENS160_DATA_STATUS_NEWDAT | ENS160_DATA_STATUS_NEWGPR ) & (x))) - -#define CONVERT_RS_RAW2OHMS_I(x) (1 << ((x) >> 11)) -#define CONVERT_RS_RAW2OHMS_F(x) (pow (2, (float)(x) / 2048)) - -typedef struct { - uint8_t aqi; - uint16_t tvoc; - uint16_t eco2; -} ENS160_DATA; - -class ScioSense_ENS160 { - - public: - ScioSense_ENS160(); - - void setI2C(uint8_t sda, uint8_t scl); // Function to redefine I2C pins - - bool begin(); // Init I2C communication, resets ENS160 and checks its PART_ID. Returns false on I2C problems or wrong PART_ID. - uint8_t revENS16x() { return this->_revENS16x; } // Report version of sensor (0: ENS160, 1: ENS161) - bool setMode(uint8_t mode); // Set operation mode of sensor - - bool initCustomMode(uint16_t stepNum); // Initialize definition of custom mode with steps - bool addCustomStep(uint16_t time, bool measureHP0, bool measureHP1, bool measureHP2, bool measureHP3, uint16_t tempHP0, uint16_t tempHP1, uint16_t tempHP2, uint16_t tempHP3); - // Add a step to custom measurement profile with definition of duration, enabled data acquisition and temperature for each hotplate - - bool readData (ENS160_DATA *data); - bool readStatus(uint8_t *status); - bool measure(bool waitForNew); // Perform measurement and stores result in internal variables - bool measureRaw(bool waitForNew); // Perform raw measurement and stores result in internal variables - bool set_envdata(float t, float h); // Writes t (degC) and h (%rh) to ENV_DATA. Returns "0" if I2C transmission is successful - bool set_envdata210(uint16_t t, uint16_t h); // Writes t and h (in ENS210 format) to ENV_DATA. Returns "0" if I2C transmission is successful - uint8_t getMajorRev() { return this->_fw_ver_major; } // Get major revision number of used firmware - uint8_t getMinorRev() { return this->_fw_ver_minor; } // Get minor revision number of used firmware - uint8_t getBuild() { return this->_fw_ver_build; } // Get build revision number of used firmware - - uint8_t getAQI() { return this->_data_aqi; } // Get AQI value of last measurement - uint16_t getTVOC() { return this->_data_tvoc; } // Get TVOC value of last measurement - uint16_t geteCO2() { return this->_data_eco2; } // Get eCO2 value of last measurement - uint16_t getAQI500() { return this->_data_aqi500; } // Get AQI500 value of last measurement - uint32_t getHP0() { return this->_hp0_rs; } // Get resistance of HP0 of last measurement - uint32_t getHP1() { return this->_hp1_rs; } // Get resistance of HP1 of last measurement - uint32_t getHP2() { return this->_hp2_rs; } // Get resistance of HP2 of last measurement - uint32_t getHP3() { return this->_hp3_rs; } // Get resistance of HP3 of last measurement - uint32_t getHP0BL() { return this->_hp0_bl; } // Get baseline resistance of HP0 of last measurement - uint32_t getHP1BL() { return this->_hp1_bl; } // Get baseline resistance of HP1 of last measurement - uint32_t getHP2BL() { return this->_hp2_bl; } // Get baseline resistance of HP2 of last measurement - uint32_t getHP3BL() { return this->_hp3_bl; } // Get baseline resistance of HP3 of last measurement - uint8_t getMISR() { return this->_misr; } // Return status code of sensor - - private: - I2cMaster i2cDevice; - bool reset(); // Sends a reset to the ENS160. Returns false on I2C problems. - bool checkPartID(); // Reads the part ID and confirms valid sensor - bool clearCommand(); // Initialize idle mode and confirms - bool getFirmware(); // Read firmware revisions - - uint8_t _revENS16x; // ENS160 or ENS161 connected? (FW >7) - - uint8_t _fw_ver_major; - uint8_t _fw_ver_minor; - uint8_t _fw_ver_build; - - uint16_t _stepCount; // Counter for custom sequence - - uint8_t _data_aqi; - uint16_t _data_tvoc; - uint16_t _data_eco2; - uint16_t _data_aqi500; - uint32_t _hp0_rs; - uint32_t _hp0_bl; - uint32_t _hp1_rs; - uint32_t _hp1_bl; - uint32_t _hp2_rs; - uint32_t _hp2_bl; - uint32_t _hp3_rs; - uint32_t _hp3_bl; - uint16_t _temp; - int _slaveaddr; // Slave address of the ENS160 - uint8_t _misr; - - uint8_t _seq_steps[1][8]; - - bool write8(uint8_t reg, uint8_t value); - bool read8 (uint8_t reg, uint8_t *value); - bool read16 (uint8_t reg, uint16_t *value); - bool read16LE (uint8_t reg, uint16_t *value); - bool readBytes (uint8_t reg, uint8_t *bytes, uint8_t len); -}; - - -#endif diff --git a/software/nano-644/test_2024-07-23/src/adafruit/sensor.h b/software/nano-644/test_2024-07-23/src/adafruit/sensor.h deleted file mode 100644 index ac7e454..0000000 --- a/software/nano-644/test_2024-07-23/src/adafruit/sensor.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * 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< /span> - * 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. - */ - -/* Update by K. Townsend (Adafruit Industries) for lighter typedefs, and - * extended sensor support to include color, voltage and current */ - -#ifndef _ADAFRUIT_SENSOR_H -#define _ADAFRUIT_SENSOR_H - -#ifndef ARDUINO -#include -#elif ARDUINO >= 100 -#include "Arduino.h" -#include "Print.h" -#else -#include "WProgram.h" -#endif - -/* Constants */ -#define SENSORS_GRAVITY_EARTH (9.80665F) /**< Earth's gravity in m/s^2 */ -#define SENSORS_GRAVITY_MOON (1.6F) /**< The moon's gravity in m/s^2 */ -#define SENSORS_GRAVITY_SUN (275.0F) /**< The sun's gravity in m/s^2 */ -#define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH) -#define SENSORS_MAGFIELD_EARTH_MAX \ - (60.0F) /**< Maximum magnetic field on Earth's surface */ -#define SENSORS_MAGFIELD_EARTH_MIN \ - (30.0F) /**< Minimum magnetic field on Earth's surface */ -#define SENSORS_PRESSURE_SEALEVELHPA \ - (1013.25F) /**< Average sea level pressure is 1013.25 hPa */ -#define SENSORS_DPS_TO_RADS \ - (0.017453293F) /**< Degrees/s to rad/s multiplier \ - */ -#define SENSORS_RADS_TO_DPS \ - (57.29577793F) /**< Rad/s to degrees/s multiplier */ -#define SENSORS_GAUSS_TO_MICROTESLA \ - (100) /**< Gauss to micro-Tesla multiplier */ - -/** Sensor types */ -typedef enum { - SENSOR_TYPE_ACCELEROMETER = (1), /**< Gravity + linear acceleration */ - SENSOR_TYPE_MAGNETIC_FIELD = (2), - SENSOR_TYPE_ORIENTATION = (3), - SENSOR_TYPE_GYROSCOPE = (4), - SENSOR_TYPE_LIGHT = (5), - SENSOR_TYPE_PRESSURE = (6), - SENSOR_TYPE_PROXIMITY = (8), - SENSOR_TYPE_GRAVITY = (9), - SENSOR_TYPE_LINEAR_ACCELERATION = - (10), /**< Acceleration not including gravity */ - SENSOR_TYPE_ROTATION_VECTOR = (11), - SENSOR_TYPE_RELATIVE_HUMIDITY = (12), - SENSOR_TYPE_AMBIENT_TEMPERATURE = (13), - SENSOR_TYPE_OBJECT_TEMPERATURE = (14), - SENSOR_TYPE_VOLTAGE = (15), - SENSOR_TYPE_CURRENT = (16), - SENSOR_TYPE_COLOR = (17), - SENSOR_TYPE_TVOC = (18), - SENSOR_TYPE_VOC_INDEX = (19), - SENSOR_TYPE_NOX_INDEX = (20), - SENSOR_TYPE_CO2 = (21), - SENSOR_TYPE_ECO2 = (22), - SENSOR_TYPE_PM10_STD = (23), - SENSOR_TYPE_PM25_STD = (24), - SENSOR_TYPE_PM100_STD = (25), - SENSOR_TYPE_PM10_ENV = (26), - SENSOR_TYPE_PM25_ENV = (27), - SENSOR_TYPE_PM100_ENV = (28), - SENSOR_TYPE_GAS_RESISTANCE = (29), - SENSOR_TYPE_UNITLESS_PERCENT = (30), - SENSOR_TYPE_ALTITUDE = (31) -} sensors_type_t; - -/** struct sensors_vec_s is used to return a vector in a common format. */ -typedef struct { - union { - float v[3]; ///< 3D vector elements - struct { - float x; ///< X component of vector - float y; ///< Y component of vector - float z; ///< Z component of vector - }; ///< Struct for holding XYZ component - /* Orientation sensors */ - struct { - float roll; /**< Rotation around the longitudinal axis (the plane body, 'X - axis'). Roll is positive and increasing when moving - downward. -90 degrees <= roll <= 90 degrees */ - float pitch; /**< Rotation around the lateral axis (the wing span, 'Y - axis'). Pitch is positive and increasing when moving - upwards. -180 degrees <= pitch <= 180 degrees) */ - float heading; /**< Angle between the longitudinal axis (the plane body) - and magnetic north, measured clockwise when viewing from - the top of the device. 0-359 degrees */ - }; ///< Struct for holding roll/pitch/heading - }; ///< Union that can hold 3D vector array, XYZ components or - ///< roll/pitch/heading - int8_t status; ///< Status byte - uint8_t reserved[3]; ///< Reserved -} sensors_vec_t; - -/** struct sensors_color_s is used to return color data in a common format. */ -typedef struct { - union { - float c[3]; ///< Raw 3-element data - /* RGB color space */ - struct { - float r; /**< Red component */ - float g; /**< Green component */ - float b; /**< Blue component */ - }; ///< RGB data in floating point notation - }; ///< Union of various ways to describe RGB colorspace - uint32_t rgba; /**< 24-bit RGBA value */ -} sensors_color_t; - -/* Sensor event (36 bytes) */ -/** struct sensor_event_s is used to provide a single sensor event in a common - * format. */ -typedef struct { - int32_t version; /**< must be sizeof(struct sensors_event_t) */ - int32_t sensor_id; /**< unique sensor identifier */ - int32_t type; /**< sensor type */ - int32_t reserved0; /**< reserved */ - int32_t timestamp; /**< time is in milliseconds */ - union { - float data[4]; ///< Raw data */ - sensors_vec_t acceleration; /**< acceleration values are in meter per second - per second (m/s^2) */ - sensors_vec_t - magnetic; /**< magnetic vector values are in micro-Tesla (uT) */ - sensors_vec_t orientation; /**< orientation values are in degrees */ - sensors_vec_t gyro; /**< gyroscope values are in rad/s */ - float temperature; /**< temperature is in degrees centigrade (Celsius) */ - float distance; /**< distance in centimeters */ - float light; /**< light in SI lux units */ - float pressure; /**< pressure in hectopascal (hPa) */ - float relative_humidity; /**< relative humidity in percent */ - float current; /**< current in milliamps (mA) */ - float voltage; /**< voltage in volts (V) */ - float tvoc; /**< Total Volatile Organic Compounds, in ppb */ - float voc_index; /**< VOC (Volatile Organic Compound) index where 100 is - normal (unitless) */ - float nox_index; /**< NOx (Nitrogen Oxides) index where 100 is normal - (unitless) */ - float CO2; /**< Measured CO2 in parts per million (ppm) */ - float eCO2; /**< equivalent/estimated CO2 in parts per million (ppm - estimated from some other measurement) */ - float pm10_std; /**< Standard Particulate Matter <=1.0 in parts per million - (ppm) */ - float pm25_std; /**< Standard Particulate Matter <=2.5 in parts per million - (ppm) */ - float pm100_std; /**< Standard Particulate Matter <=10.0 in parts per - million (ppm) */ - float pm10_env; /**< Environmental Particulate Matter <=1.0 in parts per - million (ppm) */ - float pm25_env; /**< Environmental Particulate Matter <=2.5 in parts per - million (ppm) */ - float pm100_env; /**< Environmental Particulate Matter <=10.0 in parts per - million (ppm) */ - float gas_resistance; /**< Proportional to the amount of VOC particles in - the air (Ohms) */ - float unitless_percent; /** -#include -#include - -#include "i2cmaster.hpp" - -I2cMaster::I2cMaster () { - address = 0; - timer = 0; -} - -void I2cMaster::tick1ms () { - if (timer > 0) { - timer--; - } -} - -bool I2cMaster::begin (uint8_t addr) { - this->address = addr; - // TWBR = 13; // 100kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 100000) / (2 * 100000 * 4); - TWBR = 100; // 50kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 50000) / (2 * 50000 * 4); - TWCR = (1 << TWEN); - return true; -} - -void I2cMaster::end () { - TWCR = (1 << TWEN); - TWBR = 0; -} - -bool I2cMaster::read (uint8_t *buffer, uint8_t len) { - if (start(true)) { - if (readBytes(buffer, len)) { - if (stop()) { - return true; - } - } - } - return false; -} - - -bool I2cMaster::write (const uint8_t *buffer, uint8_t len) { - if (start(false)) { - if (writeBytes(buffer, len, false)) { - if (stop()) { - return true; - } - } - } - return false; -} - -bool I2cMaster::write_P (const uint8_t *buffer, uint8_t len) { - if (start(false)) { - if (writeBytes(buffer, len, true)) { - if (stop()) { - return true; - } - } - } - return false; -} - - -bool I2cMaster::writeByteAndBuffer (uint8_t byte, const uint8_t *buffer, uint8_t len) { - if (start(false)) { - do { - TWDR = byte; - TWCR = (1 << TWINT) | (1 << TWEN); // send byte - while (!(TWCR & (1 << TWINT))) {}; // wait until last action done - if ((TWSR & 0xf8) != 0x28) { - return false; - } - byte = *buffer++; - } while (len-- > 0); - return true; - } - return false; -} - - -bool I2cMaster::write_then_read (const uint8_t *write_buffer, uint8_t write_len, uint8_t *read_buffer, uint8_t read_len) { - if (start(false)) { - if (writeBytes(write_buffer, write_len, false)) { - if (start(true)) { - if (readBytes(read_buffer, read_len)) { - if (stop()) { - return true; - } - } - } - } - } - return false; -} - -// ------------------------------------------------------------- - -bool I2cMaster::readBytes (uint8_t *buffer, uint8_t len) { - while (len-- > 0) { - if (len > 0) { - TWCR = (1 << TWEA) | (1 << TWINT) | (1 << TWEN); // read data byte with ACK enabled - } else { - TWCR = (1 << TWINT) | (1 << TWEN); // read data byte with ACK disabled - } - while (!(TWCR & (1 << TWINT))) {}; // wait until last action done - uint8_t sr = TWSR & 0xf8; - if ((len > 0 && sr != 0x50) || (len == 0 && sr != 0x58)) { - return false; - } - *buffer++ = TWDR; - } - return true; -} - -bool I2cMaster::writeBytes (const uint8_t *buffer, uint8_t len, bool fromFlash) { - while (len-- > 0) { - // printf_P(PSTR("[wB:len=%d, byte=%02x]"), len + 1, *buffer); - TWDR = fromFlash ? pgm_read_byte(buffer++) : *buffer++; - TWCR = (1 << TWINT) | (1 << TWEN); // send data byte - timer = 5; - while (timer > 0 && !(TWCR & (1 << TWINT))) {}; // wait until last action done - if (!timer || (TWSR & 0xf8) != 0x28) { - return false; - } - } - return true; -} - -bool I2cMaster::start (bool read) { - TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // send START condition - timer = 5; - while (timer > 0 && !(TWCR & (1 << TWINT))) {}; // wait until last action done - uint8_t sr = TWSR & 0xf8; - if (!timer || (sr != 0x08 && sr != 0x10)) { - return false; - } - TWDR = (address << 1) | (read ? 1 : 0); // address + R/nW - TWCR = (1 << TWINT) | (1 << TWEN); // send address/RW - timer = 5; - while (timer > 0 && !(TWCR & (1 << TWINT))) {}; // wait until last action done - sr = TWSR & 0xf8; - if (!timer || (!read && sr != 0x18) || (read && sr != 0x40)) { - return false; - } - return true; -} - -bool I2cMaster::stop () { - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); - while (TWCR & ( 1 << TWSTO)); - return true; -} - diff --git a/software/nano-644/test_2024-07-23/src/i2cmaster.hpp b/software/nano-644/test_2024-07-23/src/i2cmaster.hpp deleted file mode 100644 index 89b1e46..0000000 --- a/software/nano-644/test_2024-07-23/src/i2cmaster.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef I2C_MASTER -#define I2C_MASTER - -#include - -class I2cMaster { - public: - static void end (); - - public: - I2cMaster (); - void tick1ms (); - bool begin (uint8_t addr); - bool read (uint8_t *buffer, uint8_t len); - bool write (const uint8_t *buffer, uint8_t len); - bool write_P (const uint8_t *buffer, uint8_t len); - bool write_then_read (const uint8_t *write_buffer, uint8_t write_len, uint8_t *read_buffer, uint8_t read_len); - bool writeByteAndBuffer (uint8_t byte, const uint8_t *buffer, uint8_t len); - - private: - uint8_t address; - uint8_t timer; - bool start (bool read); - bool stop (); - bool writeBytes (const uint8_t *buffer, uint8_t len, bool fromFlash); - bool writeBytes_P (const uint8_t *buffer); - bool readBytes (uint8_t *buffer, uint8_t len); -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/i2cslave.cpp b/software/nano-644/test_2024-07-23/src/i2cslave.cpp deleted file mode 100644 index 2bf6ac2..0000000 --- a/software/nano-644/test_2024-07-23/src/i2cslave.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include -#include - -#include "i2cslave.hpp" - -I2cSlave::I2cSlave () { - timer = 0; - fromMaster.rIndex = 0; - fromMaster.wIndex = 0; - toMaster.rIndex = 0; - toMaster.wIndex = 0; -} - -void I2cSlave::tick1ms () { - if (timer > 0) { - timer--; - } -} - -bool I2cSlave::begin (uint8_t addr, bool acceptGeneralCalls) { - if (addr > 127) { - return false; - } - TWAR = addr << 1 | (acceptGeneralCalls ? 1 : 0); - TWBR = 100; // 50kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 50000) / (2 * 50000 * 4); - TWCR = (1 << TWEA) | (1 << TWEN) | (1 << TWIE); - return true; -} - -void I2cSlave::end () { - TWCR = (1 << TWEN); - TWBR = 0; -} - -int I2cSlave::read () { - return getByte(fromMaster); -} - -void I2cSlave::write (uint8_t byte) { - putByte(toMaster, byte); -} - - -void I2cSlave::putByte (RingBuffer& buffer, uint8_t byte) { - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - buffer.data[buffer.wIndex++] = byte; - if (buffer.wIndex >= sizeof(buffer.data)) { - buffer.wIndex = 0; - } - if (buffer.wIndex == buffer.rIndex) { - buffer.rIndex++; - if (buffer.rIndex >= sizeof(buffer.data)) { - buffer.rIndex = 0; - } - } - } -} - -int I2cSlave::getByte (RingBuffer& buffer) { - uint8_t b; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - if (buffer.rIndex == buffer.wIndex) { - return EOF; - } - b = buffer.data[buffer.rIndex++]; - if (buffer.rIndex >= sizeof(buffer.data)) { - buffer.rIndex = 0; - } - } - return b; -} - -void I2cSlave::handleTWIIsr () { - uint8_t sr = TWSR & 0xf8; - switch (sr) { - case 0x80: { // Previously addressed with own SLA+W; data has been received; ACK has been returned - putByte(fromMaster, TWDR); - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE); // no TWEA -> only one byte accepted - break; - } - case 0xa8: { // Own SLA+R has been received; ACK has been returned - int response = getByte(toMaster);; - TWDR = response < 0 ? 0x00 : (uint8_t)response; - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE); // no TWEA -> only one byte accepted - break; - } - default: TWCR = (1 << TWINT) | (1 << TWEA) | (1 << TWEN) | (1 << TWIE); break; - } - -} - diff --git a/software/nano-644/test_2024-07-23/src/i2cslave.hpp b/software/nano-644/test_2024-07-23/src/i2cslave.hpp deleted file mode 100644 index 2fe2dc7..0000000 --- a/software/nano-644/test_2024-07-23/src/i2cslave.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef I2C_SLAVE -#define I2C_SLAVE - -#include - -class I2cSlave { - private: - typedef struct { - uint8_t rIndex; - uint8_t wIndex; - uint8_t data[8]; - } RingBuffer; - - public: - I2cSlave (); - void tick1ms (); - bool begin (uint8_t addr, bool acceptGeneralCalls); - void end (); - void handleTWIIsr (); - int read (); - void write (uint8_t byte); - - private: - uint8_t timer; - RingBuffer fromMaster; - RingBuffer toMaster; - void putByte (RingBuffer& buffer, uint8_t byte); - int getByte (RingBuffer& buffer); - -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/main.cpp b/software/nano-644/test_2024-07-23/src/main.cpp deleted file mode 100644 index 35f309f..0000000 --- a/software/nano-644/test_2024-07-23/src/main.cpp +++ /dev/null @@ -1,412 +0,0 @@ -#include -#include -#include -#include - -#include -#include - -#include "main.hpp" -#include "units/encoder.hpp" -#include "units/i2c.hpp" -#include "units/led.hpp" -#include "units/ieee485.hpp" -#include "units/led.hpp" -#include "units/lcd.hpp" -#include "units/switch.hpp" -#include "units/rgb.hpp" -#include "units/seg7.hpp" -#include "units/poti.hpp" -#include "units/r2r.hpp" -#include "units/motor.hpp" -#include "units/portexp.hpp" -#include "units/uart1.hpp" -#include "units/modbus.hpp" -#include "units/rtc8563.hpp" -#include "units/cc1101.hpp" - -const char MAIN_CPP_DATE[] PROGMEM = __DATE__; -const char MAIN_CPP_TIME[] PROGMEM = __TIME__; -#ifdef __AVR_ATmega328P__ - const char MAIN_CPP_PART_NAME[] PROGMEM = "ATmega328P"; -#endif -#ifdef __AVR_ATmega644P__ - const char MAIN_CPP_PART_NAME[] PROGMEM = "ATmega644P"; -#endif -#ifdef __AVR_ATmega1284P__ - const char MAIN_CPP_PART_NAME[] PROGMEM = "ATmega1284P"; -#endif - -const char PSTR_DIVIDER[] PROGMEM = "\n====================================\n "; -const char PSTR_LINEFEED[] PROGMEM = "\n"; -const char PSTR_ERROR[] PROGMEM = "ERROR"; -const char PSTR_Done[] PROGMEM = "Done"; - -uint8_t hardwareVersion = 0; - -extern "C" { - void __cxa_pure_virtual () {} - int __cxa_guard_acquire(uint8_t *g) { return 0; } - void __cxa_guard_release(uint8_t *g) {} - void __cxa_guard_abort(uint8_t *g) {} - void __gxx_personality_sj0 () {} - void __cxa_rethrow () {} - void __cxa_begin_catch () {} - void __cxa_end_catch () {} - - int uart_putchar(char c, FILE *stream) { - if (c == '\n') { - uart_putchar('\r', stream); - } - if (stream == stdout) { - loop_until_bit_is_set(UCSR0A, UDRE0); - UDR0 = c; - } - return 0; - } - - - uint64_t volatile systemMillis = 0; - uint8_t volatile uartBuffer[32]; - uint8_t volatile rIndex = 0; - uint8_t volatile wIndex = 0; - - int uart_getchar (FILE *stream) { - // if (rIndex == wIndex) { - // // nothing in buffer - // return EOF; - // } - // printf_P(PSTR(" r%d"), rIndex); - while (rIndex == wIndex) { - // wait for character - } - - // don't use "char c" because german special characters would lead to negative return -> stream error - // char c = uartBuffer[rIndex++]; - - uint8_t c = uartBuffer[rIndex++]; - // printf_P(PSTR("(%02x) "), c); - if (c == '\r') { - c = '\n'; - } - putchar(c); // echo on terminal - return c; - } - - static FILE mystdout = { 0, 0, _FDEV_SETUP_WRITE , 0, 0, uart_putchar, NULL, 0 }; - static FILE mystdin = { 0, 0, _FDEV_SETUP_READ , 0, 0, NULL, uart_getchar, 0 }; - - #if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - static volatile uint16_t timerFlashGreenLed = 0; - static volatile uint16_t timerFlashRedLed = 0; - void flashRedLed (uint16_t ms) { - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - if (timerFlashRedLed == 0) { - PORTC |= (1 << PC2); - if (ms < 0xff80) { - ms += 0x80; // at least 128ms OFF after - } - timerFlashRedLed = ms; - } - } - } - void flashGreenLed (uint16_t ms) { - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - if (timerFlashGreenLed == 0) { - PORTC |= (1 << PC4); - if (ms < 0xff80) { - ms += 0x80; // at least 128ms OFF after - } - timerFlashGreenLed = ms; - } - } - } - #endif - - static volatile uint32_t timer1ms = 0; - static volatile int keyUart0 = EOF; - - Led led; - Switch sw; - Rgb rgb; - Seg7 seg7; - Poti poti; - Encoder encoder; - R2r r2r; - Motor motor; - PortExp portExp; - Lcd lcd; - Uart1 uart1; - Modbus modbus; - Ieee485 ieee485; - I2c i2cSparkfun(I2c::SparkFunEnvCombo); - I2c i2cMaster(I2c::Master); - I2c i2cSlave(I2c::Slave); - Rtc8563 rtc8563(Rtc8563::NORMAL); - Cc1101 cc1101Send(Cc1101::Send); - Cc1101 cc1101Receive(Cc1101::Receive); -} - -uint8_t detectHardwareVersion () { - ADMUX = (1 << ADLAR) | (1 << REFS0) | 7; // ADC7, VREF=AVCC=3.3V - ADCSRA = (1 << ADEN) | 7; // ADC Enable, Prescaler 128 - ADCSRA |= (1 << ADSC); // start ADC - while (ADCSRA & (1 << ADSC)) {} // wait for result - hardwareVersion = 0; // unknown board version - // printf("Hardware-Version: ADC7H = %d\n", ADCH); - #if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - - if (ADCH >= 0xf4) { - hardwareVersion = 1; - } else if (ADCH >= 0xe0) { - hardwareVersion = 2; - } - #endif - #if defined(__AVR_ATmega328P__) - if (ADCH < 0xd8 && ADCH >= 0xc0) { - hardwareVersion = 1; - } else if (ADCH < 0xd8 && ADCH >= 0xb0) { - hardwareVersion = 2; - } - #endif - - if (hardwareVersion < 1 || hardwareVersion > 2) { - #ifdef __AVR_ATmega644P__ - printf_P(PSTR("\nInvalid Hardware-Version: ADC7H = %d (ATmega644P, 3.3V)\n"), ADCH); - #elif __AVR_ATmega1284P__ - printf_P(PSTR("\nInvalid Hardware-Version: ADC7H = %d (ATmega1284P, 3.3V)\n"), ADCH); - #elif __AVR_ATmega328P__ - printf_P(PSTR("\nInvalid Hardware-Version: ADC7H = %d (ATmega328P, 5V)\n"), ADCH); - #endif - } else { - printf_P(PSTR("\n\nHardware %d detected (ADC7H=0x%02X)"), hardwareVersion, ADCH); - } - - ADMUX = 0; - ADCSRA = 0; - return hardwareVersion; -} - -void setTimer (uint32_t ms) { - ATOMIC_BLOCK(ATOMIC_FORCEON) { - timer1ms = ms; - } -} - -int wait (uint32_t ms) { - setTimer(ms); - do { - ATOMIC_BLOCK(ATOMIC_FORCEON) { - ms = timer1ms; - } - } while (ms > 0 && keyUart0 == EOF); - return keyUart0; -} - -int waitAndReadKey (uint32_t ms) { - keyUart0 = EOF; - int key = wait(ms); - keyUart0 = EOF; - return key; -} - -int main () { - - #if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - // Nano-644 LEDs (Green, Orange, Red) - DDRC |= (1 << PC7) | (1 << PC4) | (1 << PC3) | (1 << PC2); - PORTC &= ~((1 << PC7) | (1 << PC4) | (1 << PC3) | (1 << PC2)); - - // Nano-644 push button SW2 - DDRC &= ~(1 << PC5); - PORTC |= (1 << PC5); // enable internal pullup resistor - #endif - - #ifdef __AVR_ATmega328P__ - DDRB |= (1 << PB5); - PORTB &= ~(1 << PB5); - #endif - - // UART0 interface on Nano-644 - UCSR0A = (1 << U2X0); - UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 <= 1 && hardwareVersion <= 2) { - printf_P(PSTR("Hardware: %d"), hardwareVersion); - } else { - printf_P(PSTR("ERROR: Invalid Hardware (%d)"), hardwareVersion); - for(;;); - } - printf_P(PSTR_DIVIDER); - printf_P(PSTR_LINEFEED); - printf_P(PSTR("Available units:\n\n")); - for (i = 0; i < sizeof(unit) / sizeof(unit[0]); i++) { - TestUnit *pu = unit[i]; - printf_P(PSTR("%3x ... "), i); - printf_P(pu->getName()); - printf_P(PSTR_LINEFEED); - } - printf_P(PSTR("\nSelect unit: ")); - rIndex = 0; wIndex = 0; - fgets(s, sizeof(s), stdin); - } while (sscanf(s, "%x", &i) != 1 || i < 0 || i >= sizeof(unit) / sizeof(unit[0]) ); - - TestUnit *pu = unit[i]; - printf_P(PSTR("\n\n[")); printf_P(pu->getName()); printf_P(PSTR("]: ")); - keyUart0 = EOF; - - pu->init(); - for (uint8_t subtest = 0; subtest < 0xff; subtest++) { - printf_P(PSTR("\n%4d: "), subtest); - if (pu->run(subtest) < 0) { - break; - } - if (keyUart0 == 27) { - keyUart0 = EOF; - break; - } - keyUart0 = EOF; - } - pu->cleanup(); - } -} - -uint64_t millis () { - volatile uint64_t millis = systemMillis; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - millis = systemMillis; - } - return millis; -} - -#ifndef USART0_RX_vect - #define USART0_RX_vect USART_RX_vect -#endif -ISR (USART0_RX_vect) { - uint8_t b = UDR0; - keyUart0 = b; - uartBuffer[wIndex++] = b; - // printf_P(PSTR(" w%d(%02x)"), wIndex, b); - if (wIndex == rIndex) { - // buffer overflow, kick out oldest byte - rIndex++; - } -} - -#ifdef USART1_RX_vect - ISR (USART1_RX_vect) { - uint8_t b = UDR1; - if (modbus.enabled) { - modbus.handleRxByte(b); - } - if (uart1.enabled) { - uart1.handleRxByte(b); - } - if (ieee485.enabled) { - ieee485.handleRxByte(b); - } - } -#endif - -ISR (TWI_vect) { - if (i2cMaster.enabled) { - i2cMaster.handleTwiIrq(); - } else if (i2cSlave.enabled) { - i2cSlave.handleTwiIrq(); - } else if (i2cSparkfun.enabled) { - i2cSparkfun.handleTwiIrq(); - } else { - TWCR = (1 << TWINT); // clear interrupt request bit and disable TWI - } -} - -ISR (TIMER2_COMPA_vect) { // every 100us - static uint16_t timer500ms = 0; - static uint8_t timer100us = 0; - - if (encoder.enabled) { - encoder.tick100us(); - } - if (motor.enabled) { - motor.tick100us(); - } - - timer100us++; - if (timer100us >= 10) { - timer100us = 0; - if (timer1ms > 0) { - timer1ms--; - } - systemMillis++; - i2cMaster.tick1ms(); - i2cSlave.tick1ms(); - i2cSparkfun.tick1ms(); - cc1101Send.tick1ms(); - cc1101Receive.tick1ms(); - #if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - if (timerFlashRedLed > 0) { - if (--timerFlashRedLed < 128) { - PORTC &= ~(1 << PC2); // red LED - } - } - if (timerFlashGreenLed > 0) { - if (--timerFlashGreenLed < 128 ) { - PORTC &= ~(1 << PC4); // green LED - } - } - #endif - } - - timer500ms++; - if (timer500ms >= 5000) { - #if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - PORTC ^= (1 << PC3); // orange LED blinking - #endif - #ifdef __AVR_ATmega328P__ - if (!seg7.enabled) { - PORTB ^= (1 << PB5); // LED L - } - #endif - timer500ms = 0; - } -} - diff --git a/software/nano-644/test_2024-07-23/src/main.hpp b/software/nano-644/test_2024-07-23/src/main.hpp deleted file mode 100644 index 7eeff16..0000000 --- a/software/nano-644/test_2024-07-23/src/main.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef MAIN_HPP -#define MAIN_HPP - -#include -#include - -#define ENTER '\r' -#define CTRLC '\003' -#define ESCAPE 0x1b - -extern int wait (uint32_t ms); -extern int waitAndReadKey (uint32_t ms); -extern uint64_t millis (); - -extern uint8_t hardwareVersion; - -extern const char PSTR_DIVIDER[]; -extern const char PSTR_LINEFEED[]; -extern const char PSTR_ERROR[]; -extern const char PSTR_Done[]; - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - extern "C" { - extern void flashRedLed (uint16_t ms); - extern void flashGreenLed (uint16_t ms); - } -#endif - - -class TestUnit { - public: - virtual int8_t run (uint8_t subtest) = 0; - virtual void init () = 0; - virtual void cleanup () = 0; - virtual PGM_P getName () = 0; -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/cc1101.cpp b/software/nano-644/test_2024-07-23/src/units/cc1101.cpp deleted file mode 100644 index aebe713..0000000 --- a/software/nano-644/test_2024-07-23/src/units/cc1101.cpp +++ /dev/null @@ -1,753 +0,0 @@ -#include -#include -#include -#include - -#include "cc1101.hpp" -#include "../main.hpp" - -// 868MHz Modem E07-900MM1DS (chipset CC1101) -// https://jlcpcb.com/partdetail/Chengdu_Ebyte_ElecTech-E07900MM10S/C5844212 - -#ifdef __AVR_ATmega328P__ - - // Arduino-Nano-5V - // ------------------------------------ - // not available - - void Cc1101::init () {} - void Cc1101::cleanup () {} - void Cc1101::setChipEnableLow () {} - void Cc1101::setChipEnableHigh () {} - int8_t Cc1101::run (uint8_t subtest) { return -1; } - PGM_P Cc1101::getName () { return PSTR("?"); } - -#endif - - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - - // Nano-644 - // -------------------------------------------------------- - // PA4 ... nCS - // PB4 ... nSS (not used, but must be high, otherwise AVR SPI master not working) - // PB5 ... MOSI - // PB6 ... MISO - // PB7 ... SCK - - // -------------------------------------------------------- - - // Output power table from CC1101 datasheet page 59 - const Cc1101::PATABLE_INIT_ITEM_t PMEM_CC1101_PATABLE_INIT[] PROGMEM = { - { 0xc6, "9.6" }, // 9.6 dBm / 29.4mA (default value) - { 0xc0, "11" }, // 11 dBm / 34.2mA - { 0xc5, "10" }, // 10 dBm / 30.0mA - { 0xcd, "7" }, // 7 dBm / 25.8mA - { 0x86, "5" }, // 5 dBm / 19.9mA - { 0x50, "0" }, // 0 dBm / 16.8mA - { 0x37, "-6" }, // -6 dBm / 16.4mA - { 0x26, "-10" }, // 10 dBm / 14.5mA - { 0x1d, "-15" }, // 15 dBm / 13.3mA - { 0x17, "-20" }, // 20 dBm / 12.6mA - { 0x03, "-30" }, // 30 dBm / 12.0mA - }; - const Cc1101::Register_t PMEM_CC1101_REGISTER_INIT PROGMEM = { - /* 0x00: iocfg2 0x0b (----) */ { Cc1101::CHIP_NOT_READY, 0, 0 }, // GDO2 - /* 0x01: iocfg1 0x2e (----) */ { Cc1101::HIGH_IMPEDANCE_WHEN_CHIP_SELECT_HIGH, 0, 0 }, // GDO1/MISO - /* 0x02: iocfg0 0x06 (----) */ { Cc1101::SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET, 0, 0 }, // GDO0 -> PA5 - /* 0x03: fifothr 0x47 (0x07) */ { 7, 0, 1, 0 }, // fifo_thr = 0b111, close_in_rx=0, adc_retention = 1, (bit7=0) - /* 0x04: sync1 0x7a (0xd3) */ 0x7a, - /* 0x05: sync0 0x0e (0x91) */ 0x0e, - /* 0x06: pktlen 0x14 (0x3d) */ PACKET_LENGTH, - /* 0x07: pktctrl1 0x04 (----) */ { Cc1101::NO_ADDR_CHECK, 1, 0, 0, 0 }, // adr_chk=0b00, append_status=1, crc_autoflush=0, (bit4=0), pqt=0b000 - /* 0x08: pktctrl0 0x05 (----) */ { Cc1101::FIXED, 1, 0, Cc1101::NORMAL_USE_FIFO, 0, 0 }, // length_config=0b01, crc_en=1, (bit3=0), pkt_format=0b00, white_data=0, (bit7=0) - /* 0x09: addr 0x00 (----) */ 0x00, - /* 0x0a: channr 0x00 (----) */ 0x00, - /* 0x0b: fsctrl1 0x06 (0x08) */ { 6, 0, 0 }, // frqu_if=6, (bit5=0), (bit76=0b00) - /* 0x0c: fsctrl0 0x00 (----) */ { 0 }, // freqoff = 0 - /* 0x0d: frequ2 0x21 (----) */ 0x21, - /* 0x0e: frequ1 0x62 (----) */ 0x62, - /* 0x0f: frequ0 0x76 (----) */ 0x76, - /* 0x10: mdmcfg4 0xca (0x5b) */ { 0x0a, 0, 3 }, // drate_e=0x0a, chanbw_m=0, chanbw_e=3 - /* 0x11: mdmcfg3 0xf8 (----) */ { 0xf8 }, // drate_m=0xf8 - /* 0x12: mdmcfg2 0x16 (0x03) */ { Cc1101::SYNC_16_16_CARRIER_SENSE, 0, Cc1101::GFSK, 0}, // sync_mode=0b110, manchester_en=0, mod_format=0b001, dem_dcfilt_off=0 - /* 0x13: mdmcfg1 0x22 (----) */ { 2, 0, Cc1101::FOUR, 0 }, // chanspc_e=0b10, bit32=0, num_preamble=0b010, fec_en=0 - /* 0x14: mdmcfg0 0xf8 (----) */ { 0xf8 }, // chanspc_m = 0x08 - /* 0x15: deviatn 0x40 (0x47) */ { 0, 0, 4, 0 }, // deviation_m=0, (bit3=0), deviation_e=4, (bit7=0) - /* 0x16: mcsm2 0x07 (----) */ { 7, 0, 0, 0 }, // rx_time=7 (NA), rx_time_qual=0, rx_time_rssi=0, (bit76=0b00) - /* 0x17: mcsm1 0x30 (----) */ { Cc1101::TXOFF_IDLE, Cc1101::RXOFF_IDLE, Cc1101::RSSI_BELOW_THRESHOLD__UNLESS_RECEIVE_PACKET, 0 }, // mcsm1 (txoff_mode=0b00, rxoff_mode=0b00, cca_mode=0b11, (bit76=0b00) ) - /* 0x18: mcsm0 0x18 (----) */ { 0, 0, 2, Cc1101::IDLE_TO_RX_OR_TX, 0 }, // xosc_force_on=0, pin_ctrl_en=0, po_timeout=2 (149-155us), fs_autocal=0b01, (bit76=0b00) - /* 0x19: foccfg 0x16 (0x1d) */ 0x16, - /* 0x1a: bscfg 0x6c (0x1c) */ 0x6c, - /* 0x1b: agcctrl2 0x43 (0xc7) */ 0x43, - /* 0x1c: agcctrl1 0x49 (0x00) */ 0x49, - /* 0x1d: agcctrl0 0x91 (0xb2) */ 0x91, - /* 0x1e: worevt1 0x87 (----) */ 0x87, - /* 0x1f: worevt0 0x6b (----) */ 0x6b, - /* 0x20: worctrl 0xfb (0xf8) */ 0xfb, - /* 0x21: frend1 0x56 (0xb6) */ 0x56, - /* 0x22: frend0 0x10 (----) */ { 0, 0, 1, 0 }, // pa_power = 0, (bit3 = 0), lodiv_buf_current = 1, (bit76=0b00) - /* 0x23: fscal3 0xe9 (0xea) */ 0xe9, - /* 0x24: fscal2 0x2a (----) */ 0x2a, - /* 0x25: fscal1 0x00 (----) */ 0x00, - /* 0x26: fscal0 0x1f (0x11) */ 0x1f, - /* 0x27: rcctrl1 0x41 (----) */ 0x41, - /* 0x28: rcctrl0 0x00 (----) */ 0x00, - /* 0x29: fstest 0x59 (----) */ 0x59, - /* 0x2a: ptest 0x7f (----) */ 0x7f, - /* 0x2b: agctest 0x3f (----) */ 0x3f, - /* 0x2c: test2 0x81 (0x88) */ 0x81, - /* 0x2d: test1 0x35 (0x31) */ 0x35, - /* 0x2e: test0 0x09 (0x0b) */ 0x09 - }; - - // -------------------------------------------------------------------------------------- - - int8_t Cc1101::runSend (uint8_t subtest) { - if (subtest == 0) { - bool ok = true; - GDOx_CFG_t cfg0 = SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET; - ok &= writeRegister(0x02, cfg0); - return ok; - } else if (subtest > 1) { - return -1; - } - - printf_P(PSTR(" use + and - for power change (other key -> back to default)")); - - uint16_t cnt = 0; - uint8_t paIndex = 0; - uint8_t pa_power; - int key = EOF; - do { - // if ((cnt & 0x0f) == 0) { - // paIndex = (cnt >> 4) & 0x07; - // union { FREND0_t value; uint8_t byte; } frend0 = { paIndex, 0, 1, 0 }; - // printf_P(PSTR("\n switch power ")); - // if (writeRegister(FREND0, frend0.byte )) { - // printf_P(PSTR("to %d (FREND0 = 0x%02X)"), frend0.value.pa_power, frend0.byte); - // } else { - // printf_P(PSTR("fails")); - // } - // } - if (key != EOF) { - uint8_t max = (sizeof(PMEM_CC1101_PATABLE_INIT) / sizeof(PMEM_CC1101_PATABLE_INIT[0])) - 1; - switch (key) { - case '+': if (paIndex == 0) paIndex = 1; else if (paIndex > 1) paIndex--; break; - case '-': if (paIndex == 0) paIndex = max; else if (paIndex < max) paIndex++; break; - default: paIndex = 0; break; // default value - } - - const PATABLE_INIT_ITEM_t *values = PMEM_CC1101_PATABLE_INIT; - - memcpy_P(&pa_power, &((values[paIndex]).pa_power), 1); - PGM_P info = (values[paIndex]).dbm; - printf_P(PSTR("\n switch power to ")); printf_P(info); - printf_P(PSTR("dBm ")); - if (writeRegister(0x3e, pa_power )) { - printf_P(PSTR("(PATABLE = 0x%02X)"), pa_power); - } else { - printf_P(PSTR("fails")); - } - } - - MainRadioControlState state = UNKNOWN; - uint8_t data[PACKET_LENGTH]; - printf_P(PSTR("\n [%04x]: state="), cnt++); - if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) { - printf_P(PSTR("E1")); - } else { - printf_P(PSTR("0x%02x"), state); - } - data[0] = pa_power; - printf_P(PSTR(" --> send %d bytes (HEX: %02X"), sizeof(data), paIndex); - for (uint8_t i = 1; i < sizeof(data); i++) { - data[i] = uint8_t((cnt + i - 1) & 0xff); - printf_P(PSTR(" %02X"), data[i]); - } - printf_P(PSTR("] -> ")); - - if (!sendData(data, sizeof(data))) { - flashRedLed(100); - printf_P(PSTR("E1")); - continue; - } - flashGreenLed(100); - key = waitAndReadKey(2000); - printf_P(PSTR("OK")); - - } while (key == EOF || (key != ESCAPE)); - - return 0; - } - - int8_t Cc1101::runReceive (uint8_t subtest) { - if (subtest == 0) { - bool ok = true; - GDOx_CFG_t cfg0 = SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET; - ok &= writeRegister(0x02, cfg0); - return ok; - } else if (subtest > 1) { - return -1; - } - - int key = EOF; - uint16_t cnt = 0; - MainRadioControlState state; - while (key == EOF) { - printf_P(PSTR("\n [%04x] => start ... "), cnt++); - strobe(SRX); - do { - state = UNKNOWN; - if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) { - printf_P(PSTR("E1")); - _delay_ms(500); - break; - } - if (wait(0) != EOF) { - printf_P(PSTR("cancelled")); - _delay_ms(500); - break; - } - if (state == IDLE) { - printf_P(PSTR("? (IDLE)")); - _delay_ms(500); - break; - } - - } while (state != RX && state != RXFIFO_OVERFLOW); - - if (state != RX && state != RXFIFO_OVERFLOW) { - continue; - } - printf_P(PSTR("OK, receive ... ")); - - uint8_t length; - uint8_t lastLength = 0xff; - do { - uint8_t data[PACKET_LENGTH]; - if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) { - printf_P(PSTR("E2")); - _delay_ms(500); - continue; - } - if (wait(0) != EOF) { - printf_P(PSTR("cancelled")); - _delay_ms(500); - return -1; - } - if (!readStatusRegister(RXBYTES, (uint8_t *)&length)) { - printf_P(PSTR("E2")); - _delay_ms(500); - continue; - } - if (lastLength != length) { - lastLength = length; - } - if (length >= PACKET_LENGTH) { - if (receiveData(data, &length, sizeof(data))) { - if (length > 0) { - flashGreenLed(100); - printf_P(PSTR(" -> ")); - if (status.receivePacketStatusValid) { - printf_P(PSTR(" RSSI=%d, LQI=%d, CRC "), status.receivedPacketStatus.value.rssi, status.receivedPacketStatus.value.lqi); - if (status.receivedPacketStatus.value.crcOk) { - printf_P(PSTR("OK, ")); - } else { - printf_P(PSTR("ERROR, ")); - } - } - printf_P(PSTR("%d data bytes (HEX): "), length); - for (uint8_t i = 0; i < length; i++) { - printf_P(PSTR(" %02X"), data[i]); - } - printf_P(PSTR(" ... ")); - } - } - } - - } while (state == RX || state == RXFIFO_OVERFLOW); - - printf_P(PSTR("done (state=0x%02x)"), state); - } - return -1; - } - - int8_t Cc1101::runTest (uint8_t subtest) { - if (subtest > 0) { - return -1; - } - while (wait(0) == EOF) {} - return -1; - } - - - int8_t Cc1101::run (uint8_t subtest) { - switch (mode) { - case Send: return runSend(subtest); - case Receive: return runReceive(subtest); - case Test: return runTest(subtest); - default: return -1; - } - } - - uint8_t Cc1101::sendSpiByte (uint8_t b) { - SPDR = b; - while (!(SPSR & (1< "), addr, value); - if (ok && status.receivePacketStatusValid) { - printf_P(PSTR("status=0x%02x]"), status.spiResponse.byte); - } else { - printf_P(PSTR("ERR]")); - } - } - - return ok; - } - - bool Cc1101::writeRegisters (uint8_t addr, uint8_t *buffer, uint8_t length) { - bool ok = true; - uint8_t l = length; - uint8_t *p = buffer; - - addr = (addr & 0x3f) | 0x40; // write burst - setChipEnableLow(); - ok &= waitForMisoLow(); - sendSpiByte(addr); - while (length-- > 0) { - sendSpiByte(*buffer++); - } - setChipEnableHigh(); - - if (debugPrint.print.writeRegisters) { - printf_P(PSTR("\n [writeRegisters(0x%02x): "), addr & 0x3f); - while (l-- > 0) { - printf_P(PSTR(" 0x%02x"), *p++); - } - printf_P(PSTR(" -> ")); - if (ok && status.receivePacketStatusValid) { - printf_P(PSTR("status=0x%02x]"), status.spiResponse.byte); - } else { - printf_P(PSTR("ERR]")); - } - } - - return ok; - } - - - bool Cc1101::readRegister (uint8_t addr, uint8_t *value) { - bool ok = true; - addr = (addr & 0x3f) | 0x80; - setChipEnableLow(); - ok &= waitForMisoLow(); - status.spiResponse.byte = sendSpiByte(addr); - status.spiResponseValid = 1; - *value = sendSpiByte(0); - setChipEnableHigh(); - - if (debugPrint.print.readRegister) { - printf_P(PSTR("\n [readRegister(0x%02x) -> "), addr & 0x3f); - if (ok && status.spiResponseValid) { - printf_P(PSTR("0x%02x,status=0x%02x]"), *value, status.spiResponse.byte); - } else { - printf_P(PSTR("ERR]")); - } - } - return ok; - } - - bool Cc1101::readRegisters (uint8_t addr, uint8_t *buffer, uint8_t length) { - bool ok = true; - - uint8_t l = length; - uint8_t *p = buffer; - - addr |= 0xc0; // read burst - setChipEnableLow(); - ok &= waitForMisoLow(); - sendSpiByte(addr); - while (length-- > 0) { - *buffer++ = sendSpiByte(0); - } - setChipEnableHigh(); - - if (debugPrint.print.readRegisters) { - printf_P(PSTR("\n [readRegisters(0x%02x, ..., %d)] -> "), addr & 0x3f, l); - if (ok) { - while (l-- > 0) { - printf_P(PSTR(" 0x%02x"), *p++); - } - printf_P(PSTR("]")); - } else { - printf_P(PSTR("ERR]")); - } - } - - return ok; - } - - bool Cc1101::readStatusRegister (StatusAddress_t addr, uint8_t *value) { - if (addr < 0x30 || addr > 0x3d) { - return false; - } else { - return readRegisters(addr, value, 1); - } - } - - bool Cc1101::sendData (uint8_t *buffer, uint8_t length) { - timer = 10; - uint8_t ok = true; - uint8_t txbytes; - uint8_t states[16]; uint8_t statesIndex = 0; - // ok &= writeRegister(0x3f, length); - ok &= writeRegisters(0x3f, buffer, length); - ok &= readStatusRegister(TXBYTES, &txbytes); - ok &= (txbytes == 20); - if (ok) { - ok &= strobe(STX); // start sending bytes - // ok &= waitForGD0High(); // wait for start of SYNC - if (ok) { - uint8_t lastState = 0; - uint8_t state; - do { - ok &= readStatusRegister(MARCSTATE, &state); - if (state != lastState && statesIndex < 16) { - states[statesIndex++] = state; - } - lastState = state; - } while (ok && state != 0x13 && timer > 0); - ok &= state == 0x13; // check if in state TX - } - if (ok) { - uint8_t lastTxbytes = 20; - do { - ok &= readStatusRegister(TXBYTES, &txbytes); - if (lastTxbytes != txbytes) { - lastTxbytes = txbytes; - } - } while (ok && txbytes > 0 && timer > 0); - ok &= txbytes == 0; - } - } - if (!ok) { - strobe(SFTX); // flush TXfifo - } else { - uint8_t state; - uint8_t lastState = 0; - do { - ok &= readStatusRegister(MARCSTATE, &state); - if (lastState != state) { - lastState = state; - } - } while (ok && state != 0x01 && timer > 0); - ok &= state == 0x01; // check if in state IDLE - } - // ok &= waitForGD0Low(); // wait for end of package - - if (ok) { - printf_P(PSTR(" States[")); - for (uint8_t i = 0; i < statesIndex; i++) { - printf_P(PSTR(" 0x%02X"), states[i]); - } - printf_P(PSTR("] ")); - } - - return ok; - } - - bool Cc1101::receiveData (uint8_t *buffer, uint8_t *receivedLength, uint8_t maxBufferSize) { - bool ok = true; - STATUS_RXBYTES_t status; - uint8_t lastLength = 0; - uint8_t length = 0; - *receivedLength = 0; - timer = 50; - - this->status.receivePacketStatusValid = 0; - ok &= readStatusRegister(RXBYTES, &status.byte); - if (ok && status.rxbytes.num_rxbytes > 0) { - length = status.rxbytes.num_rxbytes; - - do { - _delay_us(400); // 20 Bytes in 4ms -> 200us/Byte -> CC1101 datasheet page 56: "twice that of which RF bytes are recived" - lastLength = length; - ok &= readStatusRegister(RXBYTES, &status.byte); - if (ok) { - // printf_P(PSTR(" [rxbytes=%d] "), status.byte); - length = status.byte & 0x7f; - } - ok &= timer > 0; - } while (ok && lastLength != length); - - if (ok) { - uint8_t extraBytesCount = this->status.receivePacketStatusEnabled ? 2 : 0; - if ((PACKET_LENGTH + extraBytesCount) != length) { - printf_P(PSTR(" ERROR[receive %d bytes, expect %d bytes] "), *receivedLength, PACKET_LENGTH + extraBytesCount); - *receivedLength = 0; - ok = false; - } else { - printf_P(PSTR(" OK[receive %d bytes] "), length); - *receivedLength = PACKET_LENGTH < maxBufferSize ? length - extraBytesCount : maxBufferSize; - ok &= readRegisters(0xff, buffer, *receivedLength); - if (!ok) { - *receivedLength = 0; - } else { - length -= *receivedLength; - if (length > extraBytesCount) { - printf_P(PSTR(" [WARN: buffer to small] ")); - while (length > extraBytesCount) { - uint8_t byte; - ok &= readRegister(0xff, &byte); - ok = false; - length--; - } - } - if (length > 0) { - ok &= readRegisters(0xff, this->status.receivedPacketStatus.byte, 2); - if (ok) { - this->status.receivePacketStatusValid = 1; - } - } - } - } - } - } - ok &= strobe(SFRX); - - return ok; - } - - - void Cc1101::printRegisters () { - const Register_t *regValues = &PMEM_CC1101_REGISTER_INIT; - printf_P(PSTR("\n")); - for (uint8_t addr = 0; addr < sizeof(Register_t); addr++) { - bool ok = true; - uint8_t regValue, value; - memcpy_P(®Value, ((const uint8_t *)regValues) + addr, 1); - ok &= readRegister(addr, &value); - if (value != regValue) { printf_P(PSTR(" != 0x%02x"), regValue); } - } - uint8_t data[8]; - for (uint8_t addr = 0x30; addr <= 0x3d; addr++) { - readStatusRegister((StatusAddress_t)addr, data); - } - readRegisters(0x3e, data, 8); // PATABLE - } - - bool Cc1101::resetCC1101 () { - bool ok = true; - setChipEnableLow(); - _delay_us(10); - setChipEnableHigh(); - _delay_us(50); - setChipEnableLow(); - ok &= waitForMisoLow(); - ok &= strobe(SRES); - ok &= waitForMisoLow(); - - - return ok; - } - - bool Cc1101::initRegister () { - const Register_t *regValues = &PMEM_CC1101_REGISTER_INIT; - bool ok = true; - // DebugPrint_t tmp = debugPrint.print; - // debugPrint.byte = 0xff; // print all - // printRegisters(); - - for (uint8_t addr = 0; ok && addr < sizeof(Register_t); addr++) { - uint8_t regValue; - memcpy_P(®Value, ((const uint8_t *)regValues) + addr, 1); - ok &= writeRegister(addr, regValue); - if ((addr == 0x07) && (regValue & 0x04)) { - status.receivePacketStatusEnabled = true; - } - } - - // debugPrint.print = tmp; - return ok; - } - - bool Cc1101::initPaTable () { - const PATABLE_INIT_ITEM_t *values = PMEM_CC1101_PATABLE_INIT; - uint8_t patable[8]; - uint8_t initValuesIndex = 0; - for (uint8_t i = 0; i < 8; i++) { - memcpy_P(&patable[i], &(values[initValuesIndex++].pa_power), 1); - if (initValuesIndex >= (sizeof(PMEM_CC1101_PATABLE_INIT) / sizeof(PATABLE_INIT_ITEM_t))) { - initValuesIndex = 0; - } - if (debugPrint.print.writePaTable) { - printf_P(PSTR("\nPTABLE %d: 0x%02x"), i, patable[i]); - } - } - return writeRegisters(0x3e, patable, 8); - } - -#endif - - diff --git a/software/nano-644/test_2024-07-23/src/units/cc1101.hpp b/software/nano-644/test_2024-07-23/src/units/cc1101.hpp deleted file mode 100644 index a861f09..0000000 --- a/software/nano-644/test_2024-07-23/src/units/cc1101.hpp +++ /dev/null @@ -1,281 +0,0 @@ -#ifndef CC1101_HPP -#define CC1101_HPP - -#include -#include "../main.hpp" -#include - -class Cc1101 : public TestUnit { - public: - #define PACKET_LENGTH 20 - - public: - typedef enum { Test, Send, Receive } Cc1101Mode; - typedef enum { _IDLE = 0, _RX = 1, _TX = 2, _FSTXON = 3, _CALIBRATE = 4, _SETTLING = 5, _RXFIFO_OVFL = 6, _TXFIFO_UNFL = 7 } StatusState_t; - typedef struct { uint8_t fifoBytes:4; StatusState_t state:3; uint8_t chipNotReady:1; } Status_t; - typedef struct { int8_t rssi:8; uint8_t lqi:7; uint8_t crcOk:1; } ReceivedPacketStatus_t; // CC1101 datasheet page 37 - union { - struct { - union { - Status_t value; - uint8_t byte; - } spiResponse; - union { - ReceivedPacketStatus_t value; - uint8_t byte [2]; - } receivedPacketStatus; - uint8_t spiResponseValid: 1; - uint8_t receivePacketStatusEnabled:1; - uint8_t receivePacketStatusValid:1; - }; - uint32_t dword; - } status; - - public: - Cc1101 (Cc1101Mode mode) { timer = 0; this->mode = mode; status.dword = 0; } - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName (); - - public: - void tick1ms () { if (timer > 0) timer--; }; - - private: - typedef enum { SRES = 0x30, SCAL = 0x33, SRX = 0x34, STX = 0x35, SFRX = 0x3a, SFTX = 0x3b, SIDLE = 0x36 } StrobeCommand_t; - typedef enum { MARCSTATE = 0x35, TXBYTES = 0x3A, RXBYTES = 0x3B } StatusAddress_t; - typedef struct { uint8_t writeRegister:1; uint8_t writeRegisters:1; uint8_t readRegister:1; uint8_t readRegisters:1; uint8_t writePaTable:1; } DebugPrint_t; - - private: - int8_t runSend (uint8_t subtest); - int8_t runReceive (uint8_t subtest); - int8_t runTest (uint8_t subtest); - uint8_t sendSpiByte (uint8_t b); - void triggerOn(); - void triggerOff(); - void triggerToggle (); - void setChipEnableLow (); - void setChipEnableHigh (); - bool isMisoHigh (); - bool isGd0High (); - bool waitForMisoLow (); - bool waitForGD0High (); - bool waitForGD0Low (); - bool strobe (StrobeCommand_t strobe); - bool writeRegister (uint8_t addr, uint8_t value); - bool writeRegisters (uint8_t addr, uint8_t *buffer, uint8_t length); - bool readRegister (uint8_t addr, uint8_t *value); - bool readRegisters (uint8_t addr, uint8_t *buffer, uint8_t length); - bool readStatusRegister (StatusAddress_t addr, uint8_t *value); - bool sendData (uint8_t *buffer, uint8_t length); - bool receiveData (uint8_t *buffer, uint8_t *receivedLength, uint8_t maxBufferSize); - void printRegisters (); - - bool resetCC1101 (); - bool initRegister (); - bool initPaTable (); - - - private: - Cc1101Mode mode; - uint8_t timer; - union { - DebugPrint_t print; - uint8_t byte; - } debugPrint; - - - public: - typedef enum { - IOCFG2 = 0x00, IOCFG1 = 0x01, IOCFG0 = 0x02, - FIFOTHR = 0x03, - SYNC1 = 0x04, SYNC0 = 0x05, - PKTLEN = 0x06, - PKTCTRL1 = 0x07, PKTCTRL0 = 0x08, - ADDR = 0x00, CHANNR = 0x0a, - FSCTRL1 = 0x0b, FSCTRL0 = 0x0c, - FREQU2 = 0x0d, FREQU1 = 0x0e, FREQU0 = 0x0f, - MDMCFG4 = 0x10, MDMCFG3 = 0x11, MDMCFG2 = 0x12, MDMCFG1 = 0x13, MDMCFG0 = 0x14, - DEVIATN = 0x15, - MCSM2 = 0x16, MCSM1 = 0x17, MCSM0 = 0x18, - FOCCFG = 0x19, BSCFG = 0x1a, - AGCCTRL2 = 0x1b, AGCCTRL1 = 0x1c, AGCCTRL0 = 0x1d, - WOREVT1 = 0x1e, WOREVT0 = 0x1f, WORCTRL = 0x20, - FREND1 = 0x21, FREND0 = 0x22, - FSCAL3 = 0x23, FSCAL2 = 0x24, FSCAL1 = 0x25, FSCAL0 = 0x26, - RCCTRL1 = 0x27, RCCTRL0 = 0x28, - FSTEST = 0x29, PTEST = 0x2a, AGCTEST = 0x2b, - TEST2 = 0x2c, TEST1 = 0x2d, TEST0 = 0x2e - } RegisterAddress_t; - - typedef enum { - RX_FIFO_FILLED_OR_ABOVE_THRESHHOLD = 0x00, - RX_FIFO_FILLED_OR_ABOVE_THRESHHOLD_OR_END_OF_PACKAGE_UNTIL_FIFO_EMPTY = 0x01, - TX_FIFO_FILLED_OR_ABOVE_THRESHHOLD = 0x02, - TX_FIFO_FULL_UNTIL_BELOW_THRESHHOLD = 0x03, - RX_FIFO_OVERFLOW_UNTIL_FIFO_FLUSHED = 0x04, - TX_FIFO_UNDERFLOW_UNTIL_FIFO_FLUSHED = 0x05, - SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET = 0x06, - PACKET_RECEIVED_WITH_CRC_OK_UNTIL_FIRST_BYTE_READ_FROM_RXFIFO = 0x07, - PREAMBLE_QUALITY_REACHED_UNTIL_REENTER_RX = 0x08, - RSSI_LEVEL_BELOW_THRESHOLD = 0x09, - LOCK_DETECTOR_OUTPUT = 0x0a, - SERIAL_CLOCK = 0x0b, - SERIAL_SYNCHRONOUS_DATA_OUTPUT = 0x0c, - SERIAL_ASYNC_DATA_OUTPUT = 0x0d, - CARRIER_DETECTED_UNTIL_ENTER_IDLE = 0x0e, - CRC_OK_UNTIL_REENTER_RX = 0x0f, - RX_HARD_DATA_1 = 0x16, - RX_HARD_DATA_0 = 0x17, - PA_PD = 0x1b, - LNA_PD = 0x1c, - RX_SYMBOL_TICK = 0x1d, - WAKEUP_ON_RECEIVE_EVENT0 = 0x24, - WAKEUP_ON_RECEIVE_EVENT1 = 0x25, - CLK_256 = 0x26, - CLK_32K = 0x27, - CHIP_NOT_READY = 0x29, - XOSC_STABLE = 0x2b, - HIGH_IMPEDANCE_WHEN_CHIP_SELECT_HIGH = 0x2e, - HW_TO_0 = 0x2f, - CLK_XOSC = 0x30, - CLK_XOSC_DIV_1P5 = 0x31, - CLK_XOSC_DIV_2 = 0x32, - CLK_XOSC_DIV_3 = 0x33, - CLK_XOSC_DIV_4 = 0x34, - CLK_XOSC_DIV_6 = 0x35, - CLK_XOSC_DIV_8 = 0x36, - CLK_XOSC_DIV_12 = 0x37, - CLK_XOSC_DIV_16 = 0x38, - CLK_XOSC_DIV_24 = 0x39, - CLK_XOSC_DIV_32 = 0x3a, - CLK_XOSC_DIV_48 = 0x3b, - CLK_XOSC_DIV_64 = 0x3c, - CLK_XOSC_DIV_96 = 0x3d, - CLK_XOSC_DIV_128 = 0x3e, - CLK_XOSC_DIV_192 = 0x3f - } GDOx_CFG_t; - - typedef enum { - SLEEP = 0, - IDLE = 1, - XOFF = 2, - MANCAL_VCOON = 3, - MANCAL_REGON = 4, - MANCAL = 5, - FS_WAKEUP_VCOON = 6, - FS_WAKEUP_REGON = 7, - CALIBRATE_START = 8, - SETTLING_BWBOOST = 9, - SETTLING_FS_LOCK = 10, - SETTLIN_IFADCON = 11, - CALIBRATE_END = 12, - RX = 13, - RX_END = 14, - RX_RST = 15, - TXRX_SETTLING = 16, - RXFIFO_OVERFLOW = 17, - FXTXON = 18, - TX = 19, - TX_END = 20, - RXTX_SETTLING = 21, - TXFIFO_UNDERFLOW = 22, - UNKNOWN = 255 - } MainRadioControlState; - - typedef struct { uint8_t pa_power; const char dbm[4]; } PATABLE_INIT_ITEM_t; - - typedef enum { NO_ADDR_CHECK = 0, CHECK_NO_BROADCAST = 1, CHECK_WITH_BROADCAST_0 = 2, CHECK_WITH_BROADCAST_0_AND_255 = 3 } ADR_CHK_t; - typedef enum { FIXED = 0, VARIABLE = 1, INFINITE = 2 } LENGTH_CONFIG_t; - typedef enum { NORMAL_USE_FIFO = 0, SYNC_SERIAL = 1, RANDOM_TX = 2, ASYNC_SERIAL = 3 } PKT_FORMAT_t; - typedef enum { FSK2 = 0, GFSK = 1, ASK_OOK = 3, FSK4 = 4, MSK = 7 } MOD_FORMAT_t; - typedef enum { NO_SYNC = 0, SYNC_15_16 = 1, SYNC_16_16 = 2, SYNC_30_32 = 3, CARRIER_SENSE = 4, SYNC_15_16_CARRIER_SENSE = 5, SYNC_16_16_CARRIER_SENSE = 6 , SYNC_30_326_CARRIER_SENSE = 7} SYNC_MODE_t; - typedef enum { TWO = 0, THREE = 1, FOUR = 2, SIX = 3, EIGHT = 4, TWELVE = 5, SIXTEEN = 6, TWENTYFOUR = 7 } NUM_PREAMBLE_t; - typedef enum { TXOFF_IDLE = 0, TXOFF_FSTXON = 1, STAY_IN_TX = 2, TXOFF_RX = 3 } TXOFF_MODE_t; - typedef enum { RXOFF_IDLE = 0, RXOFF_FSTXON = 1, RXOFF_TX = 2, STAY_IN_RX = 3 } RXOFF_MODE_t; - typedef enum { ALWAYS = 0, RSSI_BELOW_THRESHOLD = 1, UNLESS_RECEIVE_PACKET = 2, RSSI_BELOW_THRESHOLD__UNLESS_RECEIVE_PACKET = 3 } CCA_MODE_t; - typedef enum { NEVER = 0, IDLE_TO_RX_OR_TX = 1, RX_OR_TX_TO_IDLE = 2, RX_OR_TX_TO_IDLE_EVERY_4_TIME = 3 } FS_AUTOCAL_t; - - typedef struct { GDOx_CFG_t gdo0_cfg:6; uint8_t gdo0_inv:1; uint8_t bit7:1; } IOCFG0_t; - typedef struct { GDOx_CFG_t gdo1_cfg:6; uint8_t gdo1_inv:1; uint8_t bit7:1; } IOCFG1_t; - typedef struct { GDOx_CFG_t gdo2_cfg:6; uint8_t gdo2_inv:1; uint8_t bit7:1; } IOCFG2_t; - typedef struct { uint8_t fifo_thr:4; uint8_t close_in_rx:2; uint8_t adc_retention:1; uint8_t bit7:1; } FIFOTHR_t; - typedef struct { ADR_CHK_t adr_chk:2; uint8_t append_status:1; uint8_t crc_autoflush:1; uint8_t bit4:1; uint8_t pqt:3; } PKTCTRL1_t; - typedef struct { LENGTH_CONFIG_t length_config:2; uint8_t crc_en:1; uint8_t bit3:1; PKT_FORMAT_t pkt_format:2; uint8_t white_data:1; uint8_t bit7:1; } PKTCTRL0_t; - typedef struct { uint8_t frequ_if:5; uint8_t bit5:1; uint8_t bit76:2; } FSCTRL1_t; - typedef struct { uint8_t frequoff:8; } FSCTRL0_t; - typedef struct { uint8_t drate_e:4; uint8_t chanbw_m:2; uint8_t chanbw_e:2; } MDMCFG4_t; - typedef struct { uint8_t drate_m:8; } MDMCFG3_t; - typedef struct { SYNC_MODE_t sync_mode:3; uint8_t manchester_en:1; MOD_FORMAT_t mod_format:3; uint8_t dem_dcfilt_off:1; } MDMCFG2_t; - typedef struct { uint8_t chanspc_e:2; uint8_t bit32:2; NUM_PREAMBLE_t num_preamble:3; uint8_t fec_en:1; } MDMCFG1_t; - typedef struct { uint8_t chanspc_m:8; } MDMCFG0_t; - typedef struct { uint8_t deviation_m:3; uint8_t bit3:1; uint8_t deviation_e:3; uint8_t bit7:1; } DEVIATN_t; - typedef struct { uint8_t rx_time:3; uint8_t rx_time_qual:1; uint8_t rx_time_rssi:1; uint8_t bit765:3; } MCSM2_t; - typedef struct { TXOFF_MODE_t txoff_mode:2; RXOFF_MODE_t rxoff_mode:2; CCA_MODE_t cca_mode:2; uint8_t bit76:2; } MCSM1_t; - typedef struct { uint8_t xosc_force_on:1; uint8_t pin_ctrl_en:1; uint8_t po_timeout:2; FS_AUTOCAL_t fs_autocal:2; uint8_t bit76:2; } MCSM0_t; - typedef struct { uint8_t pa_power:3; uint8_t bit3:1; uint8_t lodiv_buf_current:2; uint8_t bit76:2; } FREND0_t; - - typedef union { - uint8_t byte; - struct { - uint8_t num_rxbytes:7; - uint8_t rxfifo_overflow:1; - } rxbytes; - } STATUS_RXBYTES_t; - - typedef struct { - IOCFG2_t iocfg2; - IOCFG1_t iocfg1; - IOCFG0_t iocfg0; - FIFOTHR_t fifothr; - uint8_t sync1; - uint8_t sync0; - uint8_t pktlen; - PKTCTRL1_t pktctrl1; - PKTCTRL0_t pktctrl0; - uint8_t addr; - uint8_t channr; - FSCTRL1_t fsctrl1; - FSCTRL0_t fsctrl0; - uint8_t frequ2; - uint8_t frequ1; - uint8_t frequ0; - MDMCFG4_t mdmcfg4; - MDMCFG3_t mdmcfg3; - MDMCFG2_t mdmcfg2; - MDMCFG1_t mdmcfg1; - MDMCFG0_t mdmcfg0; - DEVIATN_t deviatn; - MCSM2_t mcsm2; - MCSM1_t mcsm1; - MCSM0_t mcsm0; - uint8_t foccfg; - uint8_t bscfg; - uint8_t agcctrl2; - uint8_t agcctrl1; - uint8_t agcctrl0; - uint8_t worevt1; - uint8_t worevt0; - uint8_t worctrl; - uint8_t frend1; - FREND0_t frend0; - uint8_t fscal3; - uint8_t fscal2; - uint8_t fscal1; - uint8_t fscal0; - uint8_t rcctrl1; - uint8_t rcctrl0; - uint8_t fstest; - uint8_t ptest; - uint8_t agctest; - uint8_t test2; - uint8_t test1; - uint8_t test0; - - } Register_t; - - - -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/encoder.cpp b/software/nano-644/test_2024-07-23/src/units/encoder.cpp deleted file mode 100644 index 7b33b76..0000000 --- a/software/nano-644/test_2024-07-23/src/units/encoder.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include - -#include "encoder.hpp" -#include "../main.hpp" - -// Encoder signals on rotation clockwise 1 step: -// A -----____------ one char app. 1ms..2ms (rotation speed) -// B -------___----- -// one step when: A = 0, B= 1->0 - -// Encoder signals on rotation counterclockwise 1 step: -// A -----____------ one char app. 1ms..2ms (rotation speed) -// B --______----- -// one step when: A = 0, B= 0->1 - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - - // Nano-644 - // --------------------------------------------------------------- - // PB0/T0 ... Encoder A - // PB1/T1 ... Encoder B - // PB2/INT2 ... push switch of encoder (pushed = 0) - - void Encoder::init () { - DDRB &= ~((1 << PB2) | (1 << PB1) | (1 << PB0)); - PORTB |= (1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0); // enable pullup - enabled = 1; - } - - void Encoder::cleanup () { - enabled = 0; - DDRB &= ~((1 << PB2) | (1 << PB1) | (1 << PB0)); - PORTB &= ~((1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0)); - } - - bool Encoder::isPressed () { - return (PINB & (1 << PB2)) == 0; - } - - bool Encoder::getA () { - return (PINB & (1 << PB0)) == 0; - } - - bool Encoder::getB () { - return (PINB & (1 << PB1)) == 0; - } - - -#endif - -#ifdef __AVR_ATmega328P__ - - // Arduino-Nano-5V - // --------------------------------------------------------------- - // PD4/T0 ... Encoder A - // PB0 ... Encoder B - // PD7 ... push switch of encoder (pushed = 0) - - void Encoder::init () { - DDRB &= ~(1 << PB0); - DDRD &= ~((1 << PD7) | (1 << PD4)); - PORTB |= (1 << PB0); // enable pullup - PORTD |= (1 << PD7) | (1 << PD4); // enable pullup - enabled = 1; - } - - void Encoder::cleanup () { - enabled = 0; - PORTB &= ~(1 << PB0); - PORTD &= ~((1 << PD7) | (1 << PD4)); - DDRB &= ~(1 << PB0); - DDRD &= ~((1 << PD7) | (1 << PD4)); - } - - bool Encoder::isPressed () { - return (PIND & (1 << PD7)) == 0; - } - - bool Encoder::getA () { - return (PIND & (1 << PD4)) == 0; - } - - bool Encoder::getB () { - return (PINB & (1 << PB0)) == 0; - } - -#endif - - -int8_t Encoder::run (uint8_t subtest) { - switch (subtest) { - case 0: { - while (wait(10) == EOF) { - printf_P(PSTR("\r => Encoder (push to clear): ")); - printf_P(PSTR("%5d (0x%02x) "), count, (uint8_t)count); - if (isPressed()) { - reset(); - } - } - return 0; - } - } - - return -1; -} - -struct EncoderState { - int8_t a:1; // signal A - int8_t b:1; // signal B -}; - -void Encoder::tick100us () { - static EncoderState lastState = { 1, 1 }; - static EncoderState lastStableState = { 1, 1 }; - - if (!enabled) { - count = 0; - return; - } - EncoderState nextState; - nextState.a = getA() ? 1 : 0; - nextState.b = getB() ? 1 : 0; - if (nextState.a == lastState.a && nextState.b == lastState.b) { - if (lastStableState.a == 0 && nextState.b != lastStableState.b) { - if (nextState.b == 0) { - count = count < 127 ? count + 1 : 127; - } else { - count = count > -128 ? count - 1 : -128; - } - } - lastStableState.a = nextState.a; - lastStableState.b = nextState.b; - } - lastState.a = nextState.a; - lastState.b = nextState.b; -} - diff --git a/software/nano-644/test_2024-07-23/src/units/encoder.hpp b/software/nano-644/test_2024-07-23/src/units/encoder.hpp deleted file mode 100644 index 9b0861b..0000000 --- a/software/nano-644/test_2024-07-23/src/units/encoder.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef ENCODER_HPP -#define ENCODER_PP - -#include -#include "../main.hpp" -#include - -class Encoder : public TestUnit { - public: - uint8_t enabled; - int8_t count; - - public: - Encoder () { reset(); enabled = 0; }; - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName () { return PSTR("Encoder"); } - void reset () { count = 0; } - void tick100us (); - bool isPressed (); - - private: - bool getA (); - bool getB (); -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/i2c.cpp b/software/nano-644/test_2024-07-23/src/units/i2c.cpp deleted file mode 100644 index 60dd22d..0000000 --- a/software/nano-644/test_2024-07-23/src/units/i2c.cpp +++ /dev/null @@ -1,216 +0,0 @@ -#include -#include -#include -#include -#include - -#include "i2c.hpp" -#include "../adafruit/bme280.h" -#include "../main.hpp" - -// Sparkfun https://www.sparkfun.com/products/22858 -// ENS160 address 0x53 (air quality sensor) -// BME280 address 0x77 /humidity/temperature sensor) -// register 0xfe: humidity_7:0 -// register 0xfd: humidity_15:8 - -PGM_P I2c::getName () { - switch (mode) { - case SparkFunEnvCombo: return PSTR("I2C-Sparkfun Env-Combo"); - case Master: return PSTR("I2C-Master"); - case Slave: return PSTR("I2C-Slave"); - } - return "?"; -} - -void I2c::init () { - TWBR = 13; // 100kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 100000) / (2 * 100000 * 4); - TWBR = 28; // 50kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 50000) / (2 * 50000 * 4); - TWBR = 100; // 50kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 50000) / (2 * 50000 * 4); - TWCR = (1 << TWEN); - ADMUX = (1 << ADLAR) | (1 << REFS0); // ADC0, VREF=AVCC=3.3V - ADCSRA = (1 << ADEN) | 7; // ADC Enable, Prescaler 128 - enabled = true; -} - -void I2c::cleanup () { - enabled = false; - TWCR = (1 << TWEN); - TWBR = 0; - ADMUX = 0; - ADCSRA = 0; -} - -int8_t I2c::run (uint8_t subtest) { - if (subtest == 0 && mode == I2c::SparkFunEnvCombo) { - printf_P(PSTR(" BM280 ... ")); - if (!bm280.begin()) { - printf_P(PSTR("E1")); - return -1; - } - printf_P(PSTR("OK, ENS160 ... ")); - if (!ens160.begin()) { - printf_P(PSTR("E2")); - return -1; - } - if (!ens160.setMode(ENS160_OPMODE_STD)) { - printf_P(PSTR("E3")); - return -1; - } - if (!ens160.set_envdata(25.0, 65)) { - printf_P(PSTR("E4")); - return -1; - } - - printf_P(PSTR("OK")); - float accTemp = 0, accHumidity = 0; - int8_t accCount = -1; - - do { - // BME280 - float p = bm280.readPressure(); - printf_P(PSTR("\n => BM280: P= %.3fbar"), (double)p / 100000.0); - float t = bm280.readTemperature(); - printf_P(PSTR(", T= %.2f°C"), (double)t); - float h = bm280.readHumidity(); - printf_P(PSTR(", H= %.2f%%"), (double)h); - - if (accCount >= 0 && !isnanf(h) && !isnan(t)) { - accTemp += t; - accHumidity += h; - accCount++; - } - - bm280.setSampling( - Adafruit_BME280::MODE_NORMAL, - Adafruit_BME280::SAMPLING_X16, - Adafruit_BME280::SAMPLING_X16, - Adafruit_BME280::SAMPLING_X16, - Adafruit_BME280::FILTER_OFF, - Adafruit_BME280::STANDBY_MS_1000 - ); - - // ENS160 only activated every 32s to avoid wrong temperature measuerment - // if ES160 would be continously active, the temperature would be 4°C higher - // -> ES160 has not enough distance to BM280 - // This solution causes only a +0.3°C higher temperatur value - if (accCount < 0 || accCount >= 32) { - printf_P(PSTR(" | ENS160 (")); - if (accCount > 0) { - h = accHumidity / accCount; - t = accTemp / accCount; - accTemp = 0; - accHumidity = 0; - } - accCount = 0; - if (!ens160.set_envdata(t, h)) { - printf_P(PSTR("E1)")); - } else { - printf_P(PSTR("%.1f°C/%.1f%%): "), (double)t, (double)h); - if (!ens160.setMode(ENS160_OPMODE_STD)) { - printf_P(PSTR("E2")); - } else { - for (uint8_t i = 0; i < 100; i++) { - _delay_ms(15); - uint8_t status; - if (ens160.readStatus(&status)) { - if (status & ENS160_DATA_STATUS_NEWDAT) { - ENS160_DATA data; - if (ens160.readData(&data)) { - printf_P(PSTR(" aqi=%d("), data.aqi); - switch(data.aqi) { - case 1: printf_P(PSTR("excellent")); break; - case 2: printf_P(PSTR("good")); break; - case 3: printf_P(PSTR("moderate")); break; - case 4: printf_P(PSTR("poor")); break; - case 5: printf_P(PSTR("unhealthy")); break; - default: printf_P(PSTR("?")); break; - } - printf_P(PSTR("), tvoc=%dppb"), data.tvoc); - printf_P(PSTR(", eco2=%d("), data.eco2); - if (data.eco2 < 400) { - printf_P(PSTR("?")); - } else if (data.eco2 < 600) { - printf_P(PSTR("excellent")); - } else if (data.eco2 < 800) { - printf_P(PSTR("good")); - } else if (data.eco2 < 1000) { - printf_P(PSTR("fair")); - } else if (data.eco2 < 1500) { - printf_P(PSTR("poor")); - } else { - printf_P(PSTR("bad")); - } - printf_P(PSTR(")")); - } - break; - } - } - } - } - if (!ens160.setMode(ENS160_OPMODE_IDLE)) { - printf_P(PSTR("E3")); - } - } - } - - } while (wait(1000) == EOF); - - } else if (subtest == 0 && mode == I2c::Master) { - if (!master.begin(0x01)) { - printf_P(PSTR("E1")); - return -1; - } - do { - uint8_t buffer[1]; - // read poti - ADCSRA |= (1 << ADSC); // start ADC - while (ADCSRA & (1 << ADSC)) {} // wait for result - buffer[0] = ADCH; - printf_P(PSTR("\n I2C-MASTER: to slave: 0x%02x"), buffer[0]); - if (!master.write(buffer, 1)) { - printf_P(PSTR(" -> ERROR")); - } - printf_P(PSTR(", from slave: ")); - if (master.read(buffer, 1)) { - printf_P(PSTR("0x%02x"), buffer[0]); - } else { - printf_P(PSTR(" -> ERROR")); - } - } while (wait(1000) == EOF); - master.end(); - - } else if (subtest == 0 && mode == I2c::Slave) { - if (!slave.begin(0x01, false)) { - printf_P(PSTR("E1")); - return -1; - } - do { - int fromMaster = slave.read(); - if (fromMaster != EOF) { - ADCSRA |= (1 << ADSC); // start ADC - while (ADCSRA & (1 << ADSC)) {} // wait for result - slave.write(ADCH); - printf_P(PSTR("\n I2C SLAVE: from master: 0x%02x -> to master: 0x%02x"), fromMaster, ADCH); - } - } while (wait(0) == EOF); - slave.end(); - - } else { - printf_P(PSTR("end")); - return -1; - } - wait(500); - return 0; -} - -void I2c::handleTwiIrq () { - if (mode == I2c::Slave) { - DDRD |= (1 << PD7); - PORTD |= (1 << PD7); - slave.handleTWIIsr(); - PORTD &= ~(1 << PD7); - } else { - TWCR |= (1 << TWINT); // clear Interrupt Request - } -} diff --git a/software/nano-644/test_2024-07-23/src/units/i2c.hpp b/software/nano-644/test_2024-07-23/src/units/i2c.hpp deleted file mode 100644 index 2148cc0..0000000 --- a/software/nano-644/test_2024-07-23/src/units/i2c.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef I2C_HPP -#define I2C_HPP - -#include -#include "../main.hpp" -#include "../adafruit/bme280.h" -#include "../adafruit/ens160.h" -#include "../i2cmaster.hpp" -#include "../i2cslave.hpp" - - -class I2c : public TestUnit { - public: - typedef enum I2cMode { SparkFunEnvCombo, Master, Slave } I2cMode; - - private: - I2cMode mode; - Adafruit_BME280 bm280; - ScioSense_ENS160 ens160; - I2cMaster master; - I2cSlave slave; - - public: - bool enabled; - - public: - I2c (I2cMode mode) { enabled = false; this->mode = mode; } - void tick1ms () { master.tick1ms(); slave.tick1ms(); } - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName (); - void handleTwiIrq (); - // uint16_t startRead (uint8_t address); - // uint16_t startWrite (uint8_t address); - // void stop (); - // uint16_t writeByte (uint8_t data); - // uint16_t writeData (uint8_t size, const uint8_t *data); - // uint16_t readData (uint8_t size, uint8_t *data); - // int32_t compensateBm280T (int32_t adcT); -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/ieee485.cpp b/software/nano-644/test_2024-07-23/src/units/ieee485.cpp deleted file mode 100644 index 8fcb67a..0000000 --- a/software/nano-644/test_2024-07-23/src/units/ieee485.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include -#include -#include -#include - -#include "ieee485.hpp" -#include "../main.hpp" - -#ifdef __AVR_ATmega328P__ - -// Nano-328P -// ------------------------------------ -// IEE485 not supported (no UART1) - -void Ieee485::init () {} -void Ieee485::cleanup () {} -int8_t Ieee485::run (uint8_t subtest) { - return -1; -} - -#endif - - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - -// Nano-644 -// ------------------------------------ -// PB0 ... nRE .. Read enable -// PB1 ... DE .. Data enable - -#define SET_nRE (PORTB |= (1 << PB0)) -#define CLR_nRE (PORTB &= ~(1 << PB0)) -#define SET_DE (PORTB |= (1 << PB1)) -#define CLR_DE (PORTB &= ~(1 << PB1)) - -void Ieee485::init () { - // Poti - ADMUX = (1 << ADLAR) | (1 << REFS0); // ADC0, VREF=AVCC=3.3V - ADCSRA = (1 << ADEN) | 7; // ADC Enable, Prescaler 128 - - // Modbus - SET_nRE; - CLR_DE; - DDRB |= (1 << PB1) | (1 << PB0); - - // UART1 interface on Nano-644 - PORTD |= (1 << PD2); // enable RxD1 pullup - UCSR1A = (1 << U2X1); - UCSR1B = (1 << RXCIE1) | (1 << RXEN1) | (1 < send Byte 0x%02x"), ADCH); - int b; - ATOMIC_BLOCK(ATOMIC_FORCEON) { - b = receivedByte; - receivedByte = -1; - } - if (b >= 0) { - printf_P(PSTR("\n => receive Byte: 0x%02x"), b); - } - } - - } else { - printf_P(PSTR("end")); - return -1; - } - - return 0; -} - -void Ieee485::handleRxByte (uint8_t b) { - receivedByte = b; -} - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/ieee485.hpp b/software/nano-644/test_2024-07-23/src/units/ieee485.hpp deleted file mode 100644 index ffbb15c..0000000 --- a/software/nano-644/test_2024-07-23/src/units/ieee485.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef IEEE485_HPP -#define IEEE485_HPP - -#include -#include "../main.hpp" -#include - -class Ieee485 : public TestUnit { - public: - uint8_t enabled; - int16_t receivedByte; - - public: - Ieee485 () { enabled = 0; receivedByte = -1; } - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual const char *getName () { return PSTR("IEEE485"); } - void handleRxByte (uint8_t); -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/lcd.cpp b/software/nano-644/test_2024-07-23/src/units/lcd.cpp deleted file mode 100644 index e779c16..0000000 --- a/software/nano-644/test_2024-07-23/src/units/lcd.cpp +++ /dev/null @@ -1,443 +0,0 @@ -#include -#include -#include - -#include "lcd.hpp" -#include "../main.hpp" - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - - // Nano-644 / Nano-1284 - // --------------------------------------------------------------- - - // Nano-X-Base V1a V2a Beschreibung - // --------------------------------- ------- - // BL ........... PC0 PC0 Backlight ON(=1) / OFF(=0) - // E ........... PA3 PA3 LCD Enable (Verbindung via J25 erforderlich) - // R/W .......... PD6 PD6 Read/Write: Read=1, Write=0 - // RS ........... PD7 PD7 Register Select: Command=0, Data=1 - // Data ......... PB7:0 PB7:0 Achtung von 5V LCD nicht lesen! - - void Lcd::init () { - DDRA |= (1 << PA3) | (1 << PA0); - DDRB = 0xff; - DDRD |= (1 << PD7) | (1 << PD6); - initLcd(); - printf_P(PSTR("init LCD (")); - if (status == 1) { - printf_P(PSTR("OK)")); - } else { - printf_P(PSTR("ERROR %d)"), status); - } - setBacklightOn(); - } - - void Lcd::cleanup () { - clear(); - PORTA &= ~((1 << PA3) | (1 << PA0)); - DDRA &= ~((1 << PA3) | (1 << PA0)); - PORTB = 0; - DDRB = 0; - PORTD &= ~((1 << PD7) | (1 << PD6)); - DDRD &= ~((1 << PD7) | (1 << PD6)); - } - - void Lcd::setRS () { PORTD |= (1 << PD7); } - void Lcd::clrRS () { PORTD &= ~(1 << PD7); } - void Lcd::setRW () { PORTD |= (1 << PD6); } - void Lcd::clrRW () { PORTD &= ~(1 << PD6); } - void Lcd::setE () { PORTA |= (1 << PA3); } - void Lcd::clrE () { PORTA &= ~(1 << PA3); } - void Lcd::dataDirectionOut () { DDRB = 0xff; } - - void Lcd::dataDirectionIn () { - if (hardwareVersion == 1) { - // read back not allowed (missing level shifter 5V -> 3.3V) - DDRB = 0xff; - } else { - DDRB = 0x00; - } - } - - uint8_t Lcd::getData () { - if (hardwareVersion == 1) { - // read back not allowed (missing level shifter 5V -> 3.3V) - _delay_ms(1); - return 0x00; // bit 8 (busy) = 0 - } else { - return PINB; - } - } - - void Lcd::setData (uint8_t data) { - PORTB = data; - } - - void Lcd::setBacklightOn () { - PORTA |= (1 << PA0); - } - - void Lcd::setBacklightOff () { - PORTA &= ~(1 << PA0); - } - -#endif - -#ifdef __AVR_ATmega328P__ - - // Arduino Nano (5V) - // --------------------------------------------------------------- - - // Nano-X-Base V1a V2a Beschreibung - // --------------------------------- ------- - // BL ........... PC0 PC0 Backlight ON(=1) / OFF(=0) - // E ........... PC3 PC3 LCD Enable (Verbindung via J25 erforderlich) - // R/W .......... PD3 PD3 Read/Write: Read=1, Write=0 - // RS ........... PD2 PD2 Register Select: Command=0, Data=1 - // Data0 ........ PD4 PD4 - // Data1 .........PB0 PB0 - // Data2 .........PD7 PD7 - // Data3 .........PD6 PD6 - // Data4 .........PB2 PB2 - // Data5 .........PB3 PB3 - // Data6 .........PB4 PB4 - // Data7 .........PB5 PB5 - - // PC3 ..... E --> LCD Enable (Verbindung via J25 erforderlich) - // PD3 ..... R/W --> Read/Write: Read=1, Write=0 - // PD2 ..... RS --> Register Select: Command=0, Data=1 - - - void Lcd::init () { - clrRW(); - clrRS(); - clrE(); - setData(0); - DDRB |= (1 << PB5) | (1 << PB4) | (1 << PB3) | (1 << PB2) | (1 << PB0); - DDRC |= (1 << PC3) | (1 << PC0); - DDRD |= (1 << PD7) | (1 << PD6) | (1 << PD4) | (1 << PD3) | (1 << PD2); - initLcd(); - printf_P(PSTR("init LCD (")); - if (status == 1) { - printf_P(PSTR("OK)")); - } else { - printf_P(PSTR("ERROR %d)"), status); - } - setBacklightOn(); - } - - void Lcd::cleanup () { - clear(); - PORTB &= ~((1 << PB5) | (1 << PB4) | (1 << PB3) | (1 << PB2) | (1 << PB0)); - PORTC &= ~((1 << PC3) | (1 << PC0)); - PORTD &= ~((1 << PD7) | (1 << PD6) | (1 << PD4) | (1 << PD3) | (1 << PD2)); - DDRB &= ~((1 << PB5) | (1 << PB4) | (1 << PB3) | (1 << PB2) | (1 << PB0)); - DDRC &= ~((1 << PC3) | (1 << PC0)); - DDRD &= ~((1 << PD7) | (1 << PD6) | (1 << PD4) | (1 << PD3) | (1 << PD2)); - } - - void Lcd::setRS () { PORTD |= (1 << PD2); } - void Lcd::clrRS () { PORTD &= ~(1 << PD2); } - void Lcd::setRW () { PORTD |= (1 << PD3); } - void Lcd::clrRW () { PORTD &= ~(1 << PD3); } - void Lcd::setE () { PORTC |= (1 << PC3); } - void Lcd::clrE () { PORTC &= ~(1 << PC3); } - - void Lcd::setData (uint8_t data) { - if (data & 0x01) PORTD |= (1 << PD4); else PORTD &= ~((1 << PD4)); - if (data & 0x02) PORTB |= (1 << PB0); else PORTB &= ~((1 << PB0)); - if (data & 0x04) PORTD |= (1 << PD7); else PORTD &= ~((1 << PD7)); - if (data & 0x08) PORTD |= (1 << PD6); else PORTD &= ~((1 << PD6)); - if (data & 0x10) PORTB |= (1 << PB2); else PORTB &= ~((1 << PB2)); - if (data & 0x20) PORTB |= (1 << PB3); else PORTB &= ~((1 << PB3)); - if (data & 0x40) PORTB |= (1 << PB4); else PORTB &= ~((1 << PB4)); - if (data & 0x80) PORTB |= (1 << PB5); else PORTB &= ~((1 << PB5)); - } - - void Lcd::dataDirectionOut () { - if (!mode4Bit) { - DDRB |= (1 << PB0); - DDRD |= ((1 << PD7) | (1 << PD6) | (1 << PD4)); - } - DDRB |= ((1 << PB5) | (1 << PB4) | (1 << PB3) | (1 << PB2)); - } - - void Lcd::dataDirectionIn () { - if (hardwareVersion == 1) { - // read back not allowed (missing level shifter 5V -> 3.3V) - dataDirectionOut(); - } else { - if (!mode4Bit) { - DDRB &= ~(1 << PB0); - DDRD &= ~((1 << PD7) | (1 << PD6) | (1 << PD4)); - } - DDRB &= ~((1 << PB5) | (1 << PB4) | (1 << PB3) | (1 << PB2)); - } - } - - uint8_t Lcd::getData () { - if (hardwareVersion == 1) { - // read back not allowed (missing level shifter 5V -> 3.3V) - _delay_ms(1); - return 0x00; // bit 8 (busy) = 0 - } else { - uint8_t b = 0; - b |= ((PIND & (1 << PD4)) != 0) << 0; - b |= ((PINB & (1 << PB0)) != 0) << 1; - b |= ((PIND & (1 << PD7)) != 0) << 2; - b |= ((PIND & (1 << PD6)) != 0) << 3; - b |= ((PINB & (1 << PB2)) != 0) << 4; - b |= ((PINB & (1 << PB3)) != 0) << 5; - b |= ((PINB & (1 << PB4)) != 0) << 6; - b |= ((PINB & (1 << PB5)) != 0) << 7; - return b; - } - } - - void Lcd::setBacklightOn () { - PORTC |= (1 << PC0); - } - - void Lcd::setBacklightOff () { - PORTC &= ~(1 << PC0); - } - -#endif - -// Befehle für das Display - -#define DISP_CLEAR 0b00000001 // Display clear -#define DISP_ON 0b00001111 // Display on -#define DISP_OFF 0b00001011 // Display off -#define CURSOR_ON 0b00001111 // Cursor on -#define CURSOR_OFF 0b00001101 // Cursor off -#define BLINK_ON 0b00001111 // Cursor Blink -#define BLINK_OFF 0b00001110 // Cursor No Blink - -#define LCD_PULSE_LENGTH 15 -#define LCD_CMD_DISPLAY_CLEAR 0x01 // Display clear -#define LCD_CMD_CURSOR_HOME 0x02 // Move cursor digit 1 -#define LCD_CMD_SET_ENTRY_MODE 0x04 // Entry Mode Set -#define LCD_CMD_DISPLAY_ON_OFF 0x08 // Display on/off -#define LCD_CMD_SHIFT 0x10 // Display shift -#define LCD_CMD_SET_MODE4BIT 0x20 // 4/8 Bits... -#define LCD_CMD_SET_CGRAM_ADDR 0x40 // Character Generator ROM -#define LCD_CMD_SET_DDRAM_ADDR 0x80 // Display Data RAM -#define LCD_BUSY_FLAG 0x80 - - - -int8_t Lcd::run (uint8_t subtest) { - if (subtest == 0) { - for (uint8_t i = 0; i < 20 * 4; i++) { - char c = (char)(i + 32); - if (i % 20 == 0) { - setCursor(i / 20, 0); - } - putChar(c); - waitOnReady(); - } - printf_P(PSTR("LCD ")); - if (status == 1) { - printf_P(PSTR("OK")); - } else { - printf_P(PSTR("ERROR(%d)"), status); - } - while (wait(1) == EOF) { - } - - } else { - printf_P(PSTR("end")); - return -1; - } - wait(500); - return 0; -} - - -void Lcd::initLcd () { - - setData(0x00); - dataDirectionOut(); - - _delay_ms(16); // min 15ms warten für Reset des Displays - status = 0; - for (uint8_t i = 0; i < 4; i++) { - if (mode4Bit) { - setRegister(LCD_CMD_SET_MODE4BIT | 0x08); // 4 Bit, 2/4 Zeilen, 5x7 - } else { - setRegister(0x08); // 8 Bit, 2 Zeilen, 5x7 - } - if (i == 0) { - _delay_ms(5); - } else { - _delay_us(100); - } - } - - setRegister(LCD_CMD_DISPLAY_ON_OFF | 0x04); // display on, cursor off - if (!isReady(50)) { - status = -1; - return; - } - - setRegister(LCD_CMD_DISPLAY_ON_OFF | 0x04); // display on, cursor off - if (!isReady(50)) { - status = -3; - return; - } - - setRegister(LCD_CMD_DISPLAY_CLEAR); - if (!isReady(1200)) { - status = -4; - return; - } - - status = 1; -} - -void Lcd::setRegister (uint8_t cmd) { - clrRW(); - clrRS(); - writeData(cmd); -} - -void Lcd::writeData (uint8_t data) { - clrE(); - dataDirectionOut(); - if (mode4Bit) { - setData(data & 0xf0); // send High-Nibble - setE(); - _delay_us(LCD_PULSE_LENGTH); - clrE(); - _delay_us(1); - setData(data << 4); // send Low-Nibble - } else { - setData(data); // send data byte - } - setE(); - _delay_us(LCD_PULSE_LENGTH); - clrE(); - _delay_us(1); -} - -void Lcd::setDRAddr (uint8_t address) { - waitOnReady(); - setRegister(LCD_CMD_SET_DDRAM_ADDR | address); - waitOnReady(); -} - -void Lcd::waitOnReady () { - if (isReady(50) == 0) { - status = -6; - } -} - -bool Lcd::isReady (uint16_t us) { - if (status < 0) { - return false; - } - if (hardwareVersion == 1) { - // read back not allowed (missing level shifter) - _delay_ms(1); - return true; - } - - uint8_t busy; - dataDirectionIn(); - setData(0xff); // enable internal pull up - - do { - uint8_t data = 0; - setRW(); - clrRS(); - - _delay_us(1); - setE(); - _delay_us(LCD_PULSE_LENGTH); - data = getData() & 0xf0; // High Nibble - clrE(); - - _delay_us(1); - setE(); - _delay_us(LCD_PULSE_LENGTH); - data |= getData() >> 4; // Low Nibble - - clrE(); - _delay_us(1); - clrRW(); - - busy = data & LCD_BUSY_FLAG; - us = (us >= 11) ? us - 11 : 0; - } while (us > 0 && busy); - - if (status == 1 && busy) { - status = -5; - } - - setData(0x00); - dataDirectionOut(); - - return busy == 0; -} - - -void Lcd::setDisplayOn () { - if (status != 1) { - return; - } - waitOnReady(); - setRegister(LCD_CMD_DISPLAY_ON_OFF | 0x04); // display on - waitOnReady(); -} - -void Lcd::setDisplayOff () { - if (status != 1) { - return; - } - waitOnReady(); - setRegister(LCD_CMD_DISPLAY_ON_OFF); // display off - waitOnReady(); -} - -void Lcd::clear () { - if (status != 1) { - return; - } - waitOnReady(); - setRegister(LCD_CMD_DISPLAY_CLEAR); - waitOnReady(); -} - -void Lcd::setCursor (uint8_t rowIndex, uint8_t columnIndex) { - if (status != 1 || columnIndex >= 20) { - return; - } - uint8_t b; - switch (rowIndex) { - case 0: b = 0x00 + columnIndex; break; - case 1: b = 0x40 + columnIndex; break; - case 2: b = 0x14 + columnIndex; break; - case 3: b = 0x54 + columnIndex; break; - default: return; - } - setDRAddr(b); - waitOnReady(); -} - -void Lcd::putChar (char c) { - if (status != 1) { - return; - } - clrRW(); - setRS(); - writeData(c); - clrRS(); - waitOnReady(); -} - -void Lcd::puts (const char * str) { - while (*str && status == 1) { - putChar(*str++); - } -} \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/lcd.hpp b/software/nano-644/test_2024-07-23/src/units/lcd.hpp deleted file mode 100644 index 47a30cc..0000000 --- a/software/nano-644/test_2024-07-23/src/units/lcd.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef LCD_HPP -#define LCD_HPP - -#include -#include "../main.hpp" -#include - -class Lcd : public TestUnit { - public: - Lcd () { mode4Bit = hardwareVersion == 1 ? false : true; status = 0; }; - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName () { return PSTR("Lcd"); } - - private: - bool mode4Bit; - int8_t status; - - void initLcd (); - void setRegister (uint8_t cmd); - void setDRAddr (uint8_t address); - void writeData (uint8_t data); - void waitOnReady (); - bool isReady (uint16_t us); - void setDisplayOn (); - void setDisplayOff (); - void clear (); - void setCursor (uint8_t rowIndex, uint8_t columnIndex); - void putChar (char c); - void puts (const char * str); - - void setRS (); - void clrRS (); - void setRW (); - void clrRW (); - void setE (); - void clrE (); - uint8_t getData (); - void setData (uint8_t data); - void dataDirectionIn (); - void dataDirectionOut (); - void setBacklightOn (); - void setBacklightOff (); - -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/led.cpp b/software/nano-644/test_2024-07-23/src/units/led.cpp deleted file mode 100644 index e908c21..0000000 --- a/software/nano-644/test_2024-07-23/src/units/led.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include -#include -#include - -#include "led.hpp" -#include "../main.hpp" - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - - // Nano-644 / Nano 1284 - // --------------------------------------------------------------- - - // Nano-X-Base V1a V2a - // ----------------------- - // Red PD4 PD7 - // Orange/Yellow PD5 PD6 - // Green PD6 PD5 - // Blue PD7 PD4 - - void Led::init () { - PORTD &= ~((1 << PD7) | (1 << PD6) | (1 << PD5) | (1 << PD4)); - DDRD |= (1 << PD7) | (1 << PD6) | (1 << PD5) | (1 << PD4); - } - - void Led::cleanup () { - DDRD &= ~((1 << PD7) | (1 << PD6) | (1 << PD5) | (1 << PD4)); - PORTD &= ~((1 << PD7) | (1 << PD6) | (1 << PD5) | (1 << PD4)); - } - - void Led::setLed (LED led, bool on) { - if (on) { - switch(led) { - case RED: PORTD |= (1 << PD4); break; - case ORANGE: PORTD |= (1 << PD5); break; - case GREEN: PORTD |= (1 << PD6); break; - case BLUE: PORTD |= (1 << PD7); break; - } - } else { - switch(led) { - case RED: PORTD &= ~(1 << PD4); break; - case ORANGE: PORTD &= ~(1 << PD5); break; - case GREEN: PORTD &= ~(1 << PD6); break; - case BLUE: PORTD &= ~(1 << PD7); break; - } - } - } - - void Led::ledToggle (LED led) { - switch(led) { - case RED: PORTD ^= (1 << PD4); break; - case ORANGE: PORTD ^= (1 << PD5); break; - case GREEN: PORTD ^= (1 << PD6); break; - case BLUE: PORTD ^= (1 << PD7); break; - } - } - -#endif - -#ifdef __AVR_ATmega328P__ - - // Arduino-Nano-5V - // --------------------------------------------------------------- - - // Nano-X-Base V1a V2a - // ----------------------- - // Red PD5 PD2 - // Orange/Yellow PB1 PD3 - // Green PD3 PB1 - // Blue PD2 PD5 - - void Led::init () { - PORTD &= ~((1 << PD5) | (1 << PD3) | (1 << PD2)); - PORTB &= ~(1 << PB1); - DDRD |= (1 << PD5) | (1 << PD3) | (1 << PD2); - DDRB |= (1 << PB1); - } - - void Led::cleanup () { - DDRD &= ~((1 << PD5) | (1 << PD3) | (1 << PD2)); - DDRB &= ~(1 << PB1); - PORTD &= ~((1 << PD5) | (1 << PD3) | (1 << PD2)); - PORTB &= ~(1 << PB1); - } - - void Led::setLed (LED led, bool on) { - if (on) { - switch(led) { - case RED: PORTD |= (1 << PD5); break; - case ORANGE: PORTB |= (1 << PB1); break; - case GREEN: PORTD |= (1 << PD3); break; - case BLUE: PORTD |= (1 << PD2); break; - } - } else { - switch(led) { - case RED: PORTD &= ~(1 << PD5); break; - case ORANGE: PORTB &= ~(1 << PB1); break; - case GREEN: PORTD &= ~(1 << PD3); break; - case BLUE: PORTD &= ~(1 << PD2); break; - } - } - } - - void Led::ledToggle (LED led) { - switch(led) { - case RED: PORTD ^= (1 << PD5); break; - case ORANGE: PORTB ^= (1 << PB1); break; - case GREEN: PORTD ^= (1 << PD3); break; - case BLUE: PORTD ^= (1 << PD2); break; - } - } - -#endif - -void Led::ledOn (LED led) { - setLed(led, true); -} - -void Led::ledOff (LED led) { - setLed(led, false); -} - - -int8_t Led::run (uint8_t subtest) { - if (subtest <= 15) { - subtest = (subtest) % 4; - switch (subtest) { - case 0: ledOff(BLUE); ledOn(RED); break; - case 1: ledOff(RED); ledOn(ORANGE); break; - case 2: ledOff(ORANGE); ledOn(GREEN); break; - case 3: ledOff(GREEN); ledOn(BLUE); break; - } - printf_P(PSTR("Test LED D%d"), subtest + 1); - wait(500); - return 0; - } - - return -1; -} - diff --git a/software/nano-644/test_2024-07-23/src/units/led.hpp b/software/nano-644/test_2024-07-23/src/units/led.hpp deleted file mode 100644 index 780827f..0000000 --- a/software/nano-644/test_2024-07-23/src/units/led.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef LED_HPP -#define LED_HPP - -#include -#include "../main.hpp" -#include - -class Led : public TestUnit { - public: - enum LED { RED, ORANGE, GREEN, BLUE }; - - public: - Led () {}; - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName () { return PSTR("Led"); } - - void setLed (LED led, bool on); - void ledOn (LED led); - void ledOff (LED led); - void ledToggle (LED led); -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/modbus.cpp b/software/nano-644/test_2024-07-23/src/units/modbus.cpp deleted file mode 100644 index abbe36d..0000000 --- a/software/nano-644/test_2024-07-23/src/units/modbus.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include -#include - -#include "modbus.hpp" -#include "../main.hpp" - - -#ifdef __AVR_ATmega328P__ -void Modbus::init () {} -void Modbus::cleanup () {} -int8_t Modbus::run (uint8_t subtest) { return -1; } -void Modbus::handleRxByte (uint8_t b) {} -#endif - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - -// PB0 ... nRE .. Read enable -// PB1 ... DE .. Data enable - -#define SET_nRE (PORTB |= (1 << PB0)) -#define CLR_nRE (PORTB &= ~(1 << PB0)) -#define SET_DE (PORTB |= (1 << PB1)) -#define CLR_DE (PORTB &= ~(1 << PB1)) - - -void Modbus::init () { -} - -void Modbus::cleanup () { - enabled = 0; - UCSR1A = 0; - UCSR1B = 0; - UCSR1C = 0; - UBRR1H = 0; - UBRR1L = 0; - PORTD &= ~(1 << PD2); - DDRB &= ~((1 << PB1) | (1 << PB0)); - PORTB &= ~((1 << PB1) | (1 << PB0)); -} - -int8_t Modbus::run (uint8_t subtest) { - if (subtest == 0) { - SET_nRE; - CLR_DE; - DDRB |= (1 << PB1) | (1 << PB0); - - // UART1 interface on Nano-644 - PORTD |= (1 << PD2); // enable RxD1 pullup - UCSR1A = (1 << U2X1); - UCSR1B = (1 << RXCIE1) | (1 << RXEN1) | (1 <= 1 && subtest <= 4) { - uint8_t nre, de, b; - switch (subtest) { - case 1: nre = 1; de = 0; b = 0x01; break; - case 2: nre = 1; de = 1; b = 0x8e; break; - case 3: nre = 0; de = 0; b = 0x55; break; - case 4: nre = 0; de = 1; b = 0xaa; break; - default: return -1; - } - printf_P(PSTR(" DE=%u, nRE=%u send 0x%02x... "), de, nre, b); - if (nre) { - SET_nRE; - } else { - CLR_nRE; - } - if (de) { - SET_DE; - } else { - CLR_DE; - } - _delay_us(100); - receivedBytes = 0; - UDR1 = b; - _delay_ms(1); - if (receivedBytes > 0) { - printf_P(PSTR("0x%02x received"), received[0]); - receivedBytes = 0; - } else { - printf_P(PSTR("no byte received")); - } - printf_P(PSTR(" ... press key to proceed")); - while (wait(0xffffffff) == EOF) {} - CLR_DE; - SET_nRE; - - } else if (subtest == 5) { - static uint8_t frame[] = { 0x01, 0x04, 0x00, 0x00, 0x00, 0x02, 0x71, 0xcb }; - printf_P(PSTR("Modbus: lese Spannung von Eastron SDM-230 (Einphasenzähler)")); - SET_DE; - CLR_nRE; - _delay_us(100); - do { - SET_DE; - receivedBytes = 0; - for (uint8_t i = 0; i < sizeof(frame); i++) { - UCSR1A |= (1 << TXC1); - UDR1 = frame[i]; - while ((UCSR1A & (1 < Sending:")); - for (uint8_t i = 0; i < sizeof(frame); i++) { - printf_P(PSTR(" 0x%02x"), frame[i]); - } - int k = wait(100); - - printf_P(PSTR("\n RxD1:")); - if (receivedBytes == 0) { - printf_P(PSTR("?")); - } else { - for (uint8_t i = 0; i < receivedBytes; i++) { - if (i == sizeof(frame)) { - printf_P(PSTR(" ")); - } - printf_P(PSTR(" 0x%02x"), received[i]); - } - } - if (receivedBytes >= 16) { - union { - uint8_t b[4]; - float value; - } f; - f.b[0] = received[14]; - f.b[1] = received[13]; - f.b[2] = received[12]; - f.b[3] = received[11]; - printf_P(PSTR(" -> %4.8fV\n"), (double)f.value); - } - if (k != EOF) { - break; - } - - } while (wait(1000) == EOF); - - } else { - printf_P(PSTR("end")); - return -1; - } - wait(500); - return 0; -} - -void Modbus::handleRxByte (uint8_t b) { - if (receivedBytes < sizeof(received)) { - received[receivedBytes++] = b; - } -} - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/modbus.hpp b/software/nano-644/test_2024-07-23/src/units/modbus.hpp deleted file mode 100644 index 44b6a9d..0000000 --- a/software/nano-644/test_2024-07-23/src/units/modbus.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef MODBUS_HPP -#define MODBUS_HPP - -#include -#include "../main.hpp" -#include - -class Modbus : public TestUnit { - public: - uint8_t enabled; - uint8_t receivedBytes; - uint8_t received[16]; - - - public: - Modbus () { enabled = 0; receivedBytes = 0; } - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName () { return PSTR("Modbus"); } - void handleRxByte (uint8_t); -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/motor.cpp b/software/nano-644/test_2024-07-23/src/units/motor.cpp deleted file mode 100644 index 7f8fbf9..0000000 --- a/software/nano-644/test_2024-07-23/src/units/motor.cpp +++ /dev/null @@ -1,221 +0,0 @@ -#include -#include -#include - -#include "motor.hpp" -#include "../main.hpp" - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - - // Nano-644 - // --------------------------------------------------------------- - // PB0 ..... rotation-sensor - // PB2 ..... nFault - // PB3 ..... PWM (OC0A) - // PB4 ..... EN - // PA3 ..... SW3 -> push button for Motor enable control - - #define ADC0K 64 - - void Motor::init () { - DDRD |= (1 << PD7); // sensor signal toggle on PD7 (LED D4 red) - ADMUX = (1 << ADLAR) | (1 << REFS0); // ADC0, VREF=AVCC=3.3V - ADCSRA = (1 << ADEN) | 7; // ADC Enable, Prescaler 128 - TCCR0A = (1 << COM0A1) | (1 << WGM01) | (1 << WGM00); // Fast PWM on OC0A - // TCCR0B = (1 << CS02) | ( 1 << CS00); // f = 12 MHz / 1024 = 11,71875 kHz -> fPWM=45Hz - TCCR0B = (1 << CS02); // f = 12 MHz / 256 = 46,875 kHz -> fPWM=183,1Hz - DDRB |= (1 << PB4) | (1 << PB3); // Motor enable - PORTA |= (1 << PORTA3); // push button for Motor enable control - setEnable(); - enabled = 1; - } - - void Motor::cleanup () { - DDRD &= ~(1 << PD7); - ADMUX = 0; - ADCSRA = 0; - TCCR0A = 0; - TCCR0B = 0; - DDRB &= ~((1 << PB4) | (1 << PB3)); - PORTA &= ~(1 << PORTA3); - enabled = 0; - } - - bool Motor::isSW3Pressed () { - return (PINA & (1 << PC3)) == 0; - } - - void Motor::clearEnable () { - PORTB &= ~(1 << PB4); - } - - void Motor::setEnable () { - PORTB |= (1 << PB4); - } - - bool Motor::isFaultLow () { - return (PINB & (1 << PB2)) == 0; - } - - bool Motor::isSensorHigh () { - return (PINB & (1 << PB0)) != 0; - } - - void Motor::toggleD4 () { - PORTD ^= (1 << PD7); - } - -#endif - -#ifdef __AVR_ATmega328P__ - - // Arduino-Nano-5V - // --------------------------------------------------------------- - // PD4 ..... rotation-sensor - // PD7 ..... nFault - // PD6/OC0A ..... PWM - // PB2 ..... EN - // PC3 ..... SW3 -> push button for Motor enable control - - #define ADC0K 91 - - void Motor::init () { - DDRD |= (1 << PD2); // sensor signal toggle on PD2 (LED D4 red) - ADMUX = (1 << ADLAR) | (1 << REFS0); // ADC0, VREF=AVCC=5V - ADCSRA = (1 << ADEN) | 7; // ADC Enable, Prescaler 128 - TCCR0A = (1 << COM0A1) | (1 << WGM01) | (1 << WGM00); // Fast PWM on OC0A - // TCCR0B = (1 << CS02) | ( 1 << CS00); // f = 16 MHz / 1024 = 15,625 kHz -> fPWM=61.04Hz - TCCR0B = (1 << CS02); // f = 16 MHz / 256 = 62.5 kHz -> fPWM=244.14Hz - DDRB |= (1 << PB2); - DDRC &= ~(1 << PC3); - DDRD |= (1 << PD6); - DDRD &= ~((1 << PD4) | (1 << PD7)); - PORTC |= ( 1 << PC3); - PORTD |= (1 << PD7) | (1 << PD5); - setEnable(); - enabled = 1; - } - - void Motor::cleanup () { - DDRD &= ~(1 << PD2); - enabled = 0; - ADMUX = 0; - ADCSRA = 0; - TCCR0A = 0; - TCCR0B = 0; - clearEnable(); - DDRB &= ~((1 << PB2)); - DDRC &= ~(1 << PC3); - DDRD &= ~((1 << PD7) | (1 << PD6) | (1 << PD4)); - PORTC &= ~( 1 << PC3); - PORTD &= ~((1 << PD7) | (1 << PD6)); - } - - bool Motor::isSW3Pressed () { - return (PINC & (1 << PC3)) == 0; - } - - void Motor::clearEnable () { - PORTB &= ~(1 << PB2); - } - - void Motor::setEnable () { - PORTB |= (1 << PB2); - } - - bool Motor::isFaultLow () { - return (PIND & (1 << PD7)) == 0; - } - - bool Motor::isSensorHigh () { - return (PIND & (1 << PD4)) != 0; - } - - void Motor::toggleD4 () { - PORTD ^= (1 << PD2); - } - -#endif - -int8_t Motor::run (uint8_t subtest) { - switch (subtest) { - case 0: { - printf_P(PSTR("\n")); - while (wait(10) == EOF) { - - printf_P(PSTR("\r SW3=%d->"), isSW3Pressed() ? 0 : 1); - if (isSW3Pressed()) { - clearEnable(); - printf_P(PSTR("EN=0")); - } else { - setEnable(); - printf_P(PSTR("EN=1")); - } - - ADCSRA |= (1 << ADSC); // start ADC - while (ADCSRA & (1 << ADSC)) {} // wait for result - printf_P(PSTR("\r => ADC0=%3d"), ADCH); - - ADMUX = (1 << ADLAR) | (1 << REFS1) | (1 << REFS0) | 2; // ADC2, VREF=2.5V - - int16_t x = ((int16_t)(ADCH) - 5) * ADC0K / 64; - if (x < 0) x = 0; else if (x > 255) x = 255; - uint8_t dutyCycle = 0xff - (uint8_t)x; - if (dutyCycle <= 1) { - dutyCycle = 0; - } else if (dutyCycle > 254) { - dutyCycle = 255; - } - OCR0A = dutyCycle; - printf_P(PSTR(" PWM/OC0A=%3d"), dutyCycle); - - ADCSRA |= (1 << ADSC); // start ADC - while (ADCSRA & (1 << ADSC)) {} // wait for result - printf_P(PSTR(" ADC2=%3d"), ADCH); - ADMUX = (1 << ADLAR) | (1 << REFS0); // ADC0, VREF=AVCC=3.3V - - printf_P(PSTR(" nFAULT=%d"), isFaultLow() ? 0 : 1); - printf_P(PSTR(" SENSOR=%d "), isSensorHigh()); - uint16_t timer; - ATOMIC_BLOCK(ATOMIC_FORCEON) { - timer = rpmTimer; - } - float rpm = 60.0 / (float)timer / 0.0001; - if (timer > 0) { - printf_P(PSTR(" n= %5d U/min (T=%04x)"), (int)rpm, timer); - } else { - printf_P(PSTR(" no rotation (T=%04x) "), timer); - } - - } - return 0; - } - } - - return -1; -} - -void Motor::tick100us () { - static uint16_t timerH = 0; - static uint16_t timerL = 0; - static bool lastSensorHigh = false; - - bool sensorHigh = isSensorHigh(); - if (!sensorHigh && sensorHigh != lastSensorHigh && timerL > 2) { - rpmTimer = timerL + timerH; - timerL = 0; - timerH = 0; - toggleD4(); - } - if (sensorHigh) { - timerH = timerH < 0x4000 ? timerH + 1 : 0x4000; - } else { - timerL = timerL < 0x4000 ? timerL + 1 : 0x4000; - } - if (timerH >= 0x4000 || timerL >= 0x4000) { - rpmTimer = 0; // no ratation detected - } - lastSensorHigh = sensorHigh; -} - - diff --git a/software/nano-644/test_2024-07-23/src/units/motor.hpp b/software/nano-644/test_2024-07-23/src/units/motor.hpp deleted file mode 100644 index 2cbd15a..0000000 --- a/software/nano-644/test_2024-07-23/src/units/motor.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef MOTOR_HPP -#define MOTOR_HPP - -#include -#include "../main.hpp" -#include - -class Motor : public TestUnit { - public: - uint8_t enabled; - uint16_t rpmTimer; - - public: - Motor () { enabled = 0; rpmTimer = 0; }; - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName () { return PSTR("Motor"); } - void tick100us (); - - private: - bool isSW3Pressed (); - void clearEnable (); - void setEnable (); - bool isFaultLow (); - bool isSensorHigh (); - void toggleD4 (); -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/portexp.cpp b/software/nano-644/test_2024-07-23/src/units/portexp.cpp deleted file mode 100644 index a153589..0000000 --- a/software/nano-644/test_2024-07-23/src/units/portexp.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#include -#include -#include - -#include "portexp.hpp" -#include "../main.hpp" - -// Port-Expander MCP23S17 - -// SN-Print Stecker IO16 -// MCP23S17 | IO16 (MEGA2560) | Ampel-Print | | MCP23S17 | IO16 (MEGA2560) | Ampel-Print | -// ------------------------------------------ -------------------------------------------- -// GPA0 | IO16O7 (PA7) | Taster RU | | GPB0 | IO16U7 (PC7) | Taster LU | -// GPA1 | IO16O6 (PA6) | Taster RO | | GPB1 | IO16U6 (PC6) | Taster LO | -// GPA2 | IO16O5 (PA5) | U-Gruen | | GPB2 | IO16U5 (PC5) | R-Gruen | -// GPA3 | IO16O4 (PA4) | U-Gelb | | GPB3 | IO16U4 (PC4) | R-Gelb | -// GPA4 | IO16O3 (PA3) | U-Rot | | GPB4 | IO16U3 (PC3) | R-Rot | -// GPA5 | IO16O2 (PA2) | L-Gruen | | GPB5 | IO16U2 (PC2) | O-Gruen | -// GPA6 | IO16O1 (PA1) | L-Gelb | | GPB6 | IO16U1 (PC1) | O-Gelb | -// GPA7 | IO16O0 (PA0) | L-Rot | | GPB7 | IO16U0 (PC0) | O-Rot | - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - - // Nano-644 / Nano1284 - // -------------------------------------------------------- - // PA7 ... nCS - // PB5 ... MOSI - // PB6 ... MISO - // PB7 ... SCK - - void PortExp::init () { - PRR0 &= (1 << PRSPI); - PORTA |= (1 << PA7); - DDRA |= (1 << PA7); // SPI nCS - // PORTB/DDRB must be configured before SPCR !! - PORTB |= (1 << PB4); // nSS must be HIGH, otherwise SPI master will not become active!! - DDRB |= (1 << PB7) | (1 << PB5) | (1 << PB4); // SPI SCK (=PB7) and SPI MOSI (=PB5) - DDRB &= ~(1 << PB6); - - SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); // SPI enable , Master, f=12MHz/128=93,75kHz - // SPCR = (1 << SPE) | (1 << MSTR); // SPI enable , Master, f=12MHz/4 = 3MHz - } - - void PortExp::cleanup () { - DDRB &= ~(1 << PB6); // // SPI MISO (=PB6) - DDRB &= ~((1 << PB7) | (1 << PB5)); // SPI SCK (=PB7) and SPI MOSI (=PB5) - DDRA &= ~(1 << PA7); - PORTA &= ~(1 << PA7); // SPI nCS - SPCR = 0; - } - - void PortExp::setChipEnable () { - PORTA &= ~(1 << PA7); - } - - void PortExp::clearChipEnable () { - PORTA |= (1 << PA7); - } - - -#endif - -#ifdef __AVR_ATmega328P__ - - // Arduino-Nano-5V - // ------------------------------------ - // PC1 ... nCS (MANUAL (!) connection PA1 - PA7 required) - // PB3 ... MOSI - // PB4 ... MISO - // PB5 ... SCK - - void PortExp::init () { - PRR &= (1 << PRSPI); - PORTC |= (1 << PC1); - DDRC |= (1 << PC1); // SPI nCS - // PORTB/DDRB must be configured before SPCR !! - PORTB |= (1 << PB2); // nSS must be HIGH, otherwise SPI master will not become active!! - DDRB |= (1 << PB5) | (1 << PB3) | (1 << PB2); // SPI SCK (=PB5), SPI MOSI (=PB3), SPI nSS (=PB2) - - SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); // SPI enable , Master, f=16MHz/128=125kHz - // SPCR = (1 << SPE) | (1 << MSTR); // SPI enable , Master, f=12MHz/4 = 3MHz - - if (hardwareVersion == 2) { - PORTD |= (1 << PD7); // nCS when V2a/JP39.2-3 jumpered - DDRD |= (1 << PD7); - } - } - - void PortExp::cleanup () { - PORTC &= ~(1 << PC1); - DDRC &= ~(1 << PC1); - PORTB &= ~(1 << PB2); - DDRB &= ~((1 << PB5) | (1 << PB3) | (1 << PB2)); - SPCR = 0; - } - - void PortExp::setChipEnable () { - if (hardwareVersion == 2) { - PORTD &= ~(1 << PD7); - } - } - - void PortExp::clearChipEnable () { - if (hardwareVersion == 2) { - PORTD |= (1 << PD7); - } - } - -#endif - - - -int8_t PortExp::writeByte (uint8_t addr, uint8_t b) { - // no response via SPI MISO because SO stays tristate on write cycle - setChipEnable(); - SPDR = 0x40; // WRITE BYTE - while ((SPSR & (1 << SPIF)) == 0) {} - SPDR = addr; // register address - while ((SPSR & (1 << SPIF)) == 0) {} - SPDR = b; // value - while ((SPSR & (1 << SPIF)) == 0) {} - clearChipEnable(); - - _delay_us(5); - return 0; -} - -uint8_t PortExp::readByte (uint8_t addr) { - // response via SPI MISO only on third byte - setChipEnable(); - SPDR = 0x41; // write "READ BYTE" - while ((SPSR & (1 << SPIF)) == 0) {} - SPDR = addr; // write "register address" - while ((SPSR & (1 << SPIF)) == 0) {} - SPDR = 0; // additional 8 clocks to get response from port expander - while ((SPSR & (1 << SPIF)) == 0) {} - clearChipEnable(); - return SPDR; -} - -void PortExp::checkResponse (uint8_t address, uint8_t response, uint8_t desired) { - printf_P(PSTR(" (read 0x%02x -> 0x%02x"), address, response); - if (response != desired) { - printf_P(PSTR(" ERROR")); - if (response == 0xff) { - printf_P(PSTR(" JP39.2/3 jumpered (left)?")); - } - } else { - printf_P(PSTR(" OK")); - } - printf_P(PSTR(")")); -} - - -int8_t PortExp::run (uint8_t subtest) { - #ifdef __AVR_ATmega328P__ - if (hardwareVersion == 1) { - printf_P(PSTR("ERROR - nCS not controlable\n")); - return -1; - } - #endif - if (subtest == 0) { - while (wait(500) == EOF) { - printf_P(PSTR("\n => start ...")); - for (uint8_t i = 0; i < 8; i++) { - writeByte(0, ~(1 << i)); // IODIRA (Bank = 0) - writeByte(0x12, (1 << i)); // GPIOA (Bank = 0) - printf_P(PSTR("\n Bank0 - GPA%d = 1"), i); - checkResponse (0x12, readByte(0x12), (1 << i)); - wait(200); - writeByte(0x12, 0); // GPIOA (Bank = 0) - printf_P(PSTR("\n Bank0 - GPA%d = 0"), i); - checkResponse (0x12, readByte(0x12), 0); - writeByte(0, 0xff); // IODIRA (Bank = 0) - wait(200); - } - for (uint8_t i = 0; i < 8; i++) { - writeByte(1, ~(1 << i)); // IODIRB (Bank = 0) - writeByte(0x13, (1 << i)); // GPIOB (Bank = 0) - printf_P(PSTR("\n Bank0 - GPB%d = 1"), i); - checkResponse (0x13, readByte(0x13), (1 << i)); - wait(200); - writeByte(0x13, 0); // GPIOB (Bank = 0) - printf_P(PSTR("\n Bank0 - GPB%d = 0"), i); - checkResponse (0x13, readByte(0x13), 0); - writeByte(1, 0xff); // IODIRB (Bank = 0) - wait(200); - } - } - return 0; - } - - return -1; -} - diff --git a/software/nano-644/test_2024-07-23/src/units/portexp.hpp b/software/nano-644/test_2024-07-23/src/units/portexp.hpp deleted file mode 100644 index 8705662..0000000 --- a/software/nano-644/test_2024-07-23/src/units/portexp.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef PORTEXP_HPP -#define PORTEXP_HPP - -#include -#include "../main.hpp" -#include - -class PortExp : public TestUnit { - public: - PortExp () {}; - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName () { return PSTR("PortExp"); } - - private: - void setChipEnable (); - void clearChipEnable (); - int8_t writeByte (uint8_t addr, uint8_t b); - uint8_t readByte (uint8_t addr); - void checkResponse (uint8_t address, uint8_t response, uint8_t desired); -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/poti.cpp b/software/nano-644/test_2024-07-23/src/units/poti.cpp deleted file mode 100644 index 94fc5a4..0000000 --- a/software/nano-644/test_2024-07-23/src/units/poti.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include - -#include "poti.hpp" -#include "../main.hpp" - -void Poti::init () { - ADMUX = (1 << REFS0); // ADC0, VREF=AVCC=3.3V - ADCSRA = (1 << ADEN) | 7; // ADC Enable, Prescaler 128 -} - -void Poti::cleanup () { - ADMUX = 0; - ADCSRA = 0; -} - -int8_t Poti::run (uint8_t subtest) { - switch (subtest) { - case 0: { - printf_P(PSTR("\n")); - while (wait(10) == EOF) { - printf_P(PSTR("\r => Measure ADC0: ")); - ADCSRA |= (1 << ADSC); // start ADC - while (ADCSRA & (1 << ADSC)) {} // wait for result - printf_P(PSTR("%4d (0x%03x)"), ADC, ADC); - } - return 0; - } - } - - return -1; -} - - diff --git a/software/nano-644/test_2024-07-23/src/units/poti.hpp b/software/nano-644/test_2024-07-23/src/units/poti.hpp deleted file mode 100644 index b13dd29..0000000 --- a/software/nano-644/test_2024-07-23/src/units/poti.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef POTI_HPP -#define POTI_PP - -#include -#include "../main.hpp" -#include - -class Poti : public TestUnit { - public: - Poti () {}; - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName () { return PSTR("Poti"); } -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/r2r.cpp b/software/nano-644/test_2024-07-23/src/units/r2r.cpp deleted file mode 100644 index 54664b1..0000000 --- a/software/nano-644/test_2024-07-23/src/units/r2r.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include - -#include "r2r.hpp" -#include "../main.hpp" - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - // AVCC=3.3, POTI Vmax=3.3V - #define K 1.0 -#endif - -#ifdef __AVR_ATmega328P__ - // AVCC=4.7V, POTI Vmax=3.3V - #define K 1.32 -#endif - -void R2r::init () { - ADMUX = (1 << REFS0) | 2; // ADC2, VREF=AVCC (=3.3V for Nano-644/1284, =5V for Arduino Nano) - ADCSRA = (1 << ADEN) | 7; // ADC Enable, Prescaler 128 -} - -void R2r::cleanup () { - ADMUX = 0; - ADCSRA = 0; -} - -int8_t R2r::run (uint8_t subtest) { - switch (subtest) { - case 0: { - printf_P(PSTR("\n")); - while (wait(10) == EOF) { - printf_P(PSTR("\r => Measure ADC2: ")); - ADCSRA |= (1 << ADSC); // start ADC - while (ADCSRA & (1 << ADSC)) {} // wait for result - printf_P(PSTR("%4d (0x%03x)"), ADC, ADC); - // uint8_t sw = (uint8_t)( ((float)(ADC) + 4.0) / 64.0 * K ); - float swf = ((float)(ADC) * K) / 64.8 + 0.55; - uint8_t sw = (uint8_t)swf ; - printf_P(PSTR(" %3.1f => SW9:6 = %d %d% d %d "), swf, sw >> 3, (sw >> 2) & 0x01, (sw >> 1) & 0x01, sw & 0x01 ); - } - return 0; - } - } - - return -1; -} - - diff --git a/software/nano-644/test_2024-07-23/src/units/r2r.hpp b/software/nano-644/test_2024-07-23/src/units/r2r.hpp deleted file mode 100644 index 84e97e6..0000000 --- a/software/nano-644/test_2024-07-23/src/units/r2r.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef R2R_HPP -#define R2R_PP - -#include -#include "../main.hpp" -#include - -class R2r : public TestUnit { - public: - R2r () {}; - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName () { return PSTR("R2R"); } -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/rgb.cpp b/software/nano-644/test_2024-07-23/src/units/rgb.cpp deleted file mode 100644 index 3f69cbd..0000000 --- a/software/nano-644/test_2024-07-23/src/units/rgb.cpp +++ /dev/null @@ -1,152 +0,0 @@ -#include -#include - -#include "rgb.hpp" -#include "../main.hpp" - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - - // Nano-644 - // --------------------------------------------------------------- - // PB0 ..... Red (inverse logic -> 0 = ON) - // PB1 ..... Green (inverse logic -> 0 = ON) - // PB2 ..... Blue (inverse logic -> 0 = ON) - - void Rgb::init () { - ledOff(RED); - ledOff(GREEN); - ledOff(BLUE); - DDRB |= (1 << PB2) | (1 << PB1) | (1 << PB0); - } - - void Rgb::cleanup () { - ledOff(RED); - ledOff(GREEN); - ledOff(BLUE); - DDRB &= ~((1 << PB2) | (1 << PB1) | (1 << PB0)); - } - - void Rgb::setLed (LED led, bool on) { - if (on) { - switch(led) { - case RED: PORTB &= ~(1 << PB0); break; - case GREEN: PORTB &= ~(1 << PB1); break; - case BLUE: PORTB &= ~(1 << PB2); break; - } - } else { - switch(led) { - case RED: PORTB |= (1 << PB0); break; - case GREEN: PORTB |= (1 << PB1); break; - case BLUE: PORTB |= (1 << PB2); break; - } - } - } - - void Rgb::ledToggle (LED led) { - switch(led) { - case RED: PORTB ^= (1 << PB0); break; - case GREEN: PORTB ^= (1 << PB1); break; - case BLUE: PORTB ^= (1 << PB2); break; - } - } - - -#endif - -#ifdef __AVR_ATmega328P__ - - // Arduino-Nano-5V - // --------------------------------------------------------------- - // PD4 ..... Red (inverse logic -> 0 = ON) - // PB0 ..... Green (inverse logic -> 0 = ON) - // PD7 ..... Blue (inverse logic -> 0 = ON) - - void Rgb::init () { - ledOff(RED); - ledOff(GREEN); - ledOff(BLUE); - DDRB |= (1 << PB0); - DDRD |= (1 << PD7) | (1 << PD4); - } - - void Rgb::cleanup () { - ledOff(RED); - ledOff(GREEN); - ledOff(BLUE); - DDRB &= ~(1 << PB0); - DDRD &= ~((1 << PD7) | (1 << PD4)); - } - - void Rgb::setLed (LED led, bool on) { - if (on) { - switch (led) { - case RED: PORTD &= ~(1 << PD4); break; - case GREEN: PORTB &= ~(1 << PB0); break; - case BLUE: PORTD &= ~(1 << PD7); break; - } - } else { - switch (led) { - case RED: PORTD |= (1 << PD4); break; - case GREEN: PORTB |= (1 << PB0); break; - case BLUE: PORTD |= (1 << PD7); break; - } - } - } - - void Rgb::ledToggle (LED led) { - switch (led) { - case RED: PORTD ^= (1 << PD4); break; - case GREEN: PORTB ^= ~(1 << PB0); break; - case BLUE: PORTD ^= (1 << PD7); break; - } - } - -#endif - -void Rgb::ledOn (LED led) { - setLed(led, true); -} - -void Rgb::ledOff (LED led) { - setLed(led, false); -} - -int8_t Rgb::run (uint8_t subtest) { - switch (subtest) { - case 0: { - ledOn(RED); - printf_P(PSTR("Red")); - wait(3000); - ledOff(RED); - return 0; - } - - case 1: { - ledOn(GREEN); - printf_P(PSTR("Green")); - wait(3000); - ledOff(GREEN); - return 0; - } - - case 2: { - ledOn(BLUE); - printf_P(PSTR("Blue")); - wait(3000); - ledOff(BLUE); - return 0; - } - - case 3: { - ledOn(RED); ledOn(GREEN); ledOn(BLUE); - printf_P(PSTR("All")); - wait(3000); - ledOff(RED); ledOff(GREEN); ledOff(BLUE); - return 0; - } - } - - return -1; -} - - diff --git a/software/nano-644/test_2024-07-23/src/units/rgb.hpp b/software/nano-644/test_2024-07-23/src/units/rgb.hpp deleted file mode 100644 index 12e9da4..0000000 --- a/software/nano-644/test_2024-07-23/src/units/rgb.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef RGB_HPP -#define RGB_PP - -#include -#include "../main.hpp" -#include - -class Rgb : public TestUnit { - public: - enum LED { RED, GREEN, BLUE }; - - public: - Rgb () {}; - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName () { return PSTR("Rgb"); } - - void setLed (LED led, bool on); - void ledOn (LED led); - void ledOff (LED led); - void ledToggle (LED led); -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/rtc8563.cpp b/software/nano-644/test_2024-07-23/src/units/rtc8563.cpp deleted file mode 100644 index 6ae6497..0000000 --- a/software/nano-644/test_2024-07-23/src/units/rtc8563.cpp +++ /dev/null @@ -1,253 +0,0 @@ -#include -#include -#include -#include -#include - -#include "rtc8563.hpp" -#include "../adafruit/bme280.h" -#include "../main.hpp" - -// RTC BME653EMA on Nano-644 - -const char PSTR_WEEKDAYS[] PROGMEM = "So\0Mo\0Di\0Mi\0Do\0Fr\0Sa\0"; - -// const uint8_t CONFIG[] PROGMEM = { -// /* config -> */ 0x00, 0x00, -// /* enable nINT -> */ 0x01, 0x01, // TIE = 1 -// /* set clock -> */ 0x02, 0x00, 0x00, 0x08, 0x16, 0x02, 0x08, 0x24 -// }; - -void Rtc8563::handleTwiIrq () { - TWCR |= (1 << TWINT); // clear Interrupt Request -} - -#ifdef __AVR_ATmega328P__ -void Rtc8563::init () {} -void Rtc8563::cleanup () {} -int8_t Rtc8563::run (uint8_t subtest) { return -1; } -PGM_P Rtc8563::getName () { return PSTR("?"); } -#endif - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - -void Rtc8563::init () { - PORTC &= ~(1 << PC7); // nInt and nPowerOn (Q7 -> BATTERY) - DDRC |= (1 << PC7); - TWBR = 13; // 100kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 100000) / (2 * 100000 * 4); - TWBR = 28; // 50kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 50000) / (2 * 50000 * 4); - TWBR = 100; // 50kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 50000) / (2 * 50000 * 4); - TWCR = (1 << TWEN); - enabled = true; -} - -void Rtc8563::cleanup () { - enabled = false; - TWCR = (1 << TWEN); - TWBR = 0; - // PORTC &= ~(1 << PC7); - // DDRC &= ~(1 << PC7); -} - -PGM_P Rtc8563::getName () { - return PSTR("RTC-8563"); -} - -uint8_t Rtc8563::bcd2bin (uint8_t value) { - return (value >> 4) * 10 + (value & 0x0f); -} - -int8_t Rtc8563::run (uint8_t subtest) { - int key = EOF; - if (subtest == 0) { - // printf_P(PSTR(" BM280 ... ")); - rtc8563.begin(0x51); - Clock_t clock; - // uint8_t bufferConfig[] = { 0x00, 0x00, 0x01, 0x01 }; - // uint8_t bufferSetClock[] = { 0x02, 0x00, 0x00, 0x08, 0x16, 0x02, 0x08, 0x24 }; - - Rtc8563Reg_t reg; - uint8_t *pReg = (uint8_t *)(void *)® - memset(®, 0, sizeof(reg)); - - printf_P(PSTR("\n => config 8563 ... ")); - reg.reg1.field.tie = 1; - if (!rtc8563.write(pReg, 2)) { - printf_P(PSTR_ERROR); - } else { - printf_P(PSTR_Done); - } - printf_P(PSTR("\n press:")); - printf_P(PSTR("\n t .... timer on/off")); - printf_P(PSTR("\n p .... power on/off (PC7->Q1)")); - printf_P(PSTR("\n c .... init clock")); - printf_P(PSTR("\n w/W .. weekday (+/-)\n")); - printf_P(PSTR("\n y/Y .. year (+/-)")); - printf_P(PSTR("\n m/M .. month (+/-)")); - printf_P(PSTR("\n d/D .. day (+/-)")); - printf_P(PSTR("\n h/H .. hour (+/-)")); - printf_P(PSTR("\n n/N .. minute (+/-)")); - printf_P(PSTR("\n s/S .. second (+/-)\n")); - - do { - uint8_t addr = 0x00; - printf_P(PSTR("\n => read register 0-15 (hex):")); - if (!rtc8563.write_then_read(&addr, 1, pReg, sizeof(reg))) { - printf_P(PSTR_ERROR); - key = waitAndReadKey(1000); - continue; - } - memccpy(&clock, ®.clock, sizeof(clock), sizeof(clock)); - for (uint8_t i = 0; i < 16; i++) { - if (i % 4 == 0) { - printf_P(PSTR(" ")); - } - printf_P(PSTR(" %02X"), pReg[i]); - } - uint16_t year = (clock.month.field.century ? 2100 : 2000) + bcd2bin(clock.year.byte); - int8_t month = bcd2bin(clock.month.byte); - int8_t day = bcd2bin(clock.day.byte); - int8_t hrs = bcd2bin(clock.hour.byte); - int8_t min = bcd2bin(clock.min.byte); - int8_t sec = bcd2bin(clock.sec.byte); - int8_t weekday = clock.weekday.byte; - - PGM_P d = weekday >= 0 && weekday < 7 ? &PSTR_WEEKDAYS[weekday * 3] : PSTR("??"); - printf_P(PSTR(" --> ")); - printf_P(d); - printf_P(PSTR(", %d %04d-%02d-%02d %02d:%02d:%02d"), weekday, year, month, day, hrs, min, sec); - printf_P(PSTR(" - Timer=0x%02x"), reg.timer); - - key = waitAndReadKey(1000); - bool ok = true; - bool change = false; - switch (key) { - case 't': ok &= setTimer(reg.timerControl.field.enable ? 0 : 10, reg); break; - case 'c': ok &= setClock(5, 2024,8,16, 17,12,10 ); break; // ok &= rtc8563.write(bufferSetClock, sizeof(bufferSetClock)); break; - case 'p': powerOnOff(10, reg); break; - case 'y': year++; change = true; break; - case 'Y': year--; change = true; break; - case 'm': month++; change = true; break; - case 'M': month--; change = true; break; - case 'd': day++; change = true; break; - case 'D': day--; change = true; break; - case 'h': hrs++; change = true; break; - case 'H': hrs--; change = true; break; - case 'n': min++; change = true; break; - case 'N': min--; change = true; break; - case 's': sec++; change = true; break; - case 'S': sec--; change = true; break; - case 'w': weekday++; change = true; break; - case 'W': weekday--; change = true; break; - } - if (change) { - printf_P(PSTR("\n set: %04d-%02d-%02d %02d:%02d:%02d"), year, month, day, hrs, min, sec); - setClock(weekday, year, month, day, hrs, min, sec); - } - - } while (key != ESCAPE); - - return 0; - } - - return -1; -} - -bool Rtc8563::setTimer (uint8_t seconds, Rtc8563Reg_t ®) { - - reg.timerControl.field.fd = FDTIMER_1HZ; - reg.timerControl.field.enable = seconds > 0; - reg.timer = seconds; - reg.reg1.field.tie = seconds > 0; - // clear and alarm flag behavior on I2C write different to datasheet - // datasheet: tf cleared to 0, af remains unchanged - // realchip: tf remains 1 and af is set to 1 (no negative result because tie=0 and aie=0) - reg.reg1.field.tf = 0; // clear timer flag - reg.reg1.field.af = 1; // alarm flag remains unchanged - if (seconds > 0) { - printf_P(PSTR("\n Timer set to %ds (1:%02X) ... "), seconds, reg.reg1.byte); - } else { - printf_P(PSTR("\n Timer off ... ")); - } - if (rtc8563.writeByteAndBuffer(0x01, ®.reg1.byte, 1) && rtc8563.writeByteAndBuffer(14, ®.timerControl.byte, 2)) { - printf_P(PSTR("OK")); - return true; - } else { - printf_P(PSTR("fails")); - return false; - } -} - -bool Rtc8563::powerOnOff (uint8_t delayOffSeconds, Rtc8563Reg_t ®) { - int key = EOF; - if (PORTC & (1 << PC7)) { - printf_P(PSTR("\n power on ...")); - DDRC |= ( 1<< PC7); - PORTC &= ~(1 << PC7); - setTimer(0, reg); - } else { - printf_P(PSTR("\n")); - key = EOF; - for (int8_t i = 9; i > 0 && key == EOF; i--) { - printf_P(PSTR("\r press ESC to abort, power off in %ds (press key to skip timer) "), i); - key = waitAndReadKey(1000); - } - if (key == ESCAPE) { - return true; - } - setTimer(10, reg); - reg.reg1.field.af = 1; // alarm flag remains unchanged - reg.reg1.field.tf = 0; // timer flag clear - reg.reg1.field.tie = 1; // enable timer interrupt - rtc8563.writeByteAndBuffer(0x01, ®.reg1.byte, 1); - printf_P(PSTR("\n power off now ...")); - DDRC |= ( 1<< PC7); - PORTC |= (1 << PC7); - _delay_ms(5); - DDRC &= ~( 1<< PC7); - PORTC &= ~(1 << PC7); - waitAndReadKey(5000); - printf_P(PSTR("power off fails, I am still alive :-) ... proceed")); - } - return true; -} - - -bool Rtc8563::setClock (int8_t weekday, uint16_t year, int8_t month, int8_t day, int8_t hour, int8_t min, int8_t sec) { - Clock_t clock; - clock.month.field.century = (year < 2000 || year > 2100) ? 1: 0; - uint8_t y = year % 100; clock.year.field.bcdL = y % 10; clock.year.field.bcdH = y / 10; - - while (weekday < 0) { weekday += 7; } - while (weekday > 6) { weekday -= 7; } - clock.weekday.field.bcdL = weekday; - - while (month < 1) { month += 12; } - while (month > 12) { month -= 12; } - clock.month.field.bcdL = month % 10; clock.month.field.bcdH = month / 10; - - while (day < 1) { day += 31; } - while (day > 31) { day -= 31; } - clock.day.field.bcdL = day % 10; clock.day.field.bcdH = day / 10; - - while (hour < 0) { hour += 24; } - while (hour > 23) { hour -= 24; } - clock.hour.field.bcdL = hour % 10; clock.hour.field.bcdH = hour / 10; - - while (min < 0) { min += 60; } - while (min > 59) { min -= 60; } - clock.min.field.bcdL = min % 10; clock.min.field.bcdH = min / 10; - - while (sec < 0) { sec += 60; } - while (sec > 59) { sec -= 60; } - clock.sec.field.bcdL = sec % 10; clock.sec.field.bcdH = sec / 10; - - printf_P(PSTR("\n %p %p %p %p %p %p %p -> write: "), &clock.sec.byte, &clock.min.byte, &clock.hour.byte, &clock.day.byte, &clock.weekday.byte, &clock.month.byte, &clock.year.byte ); - for (uint8_t i = 0; i < sizeof(clock); i++) { - printf_P(PSTR(" %02x"), ((uint8_t *)(void *)&clock)[i]); - } - return rtc8563.writeByteAndBuffer(0x02, (uint8_t *)(void *)&clock, sizeof(clock)); -} - -#endif - diff --git a/software/nano-644/test_2024-07-23/src/units/rtc8563.hpp b/software/nano-644/test_2024-07-23/src/units/rtc8563.hpp deleted file mode 100644 index ca79713..0000000 --- a/software/nano-644/test_2024-07-23/src/units/rtc8563.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef RTC8563_HPP -#define RTC8563_HPP - -#include -#include "../main.hpp" -#include "../adafruit/bme280.h" -#include "../adafruit/ens160.h" -#include "../i2cmaster.hpp" -#include "../i2cslave.hpp" - - -class Rtc8563 : public TestUnit { - public: - typedef enum { NORMAL } Rtc8563Mode_t; - - private: - I2cMaster rtc8563; - typedef enum { FDCLOCKOUT_32768HZ = 0, FDCLOCKOUT_1024HZ = 1, FDCLOCKOUT_32HZ = 2, FDCLOCKOUT_1HZ = 3 } FDCLOCKOUT_t; - typedef enum { FDTIMER_4096HZ = 0, FDTIMER_64HZ = 1, FDTIMER_1HZ = 2, FDTIMER_1D60HZ = 3 } FDTIMER_t; - typedef struct { - union { uint8_t byte; struct { uint8_t bcdL:4; uint8_t bcdH:3; uint8_t voltageLow:1; } field; } sec; - union { uint8_t byte; struct { uint8_t bcdL:4; uint8_t bcdH:3; uint8_t notUsed:1; } field; } min; - union { uint8_t byte; struct { uint8_t bcdL:4; uint8_t bcdH:2; uint8_t notUsed:2; } field; } hour; - union { uint8_t byte; struct { uint8_t bcdL:4; uint8_t bcdH:2; uint8_t notUsed:2; } field; } day; - union { uint8_t byte; struct { uint8_t bcdL:3; } field; uint8_t notUsed:5; } weekday; - union { uint8_t byte; struct { uint8_t bcdL:4; uint8_t bcdH:1; uint8_t notUsed:2; uint8_t century:1; } field; } month; - union { uint8_t byte; struct { uint8_t bcdL:4; uint8_t bcdH:4; } field; } year; - } Clock_t; // identical to 8563 register 2..8 - - typedef struct { - union { uint8_t byte; struct { uint8_t bcdL:4; uint8_t bcdH:3; uint8_t enable:1; } field; } min; - union { uint8_t byte; struct { uint8_t bcdL:4; uint8_t bcdH:2; uint8_t notUsed:1; uint8_t enable:1; } field; } hour; - union { uint8_t byte; struct { uint8_t bcdL:4; uint8_t bcdH:2; uint8_t notUsed:1; uint8_t enable:1; } field; } day; - union { uint8_t byte; struct { uint8_t bcdL:3; } field; uint8_t notUsed:4; uint8_t enable_W:1; } weekday; - } Alarm_t; - - typedef struct { - union { uint8_t byte; struct { uint8_t notUsed210:3; uint8_t testC:1; uint8_t notUsed4:1; uint8_t stop:1; uint8_t notUsed6:1; uint8_t test1:1; } field; } reg0; - union { uint8_t byte; struct { uint8_t tie:1; uint8_t aie:1; uint8_t tf:1; uint8_t af:1; uint8_t ti_tp:1; uint8_t notUsed:3; } field; } reg1; - Clock_t clock; - Alarm_t alarm; - union { uint8_t byte; struct { FDCLOCKOUT_t fd:2; uint8_t notUsed65432:5; uint8_t enable:1; } field; } clockoutControl; - union { uint8_t byte; struct { FDTIMER_t fd:2; uint8_t notUsed65432:5; uint8_t enable:1; } field; } timerControl; - uint8_t timer; - } Rtc8563Reg_t; - - - public: - bool enabled; - - public: - Rtc8563 (Rtc8563Mode_t mode) { enabled = false; this->mode = mode; } - void tick1ms () { rtc8563.tick1ms(); } - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName (); - void handleTwiIrq (); - - private: - Rtc8563Mode_t mode; - uint8_t bcd2bin (uint8_t value); - int8_t runModeNormal (uint8_t subtest); - int8_t runModeBattery (uint8_t subtest); - bool setTimer (uint8_t seconds, Rtc8563Reg_t ®); - bool powerOnOff (uint8_t delayOffSeconds, Rtc8563Reg_t ®); - bool setClock (int8_t weekday, uint16_t year, int8_t month, int8_t day, int8_t hour, int8_t min, int8_t sec); -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/seg7.cpp b/software/nano-644/test_2024-07-23/src/units/seg7.cpp deleted file mode 100644 index f522456..0000000 --- a/software/nano-644/test_2024-07-23/src/units/seg7.cpp +++ /dev/null @@ -1,283 +0,0 @@ -#include -#include - -#include "seg7.hpp" -#include "../main.hpp" - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - - // Nano-644 / Nano 1284 - // --------------------------------------------------------------- - - // Nano-X-Base V1a V2a - // --------------------------------- - // Anode Segment A ....... PB0 PB0 - // Anode Segment B ....... PB1 PB1 - // Anode Segment C ....... PB2 PB2 - // Anode Segment D ....... PB3 PB3 - // Anode Segment E ....... PB4 PB4 - // Anode Segment F ....... PB5 PB5 - // Anode Segment G ....... PB6 PB6 - // Anode DP .............. PB7 PB7 - // --------------------------------- - // Cathode Char 1 ........ PA0 PD4 - // Cathode Char 2 ........ PA1 PD5 - // Cathode Char 3 ........ PA2 PD6 - // Cathode Char 4 ........ PA3 PD7 - // --------------------------------- - // nOE (Output Enable) ... PD5 PA1 - // Anode L1:2 ............ PD6 PA2 - // Anode L3 .............. PD7 PA3 - -void Seg7::init () { - setAnodes(0); - setCathodes(0); - DDRB = 0xff; - switch (hardwareVersion) { - case 1: { - DDRA |= (1 << PA3) | (1 << PA2) | (1 << PA1) | (1 << PA0); - DDRD |= (1 << PD7) | (1 << PD6) | (1 << PD5); - break; - } - case 2: { - DDRA |= (1 << PA3) | (1 << PA2) | (1 << PA1); - DDRD |= (1 << PD7) | (1 << PD6) | (1 << PD5) | (1 << PD4); - } - break; - } - } - - void Seg7::cleanup () { - setAnodes(0); - setCathodes(0); - DDRB = 0x00; - switch (hardwareVersion) { - case 1: { - DDRA &= ~((1 << PA3) | (1 << PA2) | (1 << PA1) | (1 << PA0)); - DDRD &= ~((1 << PD7) | (1 << PD6) | (1 << PD5)); - break; - } - case 2: { - DDRA &= ~((1 << PA3) | (1 << PA2) | (1 << PA1)); - DDRD &= ~((1 << PD7) | (1 << PD6) | (1 << PD5) | (1 << PD4)); - } - break; - } - } - - void Seg7::setAnodes (uint16_t a) { - if (a & 0x0001) PORTB |= (1 << PB0); else PORTB &= ~(1 << PB0); // Anode Char A - if (a & 0x0002) PORTB |= (1 << PB1); else PORTB &= ~(1 << PB1); // Anode Char B - if (a & 0x0004) PORTB |= (1 << PB2); else PORTB &= ~(1 << PB2); // Anode Char C - if (a & 0x0008) PORTB |= (1 << PB3); else PORTB &= ~(1 << PB3); // Anode Char D - if (a & 0x0010) PORTB |= (1 << PB4); else PORTB &= ~(1 << PB4); // Anode Char E - if (a & 0x0020) PORTB |= (1 << PB5); else PORTB &= ~(1 << PB5); // Anode Char F - if (a & 0x0040) PORTB |= (1 << PB6); else PORTB &= ~(1 << PB6); // Anode Char G - if (a & 0x0080) PORTB |= (1 << PB7); else PORTB &= ~(1 << PB7); // Anode Char DP - switch (hardwareVersion) { - case 1: { - if (a & 0x0100) PORTD |= (1 << PD6); else PORTD &= ~(1 << PD6); // Anode L1/L2 - if (a & 0x0200) PORTD |= (1 << PD7); else PORTD &= ~(1 << PD7); // Anode L3 - break; - } - case 2: { - if (a & 0x0100) PORTA |= (1 << PA2); else PORTA &= ~(1 << PA2); // Anode L1/L2 - if (a & 0x0200) PORTA |= (1 << PA3); else PORTA &= ~(1 << PA3); // Anode L3 - break; - } - } - } - - void Seg7::setCathodes (uint8_t c) { - switch (hardwareVersion) { - case 1: { - if (c & 0x01) PORTA |= (1 << PA0); else PORTA &= ~(1 << PA0); // Chathode Char 1 (most left) - if (c & 0x02) PORTA |= (1 << PA1); else PORTA &= ~(1 << PA1); // Chathode Char 2 - if (c & 0x04) PORTA |= (1 << PA2); else PORTA &= ~(1 << PA2); // Chathode Char 3 - if (c & 0x08) PORTA |= (1 << PA3); else PORTA &= ~(1 << PA3); // Chathode Char 4 (most right) - break; - } - case 2: { - if (c & 0x01) PORTD |= (1 << PD4); else PORTD &= ~(1 << PD4); // Chathode Char 1 (most left) - if (c & 0x02) PORTD |= (1 << PD5); else PORTD &= ~(1 << PD5); // Chathode Char 2 - if (c & 0x04) PORTD |= (1 << PD6); else PORTD &= ~(1 << PD6); // Chathode Char 3 - if (c & 0x08) PORTD |= (1 << PD7); else PORTD &= ~(1 << PD7); // Chathode Char 4 (most right) - break; - } - } - } - - void Seg7::setOE (bool enabled) { - switch (hardwareVersion) { - case 1: if (enabled) PORTD &= ~(1 << PD5); else PORTD |= (1 << PD5); break; - case 2: if (enabled) PORTA &= ~(1 << PA1); else PORTA |= (1 << PA1); break; - } - } - -#endif - -#ifdef __AVR_ATmega328P__ - - // Arduino-Nano-5V - // --------------------------------------------------------------- - - // Nano-X-Base V1a V2a - // --------------------------------- - // Anode Segment A ....... PD4 PD4 - // Anode Segment B ....... PB0 PB0 - // Anode Segment C ....... PD7 PD7 - // Anode Segment D ....... PD6 PD6 - // Anode Segment E ....... PB2 PB2 - // Anode Segment F ....... PB3 PB3 - // Anode Segment G ....... PB4 PB4 - // Anode DP .............. PB5 PB5 - // --------------------------------- - // Cathode Char 1 ........ PC0 PD5 - // Cathode Char 2 ........ PC1 PB1 - // Cathode Char 3 ........ PC2 PD3 - // Cathode Char 4 ........ PC3 PD2 - // --------------------------------- - // nOE (Output Enable) ... PB1 PC1 - // Anode L1:2 ............ PD3 PC2 - // Anode L3 .............. PD2 PC3 - - - void Seg7::init () { - enabled = 1; - setAnodes(0); - setCathodes(0); - switch (hardwareVersion) { - case 1: { - DDRB |= (1 << PB5) | (1 << PB4) | (1 << PB3) | (1 << PB2) | (1 << PB1) | (1 << PB0); - DDRC |= (1 << PC3) | (1 << PC2) | (1 << PC1) | (1 << PC0); - DDRD |= (1 << PD7) | (1 << PD6) | (1 << PD4) | (1 << PD3) | (1 << PD2); - break; - } - case 2: { - DDRB |= (1 << PB5) | (1 << PB4) | (1 << PB3) | (1 << PB2) | (1 << PB1) | (1 << PB0); - DDRC |= (1 << PC3) | (1 << PC2) | (1 << PC1); - DDRD |= (1 << PD7) | (1 << PD6) | (1 << PD5) | (1 << PD4) | (1 << PD3) | (1 << PD2); - break; - } - } - - } - - void Seg7::cleanup () { - enabled = 0; - setAnodes(0); - setCathodes(0); - switch (hardwareVersion) { - case 1: { - DDRB &= ~((1 << PB5) | (1 << PB4) | (1 << PB3) | (1 << PB2) | (1 << PB1) | (1 << PB0)); - DDRC &= ~((1 << PC3) | (1 << PC2) | (1 << PC1) | (1 << PC0)); - DDRD &= ~((1 << PD7) | (1 << PD6) | (1 << PD4) | (1 << PD3) | (1 << PD2)); - break; - } - case 2: { - DDRB &= ~((1 << PB5) | (1 << PB4) | (1 << PB3) | (1 << PB2) | (1 << PB1) | (1 << PB0) ); - DDRC &= ~((1 << PC3) | (1 << PC2) | (1 << PC1)); - DDRD &= ~((1 << PD7) | (1 << PD6) | (1 << PD5) | (1 << PD4) | (1 << PD3) | (1 << PD2)); - break; - } - } - - } - - void Seg7::setAnodes (uint16_t a) { - if (a & 0x0001) PORTD |= (1 << PD4); else PORTD &= ~(1 << PD4); // Anode Char A - if (a & 0x0002) PORTB |= (1 << PB0); else PORTB &= ~(1 << PB0); // Anode Char B - if (a & 0x0004) PORTD |= (1 << PD7); else PORTD &= ~(1 << PD7); // Anode Char C - if (a & 0x0008) PORTD |= (1 << PD6); else PORTD &= ~(1 << PD6); // Anode Char D - if (a & 0x0010) PORTB |= (1 << PB2); else PORTB &= ~(1 << PB2); // Anode Char E - if (a & 0x0020) PORTB |= (1 << PB3); else PORTB &= ~(1 << PB3); // Anode Char F - if (a & 0x0040) PORTB |= (1 << PB4); else PORTB &= ~(1 << PB4); // Anode Char G - if (a & 0x0080) PORTB |= (1 << PB5); else PORTB &= ~(1 << PB5); // Anode Char DP - switch (hardwareVersion) { - case 1: { - if (a & 0x0100) PORTD |= (1 << PD3); else PORTD &= ~(1 << PD3); // Anode L1/L2 - if (a & 0x0200) PORTD |= (1 << PD2); else PORTD &= ~(1 << PD2); // Anode L3 - break; - } - case 2: { - if (a & 0x0100) PORTC |= (1 << PC2); else PORTC &= ~(1 << PC2); // Anode L1/L2 - if (a & 0x0200) PORTC |= (1 << PC3); else PORTC &= ~(1 << PC3); // Anode L3 - break; - } - } - } - - void Seg7::setCathodes (uint8_t c) { - switch (hardwareVersion) { - case 1: { - if (c & 0x01) PORTC |= (1 << PC0); else PORTC &= ~(1 << PC0); // Chathode Char 1 (most left) - if (c & 0x02) PORTC |= (1 << PC1); else PORTC &= ~(1 << PC1); // Chathode Char 2 - if (c & 0x04) PORTC |= (1 << PC2); else PORTC &= ~(1 << PC2); // Chathode Char 3 - if (c & 0x08) PORTC |= (1 << PC3); else PORTC &= ~(1 << PC3); // Chathode Char 4 (most right) - break; - } - case 2: { - if (c & 0x01) PORTD |= (1 << PD5); else PORTD &= ~(1 << PD5); // Chathode Char 1 (most left) - if (c & 0x02) PORTB |= (1 << PB1); else PORTB &= ~(1 << PB1); // Chathode Char 2 - if (c & 0x04) PORTD |= (1 << PD3); else PORTD &= ~(1 << PD3); // Chathode Char 3 - if (c & 0x08) PORTD |= (1 << PD2); else PORTD &= ~(1 << PD2); // Chathode Char 4 (most right) - break; - } - } - } - - void Seg7::setOE (bool enabled) { - switch (hardwareVersion) { - case 1: if (enabled) PORTB &= ~(1 << PB1); else PORTB |= (1 << PB1); break; - case 2: if (enabled) PORTC &= ~(1 << PC1); else PORTC |= (1 << PC1); break; - } - } - -#endif - -const char *segName[] = { "A", "B", "C", "D", "E", "F", "G", "DP" }; - - -int8_t Seg7::run (uint8_t subtest) { - if (subtest == 0) { - setCathodes(0x0f); // all segment cathodes conected to GND - setAnodes(0x3ff); // all segments ON - setOE(true); - printf_P(PSTR("ON")); - wait(2000); - setAnodes(0); - return 0; - - } else if (subtest == 1) { - printf_P(PSTR("OFF")); - wait(1000); - return 0; - - } else if (subtest == 2) { - setAnodes(0x100); // L1/L2 ON - printf_P(PSTR("L1/L2 ON")); - wait(1000); - setAnodes(0); - return 0; - - } else if (subtest == 3) { - setAnodes(0x200); // L3 ON - printf_P(PSTR("L1/L2 ON")); - wait(1000); - setAnodes(0); - return 0; - - } else if (subtest < (4 + 4 * 8)) { - uint8_t chIndex = (subtest - 4) / 8; - uint8_t segIndex = (subtest - 4) % 8; - setCathodes(1 << chIndex); - setAnodes(1 << segIndex); - printf_P(PSTR("Char %d - %s -> %02x"), chIndex, segName[segIndex], (1 << segIndex)); - wait(400); - return 0; - } - - return -1; -} - - diff --git a/software/nano-644/test_2024-07-23/src/units/seg7.hpp b/software/nano-644/test_2024-07-23/src/units/seg7.hpp deleted file mode 100644 index 0e71fde..0000000 --- a/software/nano-644/test_2024-07-23/src/units/seg7.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef SEG7_HPP -#define SEG7_HPP - -#include -#include "../main.hpp" -#include - -class Seg7 : public TestUnit { - public: - bool enabled; - - public: - Seg7 () { enabled = false; } - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName () { return PSTR("Seg7"); } - - private: - void setAnodes (uint16_t); - void setCathodes (uint8_t mask); - void setOE (bool enabled); -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/switch.cpp b/software/nano-644/test_2024-07-23/src/units/switch.cpp deleted file mode 100644 index 4ce9456..0000000 --- a/software/nano-644/test_2024-07-23/src/units/switch.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include -#include - -#include "switch.hpp" -#include "../main.hpp" - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - - // Nano-644 - // --------------------------------------------------------------- - // PA0 ..... SW1 - // PA1 ..... SW2 - // PA2 ..... SW3 - // PA3 ..... SW4 - - void Switch::init () { - DDRA &= ~((1 << PORTA3) | (1 << PORTA2) | (1 << PORTA1) | (1 << PORTA0)); - PORTA |= (1 << PORTA3) | (1 << PORTA2) | (1 << PORTA1) | (1 << PORTA0); - } - - void Switch::cleanup () { - PORTA &= ~((1 << PORTA3) | (1 << PORTA2) | (1 << PORTA1) | (1 << PORTA0)); - DDRA &= ~((1 << PORTA3) | (1 << PORTA2) | (1 << PORTA1) | (1 << PORTA0)); - } - - bool Switch::isPressed (SWITCH sw) { - switch (sw) { - case SW1: return (PINA & ( 1 << PA0)) == 0; - case SW2: return (PINA & ( 1 << PA1)) == 0; - case SW3: return (PINA & ( 1 << PA2)) == 0; - case SW4: return (PINA & ( 1 << PA3)) == 0; - default: return false; - } - } - -#endif - -#ifdef __AVR_ATmega328P__ - - // Arduino-Nano-5V - // --------------------------------------------------------------- - // PC0 ..... SW1 - // PC1 ..... SW2 - // PC2 ..... SW3 - // PC3 ..... SW4 - - void Switch::init () { - DDRC &= ~((1 << PORTC3) | (1 << PORTC2) | (1 << PORTC1) | (1 << PORTC0)); - PORTC |= (1 << PORTC3) | (1 << PORTC2) | (1 << PORTC1) | (1 << PORTC0); - } - - void Switch::cleanup () { - PORTC &= ~((1 << PORTC3) | (1 << PORTC2) | (1 << PORTC1) | (1 << PORTC0)); - DDRC &= ~((1 << PORTC3) | (1 << PORTC2) | (1 << PORTC1) | (1 << PORTC0)); - } - - bool Switch::isPressed (SWITCH sw) { - switch (sw) { - case SW1: return (PINC & ( 1 << PC0)) == 0; - case SW2: return (PINC & ( 1 << PC1)) == 0; - case SW3: return (PINC & ( 1 << PC2)) == 0; - case SW4: return (PINC & ( 1 << PC3)) == 0; - default: return false; - } - } - -#endif - -int8_t Switch::run (uint8_t subtest) { - if (subtest < 16) { - SWITCH sw = (SWITCH)(subtest / 4); - switch (subtest % 4) { - case 1: { - if (!isPressed(sw)) { - printf_P(PSTR("Press SW%d"), sw + 1); - while (!isPressed(sw) && wait(0) == EOF) {} - wait(10); - } - return 0; - } - - case 0: case 2: { - if (isPressed(sw)) { - printf_P(PSTR("Release SW%d "), sw + 1); - while (isPressed(sw) && wait(0) == EOF) {} - wait(10); - } - return 0; - } - - case 3: { - return 0; - } - } - - } - - return -1; -} diff --git a/software/nano-644/test_2024-07-23/src/units/switch.hpp b/software/nano-644/test_2024-07-23/src/units/switch.hpp deleted file mode 100644 index 03bf0b2..0000000 --- a/software/nano-644/test_2024-07-23/src/units/switch.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef SWITCH_HPP -#define SWITCH_HPP - -#include -#include "../main.hpp" -#include - -class Switch : public TestUnit { - typedef enum { SW1 = 0, SW2 = 1, SW3 = 2, SW4 = 3 } SWITCH; - - public: - Switch () {}; - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName () { return PSTR("Switch"); } - bool isPressed (SWITCH sw); -}; - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/uart1.cpp b/software/nano-644/test_2024-07-23/src/units/uart1.cpp deleted file mode 100644 index 57e0bfb..0000000 --- a/software/nano-644/test_2024-07-23/src/units/uart1.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include - -#include "uart1.hpp" -#include "../main.hpp" - -#ifdef __AVR_ATmega328P__ - void Uart1::init () {} - void Uart1::cleanup () {} - int8_t Uart1::run (uint8_t subtest) { return -1; } - void Uart1::handleRxByte (uint8_t b) {} -#endif - -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - -int uart1_putchar(char c, FILE *stream) { - if (c == '\n') { - uart1_putchar('\r', stream); - } - loop_until_bit_is_set(UCSR1A, UDRE1); - UDR1 = c; - return 0; -} - -static FILE mystderr = { 0, 0, _FDEV_SETUP_WRITE , 0, 0, uart1_putchar, NULL, 0 }; - -void Uart1::init () { - PORTD |= (1 << PD2); // enable RxD1 pullup - UCSR1A = (1 << U2X1); - UCSR1B = (1 << RXCIE1) | (1 << RXEN1) | (1 < send text via UART1 now...")); - fprintf_P(stderr, PSTR("Hello UART1, ECHO-Modus active\n")); - } while (wait(5000) == EOF); - return 0; - } - - return -1; -} - -void Uart1::handleRxByte (uint8_t b) { - uart1_putchar(b, stderr); -} - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/uart1.hpp b/software/nano-644/test_2024-07-23/src/units/uart1.hpp deleted file mode 100644 index 40437e1..0000000 --- a/software/nano-644/test_2024-07-23/src/units/uart1.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef UART1_HPP -#define UART1_HPP - -#include -#include "../main.hpp" -#include - -class Uart1 : public TestUnit { - public: - uint8_t enabled; - - public: - Uart1 () { enabled = 0; } - virtual void init (); - virtual void cleanup (); - virtual int8_t run (uint8_t subtest); - virtual PGM_P getName () { return PSTR("Uart1"); } - void handleRxByte (uint8_t); -}; - -#endif \ No newline at end of file diff --git a/software/test-software/Makefile b/software/test-software/Makefile index f5eaedd..9df5e1b 100644 --- a/software/test-software/Makefile +++ b/software/test-software/Makefile @@ -1,22 +1,27 @@ -.PHONY: all release clean +.PHONY: all release clean-all clean SEP = -------------------------------------------------------- all: + @printf "\n\e[1;36m$(SEP)\n Arduino Nano\n$(SEP)\e[m\n" + -@make -C nano-328 @printf "\n\e[1;36m$(SEP)\nNano-644\n$(SEP)\e[m\n" -@make -C nano-644 @printf "\n\e[1;36m$(SEP)\n Nano-1284\n$(SEP)\e[m\n" -@make -C nano-1284 - @printf "\n\e[1;36m$(SEP)\n Arduino Nano\n$(SEP)\e[m\n" - -@make -C nano-328 release: + -@make -C nano-328 release -@make -C nano-644 release -@make -C nano-1284 release - -@make -C nano-328 release + +clean-all: clean + test -d nano-328/release && rm -r nano-328/release + test -d nano-644/release && rm -r nano-644/release + test -d nano-1284/release && rm -r nano-1284/release clean: + @make -C nano-328 clean @make -C nano-644 clean @make -C nano-1284 clean - @make -C nano-328 clean diff --git a/software/test-software/README.md b/software/test-software/README.md index c8ef394..cfc24f0 100644 --- a/software/test-software/README.md +++ b/software/test-software/README.md @@ -1,9 +1,9 @@ # Test-Software for Nano-X-Base This software supports: -* Arduino Nano (ATmega328P @16MHz) -* Nano-644 (ATmega644P @12MHz) -* Nano-1284 (ATmega1284P @12MHz) +* Arduino Nano (ATmega328P, 16MHz, 5V) +* Nano-644 (ATmega644P, 12MHz, 3.3V) +* Nano-1284 (ATmega1284P, 12MHz, 3.3V) For the Nano-X-Base hardware version: * V1a @@ -20,3 +20,18 @@ It is tested on a Debian system. * To create release folder use `make release` * To clean this folder use `make clean` (release files are not removed) + +## Flashing the target + +Ensure that bootloader is available on target. Then change to the subdirectory of your target and execute `make flash`. + +Bootloader git repository: +[https://git.htl-mechatronik.at/public/?p=bootloader-arduino.git;a=home](https://git.htl-mechatronik.at/public/?p=bootloader-arduino.git;a=home) + +For example: +``` +user@pc:~/nano-x-base/software/test-software$ cd nano-328 +user@pc:~/nano-x-base/software/test-software/nano-328$ make flash +... +user@pc:~/nano-x-base/software/test-software/nano-328$ make picocom +``` diff --git a/software/test-software/create-release b/software/test-software/create-release index 225277f..90a8fff 100755 --- a/software/test-software/create-release +++ b/software/test-software/create-release @@ -20,67 +20,101 @@ while [ ! -z "$1" ]; do shift shift - DATE_OBJDUMP=$(avr-objdump -tT "$FILE" 2>&1 | grep MAIN_CPP_DATE) + DATE_OBJDUMP=$(avr-objdump -tT "$FILE" 2>&1 | grep -e _.*DATE) if [ -z "$DATE_OBJDUMP" ]; then - printf " [1;31mERROR ($FILE -> %DIR): symbol MAIN_CPP_DATE not found\e[m\n" + printf " \e[1;31mERROR ($FILE -> $DIR): symbol DATE not found\e[m\n" exit 3 fi - TIME_OBJDUMP=$(avr-objdump -tT "$FILE" 2>&1 | grep MAIN_CPP_TIME) + TIME_OBJDUMP=$(avr-objdump -tT "$FILE" 2>&1 | grep -e _.*TIME) if [ -z "$DATE_OBJDUMP" ]; then - printf " [1;31mERROR ($FILE -> %DIR): symbol MAIN_CPP_TIME not found\e[m\n" + printf " \e[1;31mERROR ($FILE -> $DIR): symbol TIME not found\e[m\n" exit 4 fi + TEXT_SECT_READELF=$(readelf --syms ${FILE} | grep " .text") + if [ -z "$DATE_OBJDUMP" ]; then + printf " \e[1;31mERROR ($FILE -> $DIR): symbol .text not found\e[m\n" + exit 5 + fi + + avr-objcopy --dump-section .text=/tmp/.dumpsection.bin "$FILE" + SECT_TEXT_OFFSET_HEX="0x$(echo "$TEXT_SECT_READELF" | tr '\t' ' ' | tr -s ' ' | cut -d' ' -f 3)" + SECT_TEXT_OFFSET=$(( $(printf "%d" $SECT_TEXT_OFFSET_HEX) )) + DATE_OFFSET_HEX="0x$(echo "$DATE_OBJDUMP" | cut -d " " -f 1)" + DATE_LENGTH_HEX="0x$(echo "$DATE_OBJDUMP" | tr '\t' ' ' | tr -s ' ' | cut -d' ' -f 5)" + DATE_OFFSET=$(( $(printf "%d" $DATE_OFFSET_HEX) - $SECT_TEXT_OFFSET )) + DATE_LENGTH=$(( $(printf "%d" $DATE_LENGTH_HEX) - 1)) + TIME_OFFSET_HEX="0x$(echo "$TIME_OBJDUMP" | cut -d " " -f 1)" - DATE_OFFSET=$(( $(printf "%d" $DATE_OFFSET_HEX) + 148 )) - TIME_OFFSET=$(( $(printf "%d" $TIME_OFFSET_HEX) + 148 )) - - DATE_STRINGS=$(strings -a -t d "$FILE" | grep "$(printf "%7s" "$DATE_OFFSET")") - TIME_STRINGS=$(strings -a -t d "$FILE" | grep "$(printf "%7s" "$TIME_OFFSET")") + TIME_LENGTH_HEX="0x$(echo "$TIME_OBJDUMP" | tr '\t' ' ' | tr -s ' ' | cut -d' ' -f 5)" + TIME_OFFSET=$(( $(printf "%d" $TIME_OFFSET_HEX) - $SECT_TEXT_OFFSET )) + TIME_LENGTH=$(( $(printf "%d" $TIME_LENGTH_HEX) - 1)) + + DATE_STRING=$(hexdump -s ${DATE_OFFSET} -n ${DATE_LENGTH} -e "${DATE_LENGTH} \"%_p\" \"\\n\"" /tmp/.dumpsection.bin) + TIME_STRING=$(hexdump -s ${TIME_OFFSET} -n ${TIME_LENGTH} -e "${TIME_LENGTH} \"%_p\" \"\\n\"" /tmp/.dumpsection.bin) - DATE_MONTH_STRING=$(echo $DATE_STRINGS | cut -d' ' -f2) + DATE_MONTH_STRING=$(echo $DATE_STRING | cut -d' ' -f1) case "$DATE_MONTH_STRING" in - Jan) DATE_MONTH="01";; - Feb) DATE_MONTH="02";; - Mar) DATE_MONTH="03";; - Apr) DATE_MONTH="04";; - May) DATE_MONTH="05";; - Jun) DATE_MONTH="06";; - Jul) DATE_MONTH="07";; - Aug) DATE_MONTH="08";; - Sep) DATE_MONTH="09";; + Jan) DATE_MONTH="1";; + Feb) DATE_MONTH="2";; + Mar) DATE_MONTH="3";; + Apr) DATE_MONTH="4";; + May) DATE_MONTH="5";; + Jun) DATE_MONTH="6";; + Jul) DATE_MONTH="7";; + Aug) DATE_MONTH="8";; + Sep) DATE_MONTH="9";; Oct) DATE_MONTH="10";; Nov) DATE_MONTH="11";; Dec) DATE_MONTH="12";; - *) printf " [1;31mERROR ($FILE -> %DIR): invalidate date in file $FILE\e[m\n"; exit 5;; + *) printf " \e[1;31mERROR ($FILE -> $DIR): invalidate date ($DATE_STRINGS) in file $FILE\e[m\n"; exit 6;; esac - DATE_DAY=$(echo $DATE_STRINGS | cut -d' ' -f3) - DATE_YEAR=$(echo $DATE_STRINGS | cut -d' ' -f4) - TIME_VALUE=$(echo $TIME_STRINGS | cut -d' ' -f2-) - TIME_HOUR=$(echo $TIME_VALUE | cut -d ':' -f1) - TIME_MINUTE=$(echo $TIME_VALUE | cut -d ':' -f2) - TIME_SECOND=$(echo $TIME_VALUE | cut -d ':' -f3) + DATE_DAY=$(echo $DATE_STRING | cut -d' ' -f2 | sed 's/^0*//') + DATE_YEAR=$(echo $DATE_STRING | cut -d' ' -f3 | sed 's/^0*//') + TIME_VALUE=$(echo $TIME_STRING | cut -d' ' -f2-) + TIME_HOUR=$(echo $TIME_STRING | cut -d ':' -f1 | sed 's/^0*//') + TIME_MINUTE=$(echo $TIME_STRING | cut -d ':' -f2 | sed 's/^0*//') + TIME_SECOND=$(echo $TIME_STRING | cut -d ':' -f3 | sed 's/^0*//') NAME=$(printf "v%4d-%02d-%02d_%02d%02d%02d" $DATE_YEAR $DATE_MONTH $DATE_DAY $TIME_HOUR $TIME_MINUTE $TIME_SECOND | egrep ^v[0-9]{4}-[0-9]{2}-[0-9]{1,2}_[0-9]{2}[0-9]{2}[0-9]{2}$) if [ -z "$NAME" ]; then - printf " [1;31mERROR ($FILE -> %DIR): cannot create release name\e[m\n" - exit 6 + printf " \e[1;31mERROR ($FILE -> $DIR): cannot create release name\e[m\n" + exit 7 fi FILENAME=$(echo "$FILE" | rev | cut -d"/" -f1 | rev) if [ -d "$DIR/$NAME" ] && [ -f "$DIR/$NAME/$FILENAME" ]; then - echo " OK: release already done ($FILE -> $DIR/$NAME)" + echo " OK: release already created ($FILE -> $DIR/$NAME)" else test -d "$DIR/$NAME" || mkdir "$DIR/$NAME" cp -a "$FILE" "$DIR/$NAME/" if [ $? = 0 ]; then echo " OK ($FILE -> $DIR/$NAME)" else - printf " [1;31mERROR ($FILE -> %DIR)\e[m\n" + printf " \e[1;31mERROR ($FILE -> $DIR)\e[m\n" + exit 8 fi fi + for suffix in "hex" "bin"; do + SUFFIXFILE=$(echo $FILE | sed "s/.elf$/.${suffix}/") + SUFFIXFILENAME=$(echo "$SUFFIXFILE" | rev | cut -d"/" -f1 | rev) + if [ -f "$SUFFIXFILE" ]; then + if [ -d "$DIR/$NAME" ] && [ -f "$DIR/$NAME/$SUFFIXFILENAME" ]; then + echo " OK: release ${suffix}-file already created ($FILE -> $DIR/$NAME)" + else + test -d "$DIR/$NAME" || mkdir "$DIR/$NAME" + cp -a "$SUFFIXFILE" "$DIR/$NAME/" + if [ $? = 0 ]; then + echo " OK ($SUFFIXFILE -> $DIR/$NAME)" + else + printf " \e[1;31mERROR ($SUFFIXFILE -> $DIR)\e[m\n" + exit 8 + fi + fi + fi + done done diff --git a/software/test-software/create-release.old b/software/test-software/create-release.old new file mode 100755 index 0000000..225277f --- /dev/null +++ b/software/test-software/create-release.old @@ -0,0 +1,86 @@ +#!/bin/sh +#set -x + +while [ ! -z "$1" ]; do + DIR="$1" + FILE="$2" + + #echo " creating release folder for file $FILE in directory $DIR ..." + + if [ ! -d "$DIR" ]; then + printf " [1;31mERROR: missing target directory $DIR\e[m\n" + exit 1 + fi + + if [ -z "$FILE" ] || [ ! -f "$FILE" ]; then + printf " [1;31mERROR: missing file $FILE\e[m\n" + exit 2 + fi + + shift + shift + + DATE_OBJDUMP=$(avr-objdump -tT "$FILE" 2>&1 | grep MAIN_CPP_DATE) + if [ -z "$DATE_OBJDUMP" ]; then + printf " [1;31mERROR ($FILE -> %DIR): symbol MAIN_CPP_DATE not found\e[m\n" + exit 3 + fi + + TIME_OBJDUMP=$(avr-objdump -tT "$FILE" 2>&1 | grep MAIN_CPP_TIME) + if [ -z "$DATE_OBJDUMP" ]; then + printf " [1;31mERROR ($FILE -> %DIR): symbol MAIN_CPP_TIME not found\e[m\n" + exit 4 + fi + + DATE_OFFSET_HEX="0x$(echo "$DATE_OBJDUMP" | cut -d " " -f 1)" + TIME_OFFSET_HEX="0x$(echo "$TIME_OBJDUMP" | cut -d " " -f 1)" + DATE_OFFSET=$(( $(printf "%d" $DATE_OFFSET_HEX) + 148 )) + TIME_OFFSET=$(( $(printf "%d" $TIME_OFFSET_HEX) + 148 )) + + DATE_STRINGS=$(strings -a -t d "$FILE" | grep "$(printf "%7s" "$DATE_OFFSET")") + TIME_STRINGS=$(strings -a -t d "$FILE" | grep "$(printf "%7s" "$TIME_OFFSET")") + + DATE_MONTH_STRING=$(echo $DATE_STRINGS | cut -d' ' -f2) + case "$DATE_MONTH_STRING" in + Jan) DATE_MONTH="01";; + Feb) DATE_MONTH="02";; + Mar) DATE_MONTH="03";; + Apr) DATE_MONTH="04";; + May) DATE_MONTH="05";; + Jun) DATE_MONTH="06";; + Jul) DATE_MONTH="07";; + Aug) DATE_MONTH="08";; + Sep) DATE_MONTH="09";; + Oct) DATE_MONTH="10";; + Nov) DATE_MONTH="11";; + Dec) DATE_MONTH="12";; + *) printf " [1;31mERROR ($FILE -> %DIR): invalidate date in file $FILE\e[m\n"; exit 5;; + esac + + DATE_DAY=$(echo $DATE_STRINGS | cut -d' ' -f3) + DATE_YEAR=$(echo $DATE_STRINGS | cut -d' ' -f4) + TIME_VALUE=$(echo $TIME_STRINGS | cut -d' ' -f2-) + TIME_HOUR=$(echo $TIME_VALUE | cut -d ':' -f1) + TIME_MINUTE=$(echo $TIME_VALUE | cut -d ':' -f2) + TIME_SECOND=$(echo $TIME_VALUE | cut -d ':' -f3) + + NAME=$(printf "v%4d-%02d-%02d_%02d%02d%02d" $DATE_YEAR $DATE_MONTH $DATE_DAY $TIME_HOUR $TIME_MINUTE $TIME_SECOND | egrep ^v[0-9]{4}-[0-9]{2}-[0-9]{1,2}_[0-9]{2}[0-9]{2}[0-9]{2}$) + if [ -z "$NAME" ]; then + printf " [1;31mERROR ($FILE -> %DIR): cannot create release name\e[m\n" + exit 6 + fi + FILENAME=$(echo "$FILE" | rev | cut -d"/" -f1 | rev) + if [ -d "$DIR/$NAME" ] && [ -f "$DIR/$NAME/$FILENAME" ]; then + echo " OK: release already done ($FILE -> $DIR/$NAME)" + else + test -d "$DIR/$NAME" || mkdir "$DIR/$NAME" + cp -a "$FILE" "$DIR/$NAME/" + if [ $? = 0 ]; then + echo " OK ($FILE -> $DIR/$NAME)" + else + printf " [1;31mERROR ($FILE -> %DIR)\e[m\n" + fi + fi + +done + diff --git a/software/test-software/nano-1284/Makefile b/software/test-software/nano-1284/Makefile index 6a29271..8485c67 100644 --- a/software/test-software/nano-1284/Makefile +++ b/software/test-software/nano-1284/Makefile @@ -1,42 +1,62 @@ -.PHONY: all info flash flash0 flash1 flash2 picocom picocom0 picocom1 picocom2 release clean $(shell mkdir -p dist >/dev/null) $(shell mkdir -p build >/dev/null) $(shell mkdir -p sim >/dev/null) $(shell mkdir -p sim/build >/dev/null) $(shell mkdir -p release/sim >/dev/null) -NAME=test-software_nano-1284p_12mhz -SRC= $(wildcard src/*.c src/*.cpp src/*/*.c src/*/*.cpp) -HDR= $(wildcard src/*.h src/*.hpp src/*/*.h src/*/*.hpp) +# -------------------------------------------------------------------------------- +# Variables configured by engineer + +NAME=nano-x-base_test-software_nano-m1284p_12mhz +DEVICE=atmega1284p +AVRDUDE_DEVICE=m1284p +CPU_FREQUENCY=12000000 +BAUDRATE=115200 +START_ADDRESS=0 + +# -------------------------------------------------------------------------------- +# Automatic created Makefile variables + +SRC= $(wildcard src/*.c src/*.cpp src/*/*.c src/*/*.cpp) +HDR= $(wildcard src/*.h src/*.hpp src/*/*.h src/*/*.hpp) +MAINSRC= $(wildcard src/main.c src/main.cpp) OBJ_CPP = $(SRC:src/%.cpp=build/%.o) OBJ = $(OBJ_CPP:src/%.c=build/%.o) OBJ_SIM_CPP = $(SRC:src/%.cpp=sim/build/%.o) OBJ_SIM = $(OBJ_SIM_CPP:src/%.c=sim/build/%.o) -DEVICE=atmega1284p -AVRDUDE_DEVICE=m1284p - CC= avr-g++ -CFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=12000000 -c -LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=12000000 -Wl,-u,vfprintf -lprintf_flt -lm - -CFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=12000000 -g -c -c -LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=12000000 -g -Wl,-u,vfprintf -lprintf_flt -lm +CFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=$(CPU_FREQUENCY) -DBAUD_RATE=$(BAUDRATE) -DDOUBLE_SPEED -DNUM_LED_FLASHES=4 '-DMAX_TIME_COUNT=F_CPU>>4' -c +#LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=$(CPU_FREQUENCY) -Wl,-u,vfprintf -lprintf_flt -lm +LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=$(CPU_FREQUENCY) -Wl,--section-start=.text=$(START_ADDRESS) -# ------------------------------------------------ +CFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=$(CPU_FREQUENCY) -g -DBAUD_RATE=$(BAUDRATE) -DDOUBLE_SPEED -DNUM_LED_FLASHES=4 '-DMAX_TIME_COUNT=F_CPU>>4' -c +#LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=$(CPU_FREQUENCY) -g -Wl,-u,vfprintf -lprintf_flt -lm +LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=$(CPU_FREQUENCY) -g -Wl,--section-start=.text=$(START_ADDRESS) -all: dist/$(NAME).elf dist/$(NAME).s dist/$(NAME).hex sim/$(NAME).elf sim/$(NAME).s info +# -------------------------------------------------------------------------------- +# make targets -isp-fuse-$(AVRDUDE_DEVICE): - avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xFF:m -U lock:w:0xFF:m +.PHONY: all +all: dist/$(NAME).elf sim/$(NAME).elf dist/$(NAME).s dist/$(NAME).hex dist/$(NAME).bin sim/$(NAME).s info +.PHONY: info info: + @echo @avr-size --mcu=$(DEVICE) --format=avr dist/$(NAME).elf +# -------------------------------------------------------------------------------- +# dependency make for hierarchical source file structure + .depend: $(SRC) $(HDR) $(CC) -mmcu=$(DEVICE) -MM $(SRC) | sed --regexp-extended 's/^(.*\.o)\: src\/(.*)(\.cpp|\.c) (.*)/build\/\2\.o\: src\/\2\3 \4/g' > .depend +ifneq (clean,$(filter clean,$(MAKECMDGOALS))) -include .depend +endif + +# -------------------------------------------------------------------------------- +# elf, hex and assembler file creation dist/$(NAME).elf: .depend $(OBJ) $(CC) $(LFLAGS) -o $@ $(OBJ) @@ -47,13 +67,28 @@ dist/%.s: dist/%.elf dist/%.hex: dist/%.elf avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ -sim/$(NAME).elf: .depend $(OBJ_SIM) - $(CC) $(LFLAGS_SIM) -o $@ $(OBJ_SIM) - -# ensure that __DATE__ and __TIME__ macros are up to date -build/main.o: src/main.cpp $(SRC) $(HDR) +dist/%.bin: dist/%.elf + avr-objcopy -O binary $(HEX_FLASH_FLAGS) $< $@ + +# -------------------------------------------------------------------------------- +# check if the macros __DATE__ or __TIME__ are used in src/main.cpp or src/main.c + +DATE_USED= +ifneq ($(shell cat $(MAINSRC) | grep __DATE__),) + DATE_USED=true +endif +TIME_USED= +ifneq ($(shell cat $(MAINSRC) | grep __TIME__),) + TIME_USED=true +endif + +ifeq (true, $(filter true, $(DATE_USED) $(TIME_USED))) +build/main.o: $(MAIN_SRC) $(SRC) $(HDR) @mkdir -p $(dir $@) $(CC) $(CFLAGS) -o $@ $< +endif + +# -------------------------------------------------------------------------------- build/%.o: src/%.c @mkdir -p $(dir $@) @@ -63,6 +98,13 @@ build/%.o: src/%.cpp @mkdir -p $(dir $@) $(CC) $(CFLAGS) -o $@ $< +# -------------------------------------------------------------------------------- +# simulation/debugging with gdb or simuc + +sim/$(NAME).elf: .depend $(OBJ_SIM) + $(CC) $(LFLAGS_SIM) -o $@ $(OBJ_SIM) + @ln -sf $(NAME).elf sim/$(DEVICE).elf + sim/build/%.o: src/%.c @mkdir -p $(dir $@) $(CC) $(CFLAGS_SIM) -o $@ $< @@ -74,52 +116,144 @@ sim/build/%.o: src/%.cpp sim/%.s: sim/%.elf avr-objdump -d $< > $@ +ifeq (m16, $(AVRDUDE_DEVICE)) +simuc: sim/$(NAME).elf + simuc --board sure $< +endif + +ifeq (m328p, $(AVRDUDE_DEVICE)) +simuc: sim/$(NAME).elf + simuc --board arduino $< +endif + +ifeq (m644p, $(AVRDUDE_DEVICE)) +simuc: sim/$(NAME).elf + simuc --board nano-644 $< +endif + +ifeq (m1284p, $(AVRDUDE_DEVICE)) simuc: sim/$(NAME).elf simuc --board nano-1284 $< +endif gdb: sim/$(NAME).elf avr-gdb $< +# ------------------------------------------------------------- +# flash to target with arduino bootloader in bootloader-section +.PHONY: flash flash: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB0 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + avrdude -c arduino -P /dev/ttyUSB0 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -e -U flash:w:$< +.PHONY: flash0 flash0: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB0 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + avrdude -c arduino -P /dev/ttyUSB0 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -e -U flash:w:$< +.PHONY: flash1 flash1: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB1 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + avrdude -c arduino -P /dev/ttyUSB1 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -e -U flash:w:$< +.PHONY: flash2 flash2: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB2 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + avrdude -c arduino -P /dev/ttyUSB2 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -e -U flash:w:$< +.PHONY: flash-read +flash-read: + avrdude -c arduino -P /dev/ttyUSB0 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -U flash:r:/tmp/flash.bin -picocom: - # picocom sends CR for ENTER -> convert cr (\r) to lf (\n) - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0 - -picocom0: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0 +.PHONY: flash-disassemble +flash-disassemble: flash-read + avr-objdump -b binary -D -m avr5 /tmp/flash.bin > /tmp/flash.s + less /tmp/flash.s -picocom1: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB1 - -picocom2: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB2 +.PHONY: flash-hexdump +flash-hexdump: flash-read + hexdump -C /tmp/flash.bin | less +# ---------------------------------------------- +# flash to target with fischl programming device -isp-1284p: +.PHONY: isp-flash-$(AVRDUDE_DEVICE) +isp-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lock:r:-:h avrdude -c usbasp -p $(AVRDUDE_DEVICE) -isp-flash-1284p: dist/$(NAME).elf all +.PHONY: isp-flash +isp-flash: dist/$(NAME).elf all avrdude -c usbasp -p $(AVRDUDE_DEVICE) -e -U flash:w:$< -flash-1284p: dist/$(NAME).elf all - avrdude -c arduino -p $(AVRDUDE_DEVICE) -P /dev/ttyUSB0 -b 115200 -e -U flash:w:$< +.PHONY: isp-flash-$(AVRDUDE_DEVICE) +isp-flash-$(AVRDUDE_DEVICE): dist/$(NAME).elf all + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + +.PHONY: isp-read-flash-$(AVRDUDE_DEVICE) +isp-read-flash-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p m32$(AVRDUDE_DEVICE)8p -U flash:r:/tmp/flash-arduino-atmega328p__$(shell date +"%Y-%m-%d_%H%M%S") + +.PHONY: isp-fuse +isp-fuse: isp-fuse-$(AVRDUDE_DEVICE) -release: dist/$(NAME).elf sim/$(NAME).elf +.PHONY: isp-fuse-$(AVRDUDE_DEVICE) +ifeq (m16, $(AVRDUDE_DEVICE)) +isp-fuse-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0x18:m -U hfuse:w:0xD8:m -U lock:w:0xEF:m +endif +ifeq (m328p, $(AVRDUDE_DEVICE)) +isp-fuse-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xEF:m -U hfuse:w:0xD8:m -U efuse:w:0xFD:m -U lock:w:0xEF:m +endif +ifeq (m644p, $(AVRDUDE_DEVICE)) +isp-fuse-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xEF:m -U hfuse:w:0xD8:m -U efuse:w:0xFD:m -U lock:w:0xEF:m +endif +ifeq (m1284p, $(AVRDUDE_DEVICE)) +isp-fuse-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xEF:m -U hfuse:w:0xD8:m -U efuse:w:0xFD:m -U lock:w:0xEF:m +endif + +# -------------------------------------------------------- +# picocom sends CR for ENTER -> convert cr (\r) to lf (\n) + +.PHONY: picocom +picocom: + picocom -b $(BAUDRATE) --omap crlf --raise-dtr /dev/ttyUSB0 + +.PHONY: picocom0 +picocom0: + picocom -b $(BAUDRATE) --omap crlf --raise-dtr /dev/ttyUSB0 + +.PHONY: picocom1 +picocom1: + picocom -b $(BAUDRATE) --omap crlf --raise-dtr /dev/ttyUSB1 + +.PHONY: picocom2 +picocom2: + picocom -b $(BAUDRATE) --omap crlf --raise-dtr /dev/ttyUSB2 + +# -------------------------------------------------------- + +.PHONY: help +help: + @echo + @echo "Possible targets are:" + @echo " clean" + @echo " all help info" + @echo " flash flash0 flash1 flash2 flash-read flash-disassemble flash-hexdump" + @echo " isp-$(AVRDUDE_DEVICE) isp-flash-$(AVRDUDE_DEVICE) isp-fuse-$(AVRDUDE_DEVICE)" + @echo " picocom picocom0 picocom1 picocom2" + @echo " gdb simuc" + @echo + +# -------------------------------------------------------- + +.PHONY: release +release: dist/$(NAME).elf sim/$(NAME).elf dist/$(NAME).hex dist/$(NAME).bin ../create-release release $(word 1, $^) release/sim $(word 2, $^) +# -------------------------------------------------------- + +.PHONY: clean clean: @rm -r dist @rm -r build diff --git a/software/test-software/nano-1284/release/v2024-10-28_141638/test-software_nano-1284p_12mhz.elf b/software/test-software/nano-1284/release/v2024-10-28_141638/test-software_nano-1284p_12mhz.elf deleted file mode 100755 index 03b31ccf9315d39ea4add6f4e90bb24db7778a73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75868 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[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/dev/null) $(shell mkdir -p build >/dev/null) $(shell mkdir -p sim >/dev/null) $(shell mkdir -p sim/build >/dev/null) $(shell mkdir -p release/sim >/dev/null) -NAME=test-software_nano-328p_16mhz -SRC= $(wildcard src/*.c src/*.cpp src/*/*.c src/*/*.cpp) -HDR= $(wildcard src/*.h src/*.hpp src/*/*.h src/*/*.hpp) -OBJ_CPP = $(SRC:src/%.cpp=build/%.o) -OBJ = $(OBJ_CPP:src/%.c=build/%.o) -OBJ_SIM_CPP = $(SRC:src/%.cpp=sim/build/%.o) -OBJ_SIM = $(OBJ_SIM_CPP:src/%.c=sim/build/%.o) +# -------------------------------------------------------------------------------- +# Variables configured by engineer +NAME=nano-x-base_test-software_nano-m328p_16mhz DEVICE=atmega328p AVRDUDE_DEVICE=m328p +CPU_FREQUENCY=16000000 +BAUDRATE=38400 +START_ADDRESS=0 -CC= avr-g++ -CFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=16000000 -c -LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=16000000 -Wl,-u,vfprintf -lprintf_flt -lm +# -------------------------------------------------------------------------------- +# Automatic created Makefile variables -CFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=16000000 -g -c -c -LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=16000000 -g -Wl,-u,vfprintf -lprintf_flt -lm +SRC= $(wildcard src/*.c src/*.cpp src/*/*.c src/*/*.cpp) +HDR= $(wildcard src/*.h src/*.hpp src/*/*.h src/*/*.hpp) +MAINSRC= $(wildcard src/main.c src/main.cpp) +OBJ_CPP = $(SRC:src/%.cpp=build/%.o) +OBJ = $(OBJ_CPP:src/%.c=build/%.o) +OBJ_SIM_CPP = $(SRC:src/%.cpp=sim/build/%.o) +OBJ_SIM = $(OBJ_SIM_CPP:src/%.c=sim/build/%.o) +CC= avr-g++ +CFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=$(CPU_FREQUENCY) -DBAUD_RATE=$(BAUDRATE) -DDOUBLE_SPEED -DNUM_LED_FLASHES=4 '-DMAX_TIME_COUNT=F_CPU>>4' -c +#LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=$(CPU_FREQUENCY) -Wl,-u,vfprintf -lprintf_flt -lm +LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=$(CPU_FREQUENCY) -Wl,--section-start=.text=$(START_ADDRESS) -all: dist/$(NAME).elf dist/$(NAME).s dist/$(NAME).hex sim/$(NAME).elf sim/$(NAME).s info +CFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=$(CPU_FREQUENCY) -g -DBAUD_RATE=$(BAUDRATE) -DDOUBLE_SPEED -DNUM_LED_FLASHES=4 '-DMAX_TIME_COUNT=F_CPU>>4' -c +#LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=$(CPU_FREQUENCY) -g -Wl,-u,vfprintf -lprintf_flt -lm +LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=$(CPU_FREQUENCY) -g -Wl,--section-start=.text=$(START_ADDRESS) -isp-fuse-$(AVRDUDE_DEVICE): - avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xFF:m -U lock:w:0xFF:m +# -------------------------------------------------------------------------------- +# make targets -# ------------------------------------------------ +.PHONY: all +all: dist/$(NAME).elf sim/$(NAME).elf dist/$(NAME).s dist/$(NAME).hex dist/$(NAME).bin sim/$(NAME).s info +.PHONY: info info: + @echo @avr-size --mcu=$(DEVICE) --format=avr dist/$(NAME).elf +# -------------------------------------------------------------------------------- +# dependency make for hierarchical source file structure + .depend: $(SRC) $(HDR) $(CC) -mmcu=$(DEVICE) -MM $(SRC) | sed --regexp-extended 's/^(.*\.o)\: src\/(.*)(\.cpp|\.c) (.*)/build\/\2\.o\: src\/\2\3 \4/g' > .depend +ifneq (clean,$(filter clean,$(MAKECMDGOALS))) -include .depend +endif + +# -------------------------------------------------------------------------------- +# elf, hex and assembler file creation dist/$(NAME).elf: .depend $(OBJ) $(CC) $(LFLAGS) -o $@ $(OBJ) @@ -48,13 +67,28 @@ dist/%.s: dist/%.elf dist/%.hex: dist/%.elf avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ -sim/$(NAME).elf: .depend $(OBJ_SIM) - $(CC) $(LFLAGS_SIM) -o $@ $(OBJ_SIM) - -# ensure that __DATE__ and __TIME__ macros are up to date -build/main.o: src/main.cpp $(SRC) $(HDR) +dist/%.bin: dist/%.elf + avr-objcopy -O binary $(HEX_FLASH_FLAGS) $< $@ + +# -------------------------------------------------------------------------------- +# check if the macros __DATE__ or __TIME__ are used in src/main.cpp or src/main.c + +DATE_USED= +ifneq ($(shell cat $(MAINSRC) | grep __DATE__),) + DATE_USED=true +endif +TIME_USED= +ifneq ($(shell cat $(MAINSRC) | grep __TIME__),) + TIME_USED=true +endif + +ifeq (true, $(filter true, $(DATE_USED) $(TIME_USED))) +build/main.o: $(MAIN_SRC) $(SRC) $(HDR) @mkdir -p $(dir $@) $(CC) $(CFLAGS) -o $@ $< +endif + +# -------------------------------------------------------------------------------- build/%.o: src/%.c @mkdir -p $(dir $@) @@ -64,6 +98,13 @@ build/%.o: src/%.cpp @mkdir -p $(dir $@) $(CC) $(CFLAGS) -o $@ $< +# -------------------------------------------------------------------------------- +# simulation/debugging with gdb or simuc + +sim/$(NAME).elf: .depend $(OBJ_SIM) + $(CC) $(LFLAGS_SIM) -o $@ $(OBJ_SIM) + @ln -sf $(NAME).elf sim/$(DEVICE).elf + sim/build/%.o: src/%.c @mkdir -p $(dir $@) $(CC) $(CFLAGS_SIM) -o $@ $< @@ -75,52 +116,144 @@ sim/build/%.o: src/%.cpp sim/%.s: sim/%.elf avr-objdump -d $< > $@ +ifeq (m16, $(AVRDUDE_DEVICE)) +simuc: sim/$(NAME).elf + simuc --board sure $< +endif + +ifeq (m328p, $(AVRDUDE_DEVICE)) +simuc: sim/$(NAME).elf + simuc --board arduino $< +endif + +ifeq (m644p, $(AVRDUDE_DEVICE)) +simuc: sim/$(NAME).elf + simuc --board nano-644 $< +endif + +ifeq (m1284p, $(AVRDUDE_DEVICE)) simuc: sim/$(NAME).elf simuc --board nano-1284 $< +endif gdb: sim/$(NAME).elf avr-gdb $< +# ------------------------------------------------------------- +# flash to target with arduino bootloader in bootloader-section +.PHONY: flash flash: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB0 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + avrdude -c arduino -P /dev/ttyUSB0 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -e -U flash:w:$< +.PHONY: flash0 flash0: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB0 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + avrdude -c arduino -P /dev/ttyUSB0 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -e -U flash:w:$< +.PHONY: flash1 flash1: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB1 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + avrdude -c arduino -P /dev/ttyUSB1 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -e -U flash:w:$< +.PHONY: flash2 flash2: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB2 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + avrdude -c arduino -P /dev/ttyUSB2 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -e -U flash:w:$< +.PHONY: flash-read +flash-read: + avrdude -c arduino -P /dev/ttyUSB0 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -U flash:r:/tmp/flash.bin -picocom: - # picocom sends CR for ENTER -> convert cr (\r) to lf (\n) - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0 - -picocom0: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0 +.PHONY: flash-disassemble +flash-disassemble: flash-read + avr-objdump -b binary -D -m avr5 /tmp/flash.bin > /tmp/flash.s + less /tmp/flash.s -picocom1: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB1 - -picocom2: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB2 +.PHONY: flash-hexdump +flash-hexdump: flash-read + hexdump -C /tmp/flash.bin | less +# ---------------------------------------------- +# flash to target with fischl programming device -isp-1284p: +.PHONY: isp-flash-$(AVRDUDE_DEVICE) +isp-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lock:r:-:h avrdude -c usbasp -p $(AVRDUDE_DEVICE) -isp-flash-1284p: dist/$(NAME).elf all +.PHONY: isp-flash +isp-flash: dist/$(NAME).elf all avrdude -c usbasp -p $(AVRDUDE_DEVICE) -e -U flash:w:$< -flash-1284p: dist/$(NAME).elf all - avrdude -c arduino -p $(AVRDUDE_DEVICE) -P /dev/ttyUSB0 -b 115200 -e -U flash:w:$< +.PHONY: isp-flash-$(AVRDUDE_DEVICE) +isp-flash-$(AVRDUDE_DEVICE): dist/$(NAME).elf all + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + +.PHONY: isp-read-flash-$(AVRDUDE_DEVICE) +isp-read-flash-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p m32$(AVRDUDE_DEVICE)8p -U flash:r:/tmp/flash-arduino-atmega328p__$(shell date +"%Y-%m-%d_%H%M%S") + +.PHONY: isp-fuse +isp-fuse: isp-fuse-$(AVRDUDE_DEVICE) -release: dist/$(NAME).elf sim/$(NAME).elf +.PHONY: isp-fuse-$(AVRDUDE_DEVICE) +ifeq (m16, $(AVRDUDE_DEVICE)) +isp-fuse-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0x18:m -U hfuse:w:0xD8:m -U lock:w:0xEF:m +endif +ifeq (m328p, $(AVRDUDE_DEVICE)) +isp-fuse-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xEF:m -U hfuse:w:0xD8:m -U efuse:w:0xFD:m -U lock:w:0xEF:m +endif +ifeq (m644p, $(AVRDUDE_DEVICE)) +isp-fuse-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xEF:m -U hfuse:w:0xD8:m -U efuse:w:0xFD:m -U lock:w:0xEF:m +endif +ifeq (m1284p, $(AVRDUDE_DEVICE)) +isp-fuse-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xEF:m -U hfuse:w:0xD8:m -U efuse:w:0xFD:m -U lock:w:0xEF:m +endif + +# -------------------------------------------------------- +# picocom sends CR for ENTER -> convert cr (\r) to lf (\n) + +.PHONY: picocom +picocom: + picocom -b $(BAUDRATE) --omap crlf --raise-dtr /dev/ttyUSB0 + +.PHONY: picocom0 +picocom0: + picocom -b $(BAUDRATE) --omap crlf --raise-dtr /dev/ttyUSB0 + +.PHONY: picocom1 +picocom1: + picocom -b $(BAUDRATE) --omap crlf --raise-dtr /dev/ttyUSB1 + +.PHONY: picocom2 +picocom2: + picocom -b $(BAUDRATE) --omap crlf --raise-dtr /dev/ttyUSB2 + +# -------------------------------------------------------- + +.PHONY: help +help: + @echo + @echo "Possible targets are:" + @echo " clean" + @echo " all help info" + @echo " flash flash0 flash1 flash2 flash-read flash-disassemble flash-hexdump" + @echo " isp-$(AVRDUDE_DEVICE) isp-flash-$(AVRDUDE_DEVICE) isp-fuse-$(AVRDUDE_DEVICE)" + @echo " picocom picocom0 picocom1 picocom2" + @echo " gdb simuc" + @echo + +# -------------------------------------------------------- + +.PHONY: release +release: dist/$(NAME).elf sim/$(NAME).elf dist/$(NAME).hex dist/$(NAME).bin ../create-release release $(word 1, $^) release/sim $(word 2, $^) +# -------------------------------------------------------- + +.PHONY: clean clean: @rm -r dist @rm -r build diff --git a/software/test-software/nano-328/release/v2024-10-28_141640/test-software_nano-328p_16mhz.elf b/software/test-software/nano-328/release/v2024-10-28_141640/test-software_nano-328p_16mhz.elf deleted file mode 100755 index 480cd668d429fc250e10f264c8ce9fda5530648e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56356 zcmcG%3qTWB_CG!YK@vbhe4wb9ASfW@0ruYt+j z^SQ5c&pr3vb00I=GIi!Ok|YV?<44RR1Zot3Lw+QP0Jx7LRD?efNAxCwIDdx_0q(D^ z3(0}E?hnNhg3aLz)!6 zKdFhy>NDxk!Gj||`RdCrXHG(oPk=m#E`kq-E<&2I@tfmQ%Fpzj7!f+*j~`DieKTQF zQG4n7Pkyj8ADA@L(9!(~`KRtJX%BM`j#1_;oe$bB~64!rk z{^{v#Y4q8XXWv@f+;p_|{JGY7pN_vUr(u0<+l5nQBd%0b@65lNzPb2r$49#w(|`H! zwc^*@)_^BQb}g|#yYlwa&z&56muc<&==~e23-1x9uUa+!gk$uE0K!l<6eOdXjoEz` zk^&!j{i;4jMMlTAsD2fXT$ms3x_{yC1J9H_Hg0g&=16PgtH)boRLNy)mJXwc&pTt< z_nw~^yR2Zvs^XHh&u?7xBoQ=xRKa)^@f2J^K|szcTv@nmo$C2jE7k!tJY}OwqtU2{ zsdMLM&mFJITD4xkaz%k^x_(W;2K|~sRow7`cp_uHe#J_C{>nlw+S>6!L4*)sylQv> zq0*|jD=0{S0aX{n)q*gf>eYz6(VWW_@pu8N9l-cD1Y)e zRkAL56p=;@9}SstylsqE5xrHaiIY@QS1l_pC|sk8D|voxk!oGBYT3#{{hD|Xn8$}G zTvb2>sj`x%sOHVgSTJ?GYWbSt=Ty(>*RCsEGhW3fr&3SCxDSHF)Fc8uIDr#wz6Z!fAqNKQZ4Y6FmVh!w=*F3xY`BhMR>(x_=pUW>MvZhX*I%?c#uC_RVbLtG4&76|y(Rt9dc*rsy zx{MX;REWnBGnW+*j~A{5a%!e36BK-AVF59#xFG-ewNT7e#i}*M>-6hDV^wjFPaLir z1&RZ8rdkE%0cD!6eQt%1Ntiu7wRDYa_&T5N^TWo;y8CTV9TtFmW%9of^S z5kSu?e0nTIhR$JaA#eooh@3TrYu9paV%~-o>y{M}^FfqJ#Qpe>M=D~JpSU`{XMR5M z)rmgL9;S(Dy?pnAA01%rUGr9QQ{WF>G0a;nZ!;tvS#$7_w*#BI`ZA~5zhNYFRNZ|t z)DfblC!7iVyerf}#f3O>#)N>uaF+}#Rg_AdcS#%75UpTsIW{9wdB(B}2Kxs@8Dp@2 zL{N;>$-Ba8J|LvdjGQ~9qb;UAJM9dc86Cl@AdDYvg>QrHBciWw7y}O(gx@&}7+Q}-?tqb+3F9-uc6igCFbZ1_G?l|rP~_f*e5YCURvt(O@-&x98Iw*Mo1^&|5rLu|4}-w znzJ<>HDa!wCHrYNkpf?2r;5qYzR#5p`8vt!87%88aNF2)?a`i+FMgop9oDl}*RRUY zqo@g}%Y91wZtb@fDX4c&qphIPPu~lnm&*$h^6VcHyk?tPu`UEn6l?b#QhW54!$wg| zg`6_}ojf3KitJN6({9#DSw$&DS*eP?0kkF8U_>OWRC_||oTmMVEX>`K9pYFYaEEM! z_y#J9D(x$w8&6m|8at%UC?-y>g4EvNQmeMb=?1zRPgp_U!b#b}Wt5iTY}_jg}Z}qa^hM z&Rl1}O)=Z$2K#6U%UoV^C!40e(#hO^VNNr7w)Z6^wxbf1{E}o|!vwAWOj|`(>LT3R zKp$@e7$Bq-LP`fj1SUZ{rU?_YNZS4>VPLF`pxxM}u{`3xa_B`i6XnqEUI4v^t3YsV zg%%K2vlKYpM3^V)Ak|HTVL}*7F=J^SQ}Ng%B{vMVrIN;udU=g*Ba42@8jHQMt%hl| zTkN5Z`eeD4|La3rIp0P*hA6x6>kt?&tY$M2R)hR3l}MeXAj74SuU)qsdG>rsiG7*G zU@wqZ?S+z!4yiNLvAP%3r7a)Izf7{nRv= z9cMdE+ewnP6CmHsy#zP5TRy~BM}IyVS0{h}mgDCW@=v}xQDR#l$+In#{=U3M5u>%I zfrK0F9rkX!!S*Q;r`0h!D3c1x#DIp`nB8)#eUwMD3`Q$p2GF>AXdifoHUfIrZR@Z# z+AOv-o7M*M|3q$8S_e8G%q82NYcIBM;c`1{KjF#o8Gkd3AeC2ZnBI`y4}M5hwAL`a zfVu;I@od!vJ7}mi!k;#9eLLoL!giR;Z;P$imTSxY|B!Di^g~gssl@?lOT!H|6-RGx zM*8nV4K_WLtPe~L4#CRTM!TOuH z`{IDo_8N{ZAb>8`DFL0V)^tCr?7wTJ3p|L$1U; z&YqD6q$|04N7aYt^W2Mmy_m_>;#;tH~G;TLy_y(id=xt5JX>3n3 zjCV-`Wuu6?RCa}NGV=-7uZB8Y5^VXN&@eX1xskn{%y%xAFPG&Nmc^pjAfJCI=JyMTgsPDS%WeWB$5RZA(`EzHa9Ih zgEIe7t-X*KDb=)HK!{t~pWjYfGc? zK!w(@*)U4RPN9EW?yb!B9=Sg#L#(|}#~ZzBG)B!jO`&EPR~z3;jonHb@dJq;B>p+^ zyTspb6q1E(2KPl*nG| z;H;Pv*2C6DtHrv-T5Od%c}ugMENTk{x$UmnR`pC9YLh}%Z?ROZ^tg9eDlDr!?p>BD zOWq|u%x=pzOTNclzt3VR@VIyEtJt^Ps(JROyEFX0A3Vs7tZ!&DSMAp0|@`s(}i1ba5jS-y%aC89{t_ zsWZDKx8}EWm+u*$fsziE>HDt^P_>l?f*!d|^t0qDuPky|1wDt1&Hs`#j42YHB$lcy?YD4$fS%O{m* zmoKV%4O)4qV_HJqqAl5$?8a;rlhl(gau({Cq=9sq>Fsk{Lmk`I5;_m+#L(V&5%r?m z`s)^yYt4pMq^(J-`8_EM^DOKUpA%VKLm;Lg93TGM{hk&2b%i)44mm(rgS*OR-*H_4Ui&FX6PF7>F~jPyA&y==9NlG$YO<>SjA zD_>In2sx8nOg=;Y7g-HyFHV@OnOHu%{K=}7RWDX;ui9xjLoThIU|U-ERBfWou5FMv z1ZQa%YgcGDX)ClCJ_KY`k(g+iXvs3>Rux$`Sr%z_SUO4F-q>w?_*WA@F8jLd@8)*% zJ#%Qq;B61a|3%}k?WcWDdsBN+`@QCpW)GzIb7Gl0Dkm*FJ3BYKIGdNgZ#b=5r_Inl zsV&yNq}`_8t(HQ(R}%kF{c-i@hO_3j>f6-;>Or6vbYjUOti3bjleJfEcWq1Ra!H{* zm6Ml@AC`Vm`cvuE()*=y6!>_wrNqtii#I1MlsJj zpLQ;Ub~YZ`7|xmYG#_Eg20Mda4?Y?^ft*D)ge;e?Pn^Q(*mCuH^;UJQTF&LL21X_a zj7;xq_iHQ5cb0dO$$O(b+<7_j2bokPO4Q!`tI1gPICYkKf%;kP3))K4P7{t@=g+;R zxyzi;_}0yv)$b(=bse;A2-Nkv35ivYRE;E2r#q#GA&O9y2X5 z6`M9u+f2Km&gjHG+SKyjZZ{9MYTs~C+EkOc-SDkC-gsS$vTf5wXwQ&!wcBjFZ1r_A z4H0rM_;~P4@+tCoh*?^n_&BGFMe2=ev$|d_;d-V6h7+1l=&9($P{$aqzfNy^@?5B6 zpjO(`U;A^eFUaS7W|_Di_Iv$!npF#Z`S11PI9d{?@eh0Q-NtQ3?7yGu*hcN9&;~^d zlIpK&s|iFqK<562zDnJvOl7rY`^%1)@3u4!>SPWFHAyEi!gz_T5W{2~n0p`qO1?aJ zLvT!UrhL9~xpISYB=};#|EEFU23-j13fgzz-2<U@V!PA2m2jjR^ zvIP6Xj6_}AJPnS@`^Xvy7n=}o9B+IKX5pC2o&!f1KK`@>-|>`fI~&?Oq;m*{d+k6F z@Nzs@$cswMWE`5kiA{+-5}SZIA_q8j3t0Nn+-!{f`fEpDLk>%p^5d&_j9x*#Kvhw@ zKvrEN(Y_FP@$4f2;gN`7Le^E%XBBs)nkARmZEg z38AW9u6nELMAeX2B3~K$it-h%mRsI#ueQ8wdCPLbg7m@5Z?~E)4VHtJIA1Vtw&n_ zuXIAl|Mz8)8tPkqe%=-8X!jpfT79wlP$jeN(DsYl4_Pi-4w(;^UamMi=q*EA)nUFR z@#7A^#`JqDOX5|R9VD){Wb~{+4G55P>rdX57JgL(!}@70Ms4@y`Bz)Tv^8z_&A6)nG@{-<>*9<#?ijH%4FC}@_EWGW7 z&$-%@a~`y<{R;7Xx`Nt48OAg-y91-#x5z%Fu%ALxV{GYBZi=}@mKt%k?8_HlCcgC5 zWIB`2;eE`} zi#x?>%!ZtW)H~T|hEH>4D`G!DntMUQx5#MY4$5KNNjZ%+CRQhPTcKPvMzOR4efajS zR`J{{(?z-OlEbKB(Tmw>+TW5k?mF_?xa>TxABefcb&9LN%>md63w7KA7vl1rwWgT! zMNQnxic5Z-96^nxj*)pQv#1=VV8HW%@hq;tjx~-jV#^T5!j9iq6FfxbwS<6ni(B$e zGNUES81TRJ7uZY1i`F=*$>q_V>|5lc(0h2>%q3R5PFZ21y05wLTS3Qq+Jc^IUq3+0 z6yjoQqZIA1rWx;Jr#;y6ev5;X59BAL$hTmAUp?q#g~`y}4qO7~TyY-G zih5dU)OECIaXjg?@`=n*M`W`%3mx`)l_1l+{xU=4hGwIoE$y+GSPis!Ub2|6ysDS=L!h zmfHWYw9EFb+h^KW`yZBe+5UC=P5W#2^X;hUoY14o++ANcK>uq$^xK-okH`G@v;uZH zaef8oU$_x+S#zl41#ZVj7<;5n%kSPfTi7rtCDDe2Wno2lL|r`?)F)i3~^-jhkRl0zr5Mb?Tf4GM>c8Kk31H) zBcVyPBH>sR1LFdB-lk7!TzyrOWqs8#RedGgE00N?9ikHydPO4LP6oF0Wh$E6G)Cr@ z<{4ZO<+OftFS7QwTWObbd*M|S?tRB;r7(L;2~L9@)o$4D!d>!hM|U5Ua;^E;a zk=^hQ*Wl8>yDS~PYuZw0MU%m4R+?kYN_3YxsS+Dg5i4~X0ms$&yCfWhfU_`t;p|X+ zQxY@G8C4P;8|xf~mwZ^Tv1wfFSZ4}e@|0i$qq<|bt-C|rw%U|reXPCYjN57(N?PxQ z()F>n?qJ$ZQTO1i#MpSYG1s5Aj+4PjBs-kv8A=K<4fdg=0b+Y;CCT$)r;IS?On2ja z{w{gp$@|&30|-0&7i}Q*wks^7W>m(+W|cAK0$dE9*->3k!MTLkHWi*rSlF12HKBr< zKsTNv@ty|}P7D0|tIPTadS1QawNof9JM2ly*tV0~uD}ka=iEX)nFwRS#PY=Qr!RgE z`ehA5eWeusbR~qUI#mg~oI=<|h2^rygo>8b6PyeVT^mJW+CBXLe*GC6x|?$)BpO_kNAmtnn$ zn?anP(vGv_?P}y@3+&ThY;!Z+ut$$t#fN((sHl8X`8Z9y2E(M9((GoF#eVssZ@ARZ z$4Fea#88bj#rEyEpX-r^_Z&hRm6j&!++nIR#i>)(S=vR~yJV4iliH%)4Xy55Ev4u~ zZ#1niog`zmW3=f1ce0bjl}#Z8_LX-|7BZh|etUn1=X$x+LK%{!?!G6RFL*gcd8AQ& z!xL{T)27Hb1e=2!f^k-k{Q-_Cxa)z^;7ful4XaFBOy-J)3Pc4tJSa^pi&Pz74t zB&Fl8dO1QFC`*g3trhjTFdBb-lE(Ee8M~SeT%^p_GdOy6`D0CNg&Ypjbyrqs?93*O z`f`gVn)yXD@zNhPDa<#TnQgCXrZDen7F;rE<}psqug^x|Ij0IE_T^h(*AQEpFqgzU z`11_N6{YA!3q3s2XJJp=H}oI4vCtf?XZadNy}~dU9{+mLCtx>SKzvKt4&v+#Lzn3@4&G;k1bFiLX2;6^5|F=@b4O z7xFIfEbxPOTnG9BLgMIl;1`Tj5)edNS|6-OOGi9i(6PFwRt!v(PtV|Oo5R$r%D0r` zYL>WX;al@CHSTeOiI;0Jwtl7m4coTcXLQGXd)#$Q<5sJ2ewRWG(vqW9_i!Tt$`N)5A%$UrUK%7SPB`TSPH; zf`sStkSA3qvxDOgLx?&5XM_~;!xH>{h*GDegxE4r8LMyKl;-Q=# ztdX08^xC{4kaQ8p&+0)6ID>6z z-rb6!B($Z?)^mbJncGj7+O^UX4*9}7dCn{ygX!P)+13$C^QVee56Zi;P86pa>|KiC zON3`ka3;|XDGIgDOIDCmS<^OXG38AadF96{o2sD=p?~;bs>RteqEx{tD(H!IS?+Dk zUKFt~T5O3MeS9&5a86|GAmrmN8BImOh>HB&93+%X2y=4~UkkquDM;~u4=KpRHzc&J z!KS9t&8B1Krmb7d$Euo)YpS3xD22YD91twM5qbwfUZ_>a+?h#lxb?bJb~>A{OJbMl zR=a0D;ZLV8A?cY*3pj0-4ED{5*AKp=d)?t$uk818EiM$=8p`+pv=_d0hJY-DcG}%@ zV!oQxE3#>tDQmu^Ioe|kD zYv~qg?5Vvf5&rAiqkMcZg#Lk9*vab;jzuzhTZh-u!SI$2z8rGc{q(M~;@SUOq~2zM zb(&O`Z?7nU5kuUfrw5=$UaUG65507Ce&w+!=p&&lsL>keW-Xy|w2;lgnV$0!W7 z*b_?6h0;T)opAm$2u^{P!mQ8)Ii9 zrZfc5D2X(fgY*KIG17eHL5_ZH-w9ToV6&E9!}I?tu=RAz@SG&sW9KI~(&UszYi~si zUqf55aF)W#yMZbH7`YWzI=s0HDItQ- z6$o5(dsaU9x~gcxHIas3!BWAr1k01RX%IQ#v4n3qaD{NA16NH#M5`vao*vQ3=^m$# z6Er>Rj2COTS#oUi*ee-V7r`F$cIb}?4Tf#>vAB`r(Jp0;63zr>_gLPDj{J@Fn6q%I z_k`%YsMqfN^*Rl^h$#)!&*q4xZ!?!dWxJ*de801K8h@2z@%#aqG9Rrfh9xTp9JL^&{)S z27R&Y*pQFV3N0YYO5m9cB4bDDj*&aSg3T{GR{fr_u=-=Py-LA~&E2sOS|(4)+`P?= zKHvsiXjScGFE|eu>X@rEv~K^n_q&1j@3}%f_o1FU_PUFdmCc+53A!ir)(=`fbCpz2 z3PQ}GAMq*jDQtgFC>!<{f71SsR#}q`Po)&ww_U95u^R-v#rszSR3TcK))RW!6%v)tx$52pD8tylbwu4swVY-Pr2zKr>!<4j^q z^JL8kX09f!V;S^4Yc(^jy$XHLyPEk|P0;T+HR3*(td+6HXzVS7nIxW*-b#ihk~AR? za$N38*QPspyK1R2UCZw~EmdMG6PWSk~tSoBxu5{vVAxfB!CG;{qu^4Zx z><%F(aePZh+n`%PzAK^i%q6gzW$XbLuA8kV;nfKAwGiZZwmRL(TTDxpv(?Kyd1DWB z!qZRi7^T#xr)zn)FUR6oLO&qHQUS+8tn3aUCo#wJTxGT|zfzq7)*KGG(*L8r!qDn{ z77Ly_^E?IRZ6A8Yc-nI1L7fP?9L{`o={x4Z)#i*FzugB5{jbWlkh=lkGa1B(slU_w zS@VJB0PGhy$wKWqtx;P8JyDUqp;^|Cwa?mz%aDwu;mUIhV~rq;#MVAR31Ca z^wDo*BGYe+HHE8v1*w8Myf`#m|3BFf|@A^vsC))VvbF zS=4e^-N0EC&b!c^0qzWN`##088RoD9=wg`Hghdy3tY!WTE#wQ(TfEz%OV4|?F7N6F zPFLe-y>5kjd#l$+yk4uK^L452JZ3ed_{A_2gpxv=I0?ua4yiu(+wo8aeBP*gnRG$2 z6rP{@RC}6aS&yAAHxp5t1hDC>H{OB)3{xKxT(bDxk zJaK{?pnd(N{2xks>Cf2}xbhDd_M_#X%Z(m;ChwAW{nmG+^R@z|=)^GWs5YVe%}tg( zGxR!Upvt44o+X;br55I%CwP`EtWJ-W870m~6eN(U(^OB_O zY`U8KRQsv(Q|D=BS&3d31?kD$kI_-EdlKqc5JM@Z(qF?`H$xWWFdLp6~@d-v?X>o-|qiCTa~;C_J<7cZA{+lzO82U8hTr@o;9SbaL22o z^3-&yIyuj-sZf{Y)oVu5m(*=}{pq^9YFc$QPCim+cGuqTMUQ9tHmYE5*hd>dS2Bxs zqkFFAlA6iitqG&ICnvdU@18#esTVYAV25W+6r`;xssYV2kI8V0OF${!aqYZPFSqMd z?gq70Z&(^g@4SSxlwE$ZLEZRLZFe}+xVAxK8WZ8R7BoP5TOqwvt**!p=_wS7oVxpg z^pKPscV^5KM@DEY>~Rg$jbme(0kFdr%j`Or1>vH!8Ho$vDXlkPZ}ujcN3EuCuUDep z2lbwkw356{-7ROKAG_Y&i?-eEMb|(niIxDmcZ)wA4C|i+Q*Ej)iC{^^6Q_2bs=FUX z&kVV1a(7GUN{UL6xo0@~^;>r%j*02N@rIe1u1Tb8?~bG?up6rTzZ|fOozU^e@U)I^ zdaYwC)P|yZO%UC}uuQxBp0Ziq83`jrN`zaHqfoeAb@xMQz9bm?v+y5!CAx=1NH~my zSz#S;Hl$yqWR&|;(C7f#1ojQSbpuxU6=baEbh!vPnFa{th)$gY!Z^4rS$F*|;igIjId}6i(8qkfn7P!|lD|K_9n!^7^db50aUz z#Z+Hm?%xm)J9tu?(_F)uu@%y-#x@f`f%!nhgk9aL?K z%IySsO)!n>rp}@NY_1j}*j=W^mv)s4F>tNgad#kXx?p7n&|V&f=9V%fBb6iXD0?Bi zK}+_%?z-SIwOW~@pchM${|1_HvfmlVwcXU(9YCLPoOGO#ZUcR&YUzn}ZX|Om{EQ@# zwdDSjaSb{n?Q#izN8#)}U5hC_e$qH5i8YReb~jqaE}&KP0y3GwlL9y46nBM@gc;2; zvJarYFo!vmHk>ik-uI{Vu#Vu@uqPa3jzUKER|IV8>Y~fWDA*whgiCudOG4jN1$t*_3B0$hNB2&KkHfS*@fA5;uD>|0d$<&8^JLf!SAW{g+~}Wo zql{TJ$bMf*lZse6(G=Z1k`B5S#-yrstL<>+uFOU$VxZm2+^t`VwdAI&i`+`pQ6pfD zwy`4`IqvB>=7imHeear+2$-ku_{J3qX@2Xng&F1wJmBou<%(v8_YZR$nU5hn?aHfd zX%2C$N)*O%TwOQASs;90z}KV%T1}MnYw|0&Kco1XEa!G=+x@>L`90gY0ryE}VRv>| z>0o0Jw`Pl$2fyx%ryBQ&PWKGop{_55_lM9#{UxjYBvH#)?Wf?~BL7WTo2~Xg!CQ=u zz|}<5g6})vDj^KbHVAVRR>M)8sP?G;5frHEWp-nvT}DG%d_08eyJ_ z>nb?gF7NQZ2Ss%ux#yI{A?6+Cg#9o#BNx_RgcTJbE?Twt<`wU0j2hhsZl!3QR0t{L zT7Ax&+rU?p+k4X(+S2Sr15|i6-O6y@##yEOs_-YtUj9fp`!LTXa4BVHx$v}EvuC8mk!p{j z$zT-a^sR`){}yp*>EQFgQlQpb;e9Fwc%KR%-p_CyN`&DBDd8PQ#c{9#mjo+tnK3gQ zk0;_fl2BKCOwtOk&QTXV5V!o^Kv<#W-%#^dU8-B0Uof3hLz3w=1bL#PYS7LgZAWRi zP110aPfcRD;o;-Uud6Sio~D4FCQB-y9q-_0zO1y;CP4t z_dp3)B%qZxu)__|_69-N!4gvo@)ZvL{ed1JF<-_s{eUKc_J>O%DT6&_tNot8!G702 ztmeKyFAW01bo--a&A&_Li8!3C<2z?U9Z$sJoE+acgKh&?#wmUV`((c|4r_;Wrul`{ zOo!`HzwMwsR(mS=j{`d0FA7ExojuJ@WuFA}c(@*cYXV#o{XlLIP6O^Sez?nJwT}jR z6wo@jlHf{)E5%RhMA(x z_czXUg|kM#1NVUhExb_(U47J_%KxTpQ{Gk{hIbALK4P2?bwS>xtS3JqUGQEEIXwC1 zvYmzT1j9{}FI0Y}{6Q&oC)G-wMGlf~bKKT;CiG!p-!uWAWM$g#z|3t?qD&Lu80HRj zOiolp*SOg>`H1cg#=$xWXPEPdgLa&D>~)+7as{0Y>Imu%k_Ri{#A0Vc;9ZP?qgFet z$gNA{bFkDj*5GOihByn{G{Rd*U=AJA5aT9W$s?_e_JgrI`d3MINv;Om4{!yX4%{19 z?|xJJlh&oZuf3$MPpt4fd041@TsuXZtQ{8nK~7TF30o{ZSaZU5Ja(8oMVYDOpP$9r zHxFqTa!uK-{8IT3?hO@{{dP*)1MUTU9dI^aPheBvbhdKfPHDUBp6qMcS=pZ8rr@Z& zL5}8|8n=Ty43hhbBtl?S39LQTAsy&PPLF;FZ!!4yc0W)Se;NGuU~kVZbBr{nnx~s{ z%T|@WSXN!Ov+Q8mv9iy~&Kj;6?ioU;!PG(O81=RMOr$r?RnTF%U8=LP{1cd7IY@Kd zF5l7zIp6L=3!?5$*sX8}0q^FK>gri(PPBHEcB*!PmVf%ws&=~q9Ch$U6nsV&-wuFp z;RtdbI({Yd1@NdC!l58-XhJ zmBH@>w+7z`#%G|h4hK0_bO|+pJDwkdK1-cARtH$!HbyOTywZ4tdJZ1zno!4S%{Ue;b&ZNmbvLF(xJN+S|5y|1W}FxAggB0B zF2VYEhi1|B4+rE2t_>^;bOKMC+^^q&_X=q-RIuhl?H+Y7JOgbdL&(37d!Ti7$1Wb+ zz%EY9apz1b>Kqi#roW;^DQCtm%DwKI#z}O)lTDuo{nbluW%!4|`N3<0%Yr|I)8>2G zZuxQUiEp#=R97hdp*&x?R#~Q;?&fRcsI$wtJ59` zUULpA4_qI8I#e^BW!jQY+j4T!FF1)If9Xm%eP0`Ydbu3y-G9cf4#ny(<>}RWA5i&X1Oi07PzmwEp;|C zLYh1;AA+Rw2Xk@>zNR#HFdd`=C@PS;lFYIyUN6yB8B<~Sa^Ja$9u7bNObs3QS%{=s(cgnGahfo(w%gSv?= zyyUvG@#J-_#8Sz})BsK`>NrSStD>a9WV7teU zb2n~iwD&$Ow+7y|E`m3U0)HQC&^|T5dkf&b7#ABipoPNEgbwJ?8p($D9O4s6A&wT1 zX+IsVlfd4CJKR$?g{S}N(!6oKcHEw>z+3W~Hb=s_@t3Dx$-Nlr&}iX}kMK9^=+dKd zm@{_j+AgqQ^N!PD${n_D+j%FB4q5E|g-lT<^n97hf5Hqk!#N-9jAwPg>-`W%t`00i zIU$`dKN!rk-S0pxX$!m^NOLU+N0oX{zv2u|bq9^mv(X7L3Bwbj+)`)I2$_3t`s?tt z6ctIqC?;5MIJ-PsgKtnOa`d8q)O3K|m7u*(wmDw24Y!T9O|{Lpy?!0hRP}wbj(mgs z5yq*ru=Ck%_1aoJCv-r9A#f^(*TUgR*pGb=J@V(*9r8Jm`>vx_IM~IYEyLQ=Z*u+86miBY)KVr?%BiX1rp-1AMILp1#c+Q-vVhxkVu~D^_4Y;SwTw=irN7q%@ z6U5r80$Zt_yrU^zxLWqS6M8hylPht}$rm%u;ZAgd_OQC1e2er-M;MX+N&ZA0gb@&B zbz)(hdsu8rY-ViEMiqT@jurHkh~dXia>zdC|6C_jt66@uddK~Rot&r1ooLsc!xLhdh7Q^o_B=9nLhc0cu|Z5jkuB0I$&Q)`ZT*&7=Orz^ zCGnEHJGK>`3~PW=U5n|C*-u_11FTX)Ci;TUU9P* zSe8$N{WHKhz#&e#o{e_CWLxWeAw|lToZDCd}v zx~6Hffu4~vkj;83>0bKW47=ay16`M0?=r7Dh1m>RghU;-WH_A&JwuSDmqVE0pkKZm zEp4ZA5A^)1domi%hTjW-TJodU8uN{FjOoyCWZoMiondWUb}}@;14h#5MXN zSlR!cjO5-v^eyOpHJopOlTYxDEFFXEZN|I9ZN~diZ~}g=CJLS@L*E)&Gg{#$>gIG# z(dIDI2P_Vp;8u@b+^J5EaBon_I{j(*c0WT;RZnx`-*@Dz@NV^~>PJheNIy7ns8G&u zwsgHgF0oBbm}xKUx0qc3`y=xl7hO*{&byLe?A#Eu7S>!=Cz7=%TpLso>~_kKzulMw z`I}>mjsf&d686WRN`vQ#;mm+tGaxPSOxG{2=6;=$c=m5(wY`f>s@+2Fa8QX2s@p6+ zNqH0Mcp&I+cWg9s!+8i|>piZ%sIYP_ zRRyFvq~M3aukx~A34P@go_+o~i8sk} zhWq3>*o`{}yKw`x9o+8zH5zw6QQxCjTmdgix#H@doZ-fh{UM~n)*`|4jD6t4TBvqZ<+&PXJ48p$rED=IG?bM+rg}cRp?O1 z6)1n07xKS94bll-TnGmLfR(1S-WcJGEZP^`wVeMhyEkSCi-PojDG z)!my+E63M?LU_6jP6M_uT)628*C^(*9oHDXYuv-;R$1G z#mL72;3KTG4^8Cz!#*X*wm_v7IDiKZVITS?JilUC8}Eiw1^0qn^Bhvwe9&avmG$FB zI~)sn4Y9%OebyL5GQ2}Q$CUFKHx>t2dxb}_gzASb8v6F6I_%;3lU50osyl@q(H%r< z|0}_`oob}ulncChyOOdp@z6KR={D*%WuW*o^+a8STa}++97HG8-Zr)wL+Q(=J0_VE z_h}O#rh+x#9%FN9LX}ZUYp67CbWMXd**8Foz)=}jBGGn$vA??yJ>p&%ZAnY(um{5P z#zyUns)A@Ej>%E*3<1771?Sxu3uYW(V@jR39Nn(&ZbJBpE#j{M;O2k&jJUzM{rx3= zz5JwpL4F~Ap?+b0ef*LoI*CS-Ac>a@mqbg3N`^=VN`Caq@_W|*XUR8`&n3e*5|d|5 zh2I+Dl6txSF8FKgkHm-l_w_&A|MbW-&Zji|sql5-GsBU1E#g)9`(`A%rw&;)xO4D# zoO@{GsUcqs`GIriN9y74C(iv^qzT@ZdzN#5qnxN5t!&}k*HkU4ORDpndves6sEJW+ zoO{NwLBo=VUE$pHuoLiiY8dAAYIH{QGtt*ZW)PE!DMThQm6%36N@V7sAF)1WdQ5gq zCl~3*m>=NJJ(75I%9Qb{xJPHtk5`S>jM6|MB@k2%7YSF!g1PVw9|K$n;190h2LhoJ zAws{-^BY?wND(Z^*^hHcIB#_N$>EEX`VT;Nprjw%0tUlZw?ENK1$Tl#_Q?SFsWgfR zjOP#x1PJ`N1Odv09}hwUA{#A6P684%L5!RNBzOvkU_OuzY{L>ES>iAs1JXNNjC=q{ z=;LAp9@!=2i^a$>K*E-a5%`%JLa|JYdHG6s--&x;WQApJLs5ekrS zqZla#WI!c{c*<1<$Uv(YF#{4&D@G~-8MI4`Yz1WSUJmg{bqXLu_KOkNrY0ia5+h>) z8TzgmfsJiKd0dP%0irr3M&1S_>N7F&E+E6c79+4NPDKAzjJyv>%nxD&IUIggjBEyE z#CZNZWDO!w-039kz7D#ea;~s?R^T6 z*g0uRjh4=*#M4&Gq^#x?UK#(sG>z))X6=?kcQfhb>Km@g3R3&i*W!+n7f zzCf%m5a$cT`vN0kH_7fh1o5ejfBeT~F}^M)?AxeStB)z*t{k zoG*~-3yk*#9`OYx_yQAsfl0nVnlF&<3uO2LlYN0HzCflg06*&apa`e=0+0Fv(|v&~ zUtoqW@R%uK_v*taP1h;8(;d{!Ixk(xP zZ8CqG0=Lpq zI`o17^Kw9Z^KyX6c{vbrVdmq=aL(MhME1NXQ!-`}Q)WJv1D<$61NjPfl}g^av0AA>8vN29JFGi9Z8PfPSGdNx~n_{=$F`_0Y|5_Y=`qfnEZE zh5Etynjfg0j0+Ea8&qaC`1khEDxkZ722+&d2WLikqWIH*4u<%sN67DDpeKMo7^)n- z0%#@Bksf*z(BVJ}`QiK{5NK{`1L8LTjh3;%-vOYz;S%U$;JyVHYC7hJmcL$N05{V9 z#07BV0u4!UG^TZT9znbWxF7r>FT&?x)Za)*f4>A4TObqUXAaP>0gc%ry&fDd%;)P9 z`LUpf=kqZ5+3}Fme+|+f0QHaAV13XJIlnI<{aDCP<;kxV=m?;BefJ~o1FZyo=k$HcS1+?&a81kME>Cb@tuxG~hm<#mBpu9r+SPS%rKqDI{uL^J+1R8A$q#J?W zFY*1zM=@nLytIW`zD}8PIot7Q(*(bSKb4{x+c7frcBG z-W%Y!D56gQ-6EpD1Nvv6Axkd&RiJ+YT1a0475xLy@Xz@V2KqY@oecC*pp_o~ETG>6 zTHq%S=$C;O>VE^!)gu4xK-U5-^mnfTjXDGWTz($`Jr9U69{L-gvw;@)y$tlvKnVKa z2MK)xv>>k`Kz|Ojz|R=W$n$v^?PKyoPJafZ9|d(JlrI(8A|o$m50kqepipy8jZk9?pH03p~1F95wmMAraq1zM=jgFu^r7V7^L z(3^l3`nw;2o(^<`C;eZ5)&o7zLkB@ebV?L|7|^ZIfF1|5V6T~gjt5$he7NjlXE@LYMf^?x`emSn_A~Dx^YbL6FNMkw-j-T5=_W@dH4{~f+p3lSJZ!n}k9P$(7H})at zmk#OAh5Us6e?HK&ffnSm66mQwW3$HkF# zpcxU(3Eq?1!>Dg5R_sGeKkOl=AO4Wjk9x@Ik9^4KkAn1{S z4D@NBlRflop#7c(`w$Ee^j`?{h$4c(y*=kZ6< zU<8JN2#BKC1c(u0+pns(AS#{iO48WrG~JyJM#xKb)$8s`YNM7;n#qhkl5s%}F2jK1 zIV{6L#swWj#E7^>6l7pThe2e}gB(3F3Q7c*BRp6W7rt3k$p9Mc?{J9hSWpGEY z=RIM@e-Au-mdHxq{{;AQhyJtRmH4;F``Bg6yx)P(IYXb{2>p{OjE-E5&XBR-^S~2n z&%55x8v~#BR`kaN(!T?|X(Rv4_yV}nqw|aOe*pZkGpX^-{a*mjZ`1tA{C9v8DAV$L z4|sn{=V!V9r{E)5ujH#!!M_IYd!y$;Qq6xl8_m-?mel>nk>%Ea57N0{`p3W@*`)J_ z(Ax>Vl^Tv^tNZtWPv6d&3Rw8L6zt0P3h)y0lJf%TzZyI?0}u?oPlG2|kL|w=JlhfT za}W3=u<$SZ-3MNQeoqGrKaYX0HSt{NJp(?Q18QlK{$q|qUI5XT;1j?*IHVSOf=>q@ zfj%rg8*JalI+lENKKOO-)=e^gJNVHH^!{4bQwBc(J$pwW$>xXV*fk{Ub7Q>=N_5wU%^*lua_D882DlAb%nvtf%mV6KjR;AkbGdP zw(nKke*(CMeC+tM!8bbgFbMvHgU<&)pQJ`G^fTa2u*gIB`77|RPGb!QUk^SwgpV8i z74Qn=W9PdMoQFT_5B~}N;b0tZo(BJ(`*A5n|CPMpu^!@f{7UcyV6W*v1^k4wz699y zr?-Q5W<3uRRP=_ypAWGKgD1hWj{J9mw<6EO=@p#zecXh=6dl-eUrQZqtqrvig3l@|=zZQG~ z7JvwO*0$R+2D44;Xh-`uQ1nQxcmn<9`GGF7aCQBk|*~ zS2yze7vR|cp8dlcz^gXK`SI@{l!rblQS`g%-;X}!68_GS`^neVzox-AJNlRh-_fxo z!x_KatAKBUr~44NtmkU*4)jlx!k+_QKCQ9v`xS7N`D9Ab|AXKQupd;c#{W0?-feol zGX4dyS}cFW-j6=X^Tw(1<-Jdt@6}*eU#EflFg`11)wO+v;G$@o>VJzfO91>>>y zx(|F6!m;*z1^6NKXV-HzcmjP`fBR?fv1{Xe@eS~K*?9cj-~r@e`S~Sy0sG4v{(lD^ zCciyu@Zqm%T+eaf*%^2=@%Ig2tFKO|u9oqRJ-!8;zc60UTfv_?ikN5UZvubpUAmqX z`A&h?lV7++$+H07ME?L-`uBic`Cba%NlZP-@N+Zx_A@+h%H01TIMK1B)+_$>FxaL4 zEcinFLoTtm--BKHN4}QaK>oyq6+f>6yZvtfPh*_JrvDw_9jC_i(js^l_9N>N{yzx5 zEEUV+li+(L-W&dJ0oTyaK11&y`0+F~i@|q;i|}LZ;{ot3F5o$rd}`G4SR zv1eRd^{+gc=f(YT{y7u;P2x$X=|2~Iuj5~n-~-sJwU+{TU|Afm_kur;y{$6$Uj|-s z^nW#YBf(t!SN!XX;G1wZRIKE25PYIzpZ9@>;a}`oxgd-|7U?e?(owCzSUXJCh#yZd&bDW4DLah-Ov~Rd=GdU`}m>39|WJneD5>( zYVeHXe>Z{eapt=PynFeQ_ff`+{oM(E5#{xn`@aKTc3NC7{sR2uDa>j5SH7O}KSzIW z2A|ITRv#<*@O}QRQS_I2=h8n5KQ=#2fFF0{mj&;;kilGH?`7}^`n3Elg3reOMEAwWqtnwehhnpMRor{uzi2!ShC3d;3ETaxat1^_)bS& zKLtOH{yOOw{r?iY7W+UXirzEe{TIajFM=O+^nDZqKmN9O{?ou&N1wf5H~wuD!shB^ zeHVaT|IP?Ll^Dzzk;hfwV=!jxPq%_QH(&#%|6cHI<9a_X_2|#QOQ~3%{|kN$`?vY~ zC?5P3ab7F$Gr$i*Z_Lme06*gBXFYh=syM&z10UA0r0O4$|D|9>j6af}t^+@ZzV{h= zp97z?UCT%0dnb5b81IL^4R-UkdVAp=m2R}l;@GtaB;I|#FRV4B7{on)4cdhBa9qb*p#D9eUXa8_N z_%p=Am4aFSL*N0F@fontdlp<{yy!>HJAMnk9s9q{^dF0@oHrB8|77sY8F7AG2kwLT zv>Cq*d>{GB$~y;sJNmc!{TuK;2HW`ke(-wiQ&cGO{4m(955G!my(@_8=^N-j&xx0} zfe(NwJJfm}0C(?*>%AX???nC^O#gG>bCH*|$Cb#|UY*G6_2B0()Gea_HQ@c&tH@8} z)eqi#e5}7L`0G3MdZa%OcJ;Rhd=UFyX72wW_-=s6L-x;CHjTdy{QQbI{@x9);BWVt z`+op-{qs5SQ@dmTd=Wf|eTY28K3;V?@sGvY`QHfccKq$_;4bP<#G=+W0bVm4>njJo z5&2npy$}3CN1Tsu0K4n`Jh;0f_Kz<#^?wb_|Eo!4Z});-fBgyg%2Q%{T86D%@A&7@ z;A5~K(YM(1YrvPVSdpi!HwiwFjrYInz}+ExDzm=z;7@TsDMsBt2EOSXVk?+0Wy9VQU@(8%c>3<4*k7Ez7SdD%OZmZ0E zYr(c27W+FJ+}jcFp9Y)yH-k^1|8V#b|Ct1jvA!;_$R_}I4afT213uv7^Y?@QfW65j z_WxmU0%Pw0i#%=xU(0%JzPTIRh42F$Zu$MDU|H*=}ua6jf zCU}&1)@|@b;LFk9g9d*Hd?m!5H25FEZ|aEs^IEW+k(_S&zY5-URDAyMF!&)yK2L(h z$FDHs|ME@LN65PaEb=}Hd<^p0VfxPi%Ngs>4Za5K#;@DKCtx2|Uhi?_E%Xl3@7CM@ z4xaCb`TwQ#WAE2PR>uDd?CSfaCcFYcuEkk|Ux^o;;PY5d7A*4L0KTnb$;9X7-YEDW zzR4{rUQdHv`ZHh;eaj{GT>^jIk=Lc*TZzetP0{}p_yMQ?4)9Z~dDirQ7rb1EaY_FE z3HZ0FX(_{SyVPXizMRxgTAJ>a7UVmtzN`QHj&jqs1)exaWO zufl#rAA&CfyY=pM;3tow#y9;pgWdC_uYtdhu!Nq-_ebDP##?$%frrKUxy1io0Czd@ z=J>Uq_s!0@p4kX~4Ef6aQlE^2-%I|z7A*Yb!ES#2Tkwq+z_ZZD9Q5Nd zIAv`BJD1L_~w@nRg>grpk zq>&s+WSZG&YBQ`fw~F~~A8T$^w$sw8EUcwf*;PxcvaXg^Wn(R^%F#P{VJ2~SD9?T%4GXhCflzv*?u{aTiTdUvi&NP?N^zMSJ@mv zEb*px$0eJ4d@mPC8wIK4XeQf}E9Po8JSpN$jh1qAvymaqEzzQ}%^~27 z4BFlwB)oiR85~QFhS|PqSmRG>Y%)lWriN29U1hQ+-|5u6h7Ge9O4*ruRjsd3BC$j( z?cFTUnO@!A(rTD$ZPzBy+OCz|+OBP*wOw05Yr8gs)^=^yt?k-ATHCc)THCc{>-L7M z(5KSwCPy3%-F}Zs8sxcBWm9f${!rsInNhD?s?@^0ljKCA#YvjltT#7~wBFp*n(!)fGZCZ7iMbhvPkdeZ zaARw`wrI}A`{BKo8R+dxMl3`m*HjVhkZE!BxIon1`rl3UCc!Ium-G@mP{ifKyo z(b678acWv7fl9hMpU>tb8jSgUlbKv;l4u+TBt*6z{oK2m9YsnabDMrYna*a1>gcI3 zSqsalT{B#}xV(I6F6LX?qhQB`1qu&-FO#fKXLjdF0JSZ%vwFp?%=kSF48r0-F zhCkooFEu+Wqm1X7Do9!e*#At*89=|P61&nHU zFe_%kHZ0%Wn|05$VLt{qL~~;v?{Q_5T>j3N|>5~3KFlB>P2yp+1%dhY&EAFtL1#Imh{xQ z!05)rr(l!U!+Qs&Z2w{!Wn_ z`-oakOJwl7Wks^l=Y(J!%i{QIFR?o^u-SCJsw_+eGoqaGC9OSJ@DuatVm2R6?a7T) zF4l~+YQ*NIynB(c5B0|)Z$}W%C2xCcTK3EUgg$$zE(;T_!mO5lIX^=1~6KQDcD09Coqsv z)-Tq=)C8Lnzk4EAoLgU?oei}E&!n@GQ^HE6UKZ++2djXk?whweGI$ZkBDZl)KR||@NDYM$JZ`T-i$!xK;_0EKIoHeRM61Vn9 zir1>J1Vn#>MmxB957NNG-l%1W7P zXg*y@>AAGIz>Ryt2C*oD_lOI`oca>~Cs?H%_p(rP7>5#!38^F--96;1Tk&G;al&V! zyXibJ5Zw&GLuw%`)<{JpONsE+Ae096Q$sks96@`zs;WDLPD8;bMY6YNq=<+bB;+^( z`KM$ujWu@(*|G81n4={r8GB1gg~=?T9A>m_>AauRVE$~b#hOR)44B3Kph zB^oQYx7OjhujIhG$(lHpS#&&2AS#`+P*>!Zw&^v9$h*Q`0zCtda&sCY< zYEaIYRH4CwgG`#zTO_K3LR{pu#xWaeqijp^qL_`#GApGp>nxBYotdu$<1$B-@g^JP z;cllrZYbtMIoXe@KdIp2X=IOWr^;m4sXU|NvdBYcYHY-=R?Z}YS&3y~5#N=nL#hwR zQ$3P2q?gcA%jT-HDnJAnY6b_QLsu?ARZbFG)1kKgAYYxYXbl*vQ|Fqk!+n)Lhf3k> zY%Y_-?p4v$wgyv9t}9a9DkSF--P`k^(x2E6aXu(ZvWgbYd5PrFVj5XSjdEDx1T?=} ziBBS~#Haarss=o`r`dz89lwkhBYmmotRKb&Y-^^p9LcFpl=h7Ialh0HFrO=`3be($ zdc_4OE*M3fkj*8Gl42+6RSQ#Vk{QJG`~-G1oTK0dX4H+Gz7KYe+h4(Ay02Gi^2! znfT=^=Zs6+ILF45D+c8NFD( z#j7iD_KI>UBhM2jIj`J3TNkJA*^|!I*eJJi45y}S%N%85dX$`!-%zRy=4-iH9p}+| znAkA-m0<+q#xztUEVGheAy=u@*#tvcB~lTzY@JkiR4s0@Q9+|BK|}bLy^!2!idnm4 zW8~CRnx<*5@+31XY*v9;x*{V?Vn-6%bkY)|DyxkkW@OI)=o9g>$C5aiDKFB%2?QP> zgj9*ppkK4;_PcY{4QXmRyLDy{Nd@FADB?ZVqlstPa8~YQBGVuTw{2pC-M+0Ofa*#t zH9nv-y`*?I?5q>_H9<$xnBiO%A4BQdysGrI-0>&^Ek$HMpHwuI;dWze1?>`d_oT*Y zWZM_-&W-D9VZ|aqk9tq>$Cvjm)tZuZzF}7;#>1{iPBeDa z3*`hmJbg4H47AC=y4H$<<+@z8X+PQKNq~@2j|j*hax7sV5!m)dV^Q%dmWT-2*qv)C zY>%W~ipnXgjD|51&`RY+Wy!3PSdJ-ILzQp&T+OW4t!gVe$Y&|0G|93)5BKD`z7j?A z-ZCM3CnpFEm54{hYFhT)DU~oR+mSIN1vxZnSX--zZCa7Nptbg%_S#@5OsG0UOE{Kf zRI;_Ngb(2#>R`rNOT6WmJ)9~p4*7Zo{87r_9m1$N)o>nsYcZ>XmqV;XZ)#M9+7j?p z(URywKE&xs7g38=gu;x&4G?KY*XyODns{4wH}?JY^f^&oAO3c zGUlkOKAnSAoM>U(L>|544(7vjStm%bM53j*p4OYgR11*=VRM2|#qM<|&2OcW^Tfm! zJhd-&t1VSmnN5(TsE$`s6BAn|Vrx=iI!;FZKvaJX7PEGTEQJ`iP<~R?NiDl|GBxo> zLW(+wWj*MF2-$G(Ve1PySe)auJj=-yRl7aa2(!Hs7>aIO@Kp+i9a;H1!$p;hC0(=* zjlzR3Wl3D38@I4Zj?KfeV>f6%hySr~)T4iLoq0l`6mC9SnWD57E$OXRobVwi;ij6A zuwu@%cr2g<)O_}#8B#~(_J~}nE^=(iZpxxX#iRBfuzcvA0 z>JRmZ7}juoavRSWgeftGzP1TPooKQtRHUml4tr&MtH$)f8$UBVn$q=^-S;*GXva@< zIUn#^Q4tH~#6o;Tw!l2LlA{f#!Q*RF^7a@88%i9Jsbdnou)}j!bQ9Ezr3$WvF9vga z_XgCm)lw1vt}O=DUEOMhayAP+bvA1rlgN!)4E!v2lpfd{noXzPe&K`q`BiN64FuKJ z*OmaPer(_}I#AJp+}`T@QWkG1ic2mcTzT%LqXpAr?5YHe88mv*G#ZnhGAPHATXQSr z+o5u6`y7$*Yw6t~HFqY=Zq}#I1v%(Zqs3Otbn--27Sv)6cJC#fQ7vo@dTQIqNL3k> zHoQi;w(&%t1#HMw3i1k~vO^44Z_qgduNSNO7`zP|s{EYfjG80rIf;nUAO}^lp$%07 zHlZ4-cGRRF@IM(#1XNwKxx5^mNmCytSIo{(1l3LEKt-w4_{5gYHqkpLH5{U8%Mmf? zIAtAQop9Pc_@tT#N(3prE_?9cn5BI~3pz(&Y|SMvdj%WFdTqp{%GtKZ-LAJM z?M}*lkm3m26iQaW!V993=L|!2q5(&rP6;S4g1Nytb8(%=JZ()`Ez*r^<{ig4u8Hdg z9MbADCdc5-`I@ca+Ndq^4Rg2=7YS{7>6bvs6Hpyt4}GX}h=Nodka6mYY+5|lk((_! z;uQw+xLZFatFkYaXJq!3WFaP{Dr?0-8n$$;HmM#4_+Qp3LafDPX6`sk5}BIYcJ!@jZpM;4)vW= zOIx}RFz$K23t%tXC$In8&(e2ujd$kTjGJ#7H+G5Vy;g28m!-k&4fN(2x1!B@Wo=5v z=KgDb?0N4opXHCGCx4yWz4AW3v+)-F9foN-<+~$%rA7TlpG)uDoB3^H-tV`UrT70g C1!XS) diff --git a/software/test-software/nano-328/release/v2024-10-31_172629/nano-x-base_test-software_nano-m328p_16mhz.bin b/software/test-software/nano-328/release/v2024-10-31_172629/nano-x-base_test-software_nano-m328p_16mhz.bin new file mode 100755 index 0000000000000000000000000000000000000000..30364adeef30028419e050dda4eb662154d97c83 GIT binary patch literal 26652 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 literal 0 HcmV?d00001 diff --git a/software/test-software/nano-328/release/v2024-10-31_172629/nano-x-base_test-software_nano-m328p_16mhz.hex b/software/test-software/nano-328/release/v2024-10-31_172629/nano-x-base_test-software_nano-m328p_16mhz.hex new file mode 100644 index 0000000..3cb471f --- /dev/null +++ b/software/test-software/nano-328/release/v2024-10-31_172629/nano-x-base_test-software_nano-m328p_16mhz.hex @@ -0,0 +1,1667 @@ +:100000000C9448030C9470030C9470030C947003CC +:100010000C9470030C9470030C9470030C94FC0605 +:100020000C9470030C9470030C9470030C94700384 +:100030000C9470030C9470030C9470030C94700374 +:100040000C9470030C9470030C948D060C94700344 +:100050000C9470030C9470030C9470030C94700354 +:100060000C94C0060C94700307634236B79BD8A764 +:100070001A39685618AEBAAB558C1D3CB7CC5763CD +:10008000BD6DEDFD753EF6177231BF000000803F7B +:1000900008000000BE922449123EABAAAA2ABECD97 +:1000A000CCCC4C3E00000080BEABAAAAAA3E000009 +:1000B0000000BF000000803F000000000008417801 +:1000C000D3BB4387D1133D190E3CC3BD4282AD2B38 +:1000D0003E68EC8276BED98FE1A93E4C80EFFFBE30 +:1000E00001C4FF7F3F00000000006364696E6F7011 +:1000F000737578585B000A2534643A20005D3A2015 +:10010000000A0A5B000A53656C65637420756E69AA +:10011000743A2000253378202E2E2E20004552528E +:100120004F523A20496E76616C696420486172646E +:1001300077617265202825642900417661696C61C8 +:10014000626C6520756E6974733A0A0A00486172C0 +:1001500064776172653A20255300202F2000202FFC +:1001600020000A0A48617264776172652025532075 +:100170006465746563746564202841444337483D71 +:1001800030782530325829000A496E76616C6964EE +:100190002048617264776172652D56657273696F6C +:1001A0006E3A204144433748203D202564202841B1 +:1001B000546D656761333238502C203556290A005A +:1001C000563F3F005632610056316100446F6E6504 +:1001D000004552524F52000A000A3D3D3D3D3D3D13 +:1001E0003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3F +:1001F0003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D0A62 +:10020000200041546D656761333238500031373A10 +:1002100032363A3239004F63742033312032303273 +:1002200034003F0025356420283078253032782985 +:1002300020000D20203D3E20456E636F64657220D6 +:10024000287075736820746F20636C656172293A39 +:100250002000456E636F64657200656E64000A205D +:1002600049324320534C4156453A2066726F6D2007 +:100270006D61737465723A20307825303278202DA4 +:100280003E20746F206D61737465723A203078255A +:1002900030327800453100202D3E204552524F52D9 +:1002A00000307825303278002C202066726F6D2067 +:1002B000736C6176653A2000202D3E204552524FE6 +:1002C00052000A204932432D4D41535445523A20A1 +:1002D000746F20736C6176653A20307825303278FF +:1002E00000453100453300290062616400706F6F82 +:1002F00072006661697200676F6F6400657863659C +:100300006C6C656E74003F002C2065636F323D2578 +:10031000642800292C2074766F633D256470706218 +:10032000003F00756E6865616C74687900706F6F6E +:1003300072006D6F64657261746500676F6F640051 +:10034000657863656C6C656E7400206171693D252C +:10035000642800453200252E3166C2B0432F252E79 +:1003600031662525293A20004531290020207C20AE +:10037000454E533136302028002C20483D20252E74 +:1003800032662525002C20543D20252E3266C2B031 +:1003900043000A203D3E20424D3238303A20503D45 +:1003A00020252E3366626172004F4B0045340045B4 +:1003B00033004532004F4B2C20454E533136302010 +:1003C0002E2E2E200045310020424D323830202E76 +:1003D0002E2E20004932432D536C61766500493240 +:1003E000432D4D6173746572004932432D53706122 +:1003F000726B66756E20456E762D436F6D626F0071 +:100400004945454534383500656E64004552524FC4 +:100410005228256429004F4B004C4344200045528C +:10042000524F5220256429004F4B2900696E697490 +:10043000204C43442028004C6364005465737420AE +:100440004C454420442564004C6564004D6F646253 +:1004500075730020206E6F20726F746174696F6E07 +:100460002028543D253034782920200020206E3D5E +:100470002025356420552F6D696E2028543D253088 +:10048000347829002053454E534F523D25642000B7 +:10049000206E4641554C543D256400204144433272 +:1004A0003D25336400202050574D2F4F4330413DB0 +:1004B000253364000D20203D3E20414443303D253E +:1004C000336400454E3D3100454E3D30000D205314 +:1004D00057333D25642D3E000A004D6F746F720046 +:1004E0000A202042616E6B30202D20475042256447 +:1004F000203D2030000A202042616E6B30202D20EC +:100500004750422564203D2031000A202042616E80 +:100510006B30202D204750412564203D2030000ABB +:10052000202042616E6B30202D20475041256420F1 +:100530003D2031000A203D3E207374617274202EEC +:100540002E2E004552524F52202D206E4353206EC6 +:100550006F7420636F6E74726F6C61626C650A00F9 +:100560002900204F4B00204A5033392E322F3320A0 +:100570006A756D706572656420286C656674293FC4 +:1005800000204552524F520020287265616420308D +:100590007825303278202D3E203078253032780092 +:1005A000506F7274457870002534642028307825A7 +:1005B00030337829000D20203D3E204D6561737554 +:1005C000726520414443303A20000A00506F74693C +:1005D000002025332E3166203D3E205357393A36D0 +:1005E000203D2025642025642520642025642020CA +:1005F00000253464202830782530337829000D20F8 +:10060000203D3E204D656173757265204144433243 +:100610003A20000A0052325200416C6C00426C7564 +:100620006500477265656E0052656400526762003E +:100630003F0043686172202564202D202573202D02 +:100640003E2025303278004C312F4C32204F4E0066 +:100650004C312F4C32204F4E004F4646004F4E003B +:10066000536567370052656C656173652053572584 +:1006700064200050726573732053572564005377CC +:100680006974636800556172743100001A26D926B6 +:1006900011241FBECFEFD8E0DEBFCDBF12E0A0E037 +:1006A000B1E0EEEEF6E602C005900D92AE32B10773 +:1006B000D9F724E0AEE2B2E001C01D92AA3BB20736 +:1006C000E1F713E0C8E4D3E004C02197FE010E94E3 +:1006D0002829C634D107C9F70E949B240C9475338E +:1006E0000C940000FC01108211820895FC0191819C +:1006F000992311F0915091830895FC01608384E661 +:100700008093B80084E08093BC0081E0089584E089 +:100710008093BC001092B80008954150FB0194E80A +:1007200024EC4F3FD1F0442319F02093BC0002C0C9 +:100730009093BC008091BC0087FFFCCF8091B900F2 +:10074000887F442319F0803519F009C0883539F4C1 +:100750008091BB0081934150E4CF81E0089580E017 +:100760000895DC01FB0184E835E0442389F022236D +:1007700011F0949101C090819093BB008093BC00D4 +:1007800011963C9311979091BC0097FFFCCF02C04B +:1007900081E008959091B90041503196987F983248 +:1007A00021F380E00895FC0184EA8093BC0085E099 +:1007B00081838091BC0087FFFCCF9091B900987F26 +:1007C000983011F09031B1F49081990F962B90935D +:1007D000BB0084E88093BC0085E081838091BC00ED +:1007E00087FFFCCF9091B900987F611105C081E02F +:1007F000983129F080E0089581E09034D9F7089588 +:100800000F931F93CF93DF93D62F8A01C22F60E0FF +:100810000E94D303811102C080E016C0F80124E8D1 +:10082000D093BB002093BC009091BC0097FFFCCFFD +:100830009091B900987F983279F7D1919FEF9C0FF2 +:10084000CC2311F0C92FECCFDF91CF911F910F91E5 +:10085000089584E98093BC008091BC0084FDFCCFA6 +:1008600081E00895FF920F931F93CF93DF93EC01E4 +:100870008B01F42E61E00E94D303882379F04F2D81 +:10088000B801CE010E948D03882341F0CE01DF9193 +:10089000CF911F910F91FF900C94290480E0DF917C +:1008A000CF911F910F91FF900895FF920F931F9387 +:1008B000CF93DF93EC018B01F42E60E00E94D30311 +:1008C000882381F020E04F2DB801CE010E94B103B2 +:1008D000882341F0CE01DF91CF911F910F91FF90BE +:1008E0000C94290480E0DF91CF911F910F91FF902C +:1008F0000895FF920F931F93CF93DF93EC018B0129 +:10090000F42E60E00E94D303882381F021E04F2D74 +:10091000B801CE010E94B103882341F0CE01DF91DE +:10092000CF911F910F91FF900C94290480E0DF91EB +:10093000CF911F910F91FF900895CF92DF92EF9288 +:10094000FF920F931F93CF93DF93EC016B01142F52 +:10095000790160E00E94D303882301F120E0412F58 +:10096000B601CE010E94B1038823C1F061E0CE013F +:100970000E94D303882391F0402FB701CE010E943B +:100980008D03882359F0CE01DF91CF911F910F91F4 +:10099000FF90EF90DF90CF900C94290480E0DF91DE +:1009A000CF911F910F91FF90EF90DF90CF9008951E +:1009B000FC01108211821282138614860895FC01B4 +:1009C0009081992311F091509083089567FD0CC098 +:1009D000660F642B6093BA0084E68093B80085E4C8 +:1009E0008093BC0081E0089580E0089584E08093C6 +:1009F000BC001092B8000895FB012FB7F8949181C4 +:100A000081E0890F8183DB01A90FB11D12964C9300 +:100A1000883008F0118281819081891305C08F5F31 +:100A20008083883008F010822FBF0895462FBC01C4 +:100A3000655F7F4F0C94FC04FB019FB7F8948081A5 +:100A40002181821304C09FBF8FEF9FEF089521E0A3 +:100A5000280F2083DB01A80FB11D12968C9128303E +:100A600018F49FBF90E008951082FBCFBC016F5F28 +:100A70007F4F0C941C052091B900287F203819F075 +:100A8000283A49F013C04091BB00BC016F5F7F4F13 +:100A90000E94FC0409C0BC01655F7F4F0E941C05D9 +:100AA00097FD80E08093BB0085E801C085EC8093D2 +:100AB000BC000895CF93DF93909135048091340466 +:100AC0009817D1F3E091350481E08E0F80933504BF +:100AD000F0E0EA5CFB4FC081CD3009F4CAE0D0E021 +:100AE0006091B6047091B704CE010E948A2DCE01A8 +:100AF000DF91CF9108950F931F93CF93C82F8B0150 +:100B00008A3019F48DE00E947B058091B6049091A3 +:100B1000B7040817190731F48091C00085FFFCCF96 +:100B2000C093C60080E090E0CF911F910F9108958F +:100B3000089580E090E00895089508950895089537 +:100B400008950895813041F0823019F484EC91E0E9 +:100B5000089580EC91E0089588EC91E00895CF939A +:100B600087E680937C0087E880937A0080917A0002 +:100B7000806480937A0080917A0086FDFCCF109289 +:100B80005E0480917900883D30F480917900803C4A +:100B900010F081E03AC080917900883D20F4809186 +:100BA0007900803B88F580915E049FEF980F92302A +:100BB00078F0809179001F928F9388E891E09F935D +:100BC0008F930E94C62D0F900F900F900F9014C01E +:100BD000C09179000E94A2051F92CF939F938F939B +:100BE00082E691E09F938F930E94C62D0F900F9005 +:100BF0000F900F900F900F9010927C0010927A003F +:100C000080915E04CF91089582E080935E04CBCF03 +:100C1000F8946093620470936304809364049093E7 +:100C20006504789408950E940806F89480916204FF +:100C300090916304A0916404B09165047894892B29 +:100C40008A2B8B2B31F0809100019091010101964C +:100C500061F380910001909101010895CF93DF939A +:100C6000CFEFDFEFD0930101C09300010E94130684 +:100C7000D0930101C0930001DF91CF910895CF93EC +:100C8000DF93CDB7DEB728970FB6F894DEBF0FBE5F +:100C9000CDBF709156046091570450915804409113 +:100CA000590430915A0420915B0490915C04809126 +:100CB0005D0479836A835B834C833D832E839F83AA +:100CC00088878FB7F894E09156047091570460912B +:100CD00058045091590440915A0430915B0420917A +:100CE0005C0490915D04E9837A836B835C834D831C +:100CF0003E832F8398878FBF29813A814B815C8106 +:100D00006D817E818F81988528960FB6F894DEBF1D +:100D10000FBECDBFDF91CF9108951F920F920FB6F6 +:100D20000F9211242F933F938F939F93EF93FF93F1 +:100D30008091C600282F30E03093010120930001FC +:100D4000E091340491E09E0F90933404F0E0EA5C6B +:100D5000FB4F80839091340480913504981305C033 +:100D6000809135048F5F80933504FF91EF919F91BF +:100D70008F913F912F910F900FBE0F901F9018955C +:100D80001F920F920FB60F9211242F933F934F9300 +:100D90005F936F937F938F939F93AF93BF93EF93E3 +:100DA000FF9380916A03882319F08AED92E00DC0C9 +:100DB0008091D902882319F089E492E006C08091DD +:100DC000FB03882329F08BE693E00E94271903C0D8 +:100DD00080E88093BC00FF91EF91BF91AF919F910C +:100DE0008F917F916F915F914F913F912F910F90D4 +:100DF0000FBE0F901F9018951F920F920FB60F9273 +:100E000011242F933F934F935F936F937F938F930F +:100E10009F93AF93BF93EF93FF9380912704882311 +:100E200021F085E294E00E949F15809120048823A0 +:100E300021F08EE194E00E94721E809161048F5F28 +:100E40008A3018F4809361046AC010926104809122 +:100E5000620490916304A0916404B0916504892BAD +:100E60008A2B8B2B99F08091620490916304A0915E +:100E70006404B09165040197A109B10980936204EB +:100E800090936304A0936404B09365042091560486 +:100E900030915704409158045091590460915A047C +:100EA00070915B0480915C0490915D04A1E00E94CC +:100EB000E5282093560430935704409358045093E8 +:100EC000590460935A0470935B0480935C0490937C +:100ED0005D0483E593E00E94760385E593E00E943C +:100EE000DF0482EC92E00E94760384EC92E00E94A0 +:100EF000DF0484EE93E00E94760386EE93E00E9486 +:100F0000DF0480914002882319F0815080934002D1 +:100F100080913602882319F08150809336028091A7 +:100F20005F049091600401969093600480935F0445 +:100F30008838934160F080912D04811104C095B1EF +:100F400080E2892785B91092600410925F04FF91B6 +:100F5000EF91BF91AF919F918F917F916F915F9131 +:100F60004F913F912F910F900FBE0F901F901895AA +:100F7000CF93DF93EC01198218828091A70481112D +:100F80000EC087EA94E00E949905892B41F085EA1A +:100F900094E00E94720387EA94E00E949C05198AFB +:100FA0001A8A1B8A1C8A8AE694E09B838A8388E6D5 +:100FB00094E09D838C8386E694E09F838E8385EA0C +:100FC00094E099838883DF91CF910895CF93DF9345 +:100FD00000D0CDB7DEB74A83FC01808191810097B4 +:100FE00039F0698342E0BE016F5F7F4F0E94550474 +:100FF0000F900F90DF91CF910895CF92EF920F93C2 +:10100000CF93DF93EC016295660F660F607C4770AB +:101010002770822F880F880F880F262F242B282BCC +:101020002FAB0295000F007E88AD8F71082B08AFA3 +:101030008E2D8770880F880F880F9EA9292F207CFE +:101040009C2D9770E22EE82AE92AE894E7F8EEAAA8 +:1010500040E064EFCE010E94E60748AD4295469518 +:10106000477062EFCE010E94E6079EA9492F4770A4 +:1010700060E2469F90011124892F8695869586957A +:10108000877064E0869FA0011124422B532B97FBAD +:10109000992790F9492B65EFCE010E94E6079FA999 +:1010A000492F477080E2489F90011124892F86952F +:1010B00086958695877064E0869FA0011124422B57 +:1010C000532B9295969596959370492B64EFCE018C +:1010D000DF91CF910F91EF90CF900C94E6070F9393 +:1010E000CF93DF931F92CDB7DEB7FC018081918152 +:1010F000009749F0698301E09E012F5F3F4F41E077 +:10110000B9010E949D0489810F90DF91CF910F91C9 +:1011100008950F93CF93DF9300D0CDB7DEB7FC01D6 +:1011200080819181009749F0698302E09E012F5FE1 +:101130003F4F41E0B9010E949D0489819A8198271F +:10114000892798270F900F90DF91CF910F910895E5 +:101150000E94890898278927982708950C94890860 +:101160000C94A8080F93CF93DF9300D01F92CDB7B4 +:10117000DEB7FC0180819181009749F0698303E02B +:101180009E012F5F3F4F41E0B9010E949D042981DC +:101190006A81862F90E0A0E0B0E0BA2FA92F982FA7 +:1011A0008827A22B2B81BC01CD01622B0F900F90C1 +:1011B0000F90DF91CF910F9108956F927F928F9250 +:1011C0009F92AF92BF92CF92DF92EF92FF920F93D6 +:1011D0001F93CF93DF93EC019FA9892F807C8034EC +:1011E00009F043C0492F477060E2469F90011124E7 +:1011F000892F8695869586958770E4E08E9FA0015D +:101200001124422B532B9295969596959370492BCA +:1012100064EFCE010E94E6070E943F06922E832EC5 +:10122000742E652E63EFCE010E946F0883FF1FC0EE +:101230000E943F06A92CB82CC72CD62CE12CF12CEF +:1012400000E010E00E94F128203D374041055105A3 +:10125000610571058105910509F038F48FE99FE07A +:101260000197F1F700C00000DDCF80E001C081E010 +:10127000DF91CF911F910F91FF90EF90DF90CF9072 +:10128000BF90AF909F908F907F906F9008951F9325 +:10129000CF93DF93EC0168E80E94A8089E8B8D8BAA +:1012A0006AE8CE010E94A808988F8F8B6CE8CE0167 +:1012B0000E94A8089A8F898F6EE8CE010E94A80824 +:1012C0009C8F8B8F60E9CE010E94A8089E8F8D8F26 +:1012D00062E9CE010E94A80898A38F8F64E9CE012D +:1012E0000E94A8089AA389A366E9CE010E94A808D3 +:1012F0009CA38BA368E9CE010E94A8089EA38DA39E +:101300006AE9CE010E94A80898A78FA36CE9CE01D4 +:101310000E94A8089AA789A76EE9CE010E94A80892 +:101320009CA78BA761EACE010E946F088DA761EE92 +:10133000CE010E94A8089FA78EA763EECE010E944F +:101340006F0888AB64EECE010E946F08182F65EE1F +:10135000CE010E946F0890E11902900111248F7054 +:10136000282B3AAB29AB66EECE010E946F08182FEE +:1013700065EECE010E946F0890E1190290011124E0 +:1013800090E044E0959587954A95E1F7822B932B61 +:101390009CAB8BAB67EECE010E946F088DABDF91EB +:1013A000CF911F91089563EF0E946F088170089597 +:1013B000CF92DF92EF92FF920F931F93CF93DF9321 +:1013C000EC0160ED0E946F0890E0A0E0B0E089873A +:1013D0009A87AB87BC8780369105A105B10569F571 +:1013E00046EB60EECE010E94E6078FE39CE9019791 +:1013F000F1F700C00000CE010E94D3098111F5CFA2 +:10140000CE010E944709C12CD12CE12CF12C05E022 +:1014100010E025E030E045E050E063E070E0CE0110 +:101420000E94FD079FEF21EE84E091502040804014 +:10143000E1F700C0000081E001C080E0DF91CF91C2 +:101440001F910F91FF90EF90DF90CF900895CF9371 +:10145000DF93EC01888199810E947D03882329F024 +:10146000CE01DF91CF910C94D80980E0DF91CF912C +:1014700008954F925F926F927F928F929F92AF9258 +:10148000BF92CF92DF92EF92FF92CF93DF93EC0166 +:101490006AEF0E94B2086115710520E88207910584 +:1014A00009F485C06B017C0184E0F594E794D7943E +:1014B000C7948A95D1F74D885E88C701B60128E0A8 +:1014C00030E040E050E00E944327612C712CD301B2 +:1014D000C201880F991FAA1FBB1F281B390B4A0B7B +:1014E0005B0BAF89B88D0E946D274B015C01C70172 +:1014F000B60120E130E040E050E00E944327CA01FD +:10150000B90164197509860997099B01AC010E940C +:1015100013279B01AC017CE055954795379527959E +:101520007A95D1F7A98DBA8D0E946D272B013C01C8 +:10153000C501B40120E038E040E050E00E944327BC +:1015400069017A01C301B20120E030E440E050E0DB +:101550000E944327BA01A9014C0D5D1D6E1D7F1D20 +:1015600089899A89AB89BC899A01AB01280F391FF7 +:101570004A1F5B1F2D873E874F87588BA5E0B0E041 +:101580000E94622760587F4F8F4F9F4F20E031E0CD +:1015900040E050E00E944327CA01B9010E945A2A44 +:1015A00020E030E048EC52E40E94AA2904C060E048 +:1015B00070E080EC9FE7DF91CF91FF90EF90DF909C +:1015C000CF90BF90AF909F908F907F906F905F90E3 +:1015D0004F9008952F923F924F925F926F927F9219 +:1015E0008F929F92AF92BF92CF92DF92EF92FF9233 +:1015F0000F931F93CF93DF93CDB7DEB76D970FB6E1 +:10160000F894DEBF0FBECDBF1C010E94390A67EF00 +:10161000C1010E94B2086F87788B898B9A8B611504 +:1016200071058048910509F49AC2F1018585968576 +:10163000A785B0896C017D01FF0CCC08DC2C7601FC +:101640009C01AD016C2D7C2D8C2D9C2D345F414077 +:101650005109610971098109910929873A874B87E5 +:101660005C873B014C0159016A017B018C010E949E +:101670007527422E3D874E875B8B6C8B7D8B8E8BC7 +:101680009B8FD1015E963C915E975D962C91932F36 +:10169000990F990B492F592F692F792F892F0E9464 +:1016A00075270CE00E94A5282C8F3D8F49835F8B06 +:1016B000688F798F582E9A8FF10130A1278D932F43 +:1016C000990F990BA42CBD84CE84DB88EC88FD880F +:1016D0000E891B8D492F592F692F792F892F0E9431 +:1016E0007527F22E032F142FB52FF62FE72FD82EA4 +:1016F000E92EA0E00E94FA2884F421503F4F4F4F7A +:101700005F4F6F4F7F4F8F4F9F4FF22E032F142F3E +:10171000B52FF62FE72FD82EE92E2F2D302F412F62 +:101720005B2F6F2F7E2F8D2D9E2D08E00E94BE28EF +:10173000AC8CBD8CC980DF88E88CF98C052D1A8DA6 +:101740000E94DC2870588F4F9F4FD1015B96ED911E +:10175000FC915C975F01C12CD12CE12CF12C87010D +:10176000E983BA82CB82DC82ED82FE820F83188706 +:10177000C12CD12CE12CF12C00E010E00E94752747 +:10178000122F3F8B4983B52FF62FE72FF82E092F05 +:10179000A0E00E94FA2884F421503109410951093E +:1017A0006E4F7F4F8F4F9F4F122F3F8B4983B52F27 +:1017B000F62FE72FF82E092F212F3F8949815B2F24 +:1017C0006F2F7E2F8F2D902F01E20E94BE282D8F2C +:1017D000532E49835F8B688F798F8A8F9C8FA0E00F +:1017E0000E94FA2809F4C0C1D10196963C919697BF +:1017F00095962C91932F990F990BA42CBD84CE8490 +:10180000DB88EC88FD880E891B8D492F592F692FA5 +:10181000792F892F0E9475272D873E87442E5B8B59 +:101820006C8B7D8B8E8B9B8FF10134A123A1932F29 +:10183000990F990BA984BA84CB84DC847301840149 +:10184000492F592F692F792F892F0E94752701E180 +:101850000E94A528AD84BE84C42CDB88EC88FD885A +:101860000E891B8D0E94DC2859016A017B01482EDC +:10187000192F4F85588969897A8934E0759567955C +:10188000579547953A95D1F780E090E0A0E1B0E018 +:10189000841B950BA60BB70B3C014D01990C6608F8 +:1018A000762C43019C01AD01662D762D862D962D5B +:1018B0000FE10E94A528722E832E942E652EB62F3E +:1018C000A72F8A879B87F10132A121A1932F990F1E +:1018D000990B492F592F692F792F892F03E20E94E5 +:1018E000A528042D0E94DC2859016A017B018C0186 +:1018F000272D382D492D562D6B2F7A2F8A859B85C4 +:101900000E94F128E5E3AE2EFCE0BF2EC12CD12CC5 +:10191000E12CF12C00E010E00E947527AD8CB52C75 +:10192000C980DF88E88CF98C0A8D1C8D0E94D02735 +:101930002C8B3B8B2A013B014C01F22E032F142FE1 +:10194000B52DF62FE72DD82EE92CA0E00E94FA281D +:1019500084F42150304E4F4F5F4F6F4F7F4F8F4F6A +:101960009F4FF22E032F142FB52FF62FE72FD82ECF +:10197000E92E2F2D302F412F5B2F6F2F7E2F8D2D96 +:101980009E2D0DE00E94BE2829873A874B875C87F1 +:101990006F8779838D879E87D1019C963C919C9718 +:1019A0009B962C91932F990F990BA984BA846A0165 +:1019B0007B01082F1E85492F592F692F792F892FD9 +:1019C0000E9475270E947527F22E032F142FB52F22 +:1019D000F62FE72FD82EE92EA0E00E94FA2884F4F3 +:1019E0002150310941095E4F6F4F7F4F8F4F9F4FFD +:1019F000F22E032F142FB52FF62FE72FD82EE92E16 +:101A00002F2D302F412F5B2F6F2F7E2F8D2D9E2D51 +:101A100009E10E94BE28AC88BB8862017301840181 +:101A20000E94DC2829873A874B875C876F877983F8 +:101A30008D879E87F10132A521A5932F990F990BD0 +:101A4000492F592F692F792F892F0E947527122F1F +:101A50003C8B4B8BB52FF62FE72FF82E092FA0E0EC +:101A60000E94FA2884F421503109484F5F4F6F4F8C +:101A70007F4F8F4F9F4F122F3C8B4B8BB52FF62FE5 +:101A8000E72FF82E092F212F3C894B895B2F6F2FD1 +:101A90007E2F8F2D902F03E10E94BE2859016A01ED +:101AA0007B018C0129853A854B855C856F85798121 +:101AB0008D859E850E94DC28122F39874983B52F9A +:101AC000F62FE72FF82E092FA0E00E94FA2884F4C1 +:101AD00021503F4F4F4F5F4F6F4F7F4F8F4F9F4F63 +:101AE000122F39874983B52FF62FE72FF82E092FAC +:101AF000212F398549815B2F6F2F7E2F8F2D902FBE +:101B000008E00E94BE282983F32F6A017B01E82F99 +:101B1000192FD10197968D919C919897092E000CC1 +:101B2000AA0BBB0B4C015D01BB0C8808982C54011F +:101B30009C01AD01682D782D882D982D04E00E9420 +:101B4000A528A980BF2E0E2F0E94DC280E94522AB1 +:101B500020E030E040E85BE30E94342B08C060E006 +:101B600070E080EC9FE703C060E070E0CB016D9611 +:101B70000FB6F894DEBF0FBECDBFDF91CF911F919E +:101B80000F91FF90EF90DF90CF90BF90AF909F901C +:101B90008F907F906F905F904F903F902F9008951F +:101BA0004F925F926F927F928F929F92AF92BF926D +:101BB000CF92DF92EF92FF92CF93DF9300D000D0CD +:101BC00000D0CDB7DEB79E838D830E94390A6DEFBA +:101BD0008D819E810E948908A0E0B0E0811520E8F7 +:101BE0009207A105B10509F4D3C0ED81FE8185847A +:101BF0009684A784B088FCE29F1AF1E0AF0AB1088E +:101C00003EE0880F991FAA1FBB1F3A95D1F7ED81BF +:101C1000FE8141A952A9052E000C660B770B24E129 +:101C2000440F551F661F771F2A95D1F76C017D0160 +:101C3000C41AD50AE60AF70AA3A9B4A9A501940112 +:101C40000E946D27A7019601261B370B480B590BE5 +:101C5000CA01B901705C8F4F9F4F412C30E8532E61 +:101C6000612C712CA30192010E94432729833A839E +:101C70004B835C83ED81FE81A0A9B0E0A5019401B6 +:101C80000E94622720E038E040E050E00E944327B5 +:101C900069017A01F0E8DF0EE11CF11CED81FE81A3 +:101CA000A5A90A2E000CBB0BA50194010E946D276B +:101CB000812C44E0942EA12CB12CA50194010E940A +:101CC0004327CA01B901A70196010E941327A50164 +:101CD00094010E944327405E5F4FED81FE81A6A5DF +:101CE000B7A50E946D27705E8F4F9F4F20E030E4B4 +:101CF00040E050E00E94432769817A818B819C817A +:101D00000E9413276B017C01A30192010E944327CB +:101D1000CA01B9010E9413279B01AC0167E05595E8 +:101D20004795379527956A95D1F7ED81FE81A5A551 +:101D3000B0E00E94622720E130E040E050E00E94E5 +:101D40004327D701C601821B930BA40BB50BB7FF2A +:101D500003C080E090E0DC0181309105A105F9E14C +:101D6000BF0724F080E090E0A0E0B9E1BC01CD0124 +:101D70002CE095958795779567952A95D1F70E94E0 +:101D8000582A20E030E040E85AE30E94342B04C097 +:101D900060E070E080EC9FE726960FB6F894DEBF17 +:101DA0000FBECDBFDF91CF91FF90EF90DF90CF902E +:101DB000BF90AF909F908F907F906F905F904F906B +:101DC0000895CF92DF92EF92FF926A017B010E9409 +:101DD000EA0A20E030E048EC52E40E94AA29A70178 +:101DE00096010E94AA2921E03EED42E45EE30E94B2 +:101DF000A12B9B01AC0160E070E080E89FE30E94B2 +:101E00003D2920E03AE24DE257E40E94342BFF9056 +:101E1000EF90DF90CF900895CF92DF92EF92FF92F4 +:101E20000F931F93CB01BA016801790120E03AE2D8 +:101E30004DE257E40E94AA299B01AC0160E070E0EA +:101E400080E89FE30E943D2926EF38E248EA50E40B +:101E50000E94A12B9B01AC01C701B6010E94AA29D7 +:101E60001F910F91FF90EF90DF90CF900895FC01AC +:101E700061857285838594850895FC012189328965 +:101E800043895489A5E0B0E00E946227672F782F2C +:101E9000892F992787FD9A950E945A2A20E030E0E1 +:101EA00048EC52E40E94AA290895CF93DF93EC01F5 +:101EB000CB01BA0120E030E048EC52E40E94342B20 +:101EC0000E941C2A982F872F762F662725E030E066 +:101ED00040E050E00E944327298B3A8B4B8B5C8B70 +:101EE000DF91CF9108950F931F93CF93DF938C01D0 +:101EF000EB0188E2FB0111928A95E9F74BE050E093 +:101F000063E571E0CE010E944F2D1B8681E090E0D9 +:101F1000A0E0B0E08C879D87AE87BF87F801808105 +:101F20009181092E000CAA0BBB0B888B998BAA8B75 +:101F3000BB8B8DE090E0A0E0B0E08C8B9D8BAE8BF6 +:101F4000BF8B1CA21DA21EA21FA280E090E0A0E2F7 +:101F5000B2EC8C8F9D8FAE8FBF8F80E090E0AAEAAD +:101F6000B2E4888F998FAA8FBB8F8AE097EDA3E2A6 +:101F7000BCE388A399A3AAA3BBA3DF91CF911F9130 +:101F80000F910895CF93DF93EB0124E2FB011192AF +:101F90002A95E9F744E250E060E070E04883598315 +:101FA0006A837B83FC0180819181092E000CAA0B3E +:101FB000BB0B8C839D83AE83BF838DE090E0A0E05C +:101FC000B0E088879987AA87BB870E943F06288B45 +:101FD000398B4A8B5B8B8CE694E00E94390A6C8BC0 +:101FE0007D8B8E8B9F8B81E0DF91CF9108950F9336 +:101FF0001F93CF93DF938C01EB0188E2FB011192D9 +:102000008A95E9F74BE050E063E571E0CE010E946C +:102010004F2D1B8681E090E0A0E0B0E08C879D878B +:10202000AE87BF87F80180819181092E000CAA0B31 +:10203000BB0B888B998BAA8BBB8B86E090E0A0E0D2 +:10204000B0E08C8B9D8BAE8BBF8B1CA21DA21EA201 +:102050001FA280E090E0A6E9B3E48C8F9D8FAE8F45 +:10206000BF8F80E090E8A9E8B4E4888F998FAA8FA9 +:10207000BB8F86EA9BE9A4E4BCE388A399A3AAA347 +:10208000BBA3DF91CF911F910F910895CF93DF9361 +:10209000EB0124E2FB0111922A95E9F744E250E0BA +:1020A00060E070E0488359836A837B83FC01808110 +:1020B0009181092E000CAA0BBB0B8C839D83AE83F0 +:1020C000BF8386E090E0A0E0B0E088879987AA8788 +:1020D000BB870E943F06288B398B4A8B5B8B8CE633 +:1020E00094E00E94EA0A20E030E048EC52E40E94CA +:1020F000AA296C8B7D8B8E8B9F8B81E0DF91CF919A +:1021000008950F931F93CF93DF938C01EB0188E227 +:10211000FB0111928A95E9F74BE050E063E571E02D +:10212000CE010E944F2D1B8681E090E0A0E0B0E040 +:102130008C879D87AE87BF87F80180819181092EAA +:10214000000CAA0BBB0B888B998BAA8BBB8B8CE0EA +:1021500090E0A0E0B0E08C8B9D8BAE8BBF8B1CA27F +:102160001DA21EA21FA21C8E1D8E1E8E1F8E80E021 +:1021700090E0A8ECB2E4888F998FAA8FBB8F80E0A3 +:1021800090E0A0E4B0E488A399A3AAA3BBA3DF9145 +:10219000CF911F910F910895CF93DF93EB0124E22C +:1021A000FB0111922A95E9F744E250E060E070E00B +:1021B000488359836A837B83FC0180819181092E46 +:1021C000000CAA0BBB0B8C839D83AE83BF838CE07A +:1021D00090E0A0E0B0E088879987AA87BB870E943B +:1021E0003F06288B398B4A8B5B8B8CE694E00E94F0 +:1021F000D00D6C8B7D8B8E8B9F8B81E0DF91CF918F +:102200000895CF93DF93EC010E9472031A828CE74A +:102210008CAB8AE08DAB8EE78EAB8FEA8FAB88AF4D +:1022200082EA89AF1AAE80E88BAFDF91CF91089533 +:10223000CF93DF9300D0CDB7DEB74A83698342E006 +:10224000BE016F5F7F4F0E9455040F900F90DF918A +:10225000CF9108950F93CF93DF931F92CDB7DEB741 +:102260009A01698301E041E0BE016F5F7F4F0E94E8 +:102270009D040F90DF91CF910F9108950F93CF930D +:10228000DF931F92CDB7DEB79A01698302E041E088 +:10229000BE016F5F7F4F0E949D040F90DF91CF9131 +:1022A0000F9108950F931F93CF93DF9300D0CDB775 +:1022B000DEB78A01AE014F5F5F4F0E943E11882357 +:1022C00041F029813A81322723273227F8013183CF +:1022D00020830F900F90DF91CF911F910F91089560 +:1022E0000F93CF93DF931F92CDB7DEB76983022F91 +:1022F0009E012F5F3F4F41E0B9010E949D040F9066 +:10230000DF91CF910F91089540EF60E10E94181185 +:10231000EFE3FCE93197F1F700C0000008950F9357 +:102320001F93CF93DF9300D0CDB7DEB78C01AE0102 +:102330004F5F5F4F60E00E943E118FE39CE9019781 +:10234000F1F700C0000089819A818036E1E09E07A4 +:1023500021F4F801128281E008C08136914021F415 +:1023600081E0F801828301C080E00F900F90DF913F +:10237000CF911F910F9108950F931F93CF93DF93E8 +:102380001F92CDB7DEB78C0140E062E10E941811C8 +:10239000811108C08FE39CE90197F1F700C00000AC +:1023A00080E016C04CEC62E1C8010E94181188233D +:1023B00089F38FE39CE90197F1F700C00000AE01BB +:1023C0004F5F5F4F60E2C8010E942A11882311F31A +:1023D0000F90DF91CF911F910F9108950F931F934D +:1023E000CF93DF9300D01F92CDB7DEB78C010E9450 +:1023F000BC11882359F18FE39CE90197F1F700C0E4 +:1024000000004EE062E1C8010E9418118823F1F03B +:1024100023E0AE014F5F5F4F6CE4C8010E94701172 +:102420008823A1F02981F80123839A8194839B81D9 +:10243000958391E0273008F490E0F8019283EFE370 +:10244000FCE93197F1F700C0000007C08FE39CE979 +:102450000197F1F700C0000080E00F900F900F90FF +:10246000DF91CF911F910F910895633021F4FC010A +:102470002281222359F0462F60E10E941811EFE3D8 +:10248000FCE93197F1F700C00000089580E008955D +:10249000CF93DF93EC0163E50E947D038FE39CE91A +:1024A0000197F1F700C00000CE010E94841188233B +:1024B000A9F0CE010E948F11882381F061E0CE0146 +:1024C0000E943512882351F0CE010E94BC1188234E +:1024D00029F0CE01DF91CF910C94EE1180E0DF91D5 +:1024E000CF910895CF93DF9361157105D9F0EC0179 +:1024F0007F836E8361E00E943512882399F0CE01BC +:102500000E94BC11882371F042EC62E1CE010E946E +:102510001811882339F0EFE3FCE93197F1F700C097 +:10252000000007C08FE39CE90197F1F700C00000AD +:1025300080E0DF91CF9108956F927F928F929F926A +:10254000AF92BF92CF92DF92EF920F931F93CF93F0 +:10255000DF931F92CDB7DEB73C01CB01342FE02FC4 +:10256000AFE3BCE91197F1F700C0000068E170E04B +:102570000E942F278B014FEF460F4295440F440FC7 +:10258000407C3111406221114061E1114860E1104D +:10259000446060E4C3010E941811882309F471C0EB +:1025A000A80141505109569547955695479561E4C4 +:1025B000C3010E941811882309F463C0A60156952F +:1025C000479562E4C3010E941811882309F459C099 +:1025D000A5015695479563E4C3010E94181188230D +:1025E00009F44FC0A4015695479564E4C3010E94C5 +:1025F0001811811146C049895A895695479565E455 +:10260000C3010E94181181113CC0F3014681415061 +:1026100066E4C3010E941811811133C0D3011696DC +:102620008D919C911797019711F440E801C040E00B +:1026300067E4C3010E941811882319F1EFE3FCE954 +:102640003197F1F700C00000AE014F5F5F4F6FE4BC +:10265000C3010E942A118823A1F0AFE3BCE91197BE +:10266000F1F700C00000F30126813781B901606CE9 +:10267000498150E06417750729F02F5F3F4F37837A +:10268000268380E00F90DF91CF911F910F91EF9003 +:10269000DF90CF90BF90AF909F908F907F906F9082 +:1026A0000895AB0160E20C942A110F93CF93DF934E +:1026B0001F92CDB7DEB79B0141E2498305E041E0BF +:1026C000BE016F5F7F4F0E949D040F90DF91CF91FD +:1026D0000F9108950F931F93CF93DF93CDB7DEB77C +:1026E00029970FB6F894DEBF0FBECDBF8C016623CD +:1026F000F1F0AE01475F5F4F60E2C8010E942A110E +:102700008823E9F08FE99FE00197F1F700C000000E +:10271000898581FFEECF898581FF11C027E0AE0159 +:102720004F5F5F4F61E2C8010E94701108C0AE01A7 +:10273000475F5F4F60E20E942A118111ECCF80E079 +:1027400029960FB6F894DEBF0FBECDBFDF91CF91B3 +:102750001F910F9108950F931F93CF93DF93CDB7E0 +:10276000DEB729970FB6F894DEBF0FBECDBF8C0140 +:102770006623C1F08FE99FE00197F1F700C00000E8 +:10278000AE01475F5F4F60E2C8010E942A118111CC +:1027900002C080E00AC1898580FFECCF898580FF77 +:1027A000F8CF09C0AE01475F5F4F60E20E942A1177 +:1027B0008111F4CFEECF28E0AE014F5F5F4F68E4A8 +:1027C000C8010E947011882321F369817A8180E019 +:1027D00090E00E94582A20E030E040E05AE30E9456 +:1027E000342B9B01AC0160E070E080E090E40E943B +:1027F000A12B0E94232AF8016787708B818B928B13 +:102800006B817C8180E090E00E94582A20E030E0DB +:1028100040E05AE30E94342B9B01AC0160E070E081 +:1028200080E090E40E94A12B0E94232AF801678B8C +:10283000708F818F928F6D817E8180E090E00E9409 +:10284000582A20E030E040E05AE30E94342B9B01FC +:10285000AC0160E070E080E090E40E94A12B0E9457 +:10286000232AF801678F70A381A392A36F817885D3 +:1028700080E090E00E94582A20E030E040E05AE3F7 +:102880000E94342B9B01AC0160E070E080E090E49A +:102890000E94A12B0E94232AF80167A370A781A799 +:1028A00092A728E0AE014F5F5F4F68E2C8010E9427 +:1028B0007011882309F46DCF69817A8180E090E0FE +:1028C0000E94582A20E030E040E05AE30E94342B76 +:1028D0009B01AC0160E070E080E090E40E94A12BDD +:1028E0000E94232AF801638B748B858B968B6B81F6 +:1028F0007C8180E090E00E94582A20E030E040E0B7 +:102900005AE30E94342B9B01AC0160E070E080E050 +:1029100090E40E94A12B0E94232AF801638F748FF8 +:10292000858F968F6D817E8180E090E00E94582A8D +:1029300020E030E040E05AE30E94342B9B01AC01E0 +:1029400060E070E080E090E40E94A12B0E94232AC6 +:10295000F80163A374A385A396A36F81788580E0B3 +:1029600090E00E94582A20E030E040E05AE30E94C4 +:10297000342B9B01AC0160E070E080E090E40E94A9 +:10298000A12B0E94232AF80163A774A785A796A705 +:10299000AE014F5F5F4F68E3C8010E942A11882390 +:1029A00009F4F7CE9981F80193AB29960FB6F89404 +:1029B000DEBF0FBECDBFDF91CF911F910F91089564 +:1029C000CF93DF9300D000D0CDB7DEB769837A8391 +:1029D0004B835C8324E0AE014F5F5F4F63E10E9455 +:1029E00000040F900F900F900F90DF91CF910895FA +:1029F0008F929F92AF92BF92CF92DF92EF92FF920F +:102A00000F931F93CF93DF93EC014A015B01C90140 +:102A1000B80120E030E040E054E40E94342B0E94F2 +:102A2000232A6B017C0123E333E948E853E4C50121 +:102A3000B4010E943E2920E030E040E852E40E94C8 +:102A4000342B0E94232AA601CE01DF91CF911F9142 +:102A50000F91FF90EF90DF90CF90BF90AF909F903D +:102A60008F900C94E01408958FEF089582E292E025 +:102A70000895089520982AB12F762AB9289A2BB163 +:102A800020692BB921E0FC0122830895FC01128208 +:102A900028988BB18F768BB920988AB18F768AB9B6 +:102AA0000895EF92FF920F931F93CF93DF936111DD +:102AB0002CC0EC0102E312E084E2E82E82E0F82E62 +:102AC0006AE070E080E090E00E9413060196F9F45D +:102AD0001F930F930E94C62D8B811F928F93282FD7 +:102AE000082E000C330B3F938F93FF92EF920E94BE +:102AF000C62D8DB79EB708960FB6F8949EBF0FBE31 +:102B00008DBF4F99DDCF1B82DBCF8FEF01C080E0FF +:102B1000DF91CF911F910F91FF90EF90089589B1B0 +:102B20008095881F8827881F089589B182958170B4 +:102B300091E08927089583B1809581700895FC0103 +:102B40008281811102C01382089529B131E022955A +:102B500021702327279522272795220F220B83B147 +:102B60003827379533273795330F330B80E020FB19 +:102B700080F930FB81F990911F0198279370D1F46F +:102B800090911E0190FD0EC0982791FF0BC093817C +:102B900081FD04C09F3729F09F5F03C0903809F082 +:102BA0009150938380911E0120FB80F930FB81F9C5 +:102BB00080931E0180911F0120FB80F930FB81F979 +:102BC00080931F010895FC018281938183309105D8 +:102BD00040F4880F991FFC01E65BFE4F80819181D4 +:102BE000089582E791E00895E8EBF0E02DE020837E +:102BF0002CE1208324E6208324E02093BC0020E6FF +:102C000020937C0027E820937A0080579F4F21E093 +:102C1000FC012083089580579F4FFC01108284E0BF +:102C20008093BC001092B80010927C0010927A0041 +:102C300008952F923F924F925F926F927F928F9260 +:102C40009F92AF92BF92CF92DF92EF92FF920F933B +:102C50001F93CF93DF93CDB7DEB761970FB6F8948C +:102C6000DEBF0FBECDBF8C016111A5C2FC01828108 +:102C70009381009709F0E8C188EC93E09F938F93CC +:102C80000E94C62D98012C5F3F4F3D872C8767E738 +:102C9000C9010E94270A0F900F90811103C085EC93 +:102CA00093E08BC285EB93E09F938F930E94C62D98 +:102CB00058013DE3A30EB11CC5010E9448120F90BC +:102CC0000F90811103C082EB93E077C262E0C501EF +:102CD0000E943512811103C08FEA93E06EC200E0BA +:102CE00010E022E832E440E050E068EC71E4C50115 +:102CF0000E94F814811103C08CEA93E05EC289EA55 +:102D000093E09F938F930E94C62D0F900F908FEFAB +:102D10008F83412C512C32014E865F86688A798AD6 +:102D20008C859D850E94EA0A20E030E543EC57E45B +:102D30000E94AA299F938F937F936F93E2E9F3E018 +:102D4000FF93EF930E94C62D8C859D850E94390AC2 +:102D500068877987382E292E9F938F9339853F93E3 +:102D600088858F93E5E8F3E0FF93EF930E94C62DEB +:102D70008C859D850E94D00D4B018A879B879F93F0 +:102D80008F939F926F9389E793E09F938F930E9415 +:102D9000C62D0FB6F894DEBF0FBECDBF3F813F3FBB +:102DA00009F19A858B85282D392D492F582FFC0143 +:102DB000682D792D8F2F9E2F0E94F12B811112C02B +:102DC00078856985C101272F362F492F582FDB01C0 +:102DD000F1016B2F7A2F8F2F9E2F0E94F12B8823CA +:102DE00009F4FBC165E0C62ED12CE12CF12C05E0E5 +:102DF00010E025E030E045E050E063E070E08C85D5 +:102E00009D850E94FD078F81803208F413C1ECE696 +:102E1000F3E0FF93EF930E94C62D0F900F903F8138 +:102E200013162CF5632F330F770B880B990B0E9429 +:102E30005A2A6B017C019B01AC01C301B2010E94C3 +:102E4000AA294B018A879B87A70196016E857F85FA +:102E5000888999890E94AA2968877987382E292E1E +:102E6000412C512C32014E865F86688A798A9A8578 +:102E70008B85082D192D292F382FF885E985C1015B +:102E80004F2F5E2F692F722DC5010E94F8148111FA +:102E900005C088E693E09F938F93C7C08B858F937F +:102EA0009A859F939F928F922F923F92E985EF93FD +:102EB000F885FF9326E533E03F932F930E94C62DBC +:102EC00062E0C5010E9435120FB6F894DEBF0FBE56 +:102ED000CDBF811103C083E593E093C014E68FE575 +:102EE0009AEE0197F1F700C00000BE016A5F7F4FC4 +:102EF000C5010E945113882309F48AC08E8181FF85 +:102F000087C0BE016F5F7F4FC5010E9455138823A4 +:102F100009F481C089811F928F93EAE4F3E0FF9363 +:102F2000EF930E94C62D0F900F900F900F90898104 +:102F3000833091F038F4813061F0823099F48BE382 +:102F400093E012C0843059F0853061F483E293E05D +:102F50000BC080E493E008C082E393E005C08DE2FB +:102F600093E002C081E293E09F938F930E94C62D6D +:102F70000F900F908B818F938A818F9383E193E0E1 +:102F80009F938F930E94C62D8D818F938C818F93F9 +:102F900028E033E03F932F930E94C62D8C819D81C2 +:102FA0000FB6F894DEBF0FBECDBF8039F1E09F07AA +:102FB00018F486E093E01DC0883522E0920718F4EB +:102FC0008CEF92E016C0803233E0930718F487EF5D +:102FD00092E00FC0883EE3E09E0718F482EF92E093 +:102FE00008C08C3D954018F48DEE92E002C089EE49 +:102FF00092E09F938F930E94C62D0F900F9087EEC3 +:1030000092E09F938F930E94C62D0F900F9003C064 +:10301000115009F064CF61E0C5010E9435128111A1 +:1030200008C024EE32E03F932F930E94C62D0F90EC +:103030000F901F8268EE73E080E090E00E9413061C +:10304000019609F46DCEC1C08130910509F071C0BF +:1030500007581F4F61E0C8010E947D03811103C022 +:1030600081EE92E0AAC092EC692E92E0792E28EBD4 +:10307000E22E22E0F22E38EAC32E32E0D32E47E9C8 +:10308000A42E42E0B42E51EA852E52E0952E809176 +:103090007A00806480937A0080917A0086FDFCCF6C +:1030A0008091790089831F928F937F926F920E9403 +:1030B000C62D41E0BE016F5F7F4FC8010E945504DD +:1030C0000F900F900F900F90811106C0FF92EF921A +:1030D0000E94C62D0F900F90DF92CF920E94C62DB6 +:1030E00041E0BE016F5F7F4FC8010E9432040F9024 +:1030F0000F90882361F089811F928F939F928F9206 +:103100000E94C62D0F900F900F900F9006C0BF9297 +:10311000AF920E94C62D0F900F9068EE73E080E092 +:1031200090E00E941306019609F4B1CF0E94870334 +:103130004CC0029709F03FC005581F4F40E061E0C6 +:10314000C8010E94E604811103C084E992E035C001 +:103150008EE5C82E82E0D82EC8010E9436057C017B +:103160000196F1F080917A00806480937A008091DA +:103170007A0086FDFCCF60917900C8010E94160597 +:10318000809179001F928F93FF92EF92DF92CF92FE +:103190000E94C62D0F900F900F900F900F900F90E0 +:1031A00060E070E0CB010E9413060196A9F2C8010D +:1031B0000E94F6040AC08AE592E09F938F930E94D2 +:1031C000C62D0F900F908FEF29C064EF71E080E063 +:1031D00090E00E94130680E021C078856985C101D6 +:1031E000272F362F492F582F6E857F8588899989FB +:1031F0000E943E296E877F87888B998B9A858B8565 +:10320000282D392D492F582FC301B2010E943E2984 +:103210002B013C018F818F5F8F83E4CD61960FB6C8 +:10322000F894DEBF0FBECDBFDF91CF911F910F91FC +:10323000FF90EF90DF90CF90BF90AF909F908F90D6 +:103240007F906F905F904F903F902F900895FC017A +:10325000228133812230310541F4579A5F9A855893 +:103260009F4F0E943B055F9808958091BC00806845 +:103270008093BC00089508958FEF08955A9A089599 +:103280005A9808955B9A08955B980895439A089513 +:103290004398089560FF02C05C9A01C05C9861FF8A +:1032A00002C0289A01C0289862FF02C05F9A01C03C +:1032B0005F9863FF02C05E9A01C05E9864FF02C01F +:1032C0002A9A01C02A9865FF02C02B9A01C02B9848 +:1032D00066FF02C02C9A01C02C9867FF02C02D9A8D +:1032E00008952D980895FC018281811104C0209ACF +:1032F0008AB1806D8AB984B18C6384B908952091B4 +:103300005E04213011F40C947319FC018281811147 +:1033100004C020988AB18F728AB984B1837C84B941 +:10332000089580915E04813041F48FE99FE0019718 +:10333000F1F700C0000080E0089589B182958170A6 +:10334000189902C090E001C092E0282F292B99B172 +:10335000892F881F8827881F880F880F822B4E99F6 +:1033600002C030E001C038E0832B1A9902C030E07F +:1033700001C030E1832B1B9902C020E001C020E294 +:10338000822B1C9902C090E001C090E4892B1D990A +:1033900002C090E001C090E8892B0895409A0895FA +:1033A000409808951F93CF93DF93EC01162F0E944E +:1033B0004819CE010E9473198A81612F8823A1F0D8 +:1033C000607FCE010E944A19CE010E94461980E515 +:1033D0008A95F1F7CE010E94481985E08A95F1F7A8 +:1033E0000000612F6295607FCE010E944A19CE01D4 +:1033F0000E94461980E58A95F1F7CE010E9448198E +:1034000085E08A95F1F70000DF91CF911F91089533 +:103410001F93CF93DF93EC01162F0E944419CE0126 +:103420000E944019612FCE01DF91CF911F910C9422 +:10343000D219EF92FF920F931F93CF93DF93EC017A +:103440007B018B8187FD61C080915E04813041F4F6 +:103450008FE99FE00197F1F700C0000081E056C0BE +:10346000CE010E947F196FEFCE010E944A19CE0152 +:103470000E944219CE010E94401995E09A95F1F7F9 +:103480000000CE010E94461980E58A95F1F7CE0131 +:103490000E949119082FCE010E94481995E09A9533 +:1034A000F1F70000CE010E94461980E58A95F1F7F8 +:1034B000CE010E94911982958F70007F182F102BDA +:1034C000CE010E94481995E09A95F1F70000CE01CF +:1034D0000E94441910788BE0E816F10430F09BE06C +:1034E000E91AF10811F01111C2CF8B81813021F45A +:1034F000112311F08BEF8B8360E0CE010E944A19FB +:10350000CE010E94731981E0111180E0DF91CF910B +:103510001F910F91FF90EF900895CF93DF93EC01EF +:1035200062E370E00E94191A811102C08AEF8B8356 +:10353000DF91CF9108951F93CF93DF93EC01162F66 +:103540000E948D1A612F6068CE010E94081ACE0178 +:10355000DF91CF911F910C948D1A1F93CF93DF931E +:10356000EC0160E00E944A19CE010E9473198FEFAE +:1035700099EF0197F1F700C000001B8210E08A81EB +:10358000882311F068E201C068E0CE010E94081AA9 +:10359000111105C08FE19EE40197F1F704C08FE897 +:1035A00091E00197F1F700C000001F5F143039F778 +:1035B0006CE0CE010E94081A62E370E0CE010E9426 +:1035C000191A811102C08FEF1BC06CE0CE010E945E +:1035D000081A62E370E0CE010E94191A811102C03C +:1035E0008DEF0EC061E0CE010E94081A60EB74E01E +:1035F000CE010E94191A811102C08CEF01C081E036 +:103600008B83DF91CF911F910895CF93DF93EC01CE +:103610000E944419CE010E944019CE010E9448190F +:1036200060E0CE010E944A1984B18D6384B987B1EC +:10363000896087B98AB18C6D8AB9CE010E94AD1AB2 +:103640008CE294E09F938F930E94C62D8B810F9004 +:103650000F90813049F488E294E09F938F930E9409 +:10366000C62D0F900F9010C0282F082E000C330B82 +:103670003F938F938EE194E09F938F930E94C62D8A +:103680000F900F900F900F90CE01DF91CF910C947F +:10369000CE19CF93DF93FC012381213061F4EC013B +:1036A0000E948D1A6CE0CE010E94081ACE01DF91B3 +:1036B000CF910C948D1ADF91CF910895CF93DF9322 +:1036C000FC012381213061F4EC010E948D1A68E035 +:1036D000CE010E94081ACE01DF91CF910C948D1A71 +:1036E000DF91CF910895CF93DF93FC0123812130A7 +:1036F00061F4EC010E948D1A61E0CE010E94081A6B +:10370000CE01DF91CF910C948D1ADF91CF91089566 +:103710000E94731B85B1827C85B988B1867F88B988 +:103720008BB183728BB984B1827C84B987B1867F77 +:1037300087B98AB183728AB90895CF93DF93EC0178 +:103740008B818130B9F44431A8F4613039F048F00C +:10375000623031F0633071F44C5A03C0405C01C0F8 +:103760004C5E642FCE010E949B1ACE01DF91CF9157 +:103770000C948D1ADF91CF9108951F93CF93DF930F +:10378000FC0123812130A1F4162FEC010E94441981 +:10379000CE010E943E19612FCE010E94D219CE01A6 +:1037A0000E944019CE01DF91CF911F910C948D1A88 +:1037B000DF91CF911F910895FF920F931F93CF93A5 +:1037C000DF938C0161114FC0C0E084E1F82ED0E29C +:1037D000DC0F8C2F6F2D0E942327911105C040E034 +:1037E000682FC8010E949D1B6D2FC8010E94BD1B40 +:1037F000C8010E948D1ACF5FC03549F789E194E076 +:103800009F938F930E94C62DF80183810F900F9094 +:10381000813049F486E194E09F938F930E94C62DF6 +:103820000F900F9010C0282F082E000C330B3F93E1 +:103830008F938CE094E09F938F930E94C62D0F90FE +:103840000F900F900F9061E070E080E090E00E9498 +:1038500013060196C1F364EF71E080E090E00E94EE +:10386000130680E009C088E094E09F938F930E9444 +:10387000C62D0F900F908FEFDF91CF911F910F9179 +:10388000FF9008950F931F93CF93DF93EC018B016B +:10389000F80161918F01662339F08B81813021F429 +:1038A000CE010E94BD1BF4CFDF91CF911F910F91EC +:1038B00008958BB1837D8BB929988AB18C628AB9BE +:1038C000219A08958AB1837D8AB921988BB1837D2D +:1038D0008BB9299808958130910549F030F08230F4 +:1038E000910539F0039739F008955D9A0895299A62 +:1038F00008955B9A08955A9A0895CB0141110C944A +:103900006B1C6130710551F038F06230710541F087 +:103910006330710539F008955D98089529980895E8 +:103920005B9808955A9808956130710559F038F000 +:103930006230710561F06330710561F008959BB1EB +:1039400080E20AC095B182E0892785B908959BB1CC +:1039500088E002C09BB184E089278BB90895CB0130 +:103960000C946B1C40E00C947D1CCF936031E8F507 +:10397000C62FC370C23091F0C330B9F0C13039F0F6 +:1039800063E070E00E94B21C80E090E014C060E050 +:1039900070E00E94B21C81E090E00DC061E070E038 +:1039A0000E94B21C82E090E006C062E070E00E94DB +:1039B000B21C83E090E00E946B1C6C2F70E06F5F84 +:1039C0007F4F7F936F938BE394E09F938F930E943D +:1039D000C62D64EF71E080E090E00E9413060F9026 +:1039E0000F900F900F9080E001C08FEFCF9108955E +:1039F00008958FEF0895089586B183FB882780F995 +:103A000091E0892708952A9808955298FC0112821E +:103A100010927C0010927A0014BC15BC0E94031D09 +:103A200022983B988AB18F728AB943988BB18F7371 +:103A30008BB908952A9A0895CF93DF93EC01529A97 +:103A400080E680937C0087E880937A0083E884BDD9 +:103A500084E085BD229A3B98569A8AB18F768AB9BE +:103A6000439A8BB1806A8BB9CE010E941A1D81E006 +:103A70008A83DF91CF9108952F923F924F925F9268 +:103A80006F927F928F929F92AF92BF92CF92DF926E +:103A9000EF92FF920F931F93CF93DF936111FDC0BD +:103AA000EC0188ED94E09F938F930E94C62D0F90B8 +:103AB0000F9038EC232E34E0332E44EB642E44E098 +:103AC000742E05EA14E05BE9E52E54E0F52E60E97A +:103AD000C62E64E0D62E74E8A72E74E0B72EE3E578 +:103AE0004E2EE4E05E2EFCE68F2EF4E09F2E6AE080 +:103AF00070E080E090E00E941306019609F0CFC0CC +:103B000086B183FB882780F91F928F938DEC94E018 +:103B10009F938F930E94C62D0F900F900F900F9040 +:103B2000CE01339905C00E94031D3F922F9206C01B +:103B30000E941A1D83EC94E09F938F930E94C62DE0 +:103B40000F900F9080917A00806480937A0080912A +:103B50007A0086FDFCCF809179001F928F937F922F +:103B60006F920E94C62D82EE80937C002091790096 +:103B700030E0255031094BE5429FC001439F900D35 +:103B800011240F900F900F900F9097FDCF9626E085 +:103B9000959587952A95E1F78F3F910519F014F0D7 +:103BA0008FEF90E097FF02C080E090E08095823038 +:103BB00008F480E087BD1F928F931F930F930E949C +:103BC000C62D80917A00806480937A000F900F90C8 +:103BD0000F900F9080917A0086FDFCCF8091790044 +:103BE0001F928F93FF92EF920E94C62D80E68093E2 +:103BF0007C0089B1082E000C990B892F881F88271B +:103C0000881F1F928F93DF92CF920E94C62D89B199 +:103C1000829581701F928F93BF92AF920E94C62DA2 +:103C2000F8946B817C8178948DB79EB70C960FB613 +:103C3000F8949EBF0FBE8DBF6115710519F17F937A +:103C40006F9380E090E00E94582A9B01AC0160E0F5 +:103C500070E080E792E40E94AA2927E137EB41ED6A +:103C600058E30E94AA290E941C2A7F936F939F9277 +:103C70008F920E94C62D0F900F900F900F900F9073 +:103C80000F9035CF1F921F925F924F920E94C62DC8 +:103C90000F900F900F900F902ACF8FEF01C080E010 +:103CA000DF91CF911F910F91FF90EF90DF90CF9018 +:103CB000BF90AF909F908F907F906F905F904F904C +:103CC0003F902F90089589B18095881F8827881F7D +:103CD000089589B18295817008959BB184E0892708 +:103CE0008BB908951F93CF93DF93EC0111E080917E +:103CF000AF049091B0044C991CC010E02091B30423 +:103D0000222309F12091B1043091B204233031050E +:103D1000D0F0820F931F9C838B831092B204109279 +:103D2000B1041092B0041092AF04CE010E946D1E37 +:103D30000AC0811520E4920748F501969093B004DB +:103D40008093AF040DC08091B1049091B2048115AD +:103D500020E49207F0F401969093B2048093B104AA +:103D60008091AF049091B0048115904438F4809113 +:103D7000B1049091B2048115904410F01C821B8212 +:103D80001093B304DF91CF911F91089580E090E4E8 +:103D9000D5CF80E090E4E0CF419839982A9884B15B +:103DA000837D84B91CBC08958091640084708093E5 +:103DB0006400419A399A2A9A84B18C6284B98CB58C +:103DC00083658CBD80915E04823011F45F9A579AAE +:103DD000089580915E04823009F45F98089580917F +:103DE0005E04823009F45F9A08950F931F93CF9376 +:103DF000DF93EC01062F142F0E94E91E80E48EBD94 +:103E00000DB407FEFDCF0EBD0DB407FEFDCF1EBDE8 +:103E10000DB407FEFDCFCE010E94EF1E8AE18A9508 +:103E2000F1F700C080E0DF91CF911F910F910895CD +:103E30001F93CF93DF93EC01162F0E94E91E81E4BC +:103E40008EBD0DB407FEFDCF1EBD0DB407FEFDCF28 +:103E50001EBC0DB407FEFDCFCE010E94EF1E8EB535 +:103E6000DF91CF911F910895CF93DF93C42FD22F6D +:103E70001F924F931F926F9388E895E09F938F93C3 +:103E80000E94C62D0F900F900F900F900F900F90E3 +:103E9000CD1769F081E895E09F938F930E94C62D1E +:103EA0000F900F90CF3F59F486E695E002C082E66E +:103EB00095E09F938F930E94C62D0F900F9080E600 +:103EC00095E09F938F930E94C62D0F900F90DF91E6 +:103ED000CF9108952F923F924F925F926F927F926F +:103EE0008F929F92AF92BF92CF92DF92EF92FF920A +:103EF0000F931F93CF93DF93EC0180915E04813089 +:103F000049F483E495E09F938F930E94C62D0F9010 +:103F10000F90D9C06111D7C084E3282E85E0382ED8 +:103F2000CC24C394D12C2FE1422E25E0522E3AE02E +:103F3000632E35E0732E45EFA42E44E0B42E50EEF0 +:103F4000852E54E0952E64EF71E080E090E00E94B1 +:103F50001306019609F0B9C03F922F920E94C62D18 +:103F60000F900F90E12CF12C86010E2C01C0000F58 +:103F70000A94EAF7402F409560E0CE010E94F51EBA +:103F8000402F62E1CE010E94F51EFF92EF925F92F8 +:103F90004F920E94C62D62E1CE010E94181F202F71 +:103FA000482F62E1CE010E94341F68EC70E080E08F +:103FB00090E00E94130640E062E1CE010E94F51EEF +:103FC000FF92EF927F926F920E94C62D62E1CE0126 +:103FD0000E94181F20E0482F62E1CE010E94341F8A +:103FE0004FEF60E0CE010E94F51E68EC70E080E0CB +:103FF00090E00E9413068FEFE81AF80A8DB79EB77B +:1040000008960FB6F8949EBF0FBE8DBF98E0E916D4 +:10401000F10409F0A9CF00E010E07601002E01C004 +:10402000EE0C0A94EAF74E2D409561E0CE010E9415 +:10403000F51E4E2D63E1CE010E94F51E1F930F93D6 +:10404000BF92AF920E94C62D63E1CE010E94181F5D +:104050002E2D482F63E1CE010E94341F68EC70E0E2 +:1040600080E090E00E94130640E063E1CE010E94F0 +:10407000F51E1F930F939F928F920E94C62D63E1AE +:10408000CE010E94181F20E0482F63E1CE010E945C +:10409000341F4FEF61E0CE010E94F51E68EC70E026 +:1040A00080E090E00E9413060F5F1F4F8DB79EB710 +:1040B00008960FB6F8949EBF0FBE8DBF083011054D +:1040C00009F0ABCF40CF8FEF01C080E0DF91CF91FF +:1040D0001F910F91FF90EF90DF90CF90BF90AF9026 +:1040E0009F908F907F906F905F904F903F902F9018 +:1040F000089580E480937C0087E880937A00089597 +:1041000010927C0010927A0008950F931F93CF9322 +:10411000DF9361113AC08AEC95E09F938F930E94E0 +:10412000C62D0F900F9005EB15E0C8EAD5E06AE0C8 +:1041300070E080E090E00E941306019641F51F9325 +:104140000F930E94C62D80917A00806480937A003C +:104150000F900F9080917A0086FDFCCF209178001F +:104160003091790080917800909179003F932F935E +:104170009F938F93DF93CF930E94C62D0F900F9044 +:104180000F900F900F900F90D2CF8FEF01C080E073 +:10419000DF91CF911F910F91089582E480937C006D +:1041A00087E880937A00089510927C0010927A003C +:1041B0000895AF92BF92CF92DF92EF92FF920F934A +:1041C0001F93CF93DF93611185C083E196E09F93A6 +:1041D0008F930E94C62D0F900F903EEFE32E35E097 +:1041E000F32E01EF15E0C1EDD5E06AE070E080E06C +:1041F00090E00E941306019609F06EC0FF92EF92C4 +:104200000E94C62D80917A00806480937A000F907E +:104210000F9080917A0086FDFCCF2091780030913C +:10422000790080917800909179003F932F939F932C +:104230008F931F930F930E94C62D60917800709109 +:10424000790080E090E00E94582A23EC35EF48EA9C +:104250005FE30E94342B2AE939E941E852E40E94E5 +:10426000AA292DEC3CEC4CE05FE30E943E29D62EBF +:10427000C72EB82EA92EA6019501652F742F832F66 +:10428000922F0E94232A862F90E061701F926F93D5 +:1042900081FB222720F91F922F9382FB222720F9EE +:1042A0001F922F9323E0959587952A95E1F79F9389 +:1042B0008F93AF92BF92CF92DF92DF93CF930E9402 +:1042C000C62D8DB79EB744960FB6F8949EBF0FBE0D +:1042D0008DBF8BCF8FEF01C080E0DF91CF911F9119 +:1042E0000F91FF90EF90DF90CF90BF90AF90089527 +:1042F000442371F06130710539F020F062307105AE +:1043000029F008955C980895289808955F98089575 +:104310006130710539F020F06230710529F008959F +:104320005C9A0895289A08955F9A089561307105FE +:1043300049F020F06230710551F008959BB180E1A1 +:10434000892707C095B18EEF892785B908958BB16C +:1043500080588BB9089541E00C94782140E00C948A +:104360007821CF93DF93EC0160E070E00E94AE21F2 +:1043700061E070E0CE010E94AE2162E070E0CE010B +:104380000E94AE21209A8AB180698AB9DF91CF91CB +:104390000895CF93DF93EC0160E070E00E94AE21BE +:1043A00061E070E0CE010E94AE2162E070E0CE01DB +:1043B0000E94AE2120988AB18F768AB9DF91CF9181 +:1043C0000895CF93DF93EC01613009F43FC058F1B9 +:1043D000623009F44EC0633009F064C060E070E000 +:1043E0000E94AB2161E070E0CE010E94AB2162E04F +:1043F00070E0CE010E94AB2189E196E09F938F93FC +:104400000E94C62D68EB7BE080E090E00E941306DE +:1044100060E070E0CE010E94AE2161E070E0CE016C +:104420000E94AE2136C060E070E00E94AB2188E2BD +:1044300096E09F938F930E94C62D68EB7BE080E00F +:1044400090E00E94130660E070E025C061E070E03B +:104450000E94AB2182E296E09F938F930E94C62D2B +:1044600068EB7BE080E090E00E94130661E070E082 +:1044700012C062E070E00E94AB218DE196E09F9354 +:104480008F930E94C62D68EB7BE080E090E00E9455 +:10449000130662E070E0CE010E94AE210F900F90F3 +:1044A00080E001C08FEFDF91CF91089508958FEFE5 +:1044B000089580E396E00895ECEBF0E08081806859 +:1044C0008083089560FF02C05C9A01C05C9861FF20 +:1044D00002C0289A01C0289862FF02C05F9A01C0FA +:1044E0005F9863FF02C05E9A01C05E9864FF02C0DD +:1044F0002A9A01C02A9865FF02C02B9A01C02B9806 +:1045000066FF02C02C9A01C02C9867FF02C02D9A4A +:1045100001C02D9880915E04813019F0823061F0E5 +:10452000089570FF02C05B9A01C05B9871FF02C0E2 +:104530005A9A08955A98089570FF02C0429A01C08D +:10454000429871FF02C0439A08954398089580915C +:104550005E04813019F08230B1F0089560FF02C02E +:10456000409A01C0409861FF02C0419A01C0419841 +:1045700062FF02C0429A01C0429863FF02C0439AA0 +:1045800008954398089560FF02C05D9A01C05D9848 +:1045900061FF02C0299A01C0299862FF02C05B9A9C +:1045A00001C05B9863FF02C05A9A08955A98089513 +:1045B000CF93DF93EC0181E08A8360E070E0CE016D +:1045C0000E94622260E0CE010E94A72280915E04D8 +:1045D000813059F0823091F484B18F6384B987B10E +:1045E0008E6087B98AB18C6F08C084B18F6384B93B +:1045F00087B18F6087B98AB18C6D8AB9DF91CF910D +:104600000895CF93DF93EC011A8260E070E00E947E +:10461000622260E0CE010E94A72280915E04813078 +:1046200059F0823091F484B1807C84B987B1817F64 +:1046300087B98AB1837008C084B1807C84B987B19E +:10464000807F87B98AB183728AB9DF91CF9108954B +:1046500080915E04813019F0823039F0089566232C +:1046600011F029980895299A0895662311F0419828 +:104670000895419A0895CF92DF92EF92FF920F939F +:104680001F93CF93DF937C01611117C06FE00E94ED +:10469000A7226FEF73E0C7010E94622261E0C701A9 +:1046A0000E9428238DE596E09F938F930E94C62D4C +:1046B00060ED77E080E090E028C0613069F489E542 +:1046C00096E09F938F930E94C62D68EE73E080E082 +:1046D00090E00E94130620C0623039F460E071E07F +:1046E0000E94622280E596E008C06330C1F460E079 +:1046F00072E00E94622287E496E09F938F930E946B +:10470000C62D68EE73E080E090E00E94130660E042 +:1047100070E0C7010E9462220F900F9044C0643283 +:1047200008F043C0C62FD0E024978E0183E0159592 +:1047300007958A95E1F7C770DD27CC24C394D12C67 +:10474000B601002E01C0660F0A94EAF7C7010E9465 +:10475000A7220C2E02C0CC0CDD1C0A94E2F7B60195 +:10476000C7010E946222DF92CF92CC0FDD1FC05E94 +:10477000DE4F89818F9388818F931F930F9382E3FC +:1047800096E09F938F930E94C62D60E971E080E0D0 +:1047900090E00E9413068DB79EB708960FB6F89466 +:1047A0009EBF0FBE8DBF80E001C08FEFDF91CF9124 +:1047B0001F910F91FF90EF90DF90CF90089587B1F8 +:1047C000807F87B988B18F6088B9089588B1807F6C +:1047D00088B987B1807F87B908956130710581F00C +:1047E00058F06230710581F063307105A1F486B133 +:1047F00083FB882780F90CC086B18095817008956D +:1048000086B18695817004C086B182FB882780F9C5 +:1048100091E08927089580E008950F931F93CF9327 +:10482000DF93603108F04EC08C01C62FC695C69547 +:10483000D0E06370613021F0633009F44BC021C0D7 +:10484000BE010E94ED23811145C0CE0101969F93C8 +:104850008F9383E796E09F938F930E94C62D0F90CE +:104860000F900F900F90BE01C8010E94ED2381119F +:104870002BC060E070E0CB010E941306019621F589 +:10488000F2CFBE010E94ED23882321F1CE010196D3 +:104890009F938F9385E696E09F938F930E94C62DFA +:1048A0000F900F900F900F90BE01C8010E94ED2352 +:1048B000882351F060E070E0CB010E94130601965E +:1048C00019F4F2CF8FEF07C06AE070E080E090E06B +:1048D0000E94130680E0DF91CF911F910F91089500 +:1048E00008958FEF089508950F931F93CF93DF934B +:1048F000EC018B0188E791E099838883CE010496CF +:104900000E94B807CE01CD960E940111CE018758B2 +:104910009F4F0E947203CE0185589F4F0E94D8047A +:10492000FE01E057FF4F10821B830A83DF91CF9176 +:104930001F910F910895CF93DF93CDB7DEB7A09766 +:104940000FB6F894DEBF0FBECDBF259A2D9882E03A +:104950008093C00098E99093C10096E09093C200C4 +:104960001092C50093E39093C4008093B0008093AD +:10497000B10096E99093B3008093700080E191E0DC +:104980009093B7048093B60482E091E09093B504CD +:104990008093B40478948AE1E0E3F1E0DE011196BB +:1049A00001900D928A95E1F70E94AF0507ED11E0A5 +:1049B000F9EDEF2EF1E0FF2E6E012BE1C20ED11CBE +:1049C0001E013FE1230E311C6AE5462E61E0562EA2 +:1049D0007DE0672E72E0772EEDE4AE2EE1E0BE2E94 +:1049E0001F930F930E94C62DFF92EF920E94C62D37 +:1049F00082E092E09F938F930E94C62D2EE531E0D6 +:104A00003F932F930E94C62DA6E1B2E0BF93AF93D0 +:104A10000E94C62D5F924F920E94C62D7F926F9288 +:104A20000E94C62DFF92EF920E94C62D80915E04D7 +:104A30009FEF980F0FB6F894DEBF0FBECDBF923038 +:104A4000C8F40E94A2059F938F93BF92AF920E94D9 +:104A5000C62DFF92EF920E94C62D1F930F930E94C6 +:104A6000C62D8AE391E09F938F930E94C62D18A2D2 +:104A70001F8E0DC01F928F938DE191E09F938F93B6 +:104A80000E94C62D0F900F900F900F90FFCF0FB682 +:104A9000F894DEBF0FBECDBF8F8D98A18D309105EC +:104AA00048F5FC01EE0FFF1FA1E0B0E0AC0FBD1F09 +:104AB000EA0FFB1F808091809F938F9324E131E068 +:104AC0003F932F930E94C62DD401ED91FC91068057 +:104AD000F781E02DC40109959F938F930E94C62D05 +:104AE0001F930F930E94C62D8F8D98A1019698A3B6 +:104AF0008F8FCDCF85E091E09F938F930E94C62D3D +:104B000010923504109234044091B4045091B504CD +:104B100064E070E0C6010E945E2D3F922F9280E516 +:104B200091E09F938F93DF92CF920E94EC2D0FB66E +:104B3000F894DEBF0FBECDBF019709F051CF8F8D26 +:104B400098A18D30910508F04BCF880F991FE1E0B7 +:104B5000F0E0EC0FFD1FE80FF91FA080B18081E0AD +:104B600091E09F938F930E94C62DD501ED91FC910A +:104B70000680F781E02DC50109959F938F930E94D0 +:104B8000C62D8DEF90E09F938F930E94C62D8FEFDF +:104B90009FEF9093010180930001D501ED91FC916D +:104BA0000280F381E02DC50109950F900F900F90C1 +:104BB0000F900F900F90812C912C36EF632E30E0E8 +:104BC000732E44244A94542C9F928F927F926F921A +:104BD0000E94C62DD501ED91FC910190F081E02D50 +:104BE000682DC50109950F900F900F900F9087FDCC +:104BF00018C080910001909101014B9739F48FEF1B +:104C00009FEF90930101809300010BC0509201012E +:104C100040920001BFEF8B1A9B0A2FEF821691047E +:104C200099F6D501ED91FC910480F581E02DC50147 +:104C30000995CACE8CE991E09093330480933204B5 +:104C400089E192E0909331048093300484EE91E006 +:104C500090932F0480932E048CEF91E090932C047A +:104C600080932B0410922D048CEC91E090932A04F5 +:104C7000809329048AE691E090932604809325048A +:104C8000109228041092270488ED91E09093240458 +:104C90008093230484EB91E090931F0480931E047F +:104CA00010922004109222041092210480EC91E0D2 +:104CB00090931D0480931C0480E991E09093190463 +:104CC0008093180481E090915E04913009F480E0B3 +:104CD00080931A0410921B0485E292E090931604CC +:104CE000809315041092170488EA91E090930204CF +:104CF00080930104109203041092040484E891E06C +:104D00009093FD038093FC031092FE038FEF9FEFBF +:104D1000909300048093FF0360E070E08BE693E0E3 +:104D20000E94742461E070E08AED92E00E94742495 +:104D300062E070E089E492E00E94742480EF91E0E8 +:104D4000909343028093420284E492E00E947203B3 +:104D50001092460210924802109247028EE591E0AE +:104D600090933902809338021092400221E030E0A3 +:104D700030933F0220933E0210923A0210923B027F +:104D800010923C0210923D0290932F0280932E02CB +:104D90001092360282E090E09093350280933402C4 +:104DA00010923002109231021092320210923302AD +:104DB00008958CE694E00E94B80788E191E0909312 +:104DC0006B0480936A0490936904809368049093C1 +:104DD000670480936604089582E592E0089580E078 +:104DE00094E0089587E394E0089588E494E00895BA +:104DF0008CE494E008958AED94E0089580EA95E0CB +:104E000008958CEC95E0089585E196E008958CE294 +:104E100096E0089580E696E008958EE796E008957E +:104E200085E896E00895DB018F939F930E946227A7 +:104E3000BF91AF91A29F800D911DA39F900DB29F36 +:104E4000900D11240895991B79E004C0991F9617BD +:104E500008F0961B881F7A95C9F780950895AA1BBC +:104E6000BB1B51E107C0AA1FBB1FA617B70710F055 +:104E7000A61BB70B881F991F5A95A9F78095909587 +:104E8000BC01CD010895052E97FB1EF400940E94ED +:104E90005A2757FD07D00E94062907FC03D04EF47D +:104EA0000C945A2750954095309521953F4F4F4F80 +:104EB0005F4F089590958095709561957F4F8F4FC6 +:104EC0009F4F08950E942E29A59F900DB49F900D8D +:104ED000A49F800D911D11240895B7FF0C946227A3 +:104EE0000E946227821B930B0895DF93CF931F9339 +:104EF0000F939A9DF02D219FF00D8B9DF00D8A9DB3 +:104F0000E02DF10D039FF00D029FE00DF11D4E9D70 +:104F1000E00DF11D5E9DF00D4F9DF00D7F936F93A1 +:104F2000BF92AF925F934F93D5010E942E298B01C0 +:104F3000AC01D7010E942E29EB01E80FF91FD60121 +:104F40000E94C5272F913F91D6010E942E29C60F9E +:104F5000D71FE81FF91FAF91BF910E94C5272F915E +:104F60003F910E942E29C60FD71FE81FF91FD601B7 +:104F70000E942E29E60FF71F9801BE01CF011124D0 +:104F80000F911F91CF91DF9108950E942E29460F16 +:104F9000571FC81FD91F08F431960895689401C09F +:104FA000E894F92FF12B12F00C940228A0E0B0E065 +:104FB000ECEDF7E20C947428092E059422F40E947B +:104FC0005E28112392F4F0E80F26FFEFE094F094AE +:104FD00000951095B094C094D094A194BF0ACF0AC4 +:104FE000DF0AEF0AFF0A0F0B1F0B0E940D2807FCB8 +:104FF0000E945E28CDB7DEB7ECE00C949028689450 +:1050000001C0E8948F929F92CF93DF930E940D2866 +:10501000DF91CF919F908F90089588249924F40177 +:10502000E401B0E49F93AA279A158B049C04ED0534 +:10503000FE05CF05D007A10798F4AD2FDC2FCF2FA9 +:10504000FE2FE92D982C892E982F872F762F652FEC +:10505000542F432F322F2227B85031F7BF9127C04A +:105060001B2EBF91BB27220F331F441F551F661FE6 +:10507000771F881F991F881C991CEE1FFF1FCC1FCC +:10508000DD1FAA1FBB1F8A149B04EC05FD05CE057E +:10509000DF05A007B10748F08A189B08EC09FD0955 +:1050A000CE09DF09A00BB10B21601A94E1F62EF4B2 +:1050B0009401AF01BE01CD01000C0895609570957B +:1050C0008095909530954095509521953F4F4F4F45 +:1050D0005F4F6F4F7F4F8F4F9F4F08952F923F929B +:1050E0004F925F926F927F928F929F92AF92BF92F8 +:1050F000CF92DF92EF92FF920F931F93CF93DF93A4 +:10510000CDB7DEB7CA1BDB0B0FB6F894DEBF0FBE00 +:10511000CDBF09942A88398848885F846E847D844D +:105120008C849B84AA84B984C884DF80EE80FD804F +:105130000C811B81AA81B981CE0FD11D0FB6F894C5 +:10514000DEBF0FBECDBFED0108950F93083090F084 +:10515000982F872F762F652F542F432F322F2227FA +:105160000850F4CF220F331F441F551F661F771FAF +:10517000881F991F0A95B2F70F91089597FB10F8B1 +:10518000169400080F93083098F00850232F342FFE +:10519000452F562F672F782F892F902DF4CF059408 +:1051A000979587957795679557954795379527955F +:1051B0000A95AAF70F9108952A0D3B1D4C1D5D1D00 +:1051C0006E1D7F1D801F911F08950024A7FD009470 +:1051D0002A0F301D401D501D601D701D801D901D2B +:1051E00008952A193B094C095D096E097F09800B56 +:1051F000910B08950024A7FD00942A17300540055F +:10520000500560057005800590050895A1E21A2EED +:10521000AA1BBB1BFD010DC0AA1FBB1FEE1FFF1F5A +:10522000A217B307E407F50720F0A21BB30BE40BAA +:10523000F50B661F771F881F991F1A9469F76095F1 +:105240007095809590959B01AC01BD01CF010895AB +:10525000EE0FFF1F0590F491E02D0994A29FB0017D +:10526000B39FC001A39F700D811D1124911DB29F9A +:10527000700D811D1124911D08955058BB27AA2738 +:105280000E9455290C94FA2A0E94EC2A38F00E94B8 +:10529000F32A20F039F49F3F19F426F40C94D92A0C +:1052A0000EF4E095E7FB0C94D32AE92F0E940B2B18 +:1052B00058F3BA17620773078407950720F079F44B +:1052C000A6F50C942D2B0EF4E0950B2EBA2FA02DE5 +:1052D0000B01B90190010C01CA01A0011124FF27A3 +:1052E000591B99F0593F50F4503E68F11A16F0409E +:1052F000A22F232F342F4427585FF3CF469537959D +:105300002795A795F0405395C9F77EF41F16BA0B61 +:10531000620B730B840BBAF09150A1F0FF0FBB1F0F +:10532000661F771F881FC2F70EC0BA0F621F731F58 +:10533000841F48F4879577956795B795F7959E3FB5 +:1053400008F0B0CF9395880F08F09927EE0F979546 +:10535000879508950E94BE290C94FA2A0E94F32A88 +:1053600058F00E94EC2A40F029F45F3F29F00C9499 +:10537000D32A51110C942E2B0C94D92A0E940B2B5A +:1053800068F39923B1F3552391F3951B550BBB2774 +:10539000AA2762177307840738F09F5F5F4F220FB9 +:1053A000331F441FAA1FA9F335D00E2E3AF0E0E8B0 +:1053B00032D091505040E695001CCAF72BD0FE2FFA +:1053C00029D0660F771F881FBB1F2617370748078E +:1053D000AB07B0E809F0BB0B802DBF01FF27935846 +:1053E0005F4F3AF09E3F510578F00C94D32A0C940D +:1053F0002E2B5F3FE4F3983ED4F38695779567951F +:10540000B795F7959F5FC9F7880F911D969587957A +:1054100097F90895E1E0660F771F881FBB1F621799 +:1054200073078407BA0720F0621B730B840BBA0B57 +:10543000EE1F88F7E09508950E94232A6894B11121 +:105440000C942E2B08950E94132B88F09F5798F0F0 +:10545000B92F9927B751B0F0E1F0660F771F881F79 +:10546000991F1AF0BA95C9F714C0B13091F00E9493 +:105470002D2BB1E008950C942D2B672F782F8827C2 +:10548000B85F39F0B93FCCF3869577956795B395BA +:10549000D9F73EF490958095709561957F4F8F4F29 +:1054A0009F4F089597FB16F40E94DC2A0C94962ACD +:1054B000E89409C097FB3EF49095809570956195AE +:1054C0007F4F8F4F9F4F9923A9F0F92F96E9BB2764 +:1054D0009395F695879577956795B795F111F8CFE0 +:1054E000FAF4BB0F11F460FF1BC06F5F7F4F8F4F4B +:1054F0009F4F16C0882311F096E911C0772321F041 +:105500009EE8872F762F05C0662371F096E8862FD8 +:1055100070E060E02AF09A95660F771F881FDAF72F +:10552000880F9695879597F90895E894F92F96EB4B +:10553000FF2381F0121613061406440B9395F6957B +:1055400087957795679557954040FF23B9F71BC01E +:1055500099270895882351F49850D2F7872B762FF6 +:10556000652F542F432F322F20E0B1F3121613066C +:105570001406440B88233AF09A95440F551F661F72 +:10558000771F881FCAF755234AF4440F551F11F49B +:1055900060FF04C06F5F7F4F8F4F9F4F880F9695BE +:1055A000879597F9089597F99F6780E870E060E024 +:1055B00008959FEF80EC0895909580957095609583 +:1055C00050954095309521953F4F4F4F5F4F6F4F0E +:1055D0007F4F8F4F9F4F089500240A941616170689 +:1055E00018060906089500240A94121613061406D4 +:1055F00005060895092E0394000C11F4882352F037 +:10560000BB0F40F4BF2B11F460FF04C06F5F7F4FEE +:105610008F4F9F4F089557FD9058440F551F59F0D5 +:105620005F3F71F04795880F97FB991F61F09F3F8F +:1056300079F087950895121613061406551FF2CFB8 +:105640004695F1DF08C0161617061806991FF1CF08 +:1056500086957105610508940895E894BB2766272F +:105660007727CB0197F908950E94472B0C94FA2ACB +:105670000E94EC2A38F00E94F32A20F0952311F0C2 +:105680000C94D32A0C94D92A11240C942E2B0E940A +:105690000B2B70F3959FC1F3950F50E0551F629F40 +:1056A000F001729FBB27F00DB11D639FAA27F00D7B +:1056B000B11DAA1F649F6627B00DA11D661F829FA2 +:1056C0002227B00DA11D621F739FB00DA11D621F87 +:1056D000839FA00D611D221F749F3327A00D611DA4 +:1056E000231F849F600D211D822F762F6A2F112486 +:1056F0009F5750409AF0F1F088234AF0EE0FFF1FB9 +:10570000BB1F661F771F881F91505040A9F79E3F0F +:10571000510580F00C94D32A0C942E2B5F3FE4F3B8 +:10572000983ED4F3869577956795B795F795E79565 +:105730009F5FC1F7FE2B880F911D9695879597F96E +:105740000895FA01EE0FFF1F309621053105A1F1F2 +:105750006115710561F48038BFE39B0749F16894D6 +:105760009038810561F08038BFEF9B0741F09923A5 +:105770004AF5FF3FE1053105210519F1E894089448 +:10578000E795D901AA2329F4AB2FBE2FF85FD0F3F8 +:1057900010C0FF5F70F4A695E0F7F73950F019F0EC +:1057A000FF3A38F49F779F930DD00F9007FC9058E5 +:1057B000089546F00C94D92A60E070E080E89FE3F9 +:1057C00008954FE79F775F934F933F932F930E94E6 +:1057D000C52C2F913F914F915F910E94342B0C94D7 +:1057E000FE2B0E94302C880B990B089529F416F09B +:1057F0000C94D32A0C942D2B0C94D92A0E94132B91 +:10580000A8F39638A0F707F80F92E8942BE33AEA4A +:1058100048EB5FE70E944A2B0F920F920F924DB711 +:105820005EB70F920E940D2DE8E6F0E00E94542C26 +:105830004F915F91EF91FF91E595EE1FFF1F49F0AA +:10584000FE57E0684427EE0F441FFA95E1F74195B3 +:10585000550B0E94872C0F9007FE0C947B2C08950B +:10586000990F0008550FAA0BE0E8FEEF1616170671 +:10587000E807F907C0F012161306E407F50798F0D9 +:10588000621B730B840B950B39F40A2661F0232BF2 +:10589000242B252B21F408950A2609F4A140A6956E +:1058A0008FEF811D811D0895DF93CF931F930F9379 +:1058B000FF92EF92DF927B018C01689406C0DA2E92 +:1058C000EF010E94472BFE01E894A59125913591A7 +:1058D00045915591A6F3EF010E945529FE019701CC +:1058E000A801DA9469F7DF90EF90FF900F911F9174 +:1058F000CF91DF9108959B01AC0160E070E080E8FA +:105900009FE30C94AA290C94D32A0C94412D0E9455 +:10591000132BD8F39923C9F3940F511DA3F391507E +:10592000504094F059F0882332F0660F771F881F9B +:1059300091505040C1F79E3F51052CF7880F911DA3 +:105940009695879597F908955F3FACF0983E9CF047 +:10595000BB27869577956795B79508F4B1609395C1 +:10596000C1F7BB0F58F711F460FFE8CF6F5F7F4FAF +:105970008F4F9F4FE3CF0C942E2B16F00C94412D9C +:105980000C94D92A68940C94D32A0E94132BA8F360 +:105990009923C1F3AEF3DF93CF931F930F93FF923D +:1059A000C92FDD2788232AF02197660F771F881FCC +:1059B000DAF720E030E040E85FEB9FE3883920F041 +:1059C000803E38F021968F770E943E29E0E9F0E092 +:1059D00004C00E943E29EDEBF0E00E94542C8B01A4 +:1059E000BE01EC01FB2E6F5771097595771F880B6F +:1059F000990B0E945A2A28E132E741E35FE30E94B3 +:105A0000472BAF2D9801AE01FF900F911F91CF91C1 +:105A1000DF910E9455290C94FA2AFA01DC01AA0FA1 +:105A2000BB1F9B01AC01BF5728F422273327442713 +:105A3000507820C0B75190F4AB2F0024469537958D +:105A40002795011CA395D2F3002071F0220F331F7C +:105A5000441FB395DAF30ED00C943D2961307105E3 +:105A6000A0E88A07B94630F49B01AC016627772786 +:105A700088279078309621F02083318342835383A6 +:105A800008959F3F31F0915020F487957795679561 +:105A9000B795880F911D9695879597F90895FB0105 +:105AA000DC014150504048F001900D920020C9F7B0 +:105AB00001C01D9241505040E0F70895A0E0B0E0D1 +:105AC000E4E6FDE20C947828FA01238120FD03C06E +:105AD00080E090E01AC016161706D4F77A018C0100 +:105AE000EB016C01C130D10569F0C7010E94BD32E4 +:105AF0008F3FFFEF9F0761F3F60181936F012197BD +:105B00000A9781F7F6011082C801CDB7DEB7E8E049 +:105B10000C9494280F931F93CF93DF93FB01238161 +:105B200021FD03C08FEF9FEF2CC022FF16C04681DE +:105B30005781248135814217530744F4A081B181F4 +:105B40009D012F5F3F4F318320838C9326813781C6 +:105B50002F5F3F4F3783268314C08B01EC01FB017D +:105B60000084F185E02D0995892BE1F6D801169680 +:105B70008D919C911797019617969C938E931697EB +:105B8000CE01DF91CF911F910F910895A0E0B0E079 +:105B9000ECECFDE20C947C28AE01495F5F4FDA012A +:105BA0006D917D91AD0104EB14E0F8018281938148 +:105BB000DC0113962C911397286013962C930E9466 +:105BC000052ED8011296ED91FC9113972381277F22 +:105BD0002383E4E00C949828AEE0B0E0E2EFFDE22D +:105BE0000C947E2885E08C838B899C899A83898399 +:105BF000AE01495E5F4F6D897E89CE0101960E949C +:105C000082312E96E2E00C949A28ABE0B0E0EBE013 +:105C1000FEE20C946E286C017B018A01FC01178264 +:105C20001682838181FFCCC1CE0101963C01F60131 +:105C30009381F70193FD859193FF81917F018823E3 +:105C400009F4BAC1853239F493FD859193FF8191AE +:105C50007F01853229F4B60190E00E948A2DE7CFBA +:105C6000912C212C312CFFE1F315D8F08B3279F0F7 +:105C700038F4803279F08332A1F4232D20611DC0E5 +:105C80008D3261F0803369F4232D216016C0832D9D +:105C90008260382EE32DE4603E2E2AC0F32DF8609A +:105CA0001DC037FC2DC020ED280F2A3040F08E3269 +:105CB000B9F436FC81C1232D2064322E19C036FE82 +:105CC00006C08AE0989E200D1124922E11C0EAE0B1 +:105CD0002E9E200D1124222EF32DF0623F2E08C09F +:105CE0008C3621F4832D8068382E02C0883641F42A +:105CF000F70193FD859193FF81917F018111B3CFCE +:105D0000982F9F7D9554933028F40C5F1F4F9FE38D +:105D100099830DC0833631F0833771F0833509F0F4 +:105D200059C021C0F801808189830E5F1F4F8824EC +:105D30008394912C530113C02801F2E04F0E511CA3 +:105D4000F801A080B18036FE03C0692D70E002C06A +:105D50006FEF7FEFC5010E94B2324C018201F32D3B +:105D6000FF773F2E16C0280122E0420E511CF80199 +:105D7000A080B18036FE03C0692D70E002C06FEFD5 +:105D80007FEFC5010E94A7324C01F32DF0683F2E32 +:105D9000820133FC1BC0822D90E088169906B0F476 +:105DA000B60180E290E00E948A2D2A94F4CFF5019A +:105DB00037FC859137FE81915F01B60190E00E942A +:105DC0008A2D21102A9421E0821A910881149104CD +:105DD00071F7E8C0843611F0893641F5F80137FED5 +:105DE00007C060817181828193810C5F1F4F08C061 +:105DF00060817181072E000C880B990B0E5F1F4F7D +:105E0000F32DFF763F2E97FF09C0909580957095F2 +:105E100061957F4F8F4F9F4FF0683F2E2AE030E013 +:105E2000A3010E941433882E861845C0853731F4AB +:105E3000232D2F7EB22E2AE030E025C0932D997FAE +:105E4000B92E8F36C1F018F4883579F0B5C0803797 +:105E500019F0883721F0B0C0E92FE061BE2EB4FE02 +:105E60000DC0FB2DF460BF2E09C034FE0AC0292FDF +:105E70002660B22E06C028E030E005C020E130E008 +:105E800002C020E132E0F801B7FE07C060817181F5 +:105E9000828193810C5F1F4F06C06081718180E019 +:105EA00090E00E5F1F4FA3010E941433882E8618C6 +:105EB000FB2DFF773F2E36FE0DC0232D2E7FA22E09 +:105EC000891458F434FE0BC032FC09C0832D8E7E39 +:105ED000A82E05C0B82CA32C03C0B82C01C0B92C27 +:105EE000A4FE0FC0FE01E80DF11D8081803321F476 +:105EF0009A2D997EA92E09C0A2FE06C0B394B39430 +:105F000004C08A2D867809F0B394A3FC11C0A0FECA +:105F100006C0B21488F4280C922C9B180EC0B21440 +:105F200060F4B60180E290E00E948A2DB394F7CF2E +:105F3000B21418F42B1802C0982C212CA4FE10C007 +:105F4000B60180E390E00E948A2DA2FE17C0A1FC5A +:105F500003C088E790E002C088E590E0B6010CC07D +:105F60008A2D867859F0A1FE02C08BE201C080E242 +:105F7000A7FC8DE2B60190E00E948A2D891438F4C6 +:105F8000B60180E390E00E948A2D9A94F7CF8A941C +:105F9000F301E80DF11D8081B60190E00E948A2D89 +:105FA0008110F5CF222009F442CEB60180E290E0C4 +:105FB0000E948A2D2A94F6CFF6018681978102C02D +:105FC0008FEF9FEF2B96E2E10C948A2820FD09C009 +:105FD000FC0123FD05C022FF02C07383628351834D +:105FE0004083089544FD17C046FD17C0AB01BC01B6 +:105FF000DA01FB01AA0FBB1FEE1FFF1F1094D1F7A0 +:106000004A0F5B1F6E1F7F1FCB01BA01660F771F00 +:10601000881F991F09C033E001C034E0660F771F65 +:10602000881F991F3150D1F7620F711D811D911D7D +:1060300008950F931F93CF93DF938C01C8010E94A3 +:10604000BD32EC0197FD08C00E949332892BB1F755 +:10605000B801CE010E94FB32CE01DF91CF911F919A +:106060000F9108958F929F92AF92BF92EF92FF92FD +:106070000F931F93CF93DF938C01D62F7A01B22E0B +:106080000E94BD329C0133272B32310531F02D3275 +:10609000310561F48B2D8068B82ED15011F480E069 +:1060A00068C0C8010E94BD3297FDF9CFCB2DCD7FCE +:1060B0002B2D207309F58033F9F4AA24AA94AD0E90 +:1060C00009F443C0C8010E94BD3297FD3EC09C0147 +:1060D0002F7D33272835310549F4C264D250A9F108 +:1060E000C8010E94BD3297FF07C02FC0B6FE02C094 +:1060F000C26001C0C261DA2D812C912C540120EDC7 +:10610000280F283080F0C4FF04C0B8010E94FB3281 +:1061100019C02A3040F0C6FFF8CF2F7D3FEE320F76 +:10612000363098F727504C2FC501B4010E94F22F4A +:106130004B015C01C260D15059F0C8010E94BD32D0 +:1061400097FFDDCFC1FD04C0AACF812C912C540153 +:10615000C7FF08C0B094A09490948094811C911CB7 +:10616000A11CB11C2C2FB501A401C7010E94E62F70 +:1061700081E0DF91CF911F910F91FF90EF90BF9041 +:10618000AF909F908F900895A0E2B0E0EAECF0E32A +:106190000C9471285C01962E7A01F9018E010F5F33 +:1061A0001F4F680180E2D8011D928A95E9F7D50159 +:1061B00013968C9080E090E0612C712C30E061E0CF +:1061C00070E083FC259183FE21918F01522E2111D5 +:1061D00003C080E090E092C02E3511F4009751F199 +:1061E000432F50E0481759073CF42D3559F12D3213 +:1061F00019F4772009F103C0772009F46AC0452D0E +:10620000469546954695D601A40FB11D452D47707C +:106210008B0102C0000F111F4A95E2F7A8015C91A3 +:10622000452B4C93651459F0561410F45394E7CF52 +:106230005A94E5CF31E004C07724739401C0712CE7 +:106240000196BFCF772019F08E8180628E83311145 +:1062500003C08824839417C0F6019E012F5D3F4F31 +:106260008081809581932E173F07D1F7F2CFE114FB +:10627000F10429F0D7018C93F70131967F019A94AC +:10628000812C9920F9F0C5010E94BD3297FD18C0FC +:10629000FC01FF2723E0F595E7952A95E1F7EC0D42 +:1062A000FD1D208130E0AC014770552702C03595B7 +:1062B00027954A95E2F720FDDACFB5010E94FB321F +:1062C000811087CFE114F10411F0D7011C92C801AD +:1062D00015C0422F469546954695D601A40FB11D8F +:1062E000422F47708B0102C0000F111F4A95E2F741 +:1062F000A8015C91452B4C93622EA2CFA096EFE0B3 +:106300000C948D28A0E0B0E0E8E8F1E30C9471284B +:106310006C01EB015A01FC0117821682512CF60127 +:10632000E380FE01E3FC8591E3FE8191182FEF01EC +:10633000882309F4EEC090E00E949332892B21F06B +:10634000C6010E941930EBCF153241F4FE01E3FC87 +:106350001591E3FE1191EF01153281F4C6010E94FF +:10636000BD3297FDD4C0412F50E09C013327241744 +:106370003507A9F2B6010E94FB32CBC01A3239F4BC +:10638000E3FC1591E3FE1191EF0101E001C000E093 +:10639000F12C20ED210F2A3080F402606F2D70E087 +:1063A00080E090E040E20E94F22FF62EFE01E3FC36 +:1063B0001591E3FE1191EF01ECCF01FF03C0F11045 +:1063C00003C0A7C0FF24FA94183619F01C3651F008 +:1063D00010C0FE01E3FC1591E3FE1191EF011836A8 +:1063E00041F408600460FE01E3FC1591E3FE1191A5 +:1063F000EF01112309F48DC0612F70E08AEE90E067 +:106400000E949C32892B09F484C000FD07C0F5016D +:1064100080809180C50102965C0102C0812C912C84 +:106420001E3651F4F6014681578160E070E0202F5E +:10643000C4010E94E62F73CF1336A9F401FD02C0F8 +:10644000FF24F394C6010E94BD3297FD60C0811401 +:10645000910429F0F4018083C40101964C01FA945F +:10646000F110F0CF50C01B3559F49E01A4016F2DDF +:10647000C6010E94C430EC01892B09F044C03EC023 +:10648000C6010E94193097FD42C01F3661F128F401 +:10649000143639F1193651F128C0133771F0153718 +:1064A00001F123C08114910429F0F4016082C40138 +:1064B00001964C01FA94FF2071F0C6010E94BD3292 +:1064C0003C0197FD08C00E949332892B59F3B60115 +:1064D000C3010E94FB3281149104A9F0F4011082DF +:1064E00012C0006203C0006101C00064202FA4013B +:1064F0006F2DC6010E943230811105C0F6018381E3 +:10650000807329F406C000FD0ACF539408CF5520AC +:1065100019F0852D90E002C08FEF9FEFCDB7DEB769 +:10652000EFE00C948D2891110C947233803219F0A5 +:1065300089508550C8F70895FC010590061621F092 +:106540000020D9F7C00108953197CF010895FC01CB +:106550000590615070400110D8F7809590958E0F8E +:106560009F1F0895FC016150704001900110D8F701 +:10657000809590958E0F9F1F0895CF93DF93EC0128 +:106580002B8120FF33C026FF0AC02F7B2B838E81F7 +:106590009F8101969F838E838A8190E029C022FF8C +:1065A0000FC0E881F9818081082E000C990B0097BB +:1065B00019F420622B831AC03196F983E8830EC048 +:1065C000EA85FB85099597FF09C02B81019611F09B +:1065D00080E201C080E1822B8B8308C02E813F8145 +:1065E0002F5F3F4F3F832E83992702C08FEF9FEF8E +:1065F000DF91CF910895FB01238120FF12C026FD7A +:1066000010C08F3F3FEF930761F082832F7D20649E +:1066100023832681378121503109378326839927A7 +:1066200008958FEF9FEF0895FA01AA27283051F1BE +:10663000203181F1E8946F936E7F6E5F7F4F8F4FB3 +:106640009F4FAF4FB1E03ED0B4E03CD0670F781F12 +:10665000891F9A1FA11D680F791F8A1F911DA11DF7 +:106660006A0F711D811D911DA11D20D009F4689430 +:106670003F912AE0269F11243019305D3193DEF6D8 +:10668000CF010895462F4770405D4193B3E00FD08E +:10669000C9F7F6CF462F4F70405D4A3318F0495D79 +:1066A00031FD4052419302D0A9F7EACFB4E0A6955C +:1066B0009795879577956795BA95C9F7009761057E +:1066C000710508959B01AC010A2E069457954795D4 +:1066D00037952795BA95C9F7620F731F841F951FC9 +:0E66E000A01D0895992788270895F894FFCFEC +:1066EE00FFFF000000010000000000005A0500003E +:1066FE0000000002000000007B0500000000030304 +:10670E000402060208020A020C020E021002120213 +:10671E00320430042E042B042904250423041E0401 +:10672E001C041804DA0249026B03E903DE03D403E6 +:10673E00257800424D4532383000000000003415F7 +:10674E003315331536150000000051153A15461550 +:10675E00EC263F00000000001916F4150B16E31589 +:10676E00000000003C193B193B19EF260000000009 +:10677E00DC1B051B881BF22600000000B51C591CF3 +:10678E00621CF52600000000F91CF81CF81CF82607 +:10679E00000000003C1D1C1D051DFB260000000016 +:1067AE006A1FD41ECC1EFE26000000008520792014 +:1067BE008020012700000000D920CD20D4200427FE +:1067CE0000000000E121B121C921072700000000CF +:1067DE005722562256225922000000003B23D8226F +:1067EE0001230A27410042004300440045004600B1 +:1067FE004700445000000000000D24DF23E6230D67 +:0E680E00270000000071247024702410270061 +:00000001FF diff --git a/software/test-software/nano-644/Makefile b/software/test-software/nano-644/Makefile index 72f0f07..75c25e3 100644 --- a/software/test-software/nano-644/Makefile +++ b/software/test-software/nano-644/Makefile @@ -1,41 +1,62 @@ -.PHONY: all info flash flash0 flash1 flash2 picocom picocom0 picocom1 picocom2 release clean $(shell mkdir -p dist >/dev/null) $(shell mkdir -p build >/dev/null) $(shell mkdir -p sim >/dev/null) $(shell mkdir -p sim/build >/dev/null) $(shell mkdir -p release/sim >/dev/null) -NAME=test-software_nano-644_12mhz -SRC= $(wildcard src/*.c src/*.cpp src/*/*.c src/*/*.cpp) -HDR= $(wildcard src/*.h src/*.hpp src/*/*.h src/*/*.hpp) +# -------------------------------------------------------------------------------- +# Variables configured by engineer + +NAME=nano-x-base_test-software_nano-m644p_12mhz +DEVICE=atmega644p +AVRDUDE_DEVICE=m644p +CPU_FREQUENCY=12000000 +BAUDRATE=115200 +START_ADDRESS=0 + +# -------------------------------------------------------------------------------- +# Automatic created Makefile variables + +SRC= $(wildcard src/*.c src/*.cpp src/*/*.c src/*/*.cpp) +HDR= $(wildcard src/*.h src/*.hpp src/*/*.h src/*/*.hpp) +MAINSRC= $(wildcard src/main.c src/main.cpp) OBJ_CPP = $(SRC:src/%.cpp=build/%.o) OBJ = $(OBJ_CPP:src/%.c=build/%.o) OBJ_SIM_CPP = $(SRC:src/%.cpp=sim/build/%.o) OBJ_SIM = $(OBJ_SIM_CPP:src/%.c=sim/build/%.o) -DEVICE=atmega644p -AVRDUDE_DEVICE=m644p - CC= avr-g++ -CFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=12000000 -c -LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=12000000 -Wl,-u,vfprintf -lprintf_flt -lm +CFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=$(CPU_FREQUENCY) -DBAUD_RATE=$(BAUDRATE) -DDOUBLE_SPEED -DNUM_LED_FLASHES=4 '-DMAX_TIME_COUNT=F_CPU>>4' -c +#LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=$(CPU_FREQUENCY) -Wl,-u,vfprintf -lprintf_flt -lm +LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=$(CPU_FREQUENCY) -Wl,--section-start=.text=$(START_ADDRESS) -CFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=12000000 -g -c -c -LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=12000000 -g -Wl,-u,vfprintf -lprintf_flt -lm +CFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=$(CPU_FREQUENCY) -g -DBAUD_RATE=$(BAUDRATE) -DDOUBLE_SPEED -DNUM_LED_FLASHES=4 '-DMAX_TIME_COUNT=F_CPU>>4' -c +#LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=$(CPU_FREQUENCY) -g -Wl,-u,vfprintf -lprintf_flt -lm +LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=$(CPU_FREQUENCY) -g -Wl,--section-start=.text=$(START_ADDRESS) -# ------------------------------------------------ +# -------------------------------------------------------------------------------- +# make targets -all: dist/$(NAME).elf dist/$(NAME).s dist/$(NAME).hex sim/$(NAME).elf sim/$(NAME).s info +.PHONY: all +all: dist/$(NAME).elf sim/$(NAME).elf dist/$(NAME).s dist/$(NAME).hex dist/$(NAME).bin sim/$(NAME).s info -isp-fuse-$(AVRDUDE_DEVICE): - avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xFF:m -U lock:w:0xFF:m +.PHONY: info info: + @echo @avr-size --mcu=$(DEVICE) --format=avr dist/$(NAME).elf +# -------------------------------------------------------------------------------- +# dependency make for hierarchical source file structure + .depend: $(SRC) $(HDR) $(CC) -mmcu=$(DEVICE) -MM $(SRC) | sed --regexp-extended 's/^(.*\.o)\: src\/(.*)(\.cpp|\.c) (.*)/build\/\2\.o\: src\/\2\3 \4/g' > .depend +ifneq (clean,$(filter clean,$(MAKECMDGOALS))) -include .depend +endif + +# -------------------------------------------------------------------------------- +# elf, hex and assembler file creation dist/$(NAME).elf: .depend $(OBJ) $(CC) $(LFLAGS) -o $@ $(OBJ) @@ -46,13 +67,28 @@ dist/%.s: dist/%.elf dist/%.hex: dist/%.elf avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ -sim/$(NAME).elf: .depend $(OBJ_SIM) - $(CC) $(LFLAGS_SIM) -o $@ $(OBJ_SIM) - -# ensure that __DATE__ and __TIME__ macros are up to date -build/main.o: src/main.cpp $(SRC) $(HDR) +dist/%.bin: dist/%.elf + avr-objcopy -O binary $(HEX_FLASH_FLAGS) $< $@ + +# -------------------------------------------------------------------------------- +# check if the macros __DATE__ or __TIME__ are used in src/main.cpp or src/main.c + +DATE_USED= +ifneq ($(shell cat $(MAINSRC) | grep __DATE__),) + DATE_USED=true +endif +TIME_USED= +ifneq ($(shell cat $(MAINSRC) | grep __TIME__),) + TIME_USED=true +endif + +ifeq (true, $(filter true, $(DATE_USED) $(TIME_USED))) +build/main.o: $(MAIN_SRC) $(SRC) $(HDR) @mkdir -p $(dir $@) $(CC) $(CFLAGS) -o $@ $< +endif + +# -------------------------------------------------------------------------------- build/%.o: src/%.c @mkdir -p $(dir $@) @@ -62,6 +98,13 @@ build/%.o: src/%.cpp @mkdir -p $(dir $@) $(CC) $(CFLAGS) -o $@ $< +# -------------------------------------------------------------------------------- +# simulation/debugging with gdb or simuc + +sim/$(NAME).elf: .depend $(OBJ_SIM) + $(CC) $(LFLAGS_SIM) -o $@ $(OBJ_SIM) + @ln -sf $(NAME).elf sim/$(DEVICE).elf + sim/build/%.o: src/%.c @mkdir -p $(dir $@) $(CC) $(CFLAGS_SIM) -o $@ $< @@ -73,52 +116,144 @@ sim/build/%.o: src/%.cpp sim/%.s: sim/%.elf avr-objdump -d $< > $@ +ifeq (m16, $(AVRDUDE_DEVICE)) +simuc: sim/$(NAME).elf + simuc --board sure $< +endif + +ifeq (m328p, $(AVRDUDE_DEVICE)) +simuc: sim/$(NAME).elf + simuc --board arduino $< +endif + +ifeq (m644p, $(AVRDUDE_DEVICE)) +simuc: sim/$(NAME).elf + simuc --board nano-644 $< +endif + +ifeq (m1284p, $(AVRDUDE_DEVICE)) simuc: sim/$(NAME).elf simuc --board nano-1284 $< +endif gdb: sim/$(NAME).elf avr-gdb $< +# ------------------------------------------------------------- +# flash to target with arduino bootloader in bootloader-section +.PHONY: flash flash: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB0 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + avrdude -c arduino -P /dev/ttyUSB0 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -e -U flash:w:$< +.PHONY: flash0 flash0: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB0 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + avrdude -c arduino -P /dev/ttyUSB0 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -e -U flash:w:$< +.PHONY: flash1 flash1: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB1 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + avrdude -c arduino -P /dev/ttyUSB1 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -e -U flash:w:$< +.PHONY: flash2 flash2: dist/$(NAME).elf all - avrdude -c arduino -P /dev/ttyUSB2 -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + avrdude -c arduino -P /dev/ttyUSB2 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -e -U flash:w:$< +.PHONY: flash-read +flash-read: + avrdude -c arduino -P /dev/ttyUSB0 -b $(BAUDRATE) -p $(AVRDUDE_DEVICE) -U flash:r:/tmp/flash.bin -picocom: - # picocom sends CR for ENTER -> convert cr (\r) to lf (\n) - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0 +.PHONY: flash-disassemble +flash-disassemble: flash-read + avr-objdump -b binary -D -m avr5 /tmp/flash.bin > /tmp/flash.s + less /tmp/flash.s -picocom0: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0 - -picocom1: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB1 - -picocom2: - picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB2 +.PHONY: flash-hexdump +flash-hexdump: flash-read + hexdump -C /tmp/flash.bin | less +# ---------------------------------------------- +# flash to target with fischl programming device -isp-1284p: +.PHONY: isp-flash-$(AVRDUDE_DEVICE) +isp-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lock:r:-:h avrdude -c usbasp -p $(AVRDUDE_DEVICE) -isp-flash-1284p: dist/$(NAME).elf all +.PHONY: isp-flash +isp-flash: dist/$(NAME).elf all avrdude -c usbasp -p $(AVRDUDE_DEVICE) -e -U flash:w:$< -flash-1284p: dist/$(NAME).elf all - avrdude -c arduino -p $(AVRDUDE_DEVICE) -P /dev/ttyUSB0 -b 115200 -e -U flash:w:$< +.PHONY: isp-flash-$(AVRDUDE_DEVICE) +isp-flash-$(AVRDUDE_DEVICE): dist/$(NAME).elf all + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -e -U flash:w:$< + +.PHONY: isp-read-flash-$(AVRDUDE_DEVICE) +isp-read-flash-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p m32$(AVRDUDE_DEVICE)8p -U flash:r:/tmp/flash-arduino-atmega328p__$(shell date +"%Y-%m-%d_%H%M%S") + +.PHONY: isp-fuse +isp-fuse: isp-fuse-$(AVRDUDE_DEVICE) + +.PHONY: isp-fuse-$(AVRDUDE_DEVICE) +ifeq (m16, $(AVRDUDE_DEVICE)) +isp-fuse-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0x18:m -U hfuse:w:0xD8:m -U lock:w:0xEF:m +endif +ifeq (m328p, $(AVRDUDE_DEVICE)) +isp-fuse-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xEF:m -U hfuse:w:0xD8:m -U efuse:w:0xFD:m -U lock:w:0xEF:m +endif +ifeq (m644p, $(AVRDUDE_DEVICE)) +isp-fuse-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xEF:m -U hfuse:w:0xD8:m -U efuse:w:0xFD:m -U lock:w:0xEF:m +endif +ifeq (m1284p, $(AVRDUDE_DEVICE)) +isp-fuse-$(AVRDUDE_DEVICE): + avrdude -c usbasp -p $(AVRDUDE_DEVICE) -U lfuse:w:0xEF:m -U hfuse:w:0xD8:m -U efuse:w:0xFD:m -U lock:w:0xEF:m +endif + +# -------------------------------------------------------- +# picocom sends CR for ENTER -> convert cr (\r) to lf (\n) -release: dist/$(NAME).elf sim/$(NAME).elf +.PHONY: picocom +picocom: + picocom -b $(BAUDRATE) --omap crlf --raise-dtr /dev/ttyUSB0 + +.PHONY: picocom0 +picocom0: + picocom -b $(BAUDRATE) --omap crlf --raise-dtr /dev/ttyUSB0 + +.PHONY: picocom1 +picocom1: + picocom -b $(BAUDRATE) --omap crlf --raise-dtr /dev/ttyUSB1 + +.PHONY: picocom2 +picocom2: + picocom -b $(BAUDRATE) --omap crlf --raise-dtr /dev/ttyUSB2 + +# -------------------------------------------------------- + +.PHONY: help +help: + @echo + @echo "Possible targets are:" + @echo " clean" + @echo " all help info" + @echo " flash flash0 flash1 flash2 flash-read flash-disassemble flash-hexdump" + @echo " isp-$(AVRDUDE_DEVICE) isp-flash-$(AVRDUDE_DEVICE) isp-fuse-$(AVRDUDE_DEVICE)" + @echo " picocom picocom0 picocom1 picocom2" + @echo " gdb simuc" + @echo + +# -------------------------------------------------------- + +.PHONY: release +release: dist/$(NAME).elf sim/$(NAME).elf dist/$(NAME).hex dist/$(NAME).bin ../create-release release $(word 1, $^) release/sim $(word 2, $^) +# -------------------------------------------------------- + +.PHONY: clean clean: @rm -r dist @rm -r build diff --git a/software/test-software/nano-644/release/v2024-10-28_141636/test-software_nano-644_12mhz.elf b/software/test-software/nano-644/release/v2024-10-28_141636/test-software_nano-644_12mhz.elf deleted file mode 100755 index 0aa1e2f700270b068b3e43a75835550d655952e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74504 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 literal 0 HcmV?d00001 diff --git a/software/test-software/nano-644/release/v2024-10-31_172630/nano-x-base_test-software_nano-m644p_12mhz.elf b/software/test-software/nano-644/release/v2024-10-31_172630/nano-x-base_test-software_nano-m644p_12mhz.elf new file mode 100755 index 0000000000000000000000000000000000000000..2d5103b10b7008d8706727b743fd9e34a726becf GIT binary patch literal 73144 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

Zo<7bj|LoOB$sAtDRB+BZZz>)04Lf_cYrvN8nf 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 UUL-BO&foGk6Bi@Yhe_}M0Js~KJOBUy literal 0 HcmV?d00001 diff --git a/software/test-software/nano-644/release/v2024-10-31_172630/nano-x-base_test-software_nano-m644p_12mhz.hex b/software/test-software/nano-644/release/v2024-10-31_172630/nano-x-base_test-software_nano-m644p_12mhz.hex new file mode 100644 index 0000000..f3ab251 --- /dev/null +++ b/software/test-software/nano-644/release/v2024-10-31_172630/nano-x-base_test-software_nano-m644p_12mhz.hex @@ -0,0 +1,2294 @@ +:100000000C942B070C9453070C9453070C94530730 +:100010000C9453070C9453070C9453070C945307F8 +:100020000C9453070C94410B0C9453070C945307F6 +:100030000C9453070C9453070C9453070C945307D8 +:100040000C9453070C9453070C9453070C945307C8 +:100050000C94910A0C9453070C9453070C94530777 +:100060000C9453070C9453070C94050B0C945307F2 +:100070000C94C40A0C9453070C945307076342363C +:10008000B79BD8A71A39685618AEBAAB558C1D3C29 +:10009000B7CC5763BD6DEDFD753EF6177231BF00ED +:1000A0000000803F08000000BE922449123EABAA27 +:1000B000AA2ABECDCCCC4C3E00000080BEABAAAA82 +:1000C000AA3E00000000BF000000803F00000000CA +:1000D00000084178D3BB4387D1133D190E3CC3BD03 +:1000E0004282AD2B3E68EC8276BED98FE1A93E4CB0 +:1000F00080EFFFBE01C4FF7F3F000000000063648B +:10010000696E6F70737578585B000A2534643A2005 +:10011000005D3A20000A0A5B000A53656C6563744F +:1001200020756E69743A2000253378202E2E2E20FB +:10013000004552524F523A20496E76616C696420F4 +:1001400048617264776172652028256429004176D0 +:1001500061696C61626C6520756E6974733A0A0A34 +:100160000048617264776172653A20255300202F40 +:100170002000202F20000A0A4861726477617265AE +:1001800020255320646574656374656420284144A8 +:100190004337483D30782530325829000A496E7679 +:1001A000616C69642048617264776172652D56657F +:1001B0007273696F6E3A204144433748203D2025D1 +:1001C00064202841546D656761363434502C2033E7 +:1001D0002E3356290A00563F3F00563261005631F1 +:1001E0006100446F6E65004552524F52000A000A8A +:1001F0003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D2F +:100200003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D1E +:100210003D3D3D3D3D0A200041546D6567613634EA +:1002200034500031373A32363A3330004F6374205D +:1002300033312032303234000A505441424C452090 +:1002400025643A203078253032780020213D203056 +:100250007825303278000A00205B5741524E3A2010 +:1002600062756666657220746F20736D616C6C5D7B +:100270002000204F4B5B72656365697665202564BD +:100280002062797465735D2000204552524F525BA5 +:10029000726563656976652025642062797465738B +:1002A0002C206578706563742025642062797465FC +:1002B000735D20005D20002030782530325800200A +:1002C0005374617465735B004552525D005D00209C +:1002D000307825303278000A205B7265616452659F +:1002E00067697374657273283078253032782C20F2 +:1002F0002E2E2E2C202564295D202D3E20004552D7 +:10030000525D003078253032782C737461747573C7 +:100310003D3078253032785D000A205B726561647B +:100320005265676973746572283078253032782990 +:10033000202D3E20004552525D0073746174757328 +:100340003D3078253032785D00202D3E2000203071 +:100350007825303278000A205B77726974655265BF +:100360006769737465727328307825303278293A5A +:1003700020004552525D007374617475733D30788E +:10038000253032785D000A205B77726974655265AA +:10039000676973746572283078253032782C203084 +:1003A000782530327829202D3E20004F4B006661A1 +:1003B000696C73004F4B2C20696E69742050415456 +:1003C00041424C45202E2E2E20006661696C730040 +:1003D0004F4B2C20696E6974207265676973746570 +:1003E00072202E2E2E20006661696C7300207265CB +:1003F00073657420434331313031202E2E2E20007E +:1004000043432D313130312D3F0043432D313130C5 +:10041000312D546573740043432D313130312D52E9 +:100420006563656976650043432D313130312D5365 +:10043000656E6400646F6E65202873746174653D39 +:100440003078253032782900202E2E2E20002025CD +:1004500030325800256420646174612062797465CB +:10046000732028484558293A20004552524F522CB3 +:1004700020004F4B2C200020525353493D25642C23 +:10048000204C51493D25642C204352432000202D0F +:100490003E200045320063616E63656C6C656400EC +:1004A0004532004F4B2C2072656365697665202EBE +:1004B0002E2E20003F202849444C45290063616EC0 +:1004C00063656C6C6564004531000A205B2530343F +:1004D000785D203D3E207374617274202E2E2E2094 +:1004E000004F4B004531005D202D3E20002025307F +:1004F000325800202D2D3E2073656E642025642027 +:10050000627974657320284845583A20253032585E +:1005100000307825303278004531000A205B2530E4 +:1005200034785D3A2073746174653D006661696C6E +:1005300073002850415441424C45203D20307825DD +:10054000303258290064426D20000A2073776974A4 +:10055000636820706F77657220746F200020757358 +:1005600065202B20616E64202D20666F7220706FD5 +:10057000776572206368616E676520286F746865AF +:1005800072206B6579202D3E206261636B20746F51 +:100590002064656661756C742900292E06477A0E01 +:1005A00014040400000600216276CAF81622F840FE +:1005B000073018166C434991876BFB5610E92A00E7 +:1005C0001F4100597F3F813509C6392E3600C031A1 +:1005D000310000C531300000CD3700000086350005 +:1005E00000005030000000372D360000262D31303D +:1005F000001D2D313500172D323000032D33300012 +:1006000025356420283078253032782920000D20C7 +:10061000203D3E20456E636F6465722028707573BF +:100620006820746F20636C656172293A2000456E02 +:10063000636F64657200656E64000A20493243206E +:10064000534C4156453A2066726F6D206D6173744C +:1006500065723A20307825303278202D3E20746F34 +:10066000206D61737465723A2030782530327800DD +:10067000453100202D3E204552524F520030782502 +:10068000303278002C202066726F6D20736C61769A +:10069000653A2000202D3E204552524F52000A203C +:1006A0004932432D4D41535445523A20746F2073C3 +:1006B0006C6176653A20307825303278004531001B +:1006C000453300290062616400706F6F72006661DB +:1006D000697200676F6F6400657863656C6C656E46 +:1006E00074003F002C2065636F323D25642800298B +:1006F0002C2074766F633D2564707062003F007536 +:100700006E6865616C74687900706F6F72006D6FF0 +:1007100064657261746500676F6F64006578636516 +:100720006C6C656E7400206171693D25642800451C +:100730003200252E3166C2B0432F252E3166252585 +:10074000293A20004531290020207C20454E533194 +:1007500036302028002C20483D20252E32662525C5 +:10076000002C20543D20252E3266C2B043000A20C2 +:100770003D3E20424D3238303A20503D20252E3328 +:1007800066626172004F4B004534004533004532CC +:10079000004F4B2C20454E53313630202E2E2E202C +:1007A0000045310020424D323830202E2E2E2000C0 +:1007B0004932432D536C617665004932432D4D61BA +:1007C00073746572004932432D537061726B6675A4 +:1007D0006E20456E762D436F6D626F00656E64000E +:1007E0000A20203D3E207265636569766520427966 +:1007F00074653A20307825303278000A20203D3E5A +:100800002073656E6420427974652030782530321B +:1008100078004945454534383500656E64004552D9 +:10082000524F5228256429004F4B004C434420006E +:100830004552524F5220256429004F4B2900696EC2 +:100840006974204C43442028004C63640054657351 +:1008500074204C454420442564004C656400656E5A +:100860006400202D3E2025342E3866560A002030A4 +:100870007825303278002020003F000A20202020F8 +:10088000202020527844313A0020307825303278C8 +:10089000000A203D3E2053656E64696E673A004D44 +:1008A0006F646275733A206C657365205370616E76 +:1008B0006E756E6720766F6E2045617374726F6E11 +:1008C0002053444D2D323330202845696E706861C5 +:1008D00073656E7AC3A4686C65722900202E2E2E73 +:1008E000207072657373206B657920746F2070724D +:1008F0006F63656564006E6F206279746520726550 +:1009000063656976656400307825303278207265D9 +:10091000636569766564002044453D25752C206E2D +:1009200052453D25752073656E6420307825303240 +:10093000782E2E2E2000696E6974004D6F646275EA +:10094000730020206E6F20726F746174696F6E2067 +:1009500028543D253034782920200020206E3D2069 +:1009600025356420552F6D696E2028543D2530347F +:100970007829002053454E534F523D2564200020D6 +:100980006E4641554C543D25640020414443323D60 +:1009900025336400202050574D2F4F4330413D25D3 +:1009A0003364000D20203D3E20414443303D25333B +:1009B0006400454E3D3100454E3D30000D205357FB +:1009C000333D25642D3E000A004D6F746F72000A9E +:1009D000202042616E6B30202D204750422564203C +:1009E0003D2030000A202042616E6B30202D2047D0 +:1009F00050422564203D2031000A202042616E6B68 +:100A000030202D204750412564203D2030000A2011 +:100A10002042616E6B30202D204750412564203DDF +:100A20002031000A203D3E207374617274202E2E06 +:100A30002E002900204F4B00204A5033392E322FF0 +:100A400033206A756D706572656420286C65667404 +:100A5000293F00204552524F5200202872656164A0 +:100A600020307825303278202D3E203078253032E5 +:100A70007800506F727445787000253464202830F7 +:100A8000782530337829000D20203D3E204D6561CA +:100A90007375726520414443303A20000A00506F5C +:100AA0007469002025332E3166203D3E205357398E +:100AB0003A36203D202564202564252064202564C5 +:100AC0002020002534642028307825303378290010 +:100AD0000D20203D3E204D656173757265204144B7 +:100AE00043323A20000A0052325200416C6C0042FC +:100AF0006C756500477265656E00526564005267EB +:100B000062002025303278000A20257020257020D0 +:100B10002570202570202570202570202570202D1F +:100B20003E2077726974653A2000706F7765722095 +:100B30006F6666206661696C732C204920616D20A8 +:100B40007374696C6C20616C697665203A2D29207C +:100B50002E2E2E2070726F63656564000A20706F00 +:100B6000776572206F6666206E6F77202E2E2E00BE +:100B70000D2070726573732045534320746F20619C +:100B8000626F72742C20706F776572206F666620BA +:100B9000696E2025647320287072657373206B65FD +:100BA0007920746F20736B69702074696D65722988 +:100BB00020000A000A20706F776572206F6E202E69 +:100BC0002E2E006661696C73004F4B000A20546939 +:100BD0006D6572206F6666202E2E2E20000A20542E +:100BE000696D65722073657420746F2025647320AD +:100BF00028313A2530325829202E2E2E20000A2066 +:100C00007365743A20253034642D253032642D25E7 +:100C100030326420253032643A253032643A25304F +:100C2000326400202D2054696D65723D3078253086 +:100C30003278002C20256420253034642D25303274 +:100C4000642D2530326420253032643A25303264F8 +:100C50003A253032640020202D2D3E20003F3F00F9 +:100C600020253032580020000A203D3E2072656168 +:100C70006420726567697374657220302D31352088 +:100C800028686578293A000A202020732F53202EE7 +:100C90002E207365636F6E6420282B2F2D290A0088 +:100CA0000A2020206E2F4E202E2E206D696E757426 +:100CB0006520282B2F2D29000A202020682F48206E +:100CC0002E2E20686F757220282B2F2D29000A20C8 +:100CD0002020642F44202E2E2064617920282B2F81 +:100CE0002D29000A2020206D2F4D202E2E206D6FE3 +:100CF0006E746820282B2F2D29000A202020792FA0 +:100D000059202E2E207965617220282B2F2D290045 +:100D10000A202020772F57202E2E207765656B64C0 +:100D2000617920282B2F2D290A000A2020206320FA +:100D30002E2E2E2E20696E697420636C6F636B00FB +:100D40000A20202070202E2E2E2E20706F776572A4 +:100D5000206F6E2F6F666620285043372D3E51312D +:100D600029000A20202074202E2E2E2E2074696D3A +:100D70006572206F6E2F6F6666000A207072657351 +:100D8000733A000A203D3E20636F6E666967203823 +:100D9000353633202E2E2E20005254432D38353632 +:100DA0003300536F004D6F004469004D6900446F7C +:100DB0000046720053610000436861722025642080 +:100DC0002D202573202D3E2025303278004C312FE8 +:100DD0004C32204F4E004C312F4C32204F4E004FA2 +:100DE0004646004F4E00536567370052656C65619B +:100DF0007365205357256420005072657373205328 +:100E0000572564005377697463680048656C6C6F9C +:100E10002055415254312C204543484F2D4D6F648D +:100E20007573206163746976650A000A203D3E206F +:100E300073656E642074657874207669612055410D +:100E4000525431206E6F772E2E2E00556172743100 +:100E500000005739163A11241FBECFEFD0E1DEBF94 +:100E6000CDBF12E0A0E0B1E0E8EEFDE802C00590E1 +:100E70000D92A635B107D9F724E0A6E5B2E001C08E +:100E80001D92A63EB207E1F717E0CBE2D7E004C01F +:100E90002197FE010E94733CC932D107C9F70E9415 +:100EA000D2370C94F2460C940000FC01108211829F +:100EB0000895FC019181992311F091509183089537 +:100EC000FC01608384E68093B80084E08093BC00DA +:100ED00081E0089584E08093BC001092B8000895EA +:100EE0004150FB0194E824EC4F3FD1F0442319F02A +:100EF0002093BC0002C09093BC008091BC0087FF8F +:100F0000FCCF8091B900887F442319F0803519F017 +:100F100009C0883539F48091BB0081934150E4CFFA +:100F200081E0089580E00895DC01FB0184E835E06C +:100F3000442389F0222311F0949101C09081909371 +:100F4000BB008093BC0011963C9311979091BC001C +:100F500097FFFCCF02C081E008959091B900415005 +:100F60003196987F983221F380E00895FC0184EA5D +:100F70008093BC0085E081838091BC0087FFFCCF1B +:100F80009091B900987F983011F09031B1F4908130 +:100F9000990F962B9093BB0084E88093BC0085E06A +:100FA00081838091BC0087FFFCCF9091B900987F2E +:100FB000611105C081E0983129F080E0089581E059 +:100FC0009034D9F708950F931F93CF93DF93D62FC3 +:100FD0008A01C22F60E00E94B607811102C080E042 +:100FE00016C0F80124E8D093BB002093BC00909178 +:100FF000BC0097FFFCCF9091B900987F983279F7A9 +:10100000D1919FEF9C0FCC2311F0C92FECCFDF9132 +:10101000CF911F910F91089584E98093BC00809136 +:10102000BC0084FDFCCF81E00895FF920F931F93D5 +:10103000CF93DF93EC018B01F42E61E00E94B607A1 +:10104000882379F04F2DB801CE010E9470078823C4 +:1010500041F0CE01DF91CF911F910F91FF900C9441 +:101060000C0880E0DF91CF911F910F91FF900895C0 +:10107000FF920F931F93CF93DF93EC018B01F42E1C +:1010800060E00E94B607882381F020E04F2DB80170 +:10109000CE010E949407882341F0CE01DF91CF91C9 +:1010A0001F910F91FF900C940C0880E0DF91CF917D +:1010B0001F910F91FF900895FF920F931F93CF936D +:1010C000DF93EC018B01F42E60E00E94B6078823C9 +:1010D00081F021E04F2DB801CE010E9494078823B2 +:1010E00041F0CE01DF91CF911F910F91FF900C94B1 +:1010F0000C0880E0DF91CF911F910F91FF90089530 +:10110000CF92DF92EF92FF920F931F93CF93DF93D3 +:10111000EC016B01142F790160E00E94B60788236F +:1011200001F120E0412FB601CE010E9494078823EF +:10113000C1F061E0CE010E94B607882391F0402FF4 +:10114000B701CE010E947007882359F0CE01DF91CC +:10115000CF911F910F91FF90EF90DF90CF900C9463 +:101160000C0880E0DF91CF911F910F91FF90EF90DD +:10117000DF90CF900895FC011082118212821386B5 +:1011800014860895FC019081992311F09150908369 +:10119000089567FD0CC0660F642B6093BA0084E667 +:1011A0008093B80085E48093BC0081E0089580E0DE +:1011B000089584E08093BC001092B8000895FB016C +:1011C0002FB7F894918181E0890F8183DB01A90F0A +:1011D000B11D12964C93883008F011828181908164 +:1011E000891305C08F5F8083883008F010822FBF7D +:1011F0000895462FBC01655F7F4F0C94DF08FB010B +:101200009FB7F89480812181821304C09FBF8FEF24 +:101210009FEF089521E0280F2083DB01A80FB11D67 +:1012200012968C91283018F49FBF90E00895108298 +:10123000FBCFBC016F5F7F4F0C94FF082091B9007A +:10124000287F203819F0283A49F013C04091BB009C +:10125000BC016F5F7F4F0E94DF0809C0BC01655F62 +:101260007F4F0E94FF0897FD80E08093BB0085E8D8 +:1012700001C085EC8093BC000895CF93DF939091DB +:101280005D0480915C049817D1F3E0915D0481E0E6 +:101290008E0F80935D04F0E0E25AFB4FC081CD30A9 +:1012A00009F4CAE0D0E06091E2047091E304CE0159 +:1012B0000E940741CE01DF91CF9108950F931F93B4 +:1012C000CF93C82F8B018A3019F48DE00E945E09FC +:1012D0008091E2049091E3040817190731F480919A +:1012E000C00085FFFCCFC093C60080E090E0CF91A6 +:1012F0001F910F910895089580E090E0089508955A +:10130000089508950895089508952FB7F894409189 +:101310008E0450918F04452B59F4429A80383FEF48 +:10132000930710F480589F4F90938F0480938E04FE +:101330002FBF08952FB7F8944091900450919104D5 +:10134000452B59F4449A80383FEF930710F48058A6 +:101350009F4F90939104809390042FBF0895813004 +:1013600041F0823019F48AED91E0089586ED91E024 +:1013700008958EED91E00895CF9387E680937C00E9 +:1013800087E880937A0080917A00806480937A0065 +:1013900080917A0086FDFCCF1092860480917900BE +:1013A000843F10F081E005C080917900803E18F004 +:1013B00082E080938604809186049FEF980F92309C +:1013C00078F0809179001F928F938CE991E09F9340 +:1013D0008F930E9443410F900F900F900F9014C075 +:1013E000C09179000E94AF091F92CF939F938F9372 +:1013F00086E791E09F938F930E9443410F900F9057 +:101400000F900F900F900F9010927C0010927A0026 +:1014100080918604CF910895F89460938A04709324 +:101420008B0480938C0490938D04789408950E948B +:101430000C0AF89480918A0490918B04A0918C04FA +:10144000B0918D047894892B8A2B8B2B31F080916D +:10145000000190910101019661F38091000190914A +:1014600001010895CF93DF93CFEFDFEFD093010118 +:10147000C09300010E94170AD0930101C09300019C +:10148000DF91CF910895CF93DF93CDB7DEB7289743 +:101490000FB6F894DEBF0FBECDBF70917E04609191 +:1014A0007F04509180044091810430918204209106 +:1014B0008304909184048091850479836A835B839B +:1014C0004C833D832E839F8388878FB7F894E09168 +:1014D0007E0470917F04609180045091810440915A +:1014E0008204309183042091840490918504E983DF +:1014F0007A836B835C834D833E832F8398878FBF72 +:1015000029813A814B815C816D817E818F819885B3 +:1015100028960FB6F894DEBF0FBECDBFDF91CF91F6 +:1015200008951F920F920FB60F9211242F933F939D +:101530008F939F93EF93FF938091C600282F30E005 +:101540003093010120930001E0915C0491E09E0F33 +:1015500090935C04F0E0E25AFB4F808390915C042E +:1015600080915D04981305C080915D048F5F809326 +:101570005D04FF91EF919F918F913F912F910F907B +:101580000FBE0F901F9018951F920F920FB60F92DB +:1015900011242F933F934F935F936F937F938F9378 +:1015A0009F93AF93BF93CF93EF93FF93C091CE00E0 +:1015B00080912B04882329F06C2F89E294E00E940B +:1015C000712B80913F04882329F06C2F8DE394E0E8 +:1015D0000E94A43780912604882329F06C2F84E28E +:1015E00094E00E949926FF91EF91CF91BF91AF9126 +:1015F0009F918F917F916F915F914F913F912F912B +:101600000F900FBE0F901F9018951F920F920FB65C +:101610000F9211242F933F934F935F936F937F9378 +:101620008F939F93AF93BF93EF93FF938091920318 +:10163000882319F082E093E00DC080910103882394 +:1016400019F081E792E006C080912304882329F0F5 +:1016500083E993E00E94E22503C080E88093BC0008 +:10166000FF91EF91BF91AF919F918F917F916F917A +:101670005F914F913F912F910F900FBE0F901F9050 +:1016800018951F920F920FB60F9211242F933F932C +:101690004F935F936F937F938F939F93AF93BF937A +:1016A000EF93FF9380914F04882321F08DE494E021 +:1016B0000E945A2280914804882321F086E494E015 +:1016C0000E94C82C809189048F5F8A3018F480931F +:1016D000890490C01092890480918A0490918B04AF +:1016E000A0918C04B0918D04892B8A2B8B2B99F0BF +:1016F00080918A0490918B04A0918C04B0918D0408 +:101700000197A109B10980938A0490938B04A09357 +:101710008C04B0938D0420917E0430917F0440911D +:1017200080045091810460918204709183048091BF +:10173000840490918504A1E00E94303C20937E04B3 +:1017400030937F044093800450938104609382041B +:101750007093830480938404909385048BE793E0D3 +:101760000E9459078DE793E00E94C2088AEE92E03A +:101770000E9459078CEE92E00E94C2088CE094E02F +:101780000E9459078EE094E00E94C208809168028E +:10179000882319F081508093680280915E0288232B +:1017A00019F0815080935E0280918E0490918F0495 +:1017B000892B69F080918E0490918F04019790930A +:1017C0008F0480938E048038910508F442988091AC +:1017D000900490919104892B69F0809190049091EC +:1017E000910401979093910480939004803891051F +:1017F00008F444988091870490918804019690930E +:101800008804809387048838934140F098B188E039 +:10181000892788B91092880410928704FF91EF916C +:10182000BF91AF919F918F917F916F915F914F91F8 +:101830003F912F910F900FBE0F901F901895CF934F +:10184000DF93EC01198218828091D30481110EC0BC +:1018500083ED94E00E947C09892B41F081ED94E0B6 +:101860000E94550783ED94E00E947F09198A1A8A25 +:101870001B8A1C8A86E994E09B838A8384E994E02E +:101880009D838C8382E994E09F838E8381ED94E035 +:1018900099838883DF91CF910895CF93DF9300D010 +:1018A000CDB7DEB74A83FC0180819181009739F082 +:1018B000698342E0BE016F5F7F4F0E9438080F903E +:1018C0000F90DF91CF910895CF92EF920F93CF9326 +:1018D000DF93EC016295660F660F607C477027709E +:1018E000822F880F880F880F262F242B282B2FABB1 +:1018F0000295000F007E88AD8F71082B08AF8E2DEA +:101900008770880F880F880F9EA9292F207C9C2D17 +:101910009770E22EE82AE92AE894E7F8EEAA40E078 +:1019200064EFCE010E944D0C48AD4295469547703C +:1019300062EFCE010E944D0C9EA9492F477060E2D4 +:10194000469F90011124892F8695869586958770EC +:1019500064E0869FA0011124422B532B97FB99270B +:1019600090F9492B65EFCE010E944D0C9FA9492F9C +:10197000477080E2489F90011124892F86958695B3 +:101980008695877064E0869FA0011124422B532B1B +:101990009295969596959370492B64EFCE01DF91C1 +:1019A000CF910F91EF90CF900C944D0C0F93CF935C +:1019B000DF931F92CDB7DEB7FC0180819181009744 +:1019C00049F0698301E09E012F5F3F4F41E0B9017B +:1019D0000E94800889810F90DF91CF910F91089527 +:1019E0000F93CF93DF9300D0CDB7DEB7FC0180819A +:1019F0009181009749F0698302E09E012F5F3F4F7C +:101A000041E0B9010E94800889819A81982789273D +:101A100098270F900F90DF91CF910F9108950E941A +:101A2000F00C98278927982708950C94F00C0C94B3 +:101A30000F0D0F93CF93DF9300D01F92CDB7DEB77A +:101A4000FC0180819181009749F0698303E09E0148 +:101A50002F5F3F4F41E0B9010E94800829816A81D0 +:101A6000862F90E0A0E0B0E0BA2FA92F982F88270A +:101A7000A22B2B81BC01CD01622B0F900F900F90F8 +:101A8000DF91CF910F9108956F927F928F929F92E5 +:101A9000AF92BF92CF92DF92EF92FF920F931F937C +:101AA000CF93DF93EC019FA9892F807C803409F0CC +:101AB00043C0492F477060E2469F90011124892F4F +:101AC0008695869586958770E4E08E9FA001112407 +:101AD000422B532B9295969596959370492B64EFD4 +:101AE000CE010E944D0C0E94430A922E832E742E2A +:101AF000652E63EFCE010E94D60C83FF1FC00E94AB +:101B0000430AA92CB82CC72CD62CE12CF12C00E0D0 +:101B100010E00E943C3C203D3740410551056105E5 +:101B200071058105910509F038F487EB9BE0019779 +:101B3000F1F700C00000DDCF80E001C081E0DF915F +:101B4000CF911F910F91FF90EF90DF90CF90BF90BA +:101B5000AF909F908F907F906F9008951F93CF9339 +:101B6000DF93EC0168E80E940F0D9E8B8D8B6AE875 +:101B7000CE010E940F0D988F8F8B6CE8CE010E94D2 +:101B80000F0D9A8F898F6EE8CE010E940F0D9C8FEA +:101B90008B8F60E9CE010E940F0D9E8F8D8F62E9C1 +:101BA000CE010E940F0D98A38F8F64E9CE010E9491 +:101BB0000F0D9AA389A366E9CE010E940F0D9CA385 +:101BC0008BA368E9CE010E940F0D9EA38DA36AE945 +:101BD000CE010E940F0D98A78FA36CE9CE010E9441 +:101BE0000F0D9AA789A76EE9CE010E940F0D9CA741 +:101BF0008BA761EACE010E94D60C8DA761EECE01C3 +:101C00000E940F0D9FA78EA763EECE010E94D60CF7 +:101C100088AB64EECE010E94D60C182F65EECE0183 +:101C20000E94D60C90E11902900111248F70282B8C +:101C30003AAB29AB66EECE010E94D60C182F65EEAA +:101C4000CE010E94D60C90E119029001112490E07F +:101C500044E0959587954A95E1F7822B932B9CABB1 +:101C60008BAB67EECE010E94D60C8DABDF91CF918E +:101C70001F91089563EF0E94D60C81700895CF9252 +:101C8000DF92EF92FF920F931F93CF93DF93EC01BC +:101C900060ED0E94D60C90E0A0E0B0E089879A87C2 +:101CA000AB87BC8780369105A105B10569F546EB88 +:101CB00060EECE010E944D0C8FE295E70197F1F79F +:101CC00000C00000CE010E943A0E8111F5CFCE0176 +:101CD0000E94AE0DC12CD12CE12CF12C05E010E0BE +:101CE00025E030E045E050E063E070E0CE010E9486 +:101CF000640C9FE729EA83E0915020408040E1F79F +:101D000000C0000081E001C080E0DF91CF911F9111 +:101D10000F91FF90EF90DF90CF900895CF93DF93D6 +:101D2000EC01888199810E946007882329F0CE0107 +:101D3000DF91CF910C943F0E80E0DF91CF91089519 +:101D40004F925F926F927F928F929F92AF92BF92CB +:101D5000CF92DF92EF92FF92CF93DF93EC016AEF85 +:101D60000E94190D6115710520E88207910509F49B +:101D700085C06B017C0184E0F594E794D794C79407 +:101D80008A95D1F74D885E88C701B60128E030E01A +:101D900040E050E00E948E3A612C712CD301C201C8 +:101DA000880F991FAA1FBB1F281B390B4A0B5B0BFF +:101DB000AF89B88D0E94B83A4B015C01C701B601EA +:101DC00020E130E040E050E00E948E3ACA01B901C3 +:101DD00064197509860997099B01AC010E94503A64 +:101DE0009B01AC017CE055954795379527957A95F1 +:101DF000D1F7A98DBA8D0E94B83A2B013C01C501DB +:101E0000B40120E038E040E050E00E948E3A6901E1 +:101E10007A01C301B20120E030E440E050E00E94CA +:101E20008E3ABA01A9014C0D5D1D6E1D7F1D898979 +:101E30009A89AB89BC899A01AB01280F391F4A1FC7 +:101E40005B1F2D873E874F87588BA5E0B0E00E942F +:101E5000AD3A60587F4F8F4F9F4F20E031E040E018 +:101E600050E00E948E3ACA01B9010E94A53D20E0CF +:101E700030E048EC52E40E94F53C04C060E070E0C1 +:101E800080EC9FE7DF91CF91FF90EF90DF90CF90B4 +:101E9000BF90AF909F908F907F906F905F904F908A +:101EA00008952F923F924F925F926F927F928F92FE +:101EB0009F92AF92BF92CF92DF92EF92FF920F93D9 +:101EC0001F93CF93DF93CDB7DEB76D970FB6F8941E +:101ED000DEBF0FBECDBF1C010E94A00E67EFC10187 +:101EE0000E94190D6F87788B898B9A8B611571050C +:101EF0008048910509F49AC2F10185859685A785E8 +:101F0000B0896C017D01FF0CCC08DC2C76019C01B2 +:101F1000AD016C2D7C2D8C2D9C2D345F41405109E1 +:101F2000610971098109910929873A874B875C8783 +:101F30003B014C0159016A017B018C010E94C03AAE +:101F4000422E3D874E875B8B6C8B7D8B8E8B9B8F60 +:101F5000D1015E963C915E975D962C91932F990FDF +:101F6000990B492F592F692F792F892F0E94C03A39 +:101F70000CE00E94F03B2C8F3D8F49835F8B688F74 +:101F8000798F582E9A8FF10130A1278D932F990FB9 +:101F9000990BA42CBD84CE84DB88EC88FD880E8947 +:101FA0001B8D492F592F692F792F892F0E94C03AF5 +:101FB000F22E032F142FB52FF62FE72FD82EE92E50 +:101FC000A0E00E94453C84F421503F4F4F4F5F4FAB +:101FD0006F4F7F4F8F4F9F4FF22E032F142FB52F30 +:101FE000F62FE72FD82EE92E2F2D302F412F5B2FE4 +:101FF0006F2F7E2F8D2D9E2D08E00E94093CAC8C0A +:10200000BD8CC980DF88E88CF98C052D1A8D0E9463 +:10201000273C70588F4F9F4FD1015B96ED91FC91FB +:102020005C975F01C12CD12CE12CF12C8701E98355 +:10203000BA82CB82DC82ED82FE820F831887C12CAC +:10204000D12CE12CF12C00E010E00E94C03A122FBC +:102050003F8B4983B52FF62FE72FF82E092FA0E0ED +:102060000E94453C84F421503109410951096E4FC9 +:102070007F4F8F4F9F4F122F3F8B4983B52FF62FE6 +:10208000E72FF82E092F212F3F8949815B2F6F2FD2 +:102090007E2F8F2D902F01E20E94093C2D8F532E11 +:1020A00049835F8B688F798F8A8F9C8FA0E00E9415 +:1020B000453C09F4C0C1D10196963C9196979596FE +:1020C0002C91932F990F990BA42CBD84CE84DB887F +:1020D000EC88FD880E891B8D492F592F692F792F88 +:1020E000892F0E94C03A2D873E87442E5B8B6C8BD4 +:1020F0007D8B8E8B9B8FF10134A123A1932F990FA0 +:10210000990BA984BA84CB84DC8473018401492FA0 +:10211000592F692F792F892F0E94C03A01E10E941F +:10212000F03BAD84BE84C42CDB88EC88FD880E892E +:102130001B8D0E94273C59016A017B01482E192FF3 +:102140004F85588969897A8934E0759567955795DF +:1021500047953A95D1F780E090E0A0E1B0E0841B8C +:10216000950BA60BB70B3C014D01990C6608762C1C +:1021700043019C01AD01662D762D862D962D0FE134 +:102180000E94F03B722E832E942E652EB62FA72F21 +:102190008A879B87F10132A121A1932F990F990B77 +:1021A000492F592F692F792F892F03E20E94F03B85 +:1021B000042D0E94273C59016A017B018C01272DC7 +:1021C000382D492D562D6B2F7A2F8A859B850E949D +:1021D0003C3CE5E3AE2EFCE0BF2EC12CD12CE12C23 +:1021E000F12C00E010E00E94C03AAD8CB52CC98003 +:1021F000DF88E88CF98C0A8D1C8D0E941B3B2C8B90 +:102200003B8B2A013B014C01F22E032F142FB52DDD +:10221000F62FE72DD82EE92CA0E00E94453C84F44F +:102220002150304E4F4F5F4F6F4F7F4F8F4F9F4F1B +:10223000F22E032F142FB52FF62FE72FD82EE92ECD +:102240002F2D302F412F5B2F6F2F7E2F8D2D9E2D09 +:102250000DE00E94093C29873A874B875C876F878E +:1022600079838D879E87D1019C963C919C979B9604 +:102270002C91932F990F990BA984BA846A017B0141 +:10228000082F1E85492F592F692F792F892F0E94DA +:10229000C03A0E94C03AF22E032F142FB52FF62F0A +:1022A000E72FD82EE92EA0E00E94453C84F421506F +:1022B000310941095E4F6F4F7F4F8F4F9F4FF22E75 +:1022C000032F142FB52FF62FE72FD82EE92E2F2D01 +:1022D000302F412F5B2F6F2F7E2F8D2D9E2D09E1EB +:1022E0000E94093CAC88BB886201730184010E9492 +:1022F000273C29873A874B875C876F8779838D874F +:102300009E87F10132A521A5932F990F990B492F93 +:10231000592F692F792F892F0E94C03A122F3C8B99 +:102320004B8BB52FF62FE72FF82E092FA0E00E9438 +:10233000453C84F421503109484F5F4F6F4F7F4F28 +:102340008F4F9F4F122F3C8B4B8BB52FF62FE72FC4 +:10235000F82E092F212F3C894B895B2F6F2F7E2F61 +:102360008F2D902F03E10E94093C59016A017B01E6 +:102370008C0129853A854B855C856F8579818D85B2 +:102380009E850E94273C122F39874983B52FF62F4F +:10239000E72FF82E092FA0E00E94453C84F421503D +:1023A0003F4F4F4F5F4F6F4F7F4F8F4F9F4F122FBA +:1023B00039874983B52FF62FE72FF82E092F212FC4 +:1023C000398549815B2F6F2F7E2F8F2D902F08E04D +:1023D0000E94093C2983F32F6A017B01E82F192F02 +:1023E000D10197968D919C919897092E000CAA0B7C +:1023F000BB0B4C015D01BB0C8808982C54019C015F +:10240000AD01682D782D882D982D04E00E94F03BB9 +:10241000A980BF2E0E2F0E94273C0E949D3D20E0E8 +:1024200030E040E85BE30E947F3E08C060E070E07F +:1024300080EC9FE703C060E070E0CB016D960FB6C3 +:10244000F894DEBF0FBECDBFDF91CF911F910F91EA +:10245000FF90EF90DF90CF90BF90AF909F908F90C4 +:102460007F906F905F904F903F902F9008954F9284 +:102470005F926F927F928F929F92AF92BF92CF9214 +:10248000DF92EF92FF92CF93DF9300D000D000D085 +:10249000CDB7DEB79E838D830E94A00E6DEF8D8138 +:1024A0009E810E94F00CA0E0B0E0811520E8920728 +:1024B000A105B10509F4D3C0ED81FE818584968420 +:1024C000A784B088FCE29F1AF1E0AF0AB1083EE0B1 +:1024D000880F991FAA1FBB1F3A95D1F7ED81FE8186 +:1024E00041A952A9052E000C660B770B24E1440F7D +:1024F000551F661F771F2A95D1F76C017D01C41AFD +:10250000D50AE60AF70AA3A9B4A9A50194010E9475 +:10251000B83AA7019601261B370B480B590BCA0185 +:10252000B901705C8F4F9F4F412C30E8532E612CC6 +:10253000712CA30192010E948E3A29833A834B8326 +:102540005C83ED81FE81A0A9B0E0A50194010E9409 +:10255000AD3A20E038E040E050E00E948E3A690158 +:102560007A01F0E8DF0EE11CF11CED81FE81A5A9E6 +:102570000A2E000CBB0BA50194010E94B83A812CD5 +:1025800044E0942EA12CB12CA50194010E948E3A16 +:10259000CA01B901A70196010E94503AA501940110 +:1025A0000E948E3A405E5F4FED81FE81A6A5B7A5E1 +:1025B0000E94B83A705E8F4F9F4F20E030E440E0B9 +:1025C00050E00E948E3A69817A818B819C810E94C1 +:1025D000503A6B017C01A30192010E948E3ACA011C +:1025E000B9010E94503A9B01AC0167E055954795AF +:1025F000379527956A95D1F7ED81FE81A5A5B0E0C5 +:102600000E94AD3A20E130E040E050E00E948E3A76 +:10261000D701C601821B930BA40BB50BB7FF03C0F8 +:1026200080E090E0DC0181309105A105F9E1BF0770 +:1026300024F080E090E0A0E0B9E1BC01CD012CE005 +:1026400095958795779567952A95D1F70E94A33D33 +:1026500020E030E040E85AE30E947F3E04C060E0A2 +:1026600070E080EC9FE726960FB6F894DEBF0FBEB1 +:10267000CDBFDF91CF91FF90EF90DF90CF90BF90D3 +:10268000AF909F908F907F906F905F904F90089544 +:10269000CF92DF92EF92FF926A017B010E94510F6D +:1026A00020E030E048EC52E40E94F53CA70196019E +:1026B0000E94F53C21E03EED42E45EE30E94EC3EE8 +:1026C0009B01AC0160E070E080E89FE30E94883CE1 +:1026D00020E03AE24DE257E40E947F3EFF90EF9007 +:1026E000DF90CF900895CF92DF92EF92FF920F93F9 +:1026F0001F93CB01BA016801790120E03AE24DE273 +:1027000057E40E94F53C9B01AC0160E070E080E87A +:102710009FE30E94883C26EF38E248EA50E40E949A +:10272000EC3E9B01AC01C701B6010E94F53C1F9134 +:102730000F91FF90EF90DF90CF900895FC0161859D +:102740007285838594850895FC01218932894389A6 +:102750005489A5E0B0E00E94AD3A672F782F892F09 +:10276000992787FD9A950E94A53D20E030E048EC2E +:1027700052E40E94F53C0895CF93DF93EC01CB0126 +:10278000BA0120E030E048EC52E40E947F3E0E9413 +:10279000673D982F872F762F662725E030E040E0B1 +:1027A00050E00E948E3A298B3A8B4B8B5C8BDF91E9 +:1027B000CF9108950F931F93CF93DF938C01EB017B +:1027C00088E2FB0111928A95E9F74BE050E06BE754 +:1027D00071E0CE010E94B1401B8681E090E0A0E054 +:1027E000B0E08C879D87AE87BF87F801808191819B +:1027F000092E000CAA0BBB0B888B998BAA8BBB8B69 +:102800008DE090E0A0E0B0E08C8B9D8BAE8BBF8B19 +:102810001CA21DA21EA21FA280E090E0A0E2B2ECCA +:102820008C8F9D8FAE8FBF8F80E090E0AAEAB2E4DC +:10283000888F998FAA8FBB8F8AE097EDA3E2BCE3C4 +:1028400088A399A3AAA3BBA3DF91CF911F910F9156 +:102850000895CF93DF93EB0124E2FB0111922A95B7 +:10286000E9F744E250E060E070E0488359836A830E +:102870007B83FC0180819181092E000CAA0BBB0B8C +:102880008C839D83AE83BF838DE090E0A0E0B0E0B9 +:1028900088879987AA87BB870E94430A288B398B30 +:1028A0004A8B5B8B88E994E00E94A00E6C8B7D8B39 +:1028B0008E8B9F8B81E0DF91CF9108950F931F93B3 +:1028C000CF93DF938C01EB0188E2FB0111928A9593 +:1028D000E9F74BE050E06BE771E0CE010E94B140B8 +:1028E0001B8681E090E0A0E0B0E08C879D87AE87FA +:1028F000BF87F80180819181092E000CAA0BBB0BC8 +:10290000888B998BAA8BBB8B86E090E0A0E0B0E02F +:102910008C8B9D8BAE8BBF8B1CA21DA21EA21FA2F7 +:1029200080E090E0A6E9B3E48C8F9D8FAE8FBF8FDF +:1029300080E090E8A9E8B4E4888F998FAA8FBB8FD4 +:1029400086EA9BE9A4E4BCE388A399A3AAA3BBA35A +:10295000DF91CF911F910F910895CF93DF93EB01FA +:1029600024E2FB0111922A95E9F744E250E060E08D +:1029700070E0488359836A837B83FC018081918165 +:10298000092E000CAA0BBB0B8C839D83AE83BF83E7 +:1029900086E090E0A0E0B0E088879987AA87BB87AF +:1029A0000E94430A288B398B4A8B5B8B88E994E021 +:1029B0000E94510F20E030E048EC52E40E94F53CC8 +:1029C0006C8B7D8B8E8B9F8B81E0DF91CF910895F7 +:1029D0000F931F93CF93DF938C01EB0188E2FB01F0 +:1029E00011928A95E9F74BE050E06BE771E0CE0178 +:1029F0000E94B1401B8681E090E0A0E0B0E08C87AF +:102A00009D87AE87BF87F80180819181092E000CD8 +:102A1000AA0BBB0B888B998BAA8BBB8B8CE090E0AD +:102A2000A0E0B0E08C8B9D8BAE8BBF8B1CA21DA257 +:102A30001EA21FA21C8E1D8E1E8E1F8E80E090E097 +:102A4000A8ECB2E4888F998FAA8FBB8F80E090E0CA +:102A5000A0E4B0E488A399A3AAA3BBA3DF91CF917C +:102A60001F910F910895CF93DF93EB0124E2FB01B7 +:102A700011922A95E9F744E250E060E070E0488363 +:102A800059836A837B83FC0180819181092E000C2C +:102A9000AA0BBB0B8C839D83AE83BF838CE090E03D +:102AA000A0E0B0E088879987AA87BB870E94430A85 +:102AB000288B398B4A8B5B8B88E994E00E94371214 +:102AC0006C8B7D8B8E8B9F8B81E0DF91CF910895F6 +:102AD000CF93DF93EC010E9455071A828CE78CABF1 +:102AE0008AE08DAB8EE78EAB8FEA8FAB88AF82EA40 +:102AF00089AF1AAE80E88BAFDF91CF910895CF9365 +:102B0000DF9300D0CDB7DEB74A83698342E0BE01D0 +:102B10006F5F7F4F0E9438080F900F90DF91CF9129 +:102B200008950F93CF93DF931F92CDB7DEB79A012D +:102B3000698301E041E0BE016F5F7F4F0E94800822 +:102B40000F90DF91CF910F9108950F93CF93DF9363 +:102B50001F92CDB7DEB79A01698302E041E0BE0162 +:102B60006F5F7F4F0E9480080F90DF91CF910F9190 +:102B700008950F931F93CF93DF9300D0CDB7DEB7A7 +:102B80008A01AE014F5F5F4F0E94A515882341F077 +:102B900029813A81322723273227F8013183208384 +:102BA0000F900F90DF91CF911F910F9108950F9388 +:102BB000CF93DF931F92CDB7DEB76983022F9E01BB +:102BC0002F5F3F4F41E0B9010E9480080F90DF91D5 +:102BD000CF910F91089540EF60E10E947F15EFE2E1 +:102BE000F5E73197F1F700C0000008950F931F93A8 +:102BF000CF93DF9300D0CDB7DEB78C01AE014F5F2E +:102C00005F4F60E00E94A5158FE295E70197F1F70D +:102C100000C0000089819A818036E1E09E0721F49E +:102C2000F801128281E008C08136914021F481E0F0 +:102C3000F801828301C080E00F900F90DF91CF9167 +:102C40001F910F9108950F931F93CF93DF931F92BE +:102C5000CDB7DEB78C0140E062E10E947F158111A3 +:102C600008C08FE295E70197F1F700C0000080E00F +:102C700016C04CEC62E1C8010E947F15882389F3DD +:102C80008FE295E70197F1F700C00000AE014F5FBA +:102C90005F4F60E2C8010E949115882311F30F90E5 +:102CA000DF91CF911F910F9108950F931F93CF93B1 +:102CB000DF9300D01F92CDB7DEB78C010E942316A0 +:102CC000882359F18FE295E70197F1F700C00000E2 +:102CD0004EE062E1C8010E947F158823F1F023E0F5 +:102CE000AE014F5F5F4F6CE4C8010E94D715882387 +:102CF000A1F02981F80123839A8194839B81958394 +:102D000091E0273008F490E0F8019283EFE2F5E7D4 +:102D10003197F1F700C0000007C08FE295E70197F7 +:102D2000F1F700C0000080E00F900F900F90DF914E +:102D3000CF911F910F910895633021F4FC012281FE +:102D4000222359F0462F60E10E947F15EFE2F5E75C +:102D50003197F1F700C00000089580E00895CF9307 +:102D6000DF93EC0163E50E9460078FE295E701972E +:102D7000F1F700C00000CE010E94EB158823A9F0F6 +:102D8000CE010E94F615882381F061E0CE010E94F9 +:102D90009C16882351F0CE010E942316882329F027 +:102DA000CE01DF91CF910C94551680E0DF91CF9149 +:102DB0000895CF93DF9361157105D9F0EC017F83FE +:102DC0006E8361E00E949C16882399F0CE010E94D8 +:102DD0002316882371F042EC62E1CE010E947F1538 +:102DE000882339F0EFE2F5E73197F1F700C00000F2 +:102DF00007C08FE295E70197F1F700C0000080E07F +:102E0000DF91CF9108956F927F928F929F92AF92B0 +:102E1000BF92CF92DF92EF920F931F93CF93DF93E6 +:102E20001F92CDB7DEB73C01CB01342FE02FAFE2CC +:102E3000B5E71197F1F700C0000068E170E00E946B +:102E40007A3A8B014FEF460F4295440F440F407C76 +:102E50003111406221114061E1114860E11044608C +:102E600060E4C3010E947F15882309F471C0A801A2 +:102E700041505109569547955695479561E4C301D0 +:102E80000E947F15882309F463C0A60156954795D3 +:102E900062E4C3010E947F15882309F459C0A5018B +:102EA0005695479563E4C3010E947F15882309F472 +:102EB0004FC0A4015695479564E4C3010E947F1555 +:102EC000811146C049895A895695479565E4C301E1 +:102ED0000E947F1581113CC0F3014681415066E498 +:102EE000C3010E947F15811133C0D30116968D91C5 +:102EF0009C911797019711F440E801C040E067E406 +:102F0000C3010E947F15882319F1EFE2F5E731979D +:102F1000F1F700C00000AE014F5F5F4F6FE4C301E7 +:102F20000E9491158823A1F0AFE2B5E71197F1F760 +:102F300000C00000F30126813781B901606C49812E +:102F400050E06417750729F02F5F3F4F37832683C2 +:102F500080E00F90DF91CF911F910F91EF90DF9064 +:102F6000CF90BF90AF909F908F907F906F9008957B +:102F7000AB0160E20C9491150F93CF93DF931F92F6 +:102F8000CDB7DEB79B0141E2498305E041E0BE01D8 +:102F90006F5F7F4F0E9480080F90DF91CF910F915C +:102FA00008950F931F93CF93DF93CDB7DEB7299783 +:102FB0000FB6F894DEBF0FBECDBF8C016623F1F0D3 +:102FC000AE01475F5F4F60E2C8010E949115882300 +:102FD000E9F087EB9BE00197F1F700C000008985DD +:102FE00081FFEECF898581FF11C027E0AE014F5FE1 +:102FF0005F4F61E2C8010E94D71508C0AE01475F6C +:103000005F4F60E20E9491158111ECCF80E029961C +:103010000FB6F894DEBF0FBECDBFDF91CF911F91E9 +:103020000F9108950F931F93CF93DF93CDB7DEB722 +:1030300029970FB6F894DEBF0FBECDBF8C01662373 +:10304000C1F087EB9BE00197F1F700C00000AE01F3 +:10305000475F5F4F60E2C8010E949115811102C075 +:1030600080E00AC1898580FFECCF898580FFF8CF99 +:1030700009C0AE01475F5F4F60E20E949115811168 +:10308000F4CFEECF28E0AE014F5F5F4F68E4C80198 +:103090000E94D715882321F369817A8180E090E02E +:1030A0000E94A33D20E030E040E05AE30E947F3ED2 +:1030B0009B01AC0160E070E080E090E40E94EC3E97 +:1030C0000E946E3DF8016787708B818B928B6B81BC +:1030D0007C8180E090E00E94A33D20E030E040E071 +:1030E0005AE30E947F3E9B01AC0160E070E080E00B +:1030F00090E40E94EC3E0E946E3DF801678B708F59 +:10310000818F928F6D817E8180E090E00E94A33D4F +:1031100020E030E040E05AE30E947F3E9B01AC019A +:1031200060E070E080E090E40E94EC3E0E946E3D22 +:10313000F801678F70A381A392A36F81788580E0E7 +:1031400090E00E94A33D20E030E040E05AE30E947E +:103150007F3E9B01AC0160E070E080E090E40E9463 +:10316000EC3E0E946E3DF80167A370A781A792A76D +:1031700028E0AE014F5F5F4F68E2C8010E94D7159B +:10318000882309F46DCF69817A8180E090E00E9404 +:10319000A33D20E030E040E05AE30E947F3E9B01E7 +:1031A000AC0160E070E080E090E40E94EC3E0E94A0 +:1031B0006E3DF801638B748B858B968B6B817C8164 +:1031C00080E090E00E94A33D20E030E040E05AE340 +:1031D0000E947F3E9B01AC0160E070E080E090E4E3 +:1031E0000E94EC3E0E946E3DF801638F748F858FC4 +:1031F000968F6D817E8180E090E00E94A33D20E06B +:1032000030E040E05AE30E947F3E9B01AC0160E069 +:1032100070E080E090E40E94EC3E0E946E3DF80178 +:1032200063A374A385A396A36F81788580E090E063 +:103230000E94A33D20E030E040E05AE30E947F3E40 +:103240009B01AC0160E070E080E090E40E94EC3E05 +:103250000E946E3DF80163A774A785A796A7AE01EB +:103260004F5F5F4F68E3C8010E949115882309F4FE +:10327000F7CE9981F80193AB29960FB6F894DEBF8B +:103280000FBECDBFDF91CF911F910F910895CF93C6 +:10329000DF9300D000D0CDB7DEB769837A834B834C +:1032A0005C8324E0AE014F5F5F4F63E10E94E30760 +:1032B0000F900F900F900F90DF91CF9108958F9204 +:1032C0009F92AF92BF92CF92DF92EF92FF920F93B5 +:1032D0001F93CF93DF93EC014A015B01C901B80151 +:1032E00020E030E040E054E40E947F3E0E946E3DCA +:1032F0006B017C0123E333E948E853E4C501B401E1 +:103300000E94893C20E030E040E852E40E947F3E89 +:103310000E946E3DA601CE01DF91CF911F910F91CA +:10332000FF90EF90DF90CF90BF90AF909F908F90E5 +:103330000C944719FC01868197818330910540F4F4 +:10334000880F991FFC01EC59FE4F808191810895EF +:1033500080E094E00895289820981CBC2C9884B1B3 +:103360008F7084B981B18F7C81B982B18F7C82B931 +:10337000089560E070E0CB010E94170A0196C9F33E +:103380000895611102C00E94B9198FEF08956EBDB2 +:103390000DB407FEFDCF8EB50895289A089528989C +:1033A000089595B181E0892785B908951498089505 +:1033B000149A089583B186FB882780F9089580B117 +:1033C00085FB882780F908952AE0FC0120871E9953 +:1033D000FECF81E0089524E6FC012087059BFECF07 +:1033E00081E0089524E6FC0120870599FECF81E065 +:1033F00008950F931F93CF93DF93EC01162F0E9434 +:10340000D619CE010E94E419082F612F6F73CE01E7 +:103410000E94C719CE010E94D819802FDF91CF9149 +:103420001F910F910895FF920F931F93CF93DF93F6 +:10343000EC01062FF42E0E94D619CE010E94E41949 +:10344000182F602FCE010E94C7196F2DCE010E9448 +:10345000C7198A838D8181608D83CE010E94D8191E +:10346000898580FF2BC01F92FF921F920F9386E8E1 +:1034700093E09F938F930E9443410F900F900F9082 +:103480000F900F900F90112389F08D8182FF0EC055 +:103490008A811F928F9387E793E09F938F930E9477 +:1034A00043410F900F900F900F9008C082E793E078 +:1034B0009F938F930E9443410F900F90812FDF9134 +:1034C000CF911F910F91FF900895AF92BF92CF922D +:1034D000DF92EF92FF920F931F93CF93DF93EC0154 +:1034E000B42ED52E022F6F73162F10640E94D6199A +:1034F000CE010E94E419C82E612FCE010E94C71987 +:10350000EB2CFD2C5701D02EDD2041F0F50161910F +:103510005F01CE010E94C719DA94F6CFCE010E9456 +:10352000D819898581FF46C01F731F921F9386E5B6 +:1035300093E09F938F930E9443410F900F900F90C1 +:103540000F90102F8EE4A82E83E0B82E112379F06F +:10355000F70181917F011F928F93BF92AF920E94DA +:10356000434111500F900F900F900F90EFCF89E4CF +:1035700093E09F938F930E9443410F900F90CC2034 +:1035800089F08D8182FF0EC08A811F928F938AE31A +:1035900093E09F938F930E9443410F900F900F9061 +:1035A0000F9008C085E393E09F938F930E9443415F +:1035B0000F900F908C2DDF91CF911F910F91FF9065 +:1035C000EF90DF90CF90BF90AF900895EF92FF9271 +:1035D0000F931F93CF93DF93EC017A016F73162F34 +:1035E00010680E94D619CE010E94E419082F612F9D +:1035F000CE010E94C7198A838D8181608D8360E02E +:10360000CE010E94C719F7018083CE010E94D8190C +:10361000898582FF2EC01F731F921F9389E193E05B +:103620009F938F930E9443410F900F900F900F90A4 +:103630000023B9F08D8180FF14C08A811F928F937F +:10364000F70180811F928F9383E093E09F938F9384 +:103650000E9443410F900F900F900F900F900F908A +:1036600008C08EEF92E09F938F930E9443410F908A +:103670000F90802FDF91CF911F910F91FF90EF90CE +:103680000895AF92BF92CF92DF92EF92FF920F9385 +:103690001F93CF93DF938C01D62FB42ED52EC22F3C +:1036A0000E94D619C8010E94E419C82E6D2F606CC3 +:1036B000C8010E94C719EB2CFD2C5701DC2EDD2020 +:1036C00049F060E0C8010E94C719F50181935F01CC +:1036D000DA94F5CFC8010E94D819F801818583FFDB +:1036E00031C01F92CF93DF731F92DF9387ED92E07B +:1036F0009F938F930E9443410F900F900F900F90D4 +:103700000F900F90CC20B1F00FEC12E0CC2379F0A9 +:10371000F70181917F011F928F931F930F930E9456 +:103720004341C1500F900F900F900F90EFCF8DEC51 +:1037300092E002C088EC92E09F938F930E944341F5 +:103740000F900F908C2DDF91CF911F910F91FF90D3 +:10375000EF90DF90CF90BF90AF90089521E00C9450 +:10376000411B9B01205331092E30310510F40C947C +:10377000AE1B80E00895AF92BF92CF92DF92EF929E +:10378000FF920F931F93CF93DF93CDB7DEB762976E +:103790000FB6F894DEBF0FBECDBF8C01242F8AE098 +:1037A000F8018087AB016FE3C8010E94651AF82E0B +:1037B000AE014E5E5F4F6AE370E0C8010E94AE1B2F +:1037C0009A899431A1F58F2191F165E370E0C801E8 +:1037D0000E94F919F82E882351F1D12CE12CAE0169 +:1037E0004F5E5F4F65E370E0C8010E94AE1BF82298 +:1037F0008989D81659F0FFE0FE1540F0E1E0F0E0CD +:10380000EC0FFD1FEE0DF11D8083E394FF2049F0C6 +:10381000833129F0D82EF80190859111E0CFFF2453 +:10382000F39491E0833109F090E0F92261F46BE3C5 +:1038300070E0C8010E94F91960C0222389F0F801E4 +:103840008085882369F0AE014E5E5F4F6AE370E0C9 +:10385000C8010E94AE1B2A898111EFCF80E001C010 +:1038600081E091E0211190E0892309F3AE014F5EE0 +:103870005F4F65E370E0C8010E94AE1B2989882371 +:1038800039F0213039F0F80180858111EFCF02C085 +:1038900080E001C081E091E0213009F090E08923CF +:1038A00061F18FEB92E09F938F930E944341CE0191 +:1038B00001965C010F900F908C0187EBC82E82E07F +:1038C000D82E802F8A198E1570F4F80181918F01FE +:1038D0001F928F93DF92CF920E9443410F900F90DF +:1038E0000F900F90EECF84EB92E09F938F930E9406 +:1038F00043410F900F9081E001C080E062960FB6C7 +:10390000F894DEBF0FBECDBFDF91CF911F910F9115 +:10391000FF90EF90DF90CF90BF90AF9008953F92CF +:103920004F925F926F927F928F929F92AF92BF92CF +:10393000CF92DF92EF92FF920F931F93CF93DF937B +:10394000CDB7DEB767970FB6F894DEBF0FBECDBF19 +:103950006C01611105C046E062E00E94131A14C1B7 +:10396000623008F010C18DE595E09F938F930E941F +:1039700043410F900F9080E090E0EE24EA94FE2CFB +:10398000512C34E1432E4DEE642E44E0742E57EE5C +:10399000852E54E0952E2FEF30E03E8B2D8B5C0171 +:1039A0003FEFA31AB30A9F938F938BE195E09F9308 +:1039B0008F930E944341AE014B5E5F4F65E370E021 +:1039C000C6010E94AE1B0F900F900F900F908111B7 +:1039D00009C028E135E03F932F930E9443410F90A7 +:1039E0000F900EC08E898F938D898F93E1E1F5E062 +:1039F000FF93EF930E9443410F900F900F900F9011 +:103A00008F8989831F925F921F924F9283EF94E078 +:103A10009F938F930E9443418E010E5F1F4F0F9023 +:103A20000F900F900F900F900F90312C832D8A0DD7 +:103A3000F80181938F011F928F937F926F920E9462 +:103A4000434133940F900F900F900F90F3E13F128A +:103A5000EDCF9F928F920E94434144E1BE016F5F80 +:103A60007F4FC6010E94BB1B0F900F90811171C048 +:103A700084E690E00E94850984EE94E09F938F9302 +:103A80000E9443410F900F902FEFE216F20609F4C7 +:103A90005EC03BE2E316F10429F08DE2E816F10482 +:103AA00031F00CC091E0951558F45A940EC0552091 +:103AB00051F0E9E0E51548F0539407C0512C05C0DA +:103AC0005524539402C08AE0582EF5E05F9E800191 +:103AD000112407531A4F41E050E0B801CE01479638 +:103AE0000E949A408AE495E09F938F930E944341FD +:103AF0000F5F1F4F1F930F930E94434185E495E092 +:103B00009F938F930E9443414F896EE3C6010E94A9 +:103B1000131A0F900F900F900F900F900F90882313 +:103B200071F08F891F928F9382E395E09F938F931B +:103B30000E9443410F900F900F900F9008C08CE2AD +:103B400095E09F938F930E9443410F900F90C50182 +:103B500022CF84E690E00E949A0960ED77E080E051 +:103B600090E00E94320A7C0121EE34E03F932F93D3 +:103B70000E9443410F900F909BE1E916F10409F078 +:103B800083CF80E001C08FEF67960FB6F894DEBF59 +:103B90000FBECDBFDF91CF911F910F91FF90EF909E +:103BA000DF90CF90BF90AF909F908F907F906F905D +:103BB0005F904F903F9008958F929F92AF92BF92E7 +:103BC000CF92DF92EF92FF920F931F93CF93DF93E9 +:103BD00000D0CDB7DEB78C014B015A01C22EFA01DD +:103BE000108282E3F801808785818B7F8583AE0117 +:103BF0004E5F5F4F6BE370E0C8010E94AE1BF82E72 +:103C0000882309F446C08A818F7709F446C0D82EEC +:103C10008FEA94E00197F1F700C00000AE014E5F1B +:103C20005F4F6BE370E0C8010E94AE1B882321F058 +:103C30009A819F77E92E01C0ED2C91E0F801208553 +:103C4000211101C090E0F92EF82219F1DE1411F0D3 +:103C5000DE2CDECFF80185818270D82E90E044966C +:103C60002E2D30E08217930769F19F938F93F50112 +:103C700080811F928F9389E892E09F938F930E9497 +:103C80004341F50110820F900F900F900F900F900D +:103C90000F90F12C02C0E11056C06AE370E0C80139 +:103CA0000E94F9198F210F900F90DF91CF911F91F2 +:103CB0000F91FF90EF90DF90CF90BF90AF909F90CB +:103CC0008F9008959F938F9382E792E09F938F93B5 +:103CD0000E9443410F900F900F900F90F4E1FC155C +:103CE00018F42E2D2D1901C02C2DF5012083A401CF +:103CF0006FEFC8010E94411BF501811102C01082C3 +:103D0000C8CF8081E81ADE1430F688E592E09F93F0 +:103D10008F930E9443410F900F90AE014F5F5F4F12 +:103D20006FEFC8010E94E61AEA94DE14B0F3DD20BA +:103D300009F4AFCF22E0A8014D5F5F4F6FEFC801DC +:103D40000E94411BA6CF22E0A8014D5F5F4F6FEF9D +:103D5000C8010E94411BF82E882309F49ACFF8016C +:103D600085818460858399CF3F924F925F926F9255 +:103D70007F928F929F92AF92BF92CF92DF92EF92FB +:103D8000FF920F931F93CF93DF93CDB7DEB7679763 +:103D90000FB6F894DEBF0FBECDBF8C01611105C018 +:103DA00046E062E00E94131A61C1623008F05DC112 +:103DB00080E090E07C012FEFE21AF20A9F938F934C +:103DC0008AEC94E09F938F930E94434164E370E0F8 +:103DD000C8010E94F9190F900F900F900F908FEF6C +:103DE00090E09E8B8D8BAE014B5E5F4F65E370E084 +:103DF000C8010E94AE1B81110EC087EC94E09F9316 +:103E00008F930E9443419FE7EFE4F2E19150E0403D +:103E1000F040E1F714C060E070E0CB010E94170AA7 +:103E2000019691F08DEB94E09F938F930E94434114 +:103E30008FE79FE4E2E181509040E040E1F700C06D +:103E400000000F900F9019C08D899E8981309105D7 +:103E500071F484EB94E09F938F930E944341FFE7BA +:103E60002FE482E1F15020408040E1F7E8CF8D302F +:103E7000910519F0419709F0B2CF8D899E898D3057 +:103E8000910521F0419711F0C70194CF83EA94E0A6 +:103E90009F938F930E9443410F900F9084E5482E8B +:103EA00084E0582E98E4692E94E0792E2AE6C22EFA +:103EB00024E0D22E32E7A32E34E0B32E43E9842E41 +:103EC00044E0942EAE014B5E5F4F65E370E0C801A5 +:103ED0000E94AE1B81110EC0E0EAF4E0FF93EF9365 +:103EE0000E9443418FE79FE4E2E181509040E0402F +:103EF000E1F72EC060E070E0CB010E94170A019646 +:103F000091F086E994E09F938F930E9443412FE7BD +:103F10008FE492E1215080409040E1F700C0000022 +:103F20000F900F90A2C0AE01495E5F4F6BE370E04F +:103F3000C8010E94AE1B81110EC09F928F920E94F9 +:103F40004341EFE7FFE422E1E150F0402040E1F798 +:103F500000C0000071C08F89843108F46FC024E173 +:103F6000AE01495E5F4FBE016F5F7F4FC8010E9487 +:103F7000DC1D882309F462C08F89882309F45EC0A0 +:103F800084E690E00E949A098EE894E09F938F93D4 +:103F90000E944341F80185810F900F9082FF24C059 +:103FA00084818F771F928F938381282F082E000C96 +:103FB000330B3F938F9387E794E09F938F930E94F7 +:103FC0004341F80184810F900F900F900F900F9054 +:103FD0000F9087FF03C0BF92AF9202C0DF92CF92D3 +:103FE0000E9443410F900F908F891F928F935F9291 +:103FF0004F920E9443410F900F900F900F90312CE1 +:104000008F893816A8F4E1E0F0E0EC0FFD1FE30D16 +:10401000F11D80811F928F938EE494E09F938F9384 +:104020000E94434133940F900F900F900F90E8CF70 +:104030007F926F920E9443410F900F908D899E89CD +:104040008D30910509F43ECF8131910509F43ACFC5 +:104050009F938F9384E394E09F938F930E944341B7 +:104060000F900F900F900F900FCF8FEF67960FB6B6 +:10407000F894DEBF0FBECDBFDF91CF911F910F919E +:10408000FF90EF90DF90CF90BF90AF909F908F9078 +:104090007F906F905F904F903F900895FC01268134 +:1040A00037812130310531F038F02230310541F4CB +:1040B0000C94B41E0C948F1C611102C00E94B9199B +:1040C0008FEF0895AF92BF92CF92DF92EF92FF925F +:1040D0000F931F93CF93DF93CDB7DEB729970FB61A +:1040E000F894DEBF0FBECDBF7C0186E592E09F93C2 +:1040F0008F930E9443418AE9C82E85E0D82E0F9005 +:104100000F9010E09BE4A92E92E0B92E41E050E020 +:10411000B601CE0109960E949A40AE014F5F5F4FF3 +:10412000612FC7010E94E61A89859981981751F07D +:104130001F928F93BF92AF920E9443410F900F90B6 +:104140000F900F901F5F8FEFC81AD80A1F32F1F639 +:1041500000E310E0AE014F5F5F4FB801C7010E945E +:10416000B11B0F5F1F4F0E331105A1F728E0AE0101 +:104170004F5F5F4F6EE3C7010E94411B29960FB648 +:10418000F894DEBF0FBECDBFDF91CF911F910F918D +:10419000FF90EF90DF90CF90BF90AF9008951F9366 +:1041A000CF93DF93EC010E94D61988E28A95F1F74C +:1041B000CE010E94D81988EC8A95F1F7CE010E94B1 +:1041C000D619CE010E94E419182F60E370E0CE01E9 +:1041D0000E94F9191823CE010E94E4198123DF916E +:1041E000CF911F910895CF92DF92EF92FF921F938C +:1041F000CF93DF931F92CDB7DEB76C018AE9E82E2B +:1042000085E0F82E10E041E050E0B701CE010196C4 +:104210000E949A404981612FC6010E94131A1730EB +:1042200039F4998192FF04C0F601958192609583DB +:104230001F5F882331F08FEFE81AF80A1F3219F751 +:1042400081E00F90DF91CF911F91FF90EF90DF9071 +:10425000CF9008955F926F927F928F929F92AF92CC +:10426000BF92CF92DF92EF92FF920F931F93CF9363 +:10427000DF93CDB7DEB728970FB6F894DEBF0FBE39 +:10428000CDBF4C018E010F5F1F4FE12CF12C60E080 +:10429000702EC12E88E3A82E82E0B82EDD24D394A0 +:1042A000D60E6E2C5F2C85E0689FB00111246753F9 +:1042B0007A4F41E050E0C8010E949A40EAE0ED15D3 +:1042C00008F4D12CF401818584FF10C0F8018081AD +:1042D0001F928F935F926F92BF92AF920E94434161 +:1042E0000F900F900F900F900F900F90FFEFEF1A1D +:1042F000FF0A0F5F1F4F88E0E816F10411F06D2DE3 +:10430000CDCF28E0472D5C2D6EE3C4010E94651AD5 +:1043100028960FB6F894DEBF0FBECDBFDF91CF91C8 +:104320001F910F91FF90EF90DF90CF90BF90AF90D3 +:104330009F908F907F906F905F900895CF93DF93C1 +:10434000EC012898209A8091640084708093640026 +:10435000149A0C9A2C9A269884B1806B84B980E5C3 +:104360008CBD159A0D988DEE93E09F938F930E94CC +:104370004341CE010E94CF200F900F90811103C0C6 +:1043800087EE93E01FC080ED93E09F938F930E9490 +:104390004341CE010E94F3200F900F90811103C082 +:1043A0008AEC93E00FC084EB93E09F938F930E947D +:1043B0004341CE010E942A210F900F90811107C026 +:1043C0008EEA93E09F938F930E9443410CC08BEA47 +:1043D00093E09F938F930E9443418FEF8987CE0193 +:1043E0000E94622019860F900F90DF91CF9108955F +:1043F00024B1287F24B925B1276025B921E0FC012B +:1044000022830895FC01128284B1887F84B985B12A +:10441000887F85B90895EF92FF920F931F93CF93F2 +:10442000DF9361112CC0EC010EE016E080E0E82E75 +:1044300086E0F82E6AE070E080E090E00E94170AC3 +:104440000196F9F41F930F930E9443418B811F92B1 +:104450008F93282F082E000C330B3F938F93FF92DE +:10446000EF920E9443418DB79EB708960FB6F8941D +:104470009EBF0FBE8DBF1A99DDCF1B82DBCF8FEFA2 +:1044800001C080E0DF91CF911F910F91FF90EF90DD +:10449000089583B182FB882780F991E089270895E8 +:1044A00083B180958170089583B18695817091E084 +:1044B00089270895FC018281811102C01382089529 +:1044C00033B191E03927379533273795330F330BC5 +:1044D00023B1269521702927279522272795220F7A +:1044E000220B80E030FB80F920FB81F990911F01C5 +:1044F00098279370D1F490911E0190FD0EC09827DB +:1045000091FF0BC0938181FD04C09F3729F09F5F0D +:1045100003C0903809F09150938380911E0130FBC5 +:1045200080F920FB81F980931E0180911F0130FBEF +:1045300080F920FB81F980931F010895FC0182819D +:1045400093818330910540F4880F991FFC01E6594F +:10455000FE4F8081918108958AE991E00895E8EB0A +:10456000F0E02DE020832CE1208324E6208324E06A +:104570002093BC0020E620937C0027E820937A005B +:1045800080579F4F21E0FC012083089580579F4F63 +:10459000FC01108284E08093BC001092B80010925D +:1045A0007C0010927A0008952F923F924F925F9272 +:1045B0006F927F928F929F92AF92BF92CF92DF9233 +:1045C000EF92FF920F931F93CF93DF93CDB7DEB798 +:1045D00061970FB6F894DEBF0FBECDBF8C0161119D +:1045E000A5C2FC0182819381009709F0E8C184EAA9 +:1045F00097E09F938F930E94434198012C5F3F4F18 +:104600003D872C8767E7C9010E948E0E0F900F909F +:10461000811103C081EA97E08BC281E997E09F9303 +:104620008F930E94434158013DE3A30EB11CC50185 +:104630000E94AF160F900F90811103C08EE897E093 +:1046400077C262E0C5010E949C16811103C08BE80D +:1046500097E06EC200E010E022E832E440E050E073 +:1046600068EC71E4C5010E945F19811103C088E8FC +:1046700097E05EC285E897E09F938F930E94434145 +:104680000F900F908FEF8F83412C512C32014E866B +:104690005F86688A798A8C859D850E94510F20E00B +:1046A00030E543EC57E40E94F53C9F938F937F9352 +:1046B0006F93EEE6F7E0FF93EF930E9443418C8502 +:1046C0009D850E94A00E68877987382E292E9F939A +:1046D0008F9339853F9388858F93E1E6F7E0FF93C9 +:1046E000EF930E9443418C859D850E9437124B01B8 +:1046F0008A879B879F938F939F926F9385E597E01F +:104700009F938F930E9443410FB6F894DEBF0FBE74 +:10471000CDBF3F813F3F09F19A858B85282D392DEB +:10472000492F582FFC01682D792D8F2F9E2F0E9425 +:104730003C3F811112C078856985C101272F362F32 +:10474000492F582FDB01F1016B2F7A2F8F2F9E2FCE +:104750000E943C3F882309F4FBC165E0C62ED12CA2 +:10476000E12CF12C05E010E025E030E045E050E0E0 +:1047700063E070E08C859D850E94640C8F8180329F +:1047800008F413C1E8E4F7E0FF93EF930E9443417C +:104790000F900F903F8113162CF5632F330F770B7B +:1047A000880B990B0E94A53D6B017C019B01AC011C +:1047B000C301B2010E94F53C4B018A879B87A70188 +:1047C00096016E857F85888999890E94F53C688766 +:1047D0007987382E292E412C512C32014E865F8646 +:1047E000688A798A9A858B85082D192D292F382F6B +:1047F000F885E985C1014F2F5E2F692F722DC50104 +:104800000E945F19811105C084E497E09F938F9304 +:10481000C7C08B858F939A859F939F928F922F927B +:104820003F92E985EF93F885FF9322E337E03F93CA +:104830002F930E94434162E0C5010E949C160FB66F +:10484000F894DEBF0FBECDBF811103C08FE297E0A9 +:1048500093C014E687EC9FEA0197F1F700C00000CF +:10486000BE016A5F7F4FC5010E94B817882309F413 +:104870008AC08E8181FF87C0BE016F5F7F4FC501F7 +:104880000E94BC17882309F481C089811F928F93ED +:10489000E6E2F7E0FF93EF930E9443410F900F9001 +:1048A0000F900F908981833091F038F4813061F05E +:1048B000823099F487E197E012C0843059F0853056 +:1048C00061F48FEF96E00BC08CE197E008C08EE0BA +:1048D00097E005C089E097E002C08DEF96E09F93D6 +:1048E0008F930E9443410F900F908B818F938A8109 +:1048F0008F938FEE96E09F938F930E9443418D811B +:104900008F938C818F9324EE36E03F932F930E94F8 +:1049100043418C819D810FB6F894DEBF0FBECDBFA1 +:104920008039F1E09F0718F482EE96E01DC08835CB +:1049300022E0920718F488ED96E016C0803233E04A +:10494000930718F483ED96E00FC0883EE3E09E07DE +:1049500018F48EEC96E008C08C3D954018F489EC74 +:1049600096E002C085EC96E09F938F930E944341AE +:104970000F900F9083EC96E09F938F930E9443419A +:104980000F900F9003C0115009F064CF61E0C50192 +:104990000E949C16811108C020EC36E03F932F93B3 +:1049A0000E9443410F900F901F8268EE73E080E0F9 +:1049B00090E00E94170A019609F46DCEC1C08130C3 +:1049C000910509F071C007581F4F61E0C8010E94AE +:1049D0006007811103C08DEB96E0AAC09EE9692EA5 +:1049E00096E0792E24E9E22E26E0F22E34E8C32E5A +:1049F00036E0D32E43E7A42E46E0B42E5DE7852EA5 +:104A000056E0952E80917A00806480937A008091A0 +:104A10007A0086FDFCCF8091790089831F928F9365 +:104A20007F926F920E94434141E0BE016F5F7F4FD2 +:104A3000C8010E9438080F900F900F900F908111BD +:104A400006C0FF92EF920E9443410F900F90DF92B9 +:104A5000CF920E94434141E0BE016F5F7F4FC8018A +:104A60000E9415080F900F90882361F089811F9292 +:104A70008F939F928F920E9443410F900F900F90BF +:104A80000F9006C0BF92AF920E9443410F900F90CB +:104A900068EE73E080E090E00E94170A019609F446 +:104AA000B1CF0E946A074CC0029709F03FC0055879 +:104AB0001F4F40E061E0C8010E94C908811103C096 +:104AC00080E796E035C08AE3C82E86E0D82EC8017C +:104AD0000E9419097C010196F1F080917A008064AE +:104AE00080937A0080917A0086FDFCCF60917900F6 +:104AF000C8010E94F908809179001F928F93FF925C +:104B0000EF92DF92CF920E9443410F900F900F904F +:104B10000F900F900F9060E070E0CB010E94170A99 +:104B20000196A9F2C8010E94D9080AC086E396E05E +:104B30009F938F930E9443410F900F908FEF29C056 +:104B400064EF71E080E090E00E94170A80E021C0ED +:104B500078856985C101272F362F492F582F6E85FB +:104B60007F85888999890E94893C6E877F87888B99 +:104B7000998B9A858B85282D392D492F582FC30164 +:104B8000B2010E94893C2B013C018F818F5F8F8392 +:104B9000E4CD61960FB6F894DEBF0FBECDBFDF91B6 +:104BA000CF911F910F91FF90EF90DF90CF90BF902A +:104BB000AF909F908F907F906F905F904F903F90BD +:104BC0002F900895FC01228133812230310541F478 +:104BD000579A5F9A85589F4F0E941E095F980895C3 +:104BE0008091BC0080688093BC00089520E62093EB +:104BF0007C0027E820937A00289A299824B1236022 +:104C000024B95A9A22E02093C80028E92093C900C9 +:104C100026E02093CA001092CD002BE92093CC000F +:104C200021E0FC0122830895FC01128210927C0095 +:104C300010927A001092C8001092C9001092CA0017 +:104C40001092CD001092CC005A9884B18C7F84B918 +:104C500085B18C7F85B90895CF92DF92EF92FF9254 +:104C60000F931F93CF93DF938C0161114EC028984F +:104C700029988BEFE82E87E0F82ECC24CA94DC2C00 +:104C8000C0EED7E064EF71E080E090E00E94170A88 +:104C9000019609F044C080917A00806480937A0084 +:104CA00080917A0086FDFCCF8091C800806480935B +:104CB000C800289A299A809179008093CE0080912B +:104CC000C80086FFFCCF29982898809179001F9210 +:104CD0008F93FF92EF920E944341F894F8018381F1 +:104CE0009481D482C38278940F900F900F900F908C +:104CF00097FDC8CF9F938F93DF93CF930E9443413B +:104D00000F900F900F900F90BDCF8CED97E09F9379 +:104D10008F930E9443410F900F908FEF01C080E06E +:104D2000DF91CF911F910F91FF90EF90DF90CF9087 +:104D3000089570E0FC017483638308955F9A089579 +:104D40005F9808955E9A08955E980895139A08955D +:104D5000139808958FEF84B9089580918604813067 +:104D600019F48FEF84B9089514B8089580918604DA +:104D7000813041F487EB9BE00197F1F700C0000020 +:104D800080E0089583B1089565B90895109A089553 +:104D9000109808951F93CF93DF93EC01162F0E9474 +:104DA000A8268FEF84B98A81882389F0812F807F9C +:104DB00085B9CE010E94A6268CE38A95F1F7CE0133 +:104DC0000E94A82684E08A95F1F71295107F15B904 +:104DD000CE010E94A6268CE38A95F1F7CE010E94AF +:104DE000A82684E08A95F1F7DF91CF911F9108956D +:104DF0001F93CF93DF93EC01162F0E94A426CE01C0 +:104E00000E94A026612FCE01DF91CF911F910C94BB +:104E1000CA26EF92FF920F931F93CF93DF93EC017B +:104E20007B018B8187FD59C080918604813041F4DC +:104E300087EB9BE00197F1F700C0000081E04EC0D6 +:104E4000CE010E94AD268FEF85B9CE010E94A22629 +:104E5000CE010E94A02694E09A95F1F7CE010E941F +:104E6000A6268CE38A95F1F7CE010E94B626082F7C +:104E7000CE010E94A82694E09A95F1F7CE010E94F7 +:104E8000A6268CE38A95F1F7CE010E94B62682957C +:104E90008F70007F182F102BCE010E94A82694E05F +:104EA0009A95F1F7CE010E94A426912F90788BE07D +:104EB000E816F10430F08BE0E81AF10811F09111D6 +:104EC000C4CF8B81813021F4992311F08BEF8B8338 +:104ED00015B88FEF84B981E0911180E0DF91CF9117 +:104EE0001F910F91FF90EF900895CF93DF93EC0106 +:104EF00062E370E00E940927811102C08AEF8B8370 +:104F0000DF91CF9108951F93CF93DF93EC01162F7C +:104F10000E947527612F6068CE010E94F826CE019D +:104F2000DF91CF911F910C9475271F93CF93DF933F +:104F3000EC0115B88FEF84B98FE79BEB0197F1F780 +:104F400000C000001B8210E08A81882311F068E213 +:104F500001C068E0CE010E94F826111105C087E962 +:104F60009AE30197F1F704C08BE291E00197F1F722 +:104F700000C000001F5F143039F76CE0CE010E94C2 +:104F8000F82662E370E0CE010E940927811102C079 +:104F90008FEF1BC06CE0CE010E94F82662E370E048 +:104FA000CE010E940927811102C08DEF0EC061E081 +:104FB000CE010E94F82660EB74E0CE010E94092722 +:104FC000811102C08CEF01C081E08B83DF91CF9112 +:104FD0001F910895CF93DF93EC0181B1896081B96E +:104FE0008FEF84B98AB1806C8AB9CE010E9495276F +:104FF0008EE398E09F938F930E9443418B810F90A3 +:105000000F90813049F48AE398E09F938F930E9438 +:1050100043410F900F9010C0282F082E000C330B27 +:105020003F938F9380E398E09F938F930E94434137 +:105030000F900F900F900F90CE01DF91CF910C94B5 +:10504000C626CF93DF93FC012381213061F4EC016C +:105050000E9475276CE0CE010E94F826CE01DF91F8 +:10506000CF910C947527DF91CF910895CF93DF9363 +:10507000FC012381213061F4EC010E94752768E076 +:10508000CE010E94F826CE01DF91CF910C947527B6 +:10509000DF91CF910895CF93DF93FC0123812130DD +:1050A00061F4EC010E94752761E0CE010E94F826B0 +:1050B000CE01DF91CF910C947527DF91CF910895A8 +:1050C0000E944B2882B1867F82B981B1867F81B9E7 +:1050D00015B814B88BB18F738BB98AB18F738AB935 +:1050E0000895CF93DF93EC018B818130B9F4443183 +:1050F000A8F4613039F048F0623031F0633071F477 +:105100004C5A03C0405C01C04C5E642FCE010E942B +:105110008327CE01DF91CF910C947527DF91CF913A +:1051200008951F93CF93DF93FC0123812130A1F4D5 +:10513000162FEC010E94A426CE010E949E26612F0C +:10514000CE010E94CA26CE010E94A026CE01DF9188 +:10515000CF911F910C947527DF91CF911F910895E6 +:10516000FF920F931F93CF93DF938C0161114FC078 +:10517000C0E084E1F82ED0E2DC0F8C2F6F2D0E946E +:10518000603A911105C040E0682FC8010E94712863 +:105190006D2FC8010E949128C8010E947527CF5F1A +:1051A000C03549F78BE298E09F938F930E9443416B +:1051B000F80183810F900F90813049F488E298E0E4 +:1051C0009F938F930E9443410F900F9010C0282F00 +:1051D000082E000C330B3F938F938EE198E09F9342 +:1051E0008F930E9443410F900F900F900F9061E0BA +:1051F00070E080E090E00E94170A0196C1F364EF2E +:1052000071E080E090E00E94170A80E009C08AE126 +:1052100098E09F938F930E9443410F900F908FEFE0 +:10522000DF91CF911F910F91FF9008950F931F93DE +:10523000CF93DF93EC018B01F80161918F0166231D +:1052400039F08B81813021F4CE010E949128F4CF76 +:10525000DF91CF911F910F9108958BB18F708BB912 +:105260008AB1806F8AB908958AB18F708AB98BB17B +:105270008F708BB908958130910549F030F08230FC +:10528000910539F0039739F008955C9A08955D9A75 +:1052900008955E9A08955F9A0895CB0141110C9488 +:1052A0003B296130710551F038F06230710541F0F1 +:1052B0006330710539F008955C9808955D980895FC +:1052C0005E9808955F9808956130710559F038F03F +:1052D0006230710551F06330710559F008959BB14A +:1052E00080E105C09BB180E202C09BB180E48927C8 +:1052F00002C08BB180588BB90895CB010C943B2927 +:1053000040E00C944D29CF936031E8F5C62FC3706F +:10531000C23091F0C330B9F0C13039F063E070E0D1 +:105320000E94802980E090E014C060E070E00E945C +:10533000802981E090E00DC061E070E00E9480294A +:1053400082E090E006C062E070E00E94802983E085 +:1053500090E00E943B296C2F70E06F5F7F4F7F933E +:105360006F938DE498E09F938F930E94434164EF85 +:1053700071E080E090E00E94170A0F900F900F906C +:105380000F9080E001C08FEFCF9108950895FC0148 +:1053900012821092C8001092C9001092CA00109296 +:1053A000CD001092CC005A9884B18C7F84B985B11D +:1053B0008C7F85B908952F923F924F925F926F92A2 +:1053C0007F928F929F92AF92BF92CF92DF92EF9295 +:1053D000FF920F931F93CF93DF9300D000D0CDB7F0 +:1053E000DEB79C838B83611121C0289A299884B1F0 +:1053F000836084B95A9A82E08093C80088E98093D8 +:10540000C90086E08093CA001092CD008BE980939A +:10541000CC0081E0EB81FC81828386E399E09F935D +:105420008F930E9443410F900F903DC18FEF860FE5 +:10543000843008F06EC0633039F0643041F062307F +:1054400051F41EE801E009C015E500E002C01AEAC7 +:1054500001E0F12C04C011E000E0FF24F3941F925E +:105460001F931F92FF921F920F9387E199E09F93E2 +:105470008F930E9443410FB6F894DEBF0FBECDBF9D +:10548000FF2011F0289A01C02898002311F0299AD2 +:1054900001C02998EBE2F1E03197F1F700C000007C +:1054A000EB81FC8113821093CE0087EB9BE0019788 +:1054B000F1F700C000008381882389F084811F9266 +:1054C0008F9387E099E09F938F930E944341EB81F4 +:1054D000FC8113820F900F900F900F9008C086EF01 +:1054E00098E09F938F930E9443410F900F908CED13 +:1054F00098E09F938F930E9443410F900F906FEF1E +:105500007FEFCB010E94170A0196C9F32998289AC8 +:10551000CAC0653009F0BDC08FE998E09F938F93B2 +:105520000E944341299A28988BE291E00197F1F774 +:1055300000C000000F900F9081E9282E88E0382EDF +:1055400099E8492E98E0592E2BE7622E28E0722E1A +:1055500039E7832E38E0932E46E7E42E48E0F42E18 +:105560005EE6C52E58E0D52E62E6A62E68E0B62E81 +:10557000299AEB81FC81138200E711E0F801809108 +:10558000C80080648093C80081918093CE00809190 +:10559000C80085FFFCCF21E0E837F20781F7809152 +:1055A000C80086FFFCCF29983F922F920E9443416A +:1055B0000F900F90F80181918F011F928F935F924E +:1055C0004F920E9443410F900F900F900F90F1E087 +:1055D00008371F0779F764E670E080E090E00E94EA +:1055E000170A9A8389837F926F920E9443410F909A +:1055F0000F90EB81FC818381882311F010E01FC0A4 +:105600009F928F920E9443410F900F901DC01830BF +:1056100031F4FF92EF920E9443410F900F90EB8183 +:10562000FC81E10FF11D84811F928F93DF92CF9255 +:105630000E9443411F5F0F900F900F900F90EB81DE +:10564000FC818381181718F3EB81FC818381803101 +:1056500090F082899189208937853F932F939F937A +:105660008F93BF92AF920E9443410F900F900F9083 +:105670000F900F900F9089819A810196A1F468EEA6 +:1056800073E080E090E00E94170A019609F470CF61 +:105690000AC08EE598E09F938F930E9443410F903C +:1056A0000F908FEF07C064EF71E080E090E00E9400 +:1056B000170A80E00F900F900F900F90DF91CF911D +:1056C0001F910F91FF90EF90DF90CF90BF90AF9020 +:1056D0009F908F907F906F905F904F903F902F9012 +:1056E0000895FC012381203130F431E0320F3383FF +:1056F000E20FF11D64830895579810927C00109278 +:105700007A0014BC15BC24B1277E24B91398FC017F +:105710001282089580B183FB882780F991E0892760 +:1057200008952C9808952C9A0895CF93DF93EC0157 +:10573000579A80E680937C0087E880937A0083E81C +:1057400084BD84E085BD84B1886184B9139ACE019B +:105750000E94932B81E08A83DF91CF9108952F924D +:105760003F924F925F926F927F928F929F92AF92F1 +:10577000BF92CF92DF92EF92FF920F931F93CF933E +:10578000DF936111E1C0EC0187EC99E09F938F9367 +:105790000E9443410F900F9087EB482E89E0582ECE +:1057A00093EA692E99E0792E04E919E02AE8E22EBD +:1057B00029E0F22E3FE7C32E39E0D32E43E7A42E93 +:1057C00049E0B42E52E4252E59E0352E6BE5862EA5 +:1057D00069E0962E6AE070E080E090E00E94170A8F +:1057E000019609F0B3C080B183FB882780F91F922E +:1057F0008F938CEB99E09F938F930E9443410F907E +:105800000F900F900F90CE01039905C00E94912B2D +:105810005F924F9206C00E94932B82EB99E09F9378 +:105820008F930E9443410F900F9080917A00806483 +:1058300080937A0080917A0086FDFCCF8091790078 +:105840001F928F937F926F920E94434182EE8093CA +:105850007C008091790090E005970F900F900F9059 +:105860000F9097FF02C080E090E0809587BD1F9267 +:105870008F931F930F930E94434180917A0080641D +:1058800080937A000F900F900F900F9080917A0084 +:1058900086FDFCCF809179001F928F93FF92EF924B +:1058A0000E94434190E690937C0083B182FB88275D +:1058B00080F91F928F93DF92CF920E94434183B170 +:1058C00081701F928F93BF92AF920E944341F894D0 +:1058D0006B817C8178948DB79EB70C960FB6F89447 +:1058E0009EBF0FBE8DBF6115710519F17F936F9338 +:1058F00080E090E00E94A33D9B01AC0160E070E07D +:1059000080E792E40E94F53C27E137EB41ED58E354 +:105910000E94F53C0E94673D7F936F939F928F9208 +:105920000E9443410F900F900F900F900F900F9097 +:1059300051CF1F921F923F922F920E9443410F908E +:105940000F900F900F9046CF8FEF01C080E0DF9156 +:10595000CF911F910F91FF90EF90DF90CF90BF906C +:10596000AF909F908F907F906F905F904F903F90FF +:105970002F90089583B182FB882780F991E08927D1 +:10598000089583B1817008958BB180588BB90895C3 +:105990001F93CF93DF93EC0123B18091DB049091AF +:1059A000DC04122F117020FD1BC02091DF04222384 +:1059B00009F12091DD043091DE0423303105D0F06F +:1059C000820F931F9C838B831092DE041092DD0460 +:1059D0001092DC041092DB04CE010E94C42C0AC099 +:1059E000811520E4920748F501969093DC0480939A +:1059F000DB040DC08091DD049091DE04811520E46C +:105A00009207F0F401969093DE048093DD04809178 +:105A1000DB049091DC048115904438F48091DD041E +:105A20009091DE048115904410F01C821B8210932B +:105A3000DF04DF91CF911F91089580E090E4D5CFEE +:105A400080E090E4E0CFE4E6F0E080818470808341 +:105A5000179A0F9A2C9A84B1806B84B926988CB5CA +:105A600083658CBD0895269884B18F7584B90F988D +:105A700017981CBC089517980895179A08950F93C6 +:105A80001F93CF93DF93EC01062F142F0E943B2D21 +:105A900080E48EBD0DB407FEFDCF0EBD0DB407FE34 +:105AA000FDCF1EBD0DB407FEFDCFCE010E943D2DE2 +:105AB00084E18A95F1F780E0DF91CF911F910F91FA +:105AC00008951F93CF93DF93EC01162F0E943B2D77 +:105AD00081E48EBD0DB407FEFDCF1EBD0DB407FEE3 +:105AE000FDCF1EBC0DB407FEFDCFCE010E943D2DA3 +:105AF0008EB5DF91CF911F910895CF93DF93C42F7F +:105B0000D22F1F924F931F926F938AE59AE09F9333 +:105B10008F930E9443410F900F900F900F900F9022 +:105B20000F90CD1769F083E59AE09F938F930E94C1 +:105B300043410F900F90CF3F59F488E39AE002C0A1 +:105B400084E39AE09F938F930E9443410F900F90BC +:105B500082E39AE09F938F930E9443410F900F90AE +:105B6000DF91CF9108952F923F924F925F926F9263 +:105B70007F928F929F92AF92BF92CF92DF92EF92DD +:105B8000FF920F931F93CF93DF936111D8C0EC0165 +:105B900083E2282E8AE0382ECC24C394D12C2EE028 +:105BA000422E2AE0522E39EF632E39E0732E44EE56 +:105BB000A42E49E0B42E5FEC852E59E0952E64EFBB +:105BC00071E080E090E00E94170A019609F0B9C0E8 +:105BD0003F922F920E9443410F900F90E12CF12CA5 +:105BE00086010E2C01C0000F0A94EAF7402F409561 +:105BF00060E0CE010E943F2D402F62E1CE010E9465 +:105C00003F2DFF92EF925F924F920E94434162E1DB +:105C1000CE010E94612D202F482F62E1CE010E940B +:105C20007D2D68EC70E080E090E00E94170A40E073 +:105C300062E1CE010E943F2DFF92EF927F926F9220 +:105C40000E94434162E1CE010E94612D20E0482F75 +:105C500062E1CE010E947D2D4FEF60E0CE010E94F7 +:105C60003F2D68EC70E080E090E00E94170A8FEF13 +:105C7000E81AF80A8DB79EB708960FB6F8949EBF3B +:105C80000FBE8DBF98E0E916F10409F0A9CF00E03E +:105C900010E07601002E01C0EE0C0A94EAF74E2DBA +:105CA000409561E0CE010E943F2D4E2D63E1CE0173 +:105CB0000E943F2D1F930F93BF92AF920E944341CA +:105CC00063E1CE010E94612D2E2D482F63E1CE01AC +:105CD0000E947D2D68EC70E080E090E00E94170A41 +:105CE00040E063E1CE010E943F2D1F930F939F92EE +:105CF0008F920E94434163E1CE010E94612D20E01A +:105D0000482F63E1CE010E947D2D4FEF61E0CE016F +:105D10000E943F2D68EC70E080E090E00E94170A3E +:105D20000F5F1F4F8DB79EB708960FB6F8949EBFB2 +:105D30000FBE8DBF0830110509F0ABCF40CF8FEFFC +:105D400001C080E0DF91CF911F910F91FF90EF9004 +:105D5000DF90CF90BF90AF909F908F907F906F908B +:105D60005F904F903F902F90089580E480937C0047 +:105D700087E880937A00089510927C0010927A0050 +:105D800008950F931F93CF93DF9361113AC08CE96D +:105D90009AE09F938F930E9443410F900F9007E8E2 +:105DA0001AE0CAE7DAE06AE070E080E090E00E9482 +:105DB000170A019641F51F930F930E94434180916A +:105DC0007A00806480937A000F900F9080917A001F +:105DD00086FDFCCF20917800309179008091780089 +:105DE000909179003F932F939F938F93DF93CF935D +:105DF0000E9443410F900F900F900F900F900F90C3 +:105E0000D2CF8FEF01C080E0DF91CF911F910F9132 +:105E1000089582E480937C0087E880937A00089557 +:105E200010927C0010927A000895AF92BF92CF92A8 +:105E3000DF92EF92FF920F931F93CF93DF93611145 +:105E40007FC085EE9AE09F938F930E9443410F900D +:105E50000F9030EDE32E3AE0F32E03EC1AE0C3EAA4 +:105E6000DAE06AE070E080E090E00E94170A0196B4 +:105E700009F068C0FF92EF920E94434180917A003E +:105E8000806480937A000F900F9080917A0086FD55 +:105E9000FCCF20917800309179008091780090912A +:105EA00079003F932F939F938F931F930F930E949B +:105EB0004341609178007091790080E090E00E9409 +:105EC000A33D2AE939E941E852E40E94F53C2DEC72 +:105ED0003CEC4CE05FE30E94893CD62EC72EB82EE6 +:105EE000A92EA6019501652F742F832F922F0E9452 +:105EF0006E3D862F90E061701F926F9381FB222789 +:105F000020F91F922F9382FB222720F91F922F93B3 +:105F100023E0959587952A95E1F79F938F93AF920C +:105F2000BF92CF92DF92DF93CF930E9443418DB710 +:105F30009EB744960FB6F8949EBF0FBE8DBF91CF0B +:105F40008FEF01C080E0DF91CF911F910F91FF9003 +:105F5000EF90DF90CF90BF90AF900895442371F001 +:105F60006130710539F020F06230710529F0089533 +:105F700028980895299808952A9808956130710500 +:105F800039F020F06230710529F00895289A0895BB +:105F9000299A08952A9A08956130710541F020F0F8 +:105FA0006230710539F0089595B181E005C095B171 +:105FB00082E002C095B184E0892785B9089541E067 +:105FC0000C94AE2F40E00C94AE2FCF93DF93EC01F6 +:105FD00060E070E00E94E22F61E070E0CE010E947C +:105FE000E22F62E070E0CE010E94E22F84B1876070 +:105FF00084B9DF91CF910895CF93DF93EC0160E0F6 +:1060000070E00E94E22F61E070E0CE010E94E22F7A +:1060100062E070E0CE010E94E22F84B1887F84B9F3 +:10602000DF91CF910895CF93DF93EC01613009F4B4 +:106030003FC058F1623009F44EC0633009F064C0CB +:1060400060E070E00E94DF2F61E070E0CE010E940E +:10605000DF2F62E070E0CE010E94DF2F8BEE9AE02E +:106060009F938F930E94434168EB7BE080E090E038 +:106070000E94170A60E070E0CE010E94E22F61E00A +:1060800070E0CE010E94E22F36C060E070E00E9416 +:10609000DF2F8AEF9AE09F938F930E94434168EB32 +:1060A0007BE080E090E00E94170A60E070E025C08D +:1060B00061E070E00E94DF2F84EF9AE09F938F935E +:1060C0000E94434168EB7BE080E090E00E94170A69 +:1060D00061E070E012C062E070E00E94DF2F8FEE9E +:1060E0009AE09F938F930E94434168EB7BE080E0AE +:1060F00090E00E94170A62E070E0CE010E94E22F59 +:106100000F900F9080E001C08FEFDF91CF91089545 +:1061100047983F9AE8EBF0E02DE020832CE12083C4 +:1061200024E6208324E02093BC0021E0FC012483AA +:106130000895FC01148284E08093BC001092B800A2 +:10614000089589E99DE00895ECEBF0E08081806896 +:1061500080830895862F8695869586958E71982FD3 +:10616000990F990F890F6F70860F08950F931F93E2 +:10617000CF93DF938C01EA019E859C7F92609E877E +:1061800081E0611101C080E09E8580FB97F99E87C8 +:106190006F87998180FB90F99B7F98609983662334 +:1061A00089F01F929F931F926F938DED9BE09F93B9 +:1061B0008F930E9443410F900F900F900F900F907C +:1061C0000F9008C08CEC9BE09F938F930E944341FB +:1061D0000F900F900E5F1F4F21E0AE014F5F5F4F9A +:1061E00061E0C8010E94E3078823A1F0AE01425F8D +:1061F0005F4F22E06EE0C8010E94E307C82F8823AA +:1062000049F089EC9BE09F938F930E9443410F904C +:106210000F9009C083EC9BE09F938F930E944341B2 +:106220000F900F90C0E08C2FDF91CF911F910F91B5 +:106230000895CF92DF92EF92FF920F931F93CF9327 +:10624000DF937C01EA01479B10C084EB9BE09F93A6 +:106250008F930E9443413F9A4798AE0160E0C70187 +:106260000E94B6300F900F905CC082EB9BE09F9332 +:106270008F930E9443410F900F9009E010E080E758 +:10628000C82E8BE0D82E1F930F93DF92CF920E94DF +:10629000434168EE73E080E090E00E94320A0F9084 +:1062A0000F900F900F900130110531F0015011093E +:1062B0008F3F2FEF920739F34B9799F1AE016AE0C8 +:1062C000C7010E94B630898188608B7F8160898395 +:1062D000AE014F5F5F4F21E061E0C70102960E946F +:1062E000E3078CE59BE09F938F930E9443413F9A85 +:1062F000479A87E99AE30197F1F700C000003F98B9 +:10630000479868E873E180E090E00E94320A8AE2F0 +:106310009BE09F938F930E9443410F900F900F90AB +:106320000F9081E0DF91CF911F910F91FF90EF903F +:10633000DF90CF9008958F929F92AF92BF92CF92AD +:10634000DF92EF92FF920F931F93CF93DF93CDB71E +:10635000DEB727970FB6F894DEBF0FBECDBF4C0156 +:10636000362FCA011E2DFC2DEA2DBA01605D774043 +:1063700051E06536710508F450E04E8150FB47F955 +:106380004E8364E670E00E947A3A6AE00E94603AC6 +:106390008295807F982B9F8337FF02C0395FFCCFA7 +:1063A000373014F03750FCCF37708D81887F382B11 +:1063B0003D83121614F0245FFCCF2D3014F02C50C6 +:1063C000FCCF822F6AE00E946C3A9F702E81207F62 +:1063D000922B80FB94F99E83101614F0015EFCCF83 +:1063E000003214F00F51FCCF802F6AE00E946C3A0B +:1063F0009F703C81307C8370282F2295207F832FD3 +:10640000892B822B8C8317FF02C0185EFCCF1831BA +:1064100014F01851FCCF812F6AE00E946C3A9F70F3 +:106420003B81307C8370282F2295207F832F892BFE +:10643000822B8B83F7FF02C0F45CFCCFFC3314F09B +:10644000FC53FCCF8F2F6AE00E946C3A9F703A8118 +:1064500030788770282F2295207F832F892B822BDD +:106460008A83E7FF02C0E45CFCCFEC3314F0EC530A +:10647000FCCF8E2F6AE00E946C3A9F703981307891 +:106480008770282F2295207F832F892B822B898349 +:10649000CE0107969F938F9301979F938F930197B8 +:1064A0009F938F9301979F938F9301979F938F93C0 +:1064B00001979F938F938E010F5F1F4F1F930F9331 +:1064C00088E09BE09F938F930E94434178015E0197 +:1064D00088E0A80EB11C0FB6F894DEBF0FBECDBF8A +:1064E00082E0C82E8BE0D82EF70181917F011F92A8 +:1064F0008F93DF92CF920E9443410F900F900F90A5 +:106500000F90AE14BF0481F727E0A80162E0C40138 +:1065100002960E94E30727960FB6F894DEBF0FBEDF +:10652000CDBFDF91CF911F910F91FF90EF90DF9042 +:10653000CF90BF90AF909F908F9008952F923F92F1 +:106540004F925F926F927F928F929F92AF92BF9283 +:10655000CF92DF92EF92FF920F931F93CF93DF932F +:10656000CDB7DEB76E970FB6F894DEBF0FBECDBFC6 +:10657000611166C22C019C012E5F3F4F3D8F2C8F15 +:1065800061E5C9010E946007CE0101969A8F898F4B +:1065900080E1E98DFA8D11928A95E9F783E89DE013 +:1065A0009F938F930E9443418A8181608A8342E056 +:1065B000BE016F5F7F4F8C8D9D8D0E9438080F90BC +:1065C0000F90811103C087EE91E002C082EE91E04E +:1065D0009F938F930E9443410F900F908AE79DE015 +:1065E0009F938F930E94434182E69DE09F938F93F8 +:1065F0000E94434180E49DE09F938F930E9443411A +:106600008AE29DE09F938F930E94434180E19DE049 +:106610009F938F930E9443418AEF9CE09F938F93B7 +:106620000E94434183EE9CE09F938F930E944341DD +:106630008EEC9CE09F938F930E94434188EB9CE0FB +:106640009F938F930E94434180EA9CE09F938F9396 +:106650000E94434187E89CE09F938F930E944341AF +:106660000FB6F894DEBF0FBECDBF188E88E69CE053 +:106670009F938F930E94434100E19E012F5F3F4F04 +:1066800041E0BE01685E7F4F8C8D9D8D0E94800829 +:106690000F900F90811110C087EE91E09F938F9320 +:1066A0000E94434168EE73E080E090E00E94320A6D +:1066B0004C010F900F90BDC127E030E047E050E063 +:1066C000BE016D5F7F4FCE0141960E94A3409E01A7 +:1066D0002F5F3F4F790110E0812F837041F486E6F0 +:1066E0009CE09F938F930E9443410F900F90F7017E +:1066F00081917F011F928F9320E63CE03F932F937F +:106700000E9443411F5F0F900F900F900F90103128 +:1067100019F78E8987FD03C040ED57E002C044E3BE +:1067200058E08F89982F9695969596959E71292F6A +:10673000220F220F920F8F70890F1A01280E311C21 +:106740008E89982F9695969596959E71792E770CB1 +:10675000770C790E8F70780E672C8C89982F969510 +:10676000969596959E71B92EBB0CBB0CB90E8F7089 +:10677000B80EBB8E8B89982F9695969596959E719F +:10678000D92EDD0CDD0CD90E8F70D80EED2C8A8938 +:10679000982F9695969596959E71F92EFF0CFF0C65 +:1067A000F90E8F70F80ECF2C8989182F1695169533 +:1067B00016951E71912F990F990F190F8F70180F41 +:1067C000A12E0D890E8F073048F4E3E00E02C001C0 +:1067D00011249C012E55324F490104C03DE5832E02 +:1067E0003CE0932E86E59CE09F938F930E9443416B +:1067F0009F928F920E944341812F012E000C990B92 +:106800009F931F938F2D0F2C000C990B9F93FF923A +:106810008D2D0D2C000C990B9F93DF928B2D0B2C43 +:10682000000C990B9F93BF92872D072C000C990B9E +:106830009F937F923F922F92802F002E000C990BF6 +:106840009F930F9323E33CE03F932F930E94434198 +:1068500088891F928F93E3E2FCE0FF93EF930E94FD +:10686000434168EE73E080E090E00E94320A4C0100 +:106870000FB6F894DEBF0FBECDBF94E68916910423 +:1068800009F490C0F4F5FEE48F16910409F494C065 +:106890008CF438E48316910409F487C08DE48816DB +:1068A000910409F47BC094E48916910409F0C1C0F5 +:1068B000BA9479C0E7E58E16910409F485C044F4D2 +:1068C00023E58216910409F0B4C0AA24AA9478C0E2 +:1068D00039E58316910409F45AC083E688169104B9 +:1068E00009F0A7C08AE0A82E9CE0C92E21E1E22E83 +:1068F00000E128E048EE57E065E0C2010E949B31CC +:1069000098C090E789169104D1F194F4FDE68F16B2 +:10691000910409F440C02EE68216910409F449C09E +:1069200038E68316910409F084C0EE24E3943FC056 +:1069300084E788169104B1F044F4E3E78E169104DD +:1069400009F077C0AA24A3943BC0F7E78F169104FF +:10695000C9F129E78216910409F06BC03FEF231AB1 +:10696000330A34C08F8587FD02C06AE001C060E051 +:10697000AE014F5F5F4FC2010E94B6305AC0AE01F8 +:106980004F5F5F4F6AE0C2010E94193152C081E03F +:10699000281A31081BC06624639402C066246A94D6 +:1069A000670C14C0B394BB8E11C0EE24EA94ED0CB6 +:1069B0000DC0CC24C39402C0CC24CA94CF0C06C012 +:1069C000A10E04C00F5F01C001500E8F8A2D0A2C4A +:1069D000000C990B9F93AF928C2D0C2C000C990BF3 +:1069E0009F93CF928E2D0E2C000C990B9F93EF92BC +:1069F000EB8D8E2F0E2E000C990B9F93EF93862D0F +:106A0000062C000C990B9F936F923F922F922EEFC2 +:106A10003BE03F932F930E9443410B8D262DA10114 +:106A20006E8DC2010E949B310FB6F894DEBF0FBE7F +:106A3000CDBF9BE18916910409F017CE80E001C01B +:106A40008FEF6E960FB6F894DEBF0FBECDBFDF910D +:106A5000CF911F910F91FF90EF90DF90CF90BF905B +:106A6000AF909F908F907F906F905F904F903F90EE +:106A70002F90089560FF02C0289A01C0289861FFF6 +:106A800002C0299A01C0299862FF02C02A9A01C057 +:106A90002A9863FF02C02B9A01C02B9864FF02C0A2 +:106AA0002C9A01C02C9865FF02C02D9A01C02D9828 +:106AB00066FF02C02E9A01C02E9867FF02C02F9A6F +:106AC00001C02F9880918604813019F0823061F0E6 +:106AD000089570FF02C05E9A01C05E9871FF02C007 +:106AE0005F9A08955F98089570FF02C0129A01C0DE +:106AF000129871FF02C0139A089513980895809117 +:106B00008604813019F08230B1F0089560FF02C030 +:106B1000109A01C0109861FF02C0119A01C011982B +:106B200062FF02C0129A01C0129863FF02C0139A5A +:106B300008951398089560FF02C05C9A01C05C98A4 +:106B400061FF02C05D9A01C05D9862FF02C05E9A5B +:106B500001C05E9863FF02C05F9A08955F98089530 +:106B6000CF93DF93EC0160E070E00E943A3560E083 +:106B7000CE010E947F358FEF84B9809186048130E9 +:106B800041F0823061F481B18E6081B98AB1806F49 +:106B900005C081B18F6081B98AB1806E8AB9DF91F9 +:106BA000CF910895CF93DF93EC0160E070E00E94F5 +:106BB0003A3560E0CE010E947F3514B8809186049A +:106BC000813041F0823061F481B1817F81B98AB135 +:106BD0008F7005C081B1807F81B98AB18F718AB908 +:106BE000DF91CF91089580918604813019F0823031 +:106BF00039F00895662311F05D9808955D9A08951F +:106C0000662311F011980895119A0895CF92DF929A +:106C1000EF92FF920F931F93CF93DF937C0161114B +:106C200017C06FE00E947F356FEF73E0C7010E94CD +:106C30003A3561E0C7010E94F33583EE9DE09F93F2 +:106C40008F930E94434160ED77E080E090E028C0A0 +:106C5000613069F48FED9DE09F938F930E944341D3 +:106C600068EE73E080E090E00E94170A20C0623076 +:106C700039F460E071E00E943A3586ED9DE008C08D +:106C80006330C1F460E072E00E943A358DEC9DE023 +:106C90009F938F930E94434168EE73E080E090E001 +:106CA0000E94170A60E070E0C7010E943A350F9019 +:106CB0000F9044C0643208F043C0C62FD0E0249740 +:106CC0008E0183E0159507958A95E1F7C770DD275A +:106CD000CC24C394D12CB601002E01C0660F0A94B7 +:106CE000EAF7C7010E947F350C2E02C0CC0CDD1CD8 +:106CF0000A94E2F7B601C7010E943A35DF92CF92BB +:106D0000CC0FDD1FC05EDE4F89818F9388818F930A +:106D10001F930F9388EB9DE09F938F930E944341B5 +:106D200060E971E080E090E00E94170A8DB79EB79D +:106D300008960FB6F8949EBF0FBE8DBF80E001C0CD +:106D40008FEFDF91CF911F910F91FF90EF90DF9028 +:106D5000CF90089581B1807F81B982B18F6082B96F +:106D6000089582B1807F82B981B1807F81B9089511 +:106D70006130710581F058F06230710581F0633047 +:106D80007105A1F480B183FB882780F90CC080B124 +:106D900080958170089580B18695817004C080B11E +:106DA00082FB882780F991E08927089580E0089583 +:106DB0000F931F93CF93DF93603108F04EC08C0187 +:106DC000C62FC695C695D0E06370613021F0633060 +:106DD00009F44BC021C0BE010E94B836811145C0E4 +:106DE000CE0101969F938F9389EF9DE09F938F93A0 +:106DF0000E9443410F900F900F900F90BE01C80169 +:106E00000E94B83681112BC060E070E0CB010E9477 +:106E1000170A019621F5F2CFBE010E94B8368823E9 +:106E200021F1CE0101969F938F938BEE9DE09F936E +:106E30008F930E9443410F900F900F900F90BE01CF +:106E4000C8010E94B836882351F060E070E0CB01A1 +:106E50000E94170A019619F4F2CF8FEF07C06AE07B +:106E600070E080E090E00E94170A80E0DF91CF910F +:106E70001F910F910895CF93C82F8A3019F48DE098 +:106E80000E943B378091C80085FFFCCFC093CE00A5 +:106E900080E090E0CF9108955A9A22E02093C800B4 +:106EA00028E92093C90026E02093CA001092CD0063 +:106EB0002CE02093CC0020E331E03093E5042093D4 +:106EC000E40421E0FC0122830895FC011282109267 +:106ED000C8001092C9001092CA001092CD00109202 +:106EE000CC001092E5041092E40408950F931F93D0 +:106EF000CF93DF93611122C00BE21EE0CBE0DEE016 +:106F00001F930F930E944341DF93CF938091E50439 +:106F10008F938091E4048F930E94EC4068E873E1C2 +:106F200080E090E00E94170A0F900F900F900F9052 +:106F30000F900F90019621F380E001C08FEFDF9159 +:106F4000CF911F910F910895862F6091E404709165 +:106F5000E5040C943B370F931F93CF93DF93EC0121 +:106F60008B0180EA91E099838883CE0104960E9488 +:106F70001F0CCE01CD960E946815CE0187589F4FF9 +:106F80000E945507CE0185589F4F0E94BB08FE0105 +:106F9000E057FF4F10821B830A83DF91CF911F912F +:106FA0000F910895CF93DF93CDB7DEB7AC970FB6AF +:106FB000F894DEBF0FBECDBF87B18C6987B988B1A9 +:106FC000837688B93D98459A82E08093C00098E91D +:106FD0009093C10096E09093C2001092C5009CE08F +:106FE0009093C4008093B0008093B10096E9909391 +:106FF000B3008093700080E191E09093E30480936C +:10700000E20482E091E09093E1048093E0047894BC +:1070100086E2EEE3F1E0DE01119601900D928A9591 +:10702000E1F70E94BC090DEE11E0FFEEEF2EF1E05A +:10703000FF2E6E0127E2C20ED11C1E013BE2230E81 +:10704000311C6EE6462E61E0562E73E2672E72E02A +:10705000772EE1E6AE2EE1E0BE2E1F930F930E9445 +:107060004341FF92EF920E94434188E192E09F9357 +:107070008F930E94434122E731E03F932F930E9478 +:107080004341ACE2B2E0BF93AF930E9443415F92B1 +:107090004F920E9443417F926F920E944341FF9220 +:1070A000EF920E944341809186049FEF980F0FB6A4 +:1070B000F894DEBF0FBECDBF9230C8F40E94AF0976 +:1070C0009F938F93BF92AF920E944341FF92EF92A2 +:1070D0000E9443411F930F930E9443418EE491E02D +:1070E0009F938F930E9443411CA61BA60DC01F9225 +:1070F0008F9381E391E09F938F930E9443410F9080 +:107100000F900F900F90FFCF0FB6F894DEBF0FBE19 +:10711000CDBF8BA59CA58331910548F5FC01EE0FF1 +:10712000FF1FA1E0B0E0AC0FBD1FEA0FFB1F808086 +:1071300091809F938F9328E231E03F932F930E9499 +:107140004341D401ED91FC910680F781E02DC4010B +:1071500009959F938F930E9443411F930F930E9421 +:1071600043418BA59CA501969CA78BA7CDCF89E118 +:1071700091E09F938F930E94434110925D0410927F +:107180005C044091E0045091E10464E070E0C601C9 +:107190000E94C0403F922F9288E791E09F938F9387 +:1071A000DF92CF920E9469410FB6F894DEBF0FBE06 +:1071B000CDBF019709F051CF8BA59CA583319105D7 +:1071C00008F04BCF880F991FE1E0F0E0EC0FFD1FB6 +:1071D000E80FF91FA080B18085E191E09F938F9324 +:1071E0000E944341D501ED91FC910680F781E02D8D +:1071F000C50109959F938F930E94434181E191E0DE +:107200009F938F930E9443418FEF9FEF90930101D3 +:1072100080930001D501ED91FC910280F381E02D76 +:10722000C50109950F900F900F900F900F900F9040 +:10723000812C912C3AE0632E31E0732E44244A9441 +:10724000542C9F928F927F926F920E944341D5015E +:10725000ED91FC910190F081E02D682DC50109951B +:107260000F900F900F900F9087FD18C08091000134 +:10727000909101014B9739F48FEF9FEF90930101AB +:10728000809300010BC05092010140920001BFEFBA +:107290008B1A9B0A2FEF8216910499F6D501ED9176 +:1072A000FC910480F581E02DC5010995CACE84ECDE +:1072B00091E090935B0480935A0481E492E0909370 +:1072C0005904809358048CE092E090935704809383 +:1072D000560484E292E090935404809353041092F5 +:1072E000550484EF91E0909352048093510482E915 +:1072F00091E090934E0480934D04109250041092AC +:107300004F0480E092E090934C0480934B048CED0A +:1073100091E09093470480934604109248041092A1 +:107320004A041092490488EE91E0909345048093BA +:10733000440488EB91E0909341048093400481E001 +:1073400090918604913009F480E080934204109279 +:1073500043048DE492E090933E0480933D041092A8 +:107360003F0480ED91E090932A04809329041092C9 +:107370002B0410922C048CEA91E0909325048093C6 +:107380002404109226048FEF9FEF9093280480939B +:10739000270460E070E083E993E00E94AB3761E08E +:1073A00070E082E093E00E94AB3762E070E081E73A +:1073B00092E00E94AB3788E192E090936B02809359 +:1073C0006A028CE692E00E94550710926E021092BB +:1073D000700210926F0286E891E0909361028093B0 +:1073E00060021092680221E030E03093670220933F +:1073F000660210926202109263021092640210926E +:107400006502909357028093560210925E0282E0CA +:1074100090E090935D0280935C021092580210926B +:10742000590210925A0210925B02089588E994E082 +:107430000E941F0C88E191E090939704809396043A +:107440009093950480939404909393048093920472 +:1074500008958EE296E0089582E198E0089589E427 +:1074600098E008958AE598E008958BE399E00895FF +:1074700089EC99E0089582E79AE008958EE99AE010 +:10748000089587EE9AE008958EEF9AE0089586EECB +:107490009DE0089584E09EE008958BE49EE00895C9 +:1074A000DB018F939F930E94AD3ABF91AF91A29F52 +:1074B000800D911DA39F900DB29F900D11240895F2 +:1074C000991B79E004C0991F961708F0961B881F36 +:1074D0007A95C9F78095089587FB082E062687FDC3 +:1074E000819567FD61950E94603A0EF4919507FCC5 +:1074F00081950895AA1BBB1B51E107C0AA1FBB1FA2 +:10750000A617B70710F0A61BB70B881F991F5A952F +:10751000A9F780959095BC01CD010895052E97FBA4 +:107520001EF400940E94A53A57FD07D00E94513CDA +:1075300007FC03D04EF40C94A53A50954095309535 +:1075400021953F4F4F4F5F4F0895909580957095CF +:1075500061957F4F8F4F9F4F08950E94793CA59F63 +:10756000900DB49F900DA49F800D911D112408953E +:10757000B7FF0C94AD3A0E94AD3A821B930B08956D +:10758000DF93CF931F930F939A9DF02D219FF00DC2 +:107590008B9DF00D8A9DE02DF10D039FF00D029F54 +:1075A000E00DF11D4E9DE00DF11D5E9DF00D4F9D16 +:1075B000F00D7F936F93BF92AF925F934F93D5017E +:1075C0000E94793C8B01AC01D7010E94793CEB0110 +:1075D000E80FF91FD6010E94103B2F913F91D60171 +:1075E0000E94793CC60FD71FE81FF91FAF91BF91CA +:1075F0000E94103B2F913F910E94793CC60FD71FEC +:10760000E81FF91FD6010E94793CE60FF71F980189 +:10761000BE01CF0111240F911F91CF91DF910895E9 +:107620000E94793C460F571FC81FD91F08F4319696 +:107630000895689401C0E894F92FF12B12F00C948E +:107640004D3BA0E0B0E0E7E2FBE30C94BF3B092E2A +:10765000059422F40E94A93B112392F4F0E80F262E +:10766000FFEFE094F09400951095B094C094D094FE +:10767000A194BF0ACF0ADF0AEF0AFF0A0F0B1F0B04 +:107680000E94583B07FC0E94A93BCDB7DEB7ECE057 +:107690000C94DB3B689401C0E8948F929F92CF9347 +:1076A000DF930E94583BDF91CF919F908F90089578 +:1076B00088249924F401E401B0E49F93AA279A1541 +:1076C0008B049C04ED05FE05CF05D007A10798F4B7 +:1076D000AD2FDC2FCF2FFE2FE92D982C892E982F40 +:1076E000872F762F652F542F432F322F2227B85004 +:1076F00031F7BF9127C01B2EBF91BB27220F331F2D +:10770000441F551F661F771F881F991F881C991CCF +:10771000EE1FFF1FCC1FDD1FAA1FBB1F8A149B0477 +:10772000EC05FD05CE05DF05A007B10748F08A1876 +:107730009B08EC09FD09CE09DF09A00BB10B216004 +:107740001A94E1F62EF49401AF01BE01CD01000CB4 +:1077500008956095709580959095309540955095D9 +:1077600021953F4F4F4F5F4F6F4F7F4F8F4F9F4F31 +:1077700008952F923F924F925F926F927F928F92D5 +:107780009F92AF92BF92CF92DF92EF92FF920F93B0 +:107790001F93CF93DF93CDB7DEB7CA1BDB0B0FB6BA +:1077A000F894DEBF0FBECDBF09942A883988488877 +:1077B0005F846E847D848C849B84AA84B984C8840D +:1077C000DF80EE80FD800C811B81AA81B981CE0F04 +:1077D000D11D0FB6F894DEBF0FBECDBFED010895E9 +:1077E0000F93083090F0982F872F762F652F542F06 +:1077F000432F322F22270850F4CF220F331F441F6C +:10780000551F661F771F881F991F0A95B2F70F91A2 +:10781000089597FB10F8169400080F93083098F01D +:107820000850232F342F452F562F672F782F892F5D +:10783000902DF4CF059497958795779567955795F3 +:107840004795379527950A95AAF70F9108952A0D20 +:107850003B1D4C1D5D1D6E1D7F1D801F911F0895DA +:107860000024A7FD00942A0F301D401D501D601DEF +:10787000701D801D901D08952A193B094C095D0952 +:107880006E097F09800B910B08950024A7FD0094D9 +:107890002A173005400550056005700580059005E4 +:1078A0000895A1E21A2EAA1BBB1BFD010DC0AA1F41 +:1078B000BB1FEE1FFF1FA217B307E407F50720F059 +:1078C000A21BB30BE40BF50B661F771F881F991FD4 +:1078D0001A9469F760957095809590959B01AC011D +:1078E000BD01CF010895EE0FFF1F0590F491E02D2B +:1078F0000994A29FB001B39FC001A39F700D811D89 +:107900001124911DB29F700D811D1124911D0895A8 +:107910005058BB27AA270E94A03C0C94453E0E94C9 +:10792000373E38F00E943E3E20F039F49F3F19F474 +:1079300026F40C94243E0EF4E095E7FB0C941E3ED6 +:10794000E92F0E94563E58F3BA176207730784075F +:10795000950720F079F4A6F50C94783E0EF4E095A6 +:107960000B2EBA2FA02D0B01B90190010C01CA01F9 +:10797000A0011124FF27591B99F0593F50F4503EA4 +:1079800068F11A16F040A22F232F342F4427585F96 +:10799000F3CF469537952795A795F0405395C9F7AE +:1079A0007EF41F16BA0B620B730B840BBAF0915066 +:1079B000A1F0FF0FBB1F661F771F881FC2F70EC005 +:1079C000BA0F621F731F841F48F4879577956795D8 +:1079D000B795F7959E3F08F0B0CF9395880F08F0C4 +:1079E0009927EE0F9795879508950E94093D0C946D +:1079F000453E0E943E3E58F00E94373E40F029F43A +:107A00005F3F29F00C941E3E51110C94793E0C946A +:107A1000243E0E94563E68F39923B1F3552391F317 +:107A2000951B550BBB27AA2762177307840738F0ED +:107A30009F5F5F4F220F331F441FAA1FA9F335D04A +:107A40000E2E3AF0E0E832D091505040E695001CFE +:107A5000CAF72BD0FE2F29D0660F771F881FBB1FB8 +:107A6000261737074807AB07B0E809F0BB0B802D96 +:107A7000BF01FF2793585F4F3AF09E3F510578F0C2 +:107A80000C941E3E0C94793E5F3FE4F3983ED4F391 +:107A9000869577956795B795F7959F5FC9F7880F96 +:107AA000911D9695879597F90895E1E0660F771FE8 +:107AB000881FBB1F621773078407BA0720F0621B79 +:107AC000730B840BBA0BEE1F88F7E09508950E94A4 +:107AD0006E3D6894B1110C94793E08950E945E3E0B +:107AE00088F09F5798F0B92F9927B751B0F0E1F07F +:107AF000660F771F881F991F1AF0BA95C9F714C02F +:107B0000B13091F00E94783EB1E008950C94783E37 +:107B1000672F782F8827B85F39F0B93FCCF3869567 +:107B200077956795B395D9F73EF4909580957095C4 +:107B300061957F4F8F4F9F4F089597FB16F40E94DA +:107B4000273E0C94E13DE89409C097FB3EF49095E4 +:107B50008095709561957F4F8F4F9F4F9923A9F026 +:107B6000F92F96E9BB279395F695879577956795B5 +:107B7000B795F111F8CFFAF4BB0F11F460FF1BC0F9 +:107B80006F5F7F4F8F4F9F4F16C0882311F096E98C +:107B900011C0772321F09EE8872F762F05C066233A +:107BA00071F096E8862F70E060E02AF09A95660FF3 +:107BB000771F881FDAF7880F9695879597F90895AC +:107BC000E894F92F96EBFF2381F0121613061406A2 +:107BD000440B9395F6958795779567955795404013 +:107BE000FF23B9F71BC099270895882351F49850B3 +:107BF000D2F7872B762F652F542F432F322F20E07B +:107C0000B1F3121613061406440B88233AF09A9522 +:107C1000440F551F661F771F881FCAF755234AF464 +:107C2000440F551F11F460FF04C06F5F7F4F8F4FEB +:107C30009F4F880F9695879597F9089597F99F67B5 +:107C400080E870E060E008959FEF80EC08959095E3 +:107C500080957095609550954095309521953F4F52 +:107C60004F4F5F4F6F4F7F4F8F4F9F4F08950024AF +:107C70000A941616170618060906089500240A9491 +:107C800012161306140605060895092E0394000C17 +:107C900011F4882352F0BB0F40F4BF2B11F460FFA6 +:107CA00004C06F5F7F4F8F4F9F4F089557FD9058CF +:107CB000440F551F59F05F3F71F04795880F97FBB0 +:107CC000991F61F09F3F79F087950895121613066A +:107CD0001406551FF2CF4695F1DF08C01616170699 +:107CE0001806991FF1CF86957105610508940895CE +:107CF000E894BB2766277727CB0197F908950E9460 +:107D0000923E0C94453E0E94373E38F00E943E3E23 +:107D100020F0952311F00C941E3E0C94243E112467 +:107D20000C94793E0E94563E70F3959FC1F3950FD7 +:107D300050E0551F629FF001729FBB27F00DB11DEF +:107D4000639FAA27F00DB11DAA1F649F6627B00D7F +:107D5000A11D661F829F2227B00DA11D621F739F68 +:107D6000B00DA11D621F839FA00D611D221F749F76 +:107D70003327A00D611D231F849F600D211D822FBD +:107D8000762F6A2F11249F5750409AF0F1F08823E4 +:107D90004AF0EE0FFF1FBB1F661F771F881F915011 +:107DA0005040A9F79E3F510580F00C941E3E0C9464 +:107DB000793E5F3FE4F3983ED4F3869577956795D7 +:107DC000B795F795E7959F5FC1F7FE2B880F911D3B +:107DD0009695879597F90895FA01EE0FFF1F309653 +:107DE00021053105A1F16115710561F48038BFE30A +:107DF0009B0749F168949038810561F08038BFEFA6 +:107E00009B0741F099234AF5FF3FE1053105210524 +:107E100019F1E8940894E795D901AA2329F4AB2F26 +:107E2000BE2FF85FD0F310C0FF5F70F4A695E0F7A7 +:107E3000F73950F019F0FF3A38F49F779F930DD03F +:107E40000F9007FC9058089546F00C94243E60E093 +:107E500070E080E89FE308954FE79F775F934F932B +:107E60003F932F930E9410402F913F914F915F912C +:107E70000E947F3E0C94493F0E947B3F880B990BE8 +:107E8000089529F416F00C941E3E0C94783E0C9440 +:107E9000243E0E945E3EA8F39638A0F707F80F92A2 +:107EA000E8942BE33AEA48EB5FE70E94953E0F9295 +:107EB0000F920F924DB75EB70F920E945840ECE7B9 +:107EC000F0E00E949F3F4F915F91EF91FF91E59508 +:107ED000EE1FFF1F49F0FE57E0684427EE0F441FD6 +:107EE000FA95E1F74195550B0E94D23F0F9007FE9E +:107EF0000C94C63F0895990F0008550FAA0BE0E8AF +:107F0000FEEF16161706E807F907C0F0121613065B +:107F1000E407F50798F0621B730B840B950B39F49B +:107F20000A2661F0232B242B252B21F408950A2601 +:107F300009F4A140A6958FEF811D811D0895DF935F +:107F4000CF931F930F93FF92EF92DF927B018C01EF +:107F5000689406C0DA2EEF010E94923EFE01E8947A +:107F6000A5912591359145915591A6F3EF010E9478 +:107F7000A03CFE019701A801DA9469F7DF90EF9029 +:107F8000FF900F911F91CF91DF9108959B01AC015C +:107F900060E070E080E89FE30C94F53C0C941E3E9A +:107FA0000C948C400E945E3ED8F39923C9F3940F41 +:107FB000511DA3F39150504094F059F0882332F0B2 +:107FC000660F771F881F91505040C1F79E3F5105A3 +:107FD0002CF7880F911D9695879597F908955F3F27 +:107FE000ACF0983E9CF0BB27869577956795B79542 +:107FF00008F4B1609395C1F7BB0F58F711F460FF17 +:10800000E8CF6F5F7F4F8F4F9F4FE3CF0C94793E48 +:1080100016F00C948C400C94243E68940C941E3EF4 +:108020000E945E3EA8F39923C1F3AEF3DF93CF9392 +:108030001F930F93FF92C92FDD2788232AF02197E2 +:10804000660F771F881FDAF720E030E040E85FEB2B +:108050009FE3883920F0803E38F021968F770E9488 +:10806000893CE4EAF0E004C00E94893CE1EDF0E0E4 +:108070000E949F3F8B01BE01EC01FB2E6F577109DF +:108080007595771F880B990B0E94A53D28E132E773 +:1080900041E35FE30E94923EAF2D9801AE01FF9055 +:1080A0000F911F91CF91DF910E94A03C0C94453E0F +:1080B000FA01DC01AA0FBB1F9B01AC01BF5728F4DA +:1080C000222733274427507820C0B75190F4AB2F94 +:1080D0000024469537952795011CA395D2F30020DF +:1080E00071F0220F331F441FB395DAF30ED00C94B6 +:1080F000883C61307105A0E88A07B94630F49B01DD +:10810000AC016627772788279078309621F0208366 +:1081100031834283538308959F3F31F0915020F47F +:10812000879577956795B795880F911D9695879553 +:1081300097F90895FB01DC0102C005900D924150B2 +:108140005040D8F70895FB01DC012150304030F059 +:1081500001900D920416C9F7CD010895882799273B +:108160000895FB01DC014150504048F001900D9210 +:108170000020C9F701C01D9241505040E0F708951A +:10818000A0E0B0E0E6ECF0E40C94C33BFA012381FC +:1081900020FD03C080E090E01AC016161706D4F741 +:1081A0007A018C01EB016C01C130D10569F0C70186 +:1081B0000E943A468F3FFFEF9F0761F3F6018193DC +:1081C0006F0121970A9781F7F6011082C801CDB798 +:1081D000DEB7E8E00C94DF3BA0E0B0E0E2EFF0E4D3 +:1081E0000C94C73B0F811885F801838188608383D5 +:1081F000AE01455F5F4F69857A85C8010E94824163 +:10820000F8012381277F2383E4E00C94E33B0F9361 +:108210001F93CF93DF93FB01238121FD03C08FEFD9 +:108220009FEF2CC022FF16C04681578124813581E3 +:108230004217530744F4A081B1819D012F5F3F4F46 +:10824000318320838C93268137812F5F3F4F378383 +:10825000268314C08B01EC01FB010084F185E02D25 +:108260000995892BE1F6D80116968D919C91179767 +:10827000019617969C938E931697CE01DF91CF911E +:108280001F910F910895A0E0B0E0E9E4F1E40C94AF +:10829000C73BAE01495F5F4FDA016D917D91AD0142 +:1082A00000EE14E0F80182819381DC0113962C9199 +:1082B0001397286013962C930E948241D80112963E +:1082C000ED91FC9113972381277F2383E4E00C94A5 +:1082D000E33BAEE0B0E0EFE6F1E40C94C93B85E0AF +:1082E0008C838B899C899A838983AE01495E5F4F19 +:1082F0006D897E89CE0101960E94FF442E96E2E0B0 +:108300000C94E53BABE0B0E0E8E8F1E40C94B93B59 +:108310006C017B018A01FC0117821682838181FF37 +:10832000CCC1CE0101963C01F6019381F70193FD8A +:10833000859193FF81917F01882309F4BAC1853229 +:1083400039F493FD859193FF81917F01853229F462 +:10835000B60190E00E940741E7CF912C212C312CEF +:10836000FFE1F315D8F08B3279F038F4803279F0F0 +:108370008332A1F4232D20611DC08D3261F0803342 +:1083800069F4232D216016C0832D8260382EE32DE1 +:10839000E4603E2E2AC0F32DF8601DC037FC2DC0CE +:1083A00020ED280F2A3040F08E32B9F436FC81C11E +:1083B000232D2064322E19C036FE06C08AE0989E16 +:1083C000200D1124922E11C0EAE02E9E200D1124C2 +:1083D000222EF32DF0623F2E08C08C3621F4832D1F +:1083E0008068382E02C0883641F4F70193FD8591EC +:1083F00093FF81917F018111B3CF982F9F7D955479 +:10840000933028F40C5F1F4F9FE399830DC0833690 +:1084100031F0833771F0833509F059C021C0F8017C +:10842000808189830E5F1F4F88248394912C530190 +:1084300013C02801F2E04F0E511CF801A080B1805A +:1084400036FE03C0692D70E002C06FEF7FEFC501FB +:108450000E942F464C018201F32DFF773F2E16C05C +:10846000280122E0420E511CF801A080B18036FEA6 +:1084700003C0692D70E002C06FEF7FEFC5010E945D +:1084800024464C01F32DF0683F2E820133FC1BC0C3 +:10849000822D90E088169906B0F4B60180E290E053 +:1084A0000E9407412A94F4CFF50137FC859137FEED +:1084B00081915F01B60190E00E94074121102A944A +:1084C00021E0821A91088114910471F7E8C0843682 +:1084D00011F0893641F5F80137FE07C060817181DE +:1084E000828193810C5F1F4F08C060817181072ECC +:1084F000000C880B990B0E5F1F4FF32DFF763F2E5C +:1085000097FF09C090958095709561957F4F8F4F2B +:108510009F4FF0683F2E2AE030E0A3010E94914671 +:10852000882E861845C0853731F4232D2F7EB22E34 +:108530002AE030E025C0932D997FB92E8F36C1F007 +:1085400018F4883579F0B5C0803719F0883721F0F4 +:10855000B0C0E92FE061BE2EB4FE0DC0FB2DF4606B +:10856000BF2E09C034FE0AC0292F2660B22E06C0D5 +:1085700028E030E005C020E130E002C020E132E038 +:10858000F801B7FE07C060817181828193810C5F21 +:108590001F4F06C06081718180E090E00E5F1F4F29 +:1085A000A3010E949146882E8618FB2DFF773F2E4F +:1085B00036FE0DC0232D2E7FA22E891458F434FED2 +:1085C0000BC032FC09C0832D8E7EA82E05C0B82CAE +:1085D000A32C03C0B82C01C0B92CA4FE0FC0FE010F +:1085E000E80DF11D8081803321F49A2D997EA92E0A +:1085F00009C0A2FE06C0B394B39404C08A2D867845 +:1086000009F0B394A3FC11C0A0FE06C0B21488F414 +:10861000280C922C9B180EC0B21460F4B60180E2B4 +:1086200090E00E940741B394F7CFB21418F42B18CE +:1086300002C0982C212CA4FE10C0B60180E390E06B +:108640000E940741A2FE17C0A1FC03C088E790E08A +:1086500002C088E590E0B6010CC08A2D867859F0FA +:10866000A1FE02C08BE201C080E2A7FC8DE2B60150 +:1086700090E00E940741891438F4B60180E390E04D +:108680000E9407419A94F7CF8A94F301E80DF11DF7 +:108690008081B60190E00E9407418110F5CF222031 +:1086A00009F442CEB60180E290E00E9407412A948C +:1086B000F6CFF6018681978102C08FEF9FEF2B9650 +:1086C000E2E10C94D53B20FD09C0FC0123FD05C06F +:1086D00022FF02C07383628351834083089544FD67 +:1086E00017C046FD17C0AB01BC01DA01FB01AA0FA0 +:1086F000BB1FEE1FFF1F1094D1F74A0F5B1F6E1FA9 +:108700007F1FCB01BA01660F771F881F991F09C011 +:1087100033E001C034E0660F771F881F991F315086 +:10872000D1F7620F711D811D911D08950F931F9345 +:10873000CF93DF938C01C8010E943A46EC0197FD6C +:1087400008C00E941046892BB1F7B801CE010E94E3 +:108750007846CE01DF91CF911F910F9108958F92AE +:108760009F92AF92BF92EF92FF920F931F93CF937E +:10877000DF938C01D62F7A01B22E0E943A469C01DB +:1087800033272B32310531F02D32310561F48B2D39 +:108790008068B82ED15011F480E068C0C8010E94F2 +:1087A0003A4697FDF9CFCB2DCD7F2B2D207309F5C0 +:1087B0008033F9F4AA24AA94AD0E09F443C0C80189 +:1087C0000E943A4697FD3EC09C012F7D33272835F5 +:1087D000310549F4C264D250A9F1C8010E943A4659 +:1087E00097FF07C02FC0B6FE02C0C26001C0C261C1 +:1087F000DA2D812C912C540120ED280F283080F0A7 +:10880000C4FF04C0B8010E94784619C02A3040F065 +:10881000C6FFF8CF2F7D3FEE320F363098F7275046 +:108820004C2FC501B4010E946F434B015C01C26033 +:10883000D15059F0C8010E943A4697FFDDCFC1FDE3 +:1088400004C0AACF812C912C5401C7FF08C0B0945A +:10885000A09490948094811C911CA11CB11C2C2F7D +:10886000B501A401C7010E94634381E0DF91CF916C +:108870001F910F91FF90EF90BF90AF909F908F90BE +:108880000895A0E2B0E0E7E4F4E40C94BC3B5C01A2 +:10889000962E7A01F9018E010F5F1F4F680180E269 +:1088A000D8011D928A95E9F7D50113968C9080E046 +:1088B00090E0612C712C30E061E070E083FC259148 +:1088C00083FE21918F01522E211103C080E090E0A0 +:1088D00092C02E3511F4009751F1432F50E0481704 +:1088E00059073CF42D3559F12D3219F4772009F14F +:1088F00003C0772009F46AC0452D469546954695F4 +:10890000D601A40FB11D452D47708B0102C0000F89 +:10891000111F4A95E2F7A8015C91452B4C93651411 +:1089200059F0561410F45394E7CF5A94E5CF31E040 +:1089300004C07724739401C0712C0196BFCF7720B7 +:1089400019F08E8180628E83311103C08824839454 +:1089500017C0F6019E012F5D3F4F80818095819366 +:108960002E173F07D1F7F2CFE114F10429F0D70118 +:108970008C93F70131967F019A94812C9920F9F01C +:10898000C5010E943A4697FD18C0FC01FF2723E06D +:10899000F595E7952A95E1F7EC0DFD1D208130E076 +:1089A000AC014770552702C0359527954A95E2F7E7 +:1089B00020FDDACFB5010E947846811087CFE114FF +:1089C000F10411F0D7011C92C80115C0422F469541 +:1089D00046954695D601A40FB11D422F47708B01D5 +:1089E00002C0000F111F4A95E2F7A8015C91452BC8 +:1089F0004C93622EA2CFA096EFE00C94D83BA0E05F +:108A0000B0E0E5E0F5E40C94BC3B6C01EB015A01ED +:108A1000FC0117821682512CF601E380FE01E3FC73 +:108A20008591E3FE8191182FEF01882309F4EEC0B0 +:108A300090E00E941046892B21F0C6010E949643C7 +:108A4000EBCF153241F4FE01E3FC1591E3FE1191E9 +:108A5000EF01153281F4C6010E943A4697FDD4C059 +:108A6000412F50E09C01332724173507A9F2B601A6 +:108A70000E947846CBC01A3239F4E3FC1591E3FE2C +:108A80001191EF0101E001C000E0F12C20ED210F78 +:108A90002A3080F402606F2D70E080E090E040E2C8 +:108AA0000E946F43F62EFE01E3FC1591E3FE119147 +:108AB000EF01ECCF01FF03C0F11003C0A7C0FF24FA +:108AC000FA94183619F01C3651F010C0FE01E3FC80 +:108AD0001591E3FE1191EF01183641F4086004602E +:108AE000FE01E3FC1591E3FE1191EF01112309F45E +:108AF0008DC0612F70E08EEF90E00E941946892BA7 +:108B000009F484C000FD07C0F50180809180C50193 +:108B100002965C0102C0812C912C1E3651F4F601A4 +:108B20004681578160E070E0202FC4010E946343BA +:108B300073CF1336A9F401FD02C0FF24F394C601DC +:108B40000E943A4697FD60C08114910429F0F40117 +:108B50008083C40101964C01FA94F110F0CF50C00B +:108B60001B3559F49E01A4016F2DC6010E9441449A +:108B7000EC01892B09F044C03EC0C6010E94964317 +:108B800097FD42C01F3661F128F4143639F11936C9 +:108B900051F128C0133771F0153701F123C081144A +:108BA000910429F0F4016082C40101964C01FA9409 +:108BB000FF2071F0C6010E943A463C0197FD08C0B3 +:108BC0000E941046892B59F3B601C3010E947846D2 +:108BD00081149104A9F0F401108212C0006203C054 +:108BE000006101C00064202FA4016F2DC6010E9406 +:108BF000AF43811105C0F6018381807329F406C05B +:108C000000FD0ACF539408CF552019F0852D90E030 +:108C100002C08FEF9FEFCDB7DEB7EFE00C94D83BEB +:108C200091110C94EF46803219F089508550C8F7A5 +:108C30000895FC010590061621F00020D9F7C00127 +:108C400008953197CF010895FC010590615070405F +:108C50000110D8F7809590958E0F9F1F0895FC0105 +:108C60006150704001900110D8F7809590958E0F5B +:108C70009F1F0895CF93DF93EC012B8120FF33C01A +:108C800026FF0AC02F7B2B838E819F8101969F83B5 +:108C90008E838A8190E029C022FF0FC0E881F9818C +:108CA0008081082E000C990B009719F420622B8309 +:108CB0001AC03196F983E8830EC0EA85FB850995D1 +:108CC00097FF09C02B81019611F080E201C080E17D +:108CD000822B8B8308C02E813F812F5F3F4F3F83C4 +:108CE0002E83992702C08FEF9FEFDF91CF910895D8 +:108CF000FB01238120FF12C026FD10C08F3F3FEFF4 +:108D0000930761F082832F7D20642383268137813E +:108D10002150310937832683992708958FEF9FEFDC +:108D20000895FA01AA27283051F1203181F1E89401 +:108D30006F936E7F6E5F7F4F8F4F9F4FAF4FB1E04E +:108D40003ED0B4E03CD0670F781F891F9A1FA11D49 +:108D5000680F791F8A1F911DA11D6A0F711D811D4A +:108D6000911DA11D20D009F468943F912AE0269F0F +:108D700011243019305D3193DEF6CF010895462F6E +:108D80004770405D4193B3E00FD0C9F7F6CF462F4F +:108D90004F70405D4A3318F0495D31FD40524193B8 +:108DA00002D0A9F7EACFB4E0A69597958795779575 +:108DB0006795BA95C9F700976105710508959B01FC +:108DC000AC010A2E06945795479537952795BA9585 +:108DD000C9F7620F731F841F951FA01D089599275F +:088DE00088270895F894FFCFE5 +:108DE800FFFF000000010000000000003D09000036 +:108DF80000000002000000005E09000000000303FC +:108E08002C022E02300232023402360238023A02B2 +:108E180000000002000000003B37000000005A0478 +:108E280058045604530451044D044B0446044404A6 +:108E380040043D04290424040203710293036A02D6 +:108E4800600256020A0427041704C507BA07B007C8 +:108E580001040000000271CB257800424D453238EC +:108E68003000000000004E209E21AB199A19000026 +:108E780000000B22F8210222293A3F0000000000DE +:108E8800D422AF22C6229E22000000002C26F625FE +:108E980014262C3A00000000B028EA2760282F3A50 +:108EA8000000000083292D293429323A00000000EF +:108EB800DB29C629C729353A00000000AF2B952BBE +:108EC8007C2B383A00000000B32D232D332D3B3A7C +:108ED80000000000C12EB52EBC2E3E3A0000000056 +:108EE800152F092F102F413A000000001330E52FED +:108EF800FC2F443A000000009E3288309930A1309F +:108F0800000000000636B035D235473A410042002D +:108F1800430044004500460047004450000000005C +:108F280000D836AA36B1364A3A0000000076374CE7 +:068F38003765374D3A00D9 +:00000001FF diff --git a/software/test-software/release/v2024-08-18_1103/test_2024-07-23_nano-644.elf b/software/test-software/release/v2024-08-18_1103/test_2024-07-23_nano-644.elf deleted file mode 100755 index 56055784ae148ab1eda6e966397a3f8c7f2126d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71992 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 diff --git a/software/test-software/src/main.cpp b/software/test-software/src/main.cpp index 35f309f..2a7faec 100644 --- a/software/test-software/src/main.cpp +++ b/software/test-software/src/main.cpp @@ -37,10 +37,35 @@ const char MAIN_CPP_TIME[] PROGMEM = __TIME__; const char MAIN_CPP_PART_NAME[] PROGMEM = "ATmega1284P"; #endif -const char PSTR_DIVIDER[] PROGMEM = "\n====================================\n "; +#ifndef F_CPU + #if defined(__AVR_ATmega328P__) + #define F_CPU 16000000L + #define BAUD_RATE 38400 + #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) + #define F_CPU 12000000L + #define BAUD_RATE 115200 + #else + #error missing defined for F_CPU + #endif +#endif + +#ifndef BAUD_RATE + #if defined(__AVR_ATmega328P__) + #define BAUD_RATE 38400 + #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) + #define BAUD_RATE 115200 + #else + #error missing define BAUD_RATE + #endif +#endif + +const char PSTR_DIVIDER[] PROGMEM = "\n=====================================\n "; const char PSTR_LINEFEED[] PROGMEM = "\n"; const char PSTR_ERROR[] PROGMEM = "ERROR"; const char PSTR_Done[] PROGMEM = "Done"; +// const char PSTR_HARDWARE_V1a[] PROGMEM = "V1a"; +// const char PSTR_HARDWARE_V2a[] PROGMEM = "V2a"; +// const char* const PSTR_HARDWARE[] PROGMEM = { PSTR_HARDWARE_V1a, PSTR_HARDWARE_V2a }; uint8_t hardwareVersion = 0; @@ -147,6 +172,14 @@ extern "C" { Cc1101 cc1101Receive(Cc1101::Receive); } +const char *hardwareVersionPStr (uint8_t version) { + switch (version) { + case 1: return PSTR("V1a"); + case 2: return PSTR("V2a"); + default: return PSTR("V??"); + } +} + uint8_t detectHardwareVersion () { ADMUX = (1 << ADLAR) | (1 << REFS0) | 7; // ADC7, VREF=AVCC=3.3V ADCSRA = (1 << ADEN) | 7; // ADC Enable, Prescaler 128 @@ -179,9 +212,11 @@ uint8_t detectHardwareVersion () { printf_P(PSTR("\nInvalid Hardware-Version: ADC7H = %d (ATmega328P, 5V)\n"), ADCH); #endif } else { - printf_P(PSTR("\n\nHardware %d detected (ADC7H=0x%02X)"), hardwareVersion, ADCH); + // const char *pHw; memcpy_P(&pHw, PSTR_HARDWARE + hardwareVersion - 1, sizeof(const char *)); + printf_P(PSTR("\n\nHardware %S detected (ADC7H=0x%02X)"), hardwareVersionPStr(hardwareVersion), ADCH); } + ADMUX = 0; ADCSRA = 0; return hardwareVersion; @@ -232,7 +267,7 @@ int main () { UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 <= 1 && hardwareVersion <= 2) { - printf_P(PSTR("Hardware: %d"), hardwareVersion); + printf_P(PSTR("Hardware: %S"), hardwareVersionPStr(hardwareVersion)); } else { printf_P(PSTR("ERROR: Invalid Hardware (%d)"), hardwareVersion); for(;;); -- 2.39.5