From 49b2a19364b96f789c60cde900020bc329f26f97 Mon Sep 17 00:00:00 2001 From: Timo Kasper Date: Wed, 4 Mar 2015 01:28:25 +0800 Subject: [PATCH] =?UTF-8?q?Major=20improvements=20(amongst=20others=20Mifa?= =?UTF-8?q?re=20Ultralight=20and=207-Byte=20UID=20MF=20Plus=20support)=20a?= =?UTF-8?q?nd=20major=20bug=20fixes.=20Thanks=20to=20Simon=20K=C3=BCppers?= =?UTF-8?q?=20and=20Julius=20Schmalz.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Firmware/Chameleon-Mini/.cproject | 130 +- Firmware/Chameleon-Mini/.project | 61 +- Firmware/Chameleon-Mini/AntennaLevel.h | 56 +- .../Chameleon-Mini/Application/Application.h | 60 +- Firmware/Chameleon-Mini/Application/Crypto1.c | 55 - Firmware/Chameleon-Mini/Application/Crypto1.h | 55 - .../Chameleon-Mini/Application/ISO14443-3A.c | 56 +- .../Chameleon-Mini/Application/ISO14443-3A.h | 56 +- .../Application/MifareClassic.c | 239 +- .../Application/MifareClassic.h | 57 +- .../Application/MifareUltralight.c | 288 + .../Application/MifareUltralight.h | 28 + Firmware/Chameleon-Mini/Button.c | 292 +- Firmware/Chameleon-Mini/Button.h | 67 +- Firmware/Chameleon-Mini/Chameleon-Mini.bin | Bin 20268 -> 25376 bytes Firmware/Chameleon-Mini/Chameleon-Mini.c | 67 +- Firmware/Chameleon-Mini/Chameleon-Mini.eep | 6 +- Firmware/Chameleon-Mini/Chameleon-Mini.elf | Bin 303485 -> 365854 bytes Firmware/Chameleon-Mini/Chameleon-Mini.h | 56 +- Firmware/Chameleon-Mini/Chameleon-Mini.hex | 2855 +- Firmware/Chameleon-Mini/Chameleon-Mini.lss | 35572 +++++++++------- Firmware/Chameleon-Mini/Chameleon-Mini.map | 6142 +-- Firmware/Chameleon-Mini/Chameleon-Mini.sym | 1537 +- Firmware/Chameleon-Mini/Codec/Codec.c | 56 +- Firmware/Chameleon-Mini/Codec/Codec.h | 68 +- Firmware/Chameleon-Mini/Codec/ISO14443-2A.c | 85 +- Firmware/Chameleon-Mini/Codec/ISO14443-2A.h | 56 +- Firmware/Chameleon-Mini/Common.c | 55 - Firmware/Chameleon-Mini/Common.h | 56 +- Firmware/Chameleon-Mini/Configuration.c | 108 +- Firmware/Chameleon-Mini/Configuration.h | 67 +- Firmware/Chameleon-Mini/LED.c | 255 +- Firmware/Chameleon-Mini/LED.h | 136 +- Firmware/Chameleon-Mini/Log.c | 152 + Firmware/Chameleon-Mini/Log.h | 49 + Firmware/Chameleon-Mini/Makefile | 106 +- Firmware/Chameleon-Mini/Memory.c | 77 +- Firmware/Chameleon-Mini/Memory.h | 57 +- .../Chameleon-Mini/ProgramViaBootloader.bat | 8 +- Firmware/Chameleon-Mini/README.txt | 9 + Firmware/Chameleon-Mini/Random.c | 55 - Firmware/Chameleon-Mini/Random.h | 56 +- Firmware/Chameleon-Mini/Settings.c | 106 +- Firmware/Chameleon-Mini/Settings.h | 68 +- Firmware/Chameleon-Mini/System.c | 76 +- Firmware/Chameleon-Mini/System.h | 98 +- .../Chameleon-Mini/Terminal/CommandLine.c | 86 +- .../Chameleon-Mini/Terminal/CommandLine.h | 56 +- Firmware/Chameleon-Mini/Terminal/Commands.c | 186 +- Firmware/Chameleon-Mini/Terminal/Commands.h | 82 +- Firmware/Chameleon-Mini/Terminal/Terminal.c | 74 +- Firmware/Chameleon-Mini/Terminal/Terminal.h | 56 +- Firmware/Chameleon-Mini/Terminal/XModem.c | 68 +- Firmware/Chameleon-Mini/Terminal/XModem.h | 56 +- 54 files changed, 27460 insertions(+), 22798 deletions(-) create mode 100644 Firmware/Chameleon-Mini/Application/MifareUltralight.c create mode 100644 Firmware/Chameleon-Mini/Application/MifareUltralight.h create mode 100644 Firmware/Chameleon-Mini/Log.c create mode 100644 Firmware/Chameleon-Mini/Log.h create mode 100644 Firmware/Chameleon-Mini/README.txt diff --git a/Firmware/Chameleon-Mini/.cproject b/Firmware/Chameleon-Mini/.cproject index ecd4de3..b4bc4a5 100644 --- a/Firmware/Chameleon-Mini/.cproject +++ b/Firmware/Chameleon-Mini/.cproject @@ -1,73 +1,61 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - make - - program - true - true - true - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Firmware/Chameleon-Mini/.project b/Firmware/Chameleon-Mini/.project index 7b77bcf..884aab5 100644 --- a/Firmware/Chameleon-Mini/.project +++ b/Firmware/Chameleon-Mini/.project @@ -9,6 +9,58 @@ org.eclipse.cdt.managedbuilder.core.genmakebuilder clean,full,incremental, + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + @@ -20,15 +72,8 @@ org.eclipse.cdt.core.cnature - org.eclipse.cdt.core.ccnature org.eclipse.cdt.managedbuilder.core.managedBuildNature org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + de.innot.avreclipse.core.avrnature - - - Doxyfile - 1 - PARENT-2-PROJECT_LOC/Doc/Doxyfile - - diff --git a/Firmware/Chameleon-Mini/AntennaLevel.h b/Firmware/Chameleon-Mini/AntennaLevel.h index 1b390f0..4053e03 100644 --- a/Firmware/Chameleon-Mini/AntennaLevel.h +++ b/Firmware/Chameleon-Mini/AntennaLevel.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * AntennaLevel.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 24.11.2013 + * Author: skuser */ #ifndef ANTENNALEVEL_H_ diff --git a/Firmware/Chameleon-Mini/Application/Application.h b/Firmware/Chameleon-Mini/Application/Application.h index 7b7df2f..fd72214 100644 --- a/Firmware/Chameleon-Mini/Application/Application.h +++ b/Firmware/Chameleon-Mini/Application/Application.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * Application.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 18.02.2013 + * Author: skuser */ #ifndef APPLICATION_H_ @@ -58,10 +10,13 @@ #include "../Common.h" #include "../Configuration.h" +#include "../Log.h" /* Applications */ +#include "MifareUltralight.h" #include "MifareClassic.h" + /* Function wrappers */ INLINE void ApplicationInit(void) { ActiveConfiguration.ApplicationInitFunc(); @@ -77,6 +32,7 @@ INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { INLINE void ApplicationReset(void) { ActiveConfiguration.ApplicationResetFunc(); + //LogEntry(LOG_INFO_APP_RESET, NULL, 0); } INLINE void ApplicationGetUid(ConfigurationUidType Uid) { diff --git a/Firmware/Chameleon-Mini/Application/Crypto1.c b/Firmware/Chameleon-Mini/Application/Crypto1.c index cd41a1e..20b5b67 100644 --- a/Firmware/Chameleon-Mini/Application/Crypto1.c +++ b/Firmware/Chameleon-Mini/Application/Crypto1.c @@ -1,58 +1,3 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. - * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ - #include "Crypto1.h" #define PRNG_MASK 0x002D0000UL diff --git a/Firmware/Chameleon-Mini/Application/Crypto1.h b/Firmware/Chameleon-Mini/Application/Crypto1.h index 5d8d964..4c882b1 100644 --- a/Firmware/Chameleon-Mini/Application/Crypto1.h +++ b/Firmware/Chameleon-Mini/Application/Crypto1.h @@ -1,58 +1,3 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. - * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ - #ifndef CRYPTO1_H #define CRYPTO1_H diff --git a/Firmware/Chameleon-Mini/Application/ISO14443-3A.c b/Firmware/Chameleon-Mini/Application/ISO14443-3A.c index 090a0bd..25a226b 100644 --- a/Firmware/Chameleon-Mini/Application/ISO14443-3A.c +++ b/Firmware/Chameleon-Mini/Application/ISO14443-3A.c @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * ISO14443A.c * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 19.03.2013 + * Author: skuser */ #include "ISO14443-3A.h" diff --git a/Firmware/Chameleon-Mini/Application/ISO14443-3A.h b/Firmware/Chameleon-Mini/Application/ISO14443-3A.h index e38860c..939901a 100644 --- a/Firmware/Chameleon-Mini/Application/ISO14443-3A.h +++ b/Firmware/Chameleon-Mini/Application/ISO14443-3A.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * ISO14443-2A.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 19.03.2013 + * Author: skuser */ #ifndef ISO14443_3A_H_ diff --git a/Firmware/Chameleon-Mini/Application/MifareClassic.c b/Firmware/Chameleon-Mini/Application/MifareClassic.c index 1d532cb..1486be3 100644 --- a/Firmware/Chameleon-Mini/Application/MifareClassic.c +++ b/Firmware/Chameleon-Mini/Application/MifareClassic.c @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * MifareClassic.c * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 13.05.2013 + * Author: skuser */ #include "MifareClassic.h" @@ -62,13 +14,18 @@ #include "../Random.h" #define MFCLASSIC_1K_ATQA_VALUE 0x0004 +#define MFPlus_ATQA_VALUE 0x0044 #define MFCLASSIC_4K_ATQA_VALUE 0x0002 #define MFCLASSIC_1K_SAK_CL1_VALUE 0x08 #define MFCLASSIC_4K_SAK_CL1_VALUE 0x18 +#define SAK_CL1_VALUE ISO14443A_SAK_INCOMPLETE +#define SAK_CL2_VALUE ISO14443A_SAK_COMPLETE_NOT_COMPLIANT #define MEM_UID_CL1_ADDRESS 0x00 #define MEM_UID_CL1_SIZE 4 #define MEM_UID_BCC1_ADDRESS 0x04 +#define MEM_UID_CL2_ADDRESS 0x03 +#define MEM_UID_CL2_SIZE 4 #define MEM_KEY_A_OFFSET 48 /* Bytes */ #define MEM_KEY_B_OFFSET 58 /* Bytes */ #define MEM_KEY_SIZE 6 /* Bytes */ @@ -105,11 +62,17 @@ #define CMD_RESTORE_FRAME_SIZE 2 /* Bytes without CRCA */ #define CMD_TRANSFER 0xB0 #define CMD_TRANSFER_FRAME_SIZE 2 /* Bytes without CRCA */ +#define CMD_CHINESE_UNLOCK 0x40 +#define CMD_CHINESE_WIPE 0x41 +#define CMD_CHINESE_UNLOCK_RW 0x43 static enum { STATE_HALT, STATE_IDLE, - STATE_READY, + STATE_CHINESE_IDLE, + STATE_CHINESE_WRITE, + STATE_READY1, + STATE_READY2, STATE_ACTIVE, STATE_AUTHING, STATE_AUTHED_IDLE, @@ -126,6 +89,8 @@ static uint8_t BlockBuffer[MEM_BYTES_PER_BLOCK]; static uint16_t CardATQAValue; static uint8_t CardSAKValue; +static uint8_t _7BUID = 0x00; + INLINE bool CheckValueIntegrity(uint8_t* Block) { /* Value Blocks contain a value stored three times, with @@ -173,6 +138,16 @@ void MifareClassicAppInit1K(void) State = STATE_IDLE; CardATQAValue = MFCLASSIC_1K_ATQA_VALUE; CardSAKValue = MFCLASSIC_1K_SAK_CL1_VALUE; + _7BUID = 0x00; +} + +void MifarePlus1kAppInit_7B(void) +{ + State = STATE_IDLE; + CardATQAValue = MFPlus_ATQA_VALUE; + CardSAKValue = MFCLASSIC_1K_SAK_CL1_VALUE; + uint8_t UidSize = ActiveConfiguration.UidSize; + _7BUID = (UidSize == 7); } void MifareClassicAppInit4K(void) @@ -180,6 +155,7 @@ void MifareClassicAppInit4K(void) State = STATE_IDLE; CardATQAValue = MFCLASSIC_4K_ATQA_VALUE; CardSAKValue = MFCLASSIC_4K_SAK_CL1_VALUE; + _7BUID = 0x00; } void MifareClassicAppReset(void) @@ -198,22 +174,109 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) case STATE_IDLE: case STATE_HALT: if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { - State = STATE_READY; + State = STATE_READY1; return BitCount; } +#ifdef SUPPORT_MF_CLASSIC_MAGIC_MODE + else if (Buffer[0] == CMD_CHINESE_UNLOCK) { + State = STATE_CHINESE_IDLE; + Buffer[0] = ACK_VALUE; + return ACK_NAK_FRAME_SIZE; + } +#endif + break; + +#ifdef SUPPORT_MF_CLASSIC_MAGIC_MODE + case STATE_CHINESE_IDLE: + /* Support special china commands that dont require authentication. */ + if (Buffer[0] == CMD_CHINESE_UNLOCK_RW) { + /* Unlock read and write commands */ + Buffer[0] = ACK_VALUE; + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_CHINESE_WIPE) { + /* Wipe memory */ + Buffer[0] = ACK_VALUE; + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_READ) { + if (ISO14443ACheckCRCA(Buffer, CMD_READ_FRAME_SIZE)) { + /* Read command. Read data from memory and append CRCA. */ + MemoryReadBlock(Buffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + ISO14443AAppendCRCA(Buffer, MEM_BYTES_PER_BLOCK); + + return (CMD_READ_RESPONSE_FRAME_SIZE + ISO14443A_CRCA_SIZE ) + * BITS_PER_BYTE; + } else { + Buffer[0] = NAK_CRC_ERROR; + return ACK_NAK_FRAME_SIZE; + } + } else if (Buffer[0] == CMD_WRITE) { + if (ISO14443ACheckCRCA(Buffer, CMD_WRITE_FRAME_SIZE)) { + /* Write command. Store the address and prepare for the upcoming data. + * Respond with ACK. */ + CurrentAddress = Buffer[1]; + State = STATE_CHINESE_WRITE; + + Buffer[0] = ACK_VALUE; + return ACK_NAK_FRAME_SIZE; + } else { + Buffer[0] = NAK_CRC_ERROR; + return ACK_NAK_FRAME_SIZE; + } + } else if (Buffer[0] == CMD_HALT) { + /* Halts the tag. According to the ISO14443, the second + * byte is supposed to be 0. */ + if (Buffer[1] == 0) { + if (ISO14443ACheckCRCA(Buffer, CMD_HALT_FRAME_SIZE)) { + /* According to ISO14443, we must not send anything + * in order to acknowledge the HALT command. */ + State = STATE_HALT; + return ISO14443A_APP_NO_RESPONSE; + } else { + Buffer[0] = NAK_CRC_ERROR; + return ACK_NAK_FRAME_SIZE; + } + } else { + Buffer[0] = NAK_INVALID_ARG; + return ACK_NAK_FRAME_SIZE; + } + } break; - case STATE_READY: + case STATE_CHINESE_WRITE: + if (ISO14443ACheckCRCA(Buffer, MEM_BYTES_PER_BLOCK)) { + /* CRC check passed. Write data into memory and send ACK. */ + if (!ActiveConfiguration.ReadOnly) { + MemoryWriteBlock(Buffer, CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + } + + Buffer[0] = ACK_VALUE; + } else { + /* CRC Error. */ + Buffer[0] = NAK_CRC_ERROR; + } + + State = STATE_CHINESE_IDLE; + + return ACK_NAK_FRAME_SIZE; +#endif + + case STATE_READY1: if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { - State = STATE_READY; + State = STATE_READY1; return BitCount; } else if (Buffer[0] == ISO14443A_CMD_SELECT_CL1) { /* Load UID CL1 and perform anticollision */ - uint8_t UidCL1[4]; - MemoryReadBlock(UidCL1, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); - - if (ISO14443ASelect(Buffer, &BitCount, UidCL1, CardSAKValue)) { - State = STATE_ACTIVE; + uint8_t UidCL1[ISO14443A_CL_UID_SIZE]; + + if (_7BUID) { + MemoryReadBlock(&UidCL1[1], MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE-1); + UidCL1[0] = ISO14443A_UID0_CT; + if (ISO14443ASelect(Buffer, &BitCount, UidCL1, SAK_CL1_VALUE)) + State = STATE_READY2; + } else { + MemoryReadBlock(UidCL1, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + if (ISO14443ASelect(Buffer, &BitCount, UidCL1, CardSAKValue)) + State = STATE_ACTIVE; } return BitCount; @@ -223,9 +286,29 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) } break; + case STATE_READY2: + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + State = STATE_READY1; + return BitCount; + } else if (Buffer[0] == ISO14443A_CMD_SELECT_CL2) { + /* Load UID CL2 and perform anticollision */ + uint8_t UidCL2[ISO14443A_CL_UID_SIZE]; + MemoryReadBlock(UidCL2, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + + if (ISO14443ASelect(Buffer, &BitCount, UidCL2, CardSAKValue)) { + State = STATE_ACTIVE; + } + + return BitCount; + } else { + /* Unknown command. Enter HALT state. */ + State = STATE_HALT; + } + break; + case STATE_ACTIVE: - if (ISO14443AWakeUp(Buffer, &BitCount, MFCLASSIC_1K_ATQA_VALUE)) { - State = STATE_READY; + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + State = STATE_READY1; return BitCount; } else if (Buffer[0] == CMD_HALT) { /* Halts the tag. According to the ISO14443, the second @@ -255,7 +338,10 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) /* Generate a random nonce and read UID and key from memory */ RandomGetBuffer(CardNonce, sizeof(CardNonce)); - MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + if (_7BUID) + MemoryReadBlock(Uid, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); MemoryReadBlock(Key, KeyAddress, MEM_KEY_SIZE); /* Precalculate the reader response from card-nonce */ @@ -416,7 +502,10 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) /* Generate a random nonce and read UID and key from memory */ RandomGetBuffer(CardNonce, sizeof(CardNonce)); - MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + if (_7BUID) + MemoryReadBlock(Uid, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); MemoryReadBlock(Key, KeyAddress, MEM_KEY_SIZE); /* Precalculate the reader response from card-nonce */ @@ -538,15 +627,27 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) void MifareClassicGetUid(ConfigurationUidType Uid) { - MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + if (_7BUID) { + //Uid[0]=0x88; + MemoryReadBlock(&Uid[0], MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE-1); + MemoryReadBlock(&Uid[3], MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + } + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); } void MifareClassicSetUid(ConfigurationUidType Uid) { - uint8_t BCC = Uid[0] ^ Uid[1] ^ Uid[2] ^ Uid[3]; + if (_7BUID) { + //Uid[0]=0x88; + MemoryWriteBlock(Uid, MEM_UID_CL1_ADDRESS, ActiveConfiguration.UidSize); + } + else { + uint8_t BCC = Uid[0] ^ Uid[1] ^ Uid[2] ^ Uid[3]; - MemoryWriteBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); - MemoryWriteBlock(&BCC, MEM_UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE); + MemoryWriteBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + MemoryWriteBlock(&BCC, MEM_UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE); + } } diff --git a/Firmware/Chameleon-Mini/Application/MifareClassic.h b/Firmware/Chameleon-Mini/Application/MifareClassic.h index 756ccaa..fcfe1e1 100644 --- a/Firmware/Chameleon-Mini/Application/MifareClassic.h +++ b/Firmware/Chameleon-Mini/Application/MifareClassic.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * MifareClassic.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 13.05.2013 + * Author: skuser */ #ifndef MIFARECLASSIC_H_ @@ -64,6 +16,7 @@ #define MIFARE_CLASSIC_4K_MEM_SIZE 4096 void MifareClassicAppInit1K(void); +void MifarePlus1kAppInit_7B(void); void MifareClassicAppInit4K(void); void MifareClassicAppReset(void); void MifareClassicAppTask(void); diff --git a/Firmware/Chameleon-Mini/Application/MifareUltralight.c b/Firmware/Chameleon-Mini/Application/MifareUltralight.c new file mode 100644 index 0000000..a31a13b --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/MifareUltralight.c @@ -0,0 +1,288 @@ +/* + * MifareUltralight.c + * + * Created on: 20.03.2013 + * Author: skuser + */ + +#include "MifareUltralight.h" +#include "ISO14443-3A.h" +#include "../Codec/ISO14443-2A.h" +#include "../Memory.h" + + +#define ATQA_VALUE 0x0044 +#define SAK_CL1_VALUE ISO14443A_SAK_INCOMPLETE +#define SAK_CL2_VALUE ISO14443A_SAK_COMPLETE_NOT_COMPLIANT + +#define ACK_VALUE 0x0A +#define ACK_FRAME_SIZE 4 /* Bits */ +#define NAK_INVALID_ARG 0x00 +#define NAK_CRC_ERROR 0x01 +#define NAK_EEPROM_ERROR 0x05 +#define NAK_OTHER_ERROR 0x06 +#define NAK_FRAME_SIZE 4 + +#define CMD_READ 0x30 +#define CMD_READ_FRAME_SIZE 2 /* without CRC bytes */ +#define CMD_WRITE 0xA2 +#define CMD_WRITE_FRAME_SIZE 6 /* without CRC bytes */ +#define CMD_COMPAT_WRITE 0xA0 +#define CMD_COMPAT_WRITE_FRAME_SIZE 2 +#define CMD_HALT 0x50 + +#define UID_CL1_ADDRESS 0x00 /* In Card Memory */ +#define UID_CL1_SIZE 3 /* In Bytes */ +#define UID_BCC1_ADDRESS 0x03 +#define UID_CL2_ADDRESS 0x04 +#define UID_CL2_SIZE 4 +#define UID_BCC2_ADDRESS 0x08 + +#define BYTES_PER_PAGE 4 +#define PAGE_ADDRESS_MASK 0x0F + +#define BYTES_PER_READ 16 +#define PAGE_READ_MIN 0x00 +#define PAGE_READ_MAX 0x0F + +#define BYTES_PER_WRITE 4 +#define PAGE_WRITE_MIN 0x02 +#define PAGE_WRITE_MAX 0x0F + +#define BYTES_PER_COMPAT_WRITE 16 + +static enum { + STATE_HALT, + STATE_IDLE, + STATE_READY1, + STATE_READY2, + STATE_ACTIVE, + STATE_COMPAT_WRITE +} State; + +static uint8_t CompatWritePageAddress; + +void MifareUltralightAppInit(void) +{ + State = STATE_IDLE; +} + +void MifareUltralightAppReset(void) +{ + State = STATE_IDLE; +} + +void MifareUltralightAppTask(void) +{ + +} + + +uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + uint8_t Cmd = Buffer[0]; + + switch(State) { + case STATE_IDLE: + case STATE_HALT: + if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE)) { + /* We received a REQA or WUPA command, so wake up. */ + State = STATE_READY1; + return BitCount; + } + break; + + case STATE_READY1: + if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE)) { + State = STATE_READY1; + return BitCount; + } else if (Cmd == ISO14443A_CMD_SELECT_CL1) { + /* Load UID CL1 and perform anticollision. Since + * MF Ultralight use a double-sized UID, the first byte + * of CL1 has to be the cascade-tag byte. */ + uint8_t UidCL1[ISO14443A_CL_UID_SIZE] = { [0] = ISO14443A_UID0_CT }; + + MemoryReadBlock(&UidCL1[1], UID_CL1_ADDRESS, UID_CL1_SIZE); + + if (ISO14443ASelect(Buffer, &BitCount, UidCL1, SAK_CL1_VALUE)) { + /* CL1 stage has ended successfully */ + State = STATE_READY2; + } + + return BitCount; + } else { + /* Unknown command. Enter halt state */ + State = STATE_IDLE; + } + break; + + case STATE_READY2: + if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE)) { + State = STATE_READY1; + return BitCount; + } else if (Cmd == ISO14443A_CMD_SELECT_CL2) { + /* Load UID CL2 and perform anticollision */ + uint8_t UidCL2[ISO14443A_CL_UID_SIZE]; + + MemoryReadBlock(UidCL2, UID_CL2_ADDRESS, UID_CL2_SIZE); + + if (ISO14443ASelect(Buffer, &BitCount, UidCL2, SAK_CL2_VALUE)) { + /* CL2 stage has ended successfully. This means + * our complete UID has been sent to the reader. */ + State = STATE_ACTIVE; + } + + return BitCount; + } else { + /* Unknown command. Enter halt state */ + State = STATE_IDLE; + } + break; + + case STATE_ACTIVE: + if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE)) { + State = STATE_READY1; + return BitCount; + } else if (Cmd == CMD_READ) { + uint8_t PageAddress = Buffer[1]; + + if (ISO14443ACheckCRCA(Buffer, CMD_READ_FRAME_SIZE)) { + if ( (PageAddress >= PAGE_READ_MIN) + && (PageAddress <= PAGE_READ_MAX) ) { + /* TODO: Missing address wrap around behaviour. + * Implement using a for-loop copying 4 bytes each iteration + * and mask pageaddress */ + MemoryReadBlock(Buffer, PageAddress * BYTES_PER_PAGE, BYTES_PER_READ); + ISO14443AAppendCRCA(Buffer, BYTES_PER_READ); + return (BYTES_PER_READ + ISO14443A_CRCA_SIZE) * 8; + } else { + Buffer[0] = NAK_INVALID_ARG; + return NAK_FRAME_SIZE; + } + } else { + Buffer[0] = NAK_CRC_ERROR; + return NAK_FRAME_SIZE; + } + } else if (Cmd == CMD_WRITE) { + /* This is a write command containing 4 bytes of data that + * should be written to the given page address. */ + uint8_t PageAddress = Buffer[1]; + if (ISO14443ACheckCRCA(Buffer, CMD_WRITE_FRAME_SIZE)) { + /* CRC check passed */ + if ( (PageAddress >= PAGE_WRITE_MIN) + && (PageAddress <= PAGE_WRITE_MAX) ) { + /* PageAddress is within bounds. */ + + if (!ActiveConfiguration.ReadOnly) { + MemoryWriteBlock(&Buffer[2], PageAddress * BYTES_PER_PAGE, BYTES_PER_WRITE); + } else { + /* If the chameleon is in read only mode, it silently + * ignores any attempt to write data. */ + } + + Buffer[0] = ACK_VALUE; + return ACK_FRAME_SIZE; + + } else { + Buffer[0] = NAK_INVALID_ARG; + return NAK_FRAME_SIZE; + } + } else { + Buffer[0] = NAK_CRC_ERROR; + return NAK_FRAME_SIZE; + } + } else if (Cmd == CMD_COMPAT_WRITE) { + /* The Mifare compatbility write command is a 2-frame command. + * The first frame contains the page-address and the second frame + * holds the data. */ + uint8_t PageAddress = Buffer[1]; + + if (ISO14443ACheckCRCA(Buffer, CMD_COMPAT_WRITE_FRAME_SIZE)) { + if ( (PageAddress >= PAGE_WRITE_MIN) + && (PageAddress <= PAGE_WRITE_MAX) ) { + /* CRC check passed and page-address is within bounds. + * Store address and proceed to receiving the data. */ + CompatWritePageAddress = PageAddress; + State = STATE_COMPAT_WRITE; + + Buffer[0] = ACK_VALUE; + return ACK_FRAME_SIZE; + } else { + Buffer[0] = NAK_INVALID_ARG; + return NAK_FRAME_SIZE; + } + } else { + Buffer[0] = NAK_CRC_ERROR; + return NAK_FRAME_SIZE; + } + } else if (Cmd == CMD_HALT) { + /* Halts the tag. According to the ISO14443, the second + * byte is supposed to be 0. */ + if (Buffer[1] == 0) { + if (ISO14443ACheckCRCA(Buffer, 2)) { + /* According to ISO14443, we must not send anything + * in order to acknowledge the HALT command. */ + State = STATE_HALT; + return ISO14443A_APP_NO_RESPONSE; + } else { + Buffer[0] = NAK_CRC_ERROR; + return NAK_FRAME_SIZE; + } + } else { + Buffer[0] = NAK_INVALID_ARG; + return NAK_FRAME_SIZE; + } + } else { + /* Unknown command. Enter halt state */ + State = STATE_IDLE; + } + break; + + case STATE_COMPAT_WRITE: + /* Compatibility write. Receiving 16 bytes of data of which 4 bytes are valid. */ + if (ISO14443ACheckCRCA(Buffer, BYTES_PER_COMPAT_WRITE)) { + /* We don't perform any checks here. You will be able to program the + * whole memory. Also there is no OTP behaviour. */ + if (!ActiveConfiguration.ReadOnly) { + MemoryWriteBlock(Buffer, CompatWritePageAddress * BYTES_PER_PAGE, BYTES_PER_WRITE); + } else { + /* If we are told to be read only, we silently ignore the write command + * and pretend to have written data. */ + } + + State = STATE_ACTIVE; + Buffer[0] = ACK_VALUE; + return ACK_FRAME_SIZE; + } else { + State = STATE_ACTIVE; + Buffer[0] = NAK_CRC_ERROR; + return NAK_FRAME_SIZE; + } + + default: + /* Unknown state? Should never happen. */ + break; + } + + /* No response has been sent, when we reach here */ + return ISO14443A_APP_NO_RESPONSE; +} + +void MifareUltralightGetUid(ConfigurationUidType Uid) +{ + /* Read UID from memory */ + MemoryReadBlock(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE); + MemoryReadBlock(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE); +} + +void MifareUltralightSetUid(ConfigurationUidType Uid) +{ + /* Calculate check bytes and write everything into memory */ + uint8_t BCC1 = ISO14443A_UID0_CT ^ Uid[0] ^ Uid[1] ^ Uid[2]; + uint8_t BCC2 = Uid[3] ^ Uid[4] ^ Uid[5] ^ Uid[6]; + + MemoryWriteBlock(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE); + MemoryWriteBlock(&BCC1, UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE); + MemoryWriteBlock(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE); + MemoryWriteBlock(&BCC2, UID_BCC2_ADDRESS, ISO14443A_CL_BCC_SIZE); +} diff --git a/Firmware/Chameleon-Mini/Application/MifareUltralight.h b/Firmware/Chameleon-Mini/Application/MifareUltralight.h new file mode 100644 index 0000000..a1a5b85 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/MifareUltralight.h @@ -0,0 +1,28 @@ +/* + * MifareUltralight.h + * + * Created on: 20.03.2013 + * Author: skuser + */ + +#ifndef MIFAREULTRALIGHT_H_ +#define MIFAREULTRALIGHT_H_ + +#include "Application.h" +#include "ISO14443-3A.h" + +#define MIFARE_ULTRALIGHT_UID_SIZE ISO14443A_UID_SIZE_DOUBLE +#define MIFARE_ULTRALIGHT_MEM_SIZE 64 + +void MifareUltralightAppInit(void); +void MifareUltralightAppReset(void); +void MifareUltralightAppTask(void); + +uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount); + +void MifareUltralightGetUid(ConfigurationUidType Uid); +void MifareUltralightSetUid(ConfigurationUidType Uid); + + + +#endif /* MIFAREULTRALIGHT_H_ */ diff --git a/Firmware/Chameleon-Mini/Button.c b/Firmware/Chameleon-Mini/Button.c index 8daafd0..da57861 100644 --- a/Firmware/Chameleon-Mini/Button.c +++ b/Firmware/Chameleon-Mini/Button.c @@ -1,64 +1,11 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. - * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ - #include "Button.h" #include "Random.h" #include "Common.h" #include "Settings.h" #include "Memory.h" +#define LONG_PRESS_TICK_COUNT 10 + static const char PROGMEM ButtonActionTable[][32] = { [BUTTON_ACTION_NONE] = "NONE", @@ -72,6 +19,97 @@ static const char PROGMEM ButtonActionTable[][32] = [BUTTON_ACTION_RECALL_MEM] = "RECALL_MEM", }; +static void ExecuteButtonAction(ButtonActionEnum ButtonAction) +{ + uint8_t UidBuffer[32]; + + if (ButtonAction == BUTTON_ACTION_UID_RANDOM) { + for (uint8_t i=0; i 0) { + if (Carry) { + if (UidBuffer[i] == 0xFF) { + Carry = 1; + } else { + Carry = 0; + } + + UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF; + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i; + + for (i=0; i 0) { + if (Carry) { + if (UidBuffer[i] == 0x00) { + Carry = 1; + } else { + Carry = 0; + } + + UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF; + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_CYCLE_SETTINGS) { + SettingsCycle(); + } else if (ButtonAction == BUTTON_ACTION_STORE_MEM) { + MemoryStore(); + } else if (ButtonAction == BUTTON_ACTION_RECALL_MEM) { + MemoryRecall(); + } +} + void ButtonInit(void) { BUTTON_PORT.DIRCLR = BUTTON_MASK; @@ -80,101 +118,31 @@ void ButtonInit(void) void ButtonTick(void) { - static uint8_t LastButtonState = 0; + static uint8_t PressTickCounter = 0; uint8_t ThisButtonState = ~BUTTON_PORT.IN; - uint8_t ThisButtonChange = ThisButtonState ^ LastButtonState; - uint8_t ThisButtonPress = ThisButtonChange & ThisButtonState; - LastButtonState = ThisButtonState; - if ( ThisButtonPress & BUTTON_MASK ) { - uint8_t UidBuffer[32]; - ButtonActionEnum ButtonAction = GlobalSettings.ActiveSettingPtr->ButtonAction; + if (ThisButtonState & BUTTON_MASK) { + /* Button is currently pressed */ + if (PressTickCounter < LONG_PRESS_TICK_COUNT) { + /* Count ticks while button is being pressed */ + PressTickCounter++; + } else if (PressTickCounter == LONG_PRESS_TICK_COUNT) { + /* Long button press detected execute button action and advance PressTickCounter + * to an invalid state. */ + ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonLongAction); + PressTickCounter++; + } else { + /* Button is still pressed, ignore */ + } + } else if (!(ThisButtonState & BUTTON_MASK)) { + /* Button is currently not being pressed. Check if PressTickCounter contains + * a recent short button press. */ + if ( (PressTickCounter > 0) && (PressTickCounter <= LONG_PRESS_TICK_COUNT) ) { + /* We have a short button press */ + ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonAction); + } - if (ButtonAction == BUTTON_ACTION_UID_RANDOM) { - for (uint8_t i=0; i 0) { - if (Carry) { - if (UidBuffer[i] == 0xFF) { - Carry = 1; - } else { - Carry = 0; - } - - UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF; - } - } - - ApplicationSetUid(UidBuffer); - } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_DECREMENT) { - ApplicationGetUid(UidBuffer); - bool Carry = 1; - uint8_t i; - - for (i=0; i 0) { - if (Carry) { - if (UidBuffer[i] == 0x00) { - Carry = 1; - } else { - Carry = 0; - } - - UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF; - } - } - - ApplicationSetUid(UidBuffer); - } else if (ButtonAction == BUTTON_ACTION_CYCLE_SETTINGS) { - SettingsCycle(); - } else if (ButtonAction == BUTTON_ACTION_STORE_MEM) { - MemoryStore(); - } else if (ButtonAction == BUTTON_ACTION_RECALL_MEM) { - MemoryRecall(); - } + PressTickCounter = 0; } } @@ -207,30 +175,45 @@ void ButtonGetActionList(char* ListOut, uint16_t BufferSize) *ListOut = '\0'; } -void ButtonSetActionById(ButtonActionEnum Action) +void ButtonSetActionById(ButtonTypeEnum Type, ButtonActionEnum Action) { #ifndef BUTTON_SETTING_GLOBAL - GlobalSettings.ActiveSettingPtr->ButtonAction = Action; + if (Type == BUTTON_PRESS_SHORT) { + GlobalSettings.ActiveSettingPtr->ButtonAction = Action; + } else if (Type == BUTTON_PRESS_LONG) { + GlobalSettings.ActiveSettingPtr->ButtonLongAction = Action; + } #else /* Write button action to all settings when using global settings */ for (uint8_t i=0; iButtonAction], BufferSize); + if (Type == BUTTON_PRESS_SHORT) { + strncpy_P(ActionOut, ButtonActionTable[GlobalSettings.ActiveSettingPtr->ButtonAction], BufferSize); + } else if (Type == BUTTON_PRESS_LONG) { + strncpy_P(ActionOut, ButtonActionTable[GlobalSettings.ActiveSettingPtr->ButtonLongAction], BufferSize); + } else { + /* Should not happen (TM) */ + *ActionOut = '\0'; + } } -bool ButtonSetActionByName(const char* Action) +bool ButtonSetActionByName(ButtonTypeEnum Type, const char* Action) { uint8_t i; for (i=0; iD(eFfe2uVPHrC85rIkW?*=In1SKtVFrfhhZz{29tQb&gZRV43=H=VGcepe%)oH_FayKQ!wd}9 z4>K@aJMFdRM1z;O651H-|?3=I1Z zGcfEu%)qewFayKR!wd}D4>K@qJkl(9tUb)Yu=+3q!^*=949gEQ zFf2XHz_9o*1H;0@3=H!RGce3O%)l`FFayKP!wd}54>K@KJSx$UE+fr{apNgkwp<~ki3tp zTS&a8pL39_ud5%(^9X4MkbDp*OmHXw$%FN~xDwEhU4e6?vyW?huxm(&r=NQ;lEqMF zaEO19YrL;34(BrjxjH-g_~2IH@8$+I2}1e0`uYb&Lf9ZO#5Ks*)6dZd#0FsPr+=9%U z)D(sC%#sWR$FLw>cV}k>)nEogQv)L-V+KQG14{!#1`|DVJtGFyVg_jHQ!Qlxp-{`}?_hx`SN`CVB*$1#<;M zJ<&sAr{E;PAXi5he?K3j=vEOD5(*6fSqIh(CM<+Nl#743AF{YDSTx8r*cCZPIDth& z1KfigT@Z2S3l{Zt^$qrnLWqJ)jSvd;bioiU5ON9)2|@N+o6sboZm4LykG~(pgL8yd z2rU%yadmMIa&?6V#3rGALfb*2L9R%iJ|T2P=&X>Bzq_wLlFRN1y%2f~7DdiMAB0qd zxrCt!5#&rL_7rvzhQtX}fPsM_P#DDaaPUq?TrU}9ikIB8^HXyxe_=IG<;0#l$68te$qjHiqY zjNl3a9D^KvT|-=hz_vpPK^6IZ=ilFdbZ`IJ{Q{2`JlOE)-HT7pm=3T`;GML{awGfA z?|P3Gz1;AK@qp~4l{TB$AAV=Pz%#|wu>C;q1->aJe0)6C!@=fvJeK7H>#)paDG&rX=Ok`$h{QvHJ!$d}whQEK#ADGO{ z(t43^3Zr1gb-pR?ynIuX`0t%tFB1`}C#e(2QJ{Ql(erw1w%4IZ3le0*N- zvB86m$H?kmJ%q_#IsfMUN2tnk=jA8yPvYOkKS@yK|9Oe24HGLEn*Vbh=y=dDxq_kN zZOeX8m^3i_o%-)U!^8lFwuFYs0SpZj0~s3s|2Yq$oBsbfFEA;LLGgjYZkVjbHDR(kR~sl)xfCWlGc-S&@StHb7t4gn+$;@~c~~Y)=4DZs%)p{BnTe%g z;u*${goepy7&)dw?0xb4!-K|V2(SBL!{i1Aj;WyV@2dxefA^b)$w3StH-U6P+|>O4 z&-s=&4UKMbDm@Bizgo*G&D9QG&DbW^5H>CV_$ts^Mj`#vHrS-=7z@h z`i5qXsqGIQy!!Btcl+n9^9XJexm$D z{)rq@?=aR(ELZOQoG$$S{4GY-1GN*&l>i9u-@>@p3 zX&_xH6BPx&o^Lgn$g227q6y?8j;WrLK{AZfZk^|t$}?r3F2_`eFU9oJlr=xRVf=c( zbFyH-!|x!~@)J3x@=e*N3&SAwAUE9syGc>hkagzAB!fcMhL67(RrpQi6$1=89UcTc z5I=As_Ri$<1wHx`9&kr>PG0fhHPXBlKOheJ6ur#Aq5wwI*1#;>RTMV)maOTJ#%&y9^{gGzPXA zT=>!o<|%xbsy{Jgn!$uGjwTO2fy{9T4>Y;)DLfe2BuBy9=Rr9gWE+V7&G;_tzwd$v zTOKTv-p)OXaf$d=c8)J|89|}r_(6}~Uj7bao zN0vX>LFP0}R~c>$-w#D$z{ z|Nopfn7oivVd4T#fk~KR4wF;a)c-#_ukcV|avGcR0|g{~3QrWEI@dC$sh6ueV3q6C zpQXQAf46$WKi9ReA)TE;bFt% zR5p&OpftyDf#Jg0?f14r#6abK8rzHq6DFs!&3ZUtaw6OO2NNbQ;}n>*oO8mP36qy{ z&UiRs@)FL5$!TouZ%J|2gohwA8~)lI=zZMT-1Vrdx#2~3bK9$)W`&35Zzntfg^>Z0 zKVh!M<`adQ)5KXuhhc@d^p{32b?Q$I>STfbbrRnJ2IIpYcG zi<~^-vg{mRUNA10l*TpzDcxL{gqfCLVh1Kc(h^9I0~S3ESj0;7kW&@RBv5$5QZGyl zWcq1#?n1V|^C}o3O6F{UMZ03OC8{IAQ85O2Ce$e5!m3N#7a=*jGg`95x|C|T8 z)nVcSPEdZI_#N5B=qf-qp^JgkyZ?W79^~SLNeej9?g=9WJwZq-D8#_~*(m zl-(%%laWzWkd^ZT)A@vltq*dpB|mI|*FFCyyq|D?!ubjNC#;_^e?tF+`U&|H;wSh| zh&-l0$$k={6bZ_w+S5TPxVKqTFOtzwwBxz)JMxlU`8W*>tPvb<>|F9#L6VJyv^GjxSXQIUA)K!G8D> zbx^m_NEedQA3Qv#_x3w*(Uhnzad3v9p=IcFq(Wj@?Zr$$J9N(PLUfFJ@ z;;L(*znw8dx{#AiT%4WbgV(_wjIUaMw}N7U)Rh0K{dYS^pTVRBoFFq` z=>{YYN*kb37?fUc$%W{G@(nIoP`u)j1En319631z)dw6;yvu{Gi5fE)P;wI02NN3nnb&Ec*w^O$8IM<)#M{7jiy>=C=pXS_WMV6e7=| zx#{tX2a^|YqN@PK1bTh~)tl&IApfC@flOzU7Uyo`pAODXptJ=}jUO(b^J|Q6%xJA_ zy#=oAL20wIaaLm&|7`i6jG(%Gh4@bPo8KEBXv52SP+JjKuCt$@KY?Q^D0H@+<7}2{ z)^4_GZajxv4`ebrimE&a0_QP@ujn}llz(9PX2S=+uz25tA{SXaKipzG!FN;c4`c7d z#>sC)|FVKygzOHEsTquwjL*+EJU|si)IFe_z5txl8x3B5XfojZ5_+K7fb&bqffj?x zkF5rrU#1*rGvNHP`9Qk?=a)?fIt)0!bRJlM=4()YfmO3Zne)ry10Qwz82RJn{WsqF z!T6r{qijR-=P3;nSv7x%ZTS3PBBSPqiAi8Jjcj1O);Q}f1<4710`j{4+f2j4-5qr9vB7~G#gF>)wB!0-@s`?@n!jWW96HloAf6<_`&#s|EIh|qu~R8d(ICAP`-b> zL$hK)#`nqRC2p7EHK_@UNsfXra~uOe<`jI-KOb-@@ci@J{^ucKl79ZdgKrNSo-{Rg zJZ$R*g)#?Q+kcJ&4HGA+GzN4TtoR@>X_5*^e3D9+LBNMDgOlH3J)p)$p8Ftm{qYTx zL26*)4UG)C;e)DQLl)F0IUQ-2lt#~<21F@pC`jIi}j zI#Bv2meBsmweuayk{=okCVt?UnlPD1GhwojX2N6%&4kHvnhBFtG!rIkX(miI&`g+Y zrU_EPtC=uaSTkX=q-MfodCi2$s+tLtwKWqa8)_y@HrM2s`kS#sS@A=oLE{I3CXT5K zCUR+Rn8>Y}GqK@O2Do>a6KRCz8H|45s zr}oE>X)h2w&M$Tc(q19>CqJgWLGTuSOnZmmRenr+Py#n6@MGE|1W)s0+7kqi@nhOE z1n=etSf7$(YQlp?{Q`JTkz;D&gYV~)9(+BY{NVHXlm{Qrr#^UpKJCHV^XU&>pU-&k z@;t1M_nJ{eKSRIa!GuSAQ}$~oBC!e{oCEi*Iwc!EB)WP)g*7jzGL&>}Hf`TFnTt@1E`o#}*re8e+_!2p%dZ2(E@@{>TNx`e)9fP{g;hlU6I z6Ch@AOzmvmc~f9Ar>3KRz=K(gO8mz1pk6H~_+i6GP(PKGO<>Y=4bB4%6Is|= z{@Wh_iLrsjAo>(PHye6`>nM31rii^B|jA|GqsBQpL)~F%@JZ$X(Mlj)8m5tZawQ3rw1+F<~ML+tmMW z&QEwWVKN(AgVD`TjR6glL1w~ar~H3@9@Kva$##Ner)w-Z56fRu8)t|cewflYLl{(F zOxFOBGc>+K^D<~u3^dAytuA{J@|(!ItQ|*PHbZ|xVe4P!0}}=94}k0y)SRgt`7vR# zfM&vEam|FuVwwq)Wi=Bf%V;J{R@O|ItfZMRSyMA%vW8~DWPQzq$$FXzlT9@fCYxv` zOt#icm~5p93N1*O&Q#v`2^3}^9>iB56G5hdOahq#G6AI9TJyJUVG2>w=yf)1InDH3FbNra`6v31HnDHFJ`}iT_C4zSnTEc?HD?xRm2egz0@$uD- zdl*4=AS{)qo~hamj~+bx z_MoX5l2;oh&eCWyko*8q2hne*!#BlV4Z@DpdBZsU?}zir51SrryVs*Hdbv^X<@p|c zkou`dK)M?ZI6qo^Xfi1L*lbYvp~=AUBdE5_U~B#V`+Up8hRMy zr4Z!+2lOFWUif8n8>E7D9C<5;qf0vh2}quf=!@MQAFYWVN`5X z6l6Wn(Aa3~_@TjA@B=6;1tzg+fXXa169|Sz$n-ZqG zN`1FFD15aZL*fS#zW*n`#|U4Jsi2vbhvyp}ym|cd(Zq?J{4*cDvHr<^@jJ&<(2VMA z4TZ^bG;|&-OrEQu`oQ3U!sK}x29xJ&2uxa_Auws7hQOpn8Um9RYcxz=qA_9eQVou& z>JJnq&(_d+WJrYC^OH~LPnbAcW2yn?mzDz$K1?^@{Ni&U;j6;Ll^P8b=V)k%bAEYq zz~I4z2aMA-#4Xu5zla>ncnB)LL3NnGq}dvc56(~Im^#^j^GnQu9Umqii4?$&WJ)HhyRT>zZhA<8z|{$c7dJ%MTrffgidJ z9X~)!Oask-gL{(*TUre{zl0y?Hst&gaNvYt;pbxpoL>SD95pojo(NZ+Fma9s%zYqs z!c;i#MZtrf$1@*!-SNDS=&Lq9n18-u@=A>ss2f4PQJA<)!(ifajh~E9V!rt{G@oQ- zoYpXTnZ|_4%QYG-CbDvVSbM$=s=ncTDm*+ubs@-~ATuDYo^@Ve(j0I|f<`;$XgEw< zpb;=}p+>^QMH&SY7i&D2xJ2W_#HAVvFATtLihmy6es~YzpN5GGG$u@3 zsIg$;B8?3b7i%;`%=cgKzu&)M@&b(slNV|%n7l}1!{o&pjSqazAHCNjyx=@BZfg7p zN(~S{5Nku)gW~f7la^@+Oj@oXFlmJbs6_w@o#*FL;IY*S4aK|X5UJ|?xrT|eH5v_O zerN~x)Eg$w)0i-EzQ!Cz&@3=4{da0l{0<6ZP)i28yx{kSiE}k(=uZroFnO*79S8E`8rTh~iWeI4ugJbIam{|r4pZiTee(E=V_^H?U z;-_ANl^;3`EI)J`YJL}(v`Rx@(rS$d=Nl%j(wH!DwFblVi=P;$H%wloF=6s*jVtFL zOkAb$Vd82HP^uJYf~jwqXrtMoocXceIPzn!vFFFPkAFU5IiPQB_(9iL@k2eM;zUKk zALqX_3N(RQ7Hto2=v|l>z<6=q1|C6`#wXJrtl--zx0Ml;Gc=n)V-A{)o!XpV><{qA z%loq$3bHzW?|38d;OWC351vfy6X*PreBjw*7(42~^QSO&;DHyfnty=N zdHw`mL6xq!>Ha6qt2{7x@a4Sn1A_-2&nrDJc<}DL;sb*Rug`;Kf?k~e%2)(9G4s=L zM#gC%6FbgxOkMD3+k>VDg422?3r-iE)-zdjde7roj~XWL(3miJr$*0f5PO%#gvq-# z1SW0N5SX+(;^~X~-_L*Fuzce3 z#s>|}9WR=jn;*0{w>*%V)-xHpGNryP0ki@Iu_C8`^8Cr~C;x}bgI2Emcp%)=_Hx35 zw$;;DcRif&pke*Q^$(u>1lt6%0c2C>i{|FO2Mx^+9({Wt)b@Yk`-$@>_D|%Wz`u`w zg8T%DsR$eNC&TQRFj0f8Vd4gjsRfD;K%>ze{7u>olQ(Egn7Bq`rt-p%GxVnyfa(XQ z12gpJ6eNC}_@L=8sNcU%qhaEDjYh%T0}T^5YP3zAsm%GM@PNV#4Q++V8#NjxZqb-9 zajOQX1l^)BVe(du_JWz}o!W_C9!%V!@nPal4aLb1ChySrFnOm2s9s&K(J*n1#>5Am z>J5|EXmq@2nC#2}bH6^44+JJTaDe)zJ{$s*oH-jNuG8pHuKd{Z8Z;u9#yMefI;X&- zwO|u{I6)#~=o6q+=N0@%$yuyRN^T^?74-d(PiEA}LGZelDR(t@>OVk`t_zIe<*a4oa=sE!N zkNresAA$O3KR$rwIKmFJ7-W72g=WLw?FSm3G)#751J$8xH6ESsG~oOaeW1(Wrv~yTGSe(Qe>D(4^}(Fa<8#Q`$Ml?@aYYc=+r2bn(M zNyFck0~02@vb9ZZ0LRrPjR_MsgX3zG#)Qe6HRdpaM#_}6Ilq)2P?)$y!(if84M?r- z2VNnzR%7OQkhyMbp!##I1}r2S8bRiDL*+oF{926`D6i{5!{oIZwdebvBV1T^{=vju z8XqR^)@W#K6f^_-*_BOU;wBA)iJReR2-E^m{A4)o!Q@>UA13dH+jbsYKST0mBiLq$ zYrIiRWe1z;#?}tD-xll|SGFHu+Kuhx`3aNV*s8%iS2hoD{k~R13p|GN;K{cKEf1QS zg}M&BxcH#ySzj}#Y-oKTG_7Z{(DcR!LDPCB2TgB!5HPK0a=>({X)=?frZ+#3oYpgW z*3%iyGoH?Dp73O1^R(v1=Cd-3rG#a78zyeo zXcUY(05T2Kk_GhyJ>%p3!=}1Vh2aMi*)=~*cA2wMr%!}y1BLSw_kJsO~S$LIqMU#1zY{5Z*U=0}hVPBJ3a(161D z{{)VypgGBmFVl25IM{L*-!!JP9$@A)5$lNvi4X9#zkpWN8h zI77JQ{FKJ-#u>s5=chLIG|mvNIp6Z2p*isZ$UgzsK_$u_4ULBe4~jtIllN#e!u^tY zK4Icsje-Yh{N?f>?D8N0JaY1lt>rw3o$>%QKg2i<*%fwRS9rl);R>mpp@@DSpXdu)(+d2>zS zrNINi^PP>Lu(xV7Y}Rg6YM#?Lxw%=rNxf6OrCH;V!2?FH>1klonZTxZp6}Of3g|Q7 z_~3LN6sL`XQs=)s_&*P{E)?X$6O2sL_@;bg;|J@6xa;XPP+aA}b*i5KFlnzw>x19t zAo5qi@-gQHCPC8Av2&0b{K21>=CQT>C^Z1lSA?Xf-M*z36RmTi16VIr&M zbOX*04G$V7BUCmaoAab6INpCOtCYYqhhH8Z;P?=AKw;v3jR_MEXxw1znb>B;`DNXKCR5HY zs}D4o9Q+2#wfi)>9^7E;nGDK_7r}M*vID&a0pD&g{+Ylx#aN|Z6_m<8HbB@n7$L1p zp=k)&rsmIZS>b6tlZB^?Aj!5ge}&6}+NPkCaDs8?)keXYhxn$Hs7!n?L;VNigl13- z?9%|bqVGJYW#M$N#enle+j(^N`+?o>eW2Nr^TX7G4HFM(fKsT*VOWZTl@y@T1LWE{ z6DJsPemQhxf;s1h`13ayg{JjP6q?>)!TBNLyzsO+6NRUP%8j7&BGcwf6qybxJABTI zPMb4PbULW~a68}fpl329?;2bMwQTl*%MTkgcS(L|GUfc>b?^tHLi5CCP#)h0E)6x# zS1?}Gxz2cI!lCOus^1wKC)YDxp7QD8eW9=CA-UP)D#-m+;2a5J*&Td$eb$2+>NgnY zOfEhDgR!Bp*@W{;?!iVA&M(>r8;m)>m>g-a;`|bJu)&n`!?$yw5)q_N_6V#zeRu8# zPX zf2h%h^NZWzCL7K#oCh1MIlqJ-ZU}2K;P|lo03`Qcy8^QL{6UZ#dWt7BPB7#A;(jFS zalwOV#t#qs=P%&dC?lwn$7ufGFyBR)ln2Kc`KH*jf#R%=5u{V}NcV#md>>^%xfhh1 zL1Vx7*xVijJlM(z8p{Ti9{r6ClaFY0v^GpWs?pinF!`89S8K!M;~EK13Ldn)nenLl zdc(vc8V!?AXf#Ybs?jj{q(;NUV;T*UPiZtvJg(6&`LqUTe7WPzj7MqLmoaV!n`?Zv zzY&z?J6a*Bxw940KI&=(g$1b9wNFFgk--DcbC5Vn0{b%=UK7S0gyfmn11A{QUi-oL zrQ!0me$^X{BGY;%i%b`t_GiNBYoL77+Wf8I7+6MZTF+#$>EhG=OxOpOX>V3(oG|f- zhNd`ZGz(H5fpWLNIaqoJ#XKm#I)T%>{ecEk&M%zjXXsA|n`FT8W%Z#3FMR*oMU zYz#j%+9-Z#vJw2yV14l$#H<#0o_>C|)spjz|3QIC`@l8){j-od50dvm`R&@-t_P6% z{NmY!iH9`|9wvil;9>R7H@0o(ZZPUh7MwO`G9qQ~J_|_$S1yBM^6UXn8fch&Sfl4b z!{mJ$J=b7q7-YjzsM>vCwdW4O)Pm|`Q27I~ebQOg#t9RTYG?|VpI2*~F!7j%rf|{u z2@{WNbPDI4|1jZ%h5|S&dnSX}{5qeed{E)n`8MU-ln*LmSAH;pT2}hHu(nl)O2dzd zIvXE!t97V0G=G?IQiBm3@{M3Ns_yTXe=xoe|L>2`y-H=lkBvHp4;HI+fpwqKcytvM z!=QBXVZtd5RQ=a4|6qKFqW_G_fgcxjHaN`7{xIP*n(iH!e=xp9 z(VeD}@S{-2@IkU#n`#5JWK?)$@Q@K4KN}uq!{evt4QL<7JvN1jXEYinUeIWm3K|E! zf8fm3Y0xqx`0TN(urd}D7x&MA;`qbEe7G5q8g&}9Mt^guL)q~255~ksbTzQ{$C^tS zj0P`2IeMYa4aPkaLa%nK{$OmJ+|S6ZvuVl(6>gnvQ?^anpyG2`8y*|)R37~JsPpl` zd$m5*YmB{#{C^vRBY6vTzQEBXM)DV_GquSWhs39zUW3zhOE?v z?6J7RI8(hteV%rc_GWE`iTgCP4LHBtJ)mWv_yx9Vxnc4djgxw}^j_=zS2-~0tVS=R zlDe@v!{l=s-uj{HY2dvR=QUpFKbZPp@&%1Ix*+Hc%#9h>buX-OQ?b8Uj0?K8O@+1qYx*4om8eGFR z3i5+>#Mp>dK0)^YIw$b6lNg41=1dnPuRaeldTpzHC32QiEr9%{quw&xGd zVXfPC9Qgg02=&`Njm}2FX>%qDPVZDd)gUx& z&P1WbQ=oY} zs=|}#^9E1C&MQ25dCuU;lXD7B%Fh`*DT43rI6wIhV`Jl?22>X{G@j6EZv3Hj;F0*f z?TpJ99Sb0Bj288icVX^17|{9sJalIB`~=AA5Qcjv^cx;*zk5cR^NZPm122Buy`kUm zVEx@=Q!ff0$oL56t$^}gfq4s|yvJbPEGX{|m^T^9y9(y@KzZlDywPC6 zc$$%Mdb;+>kDnPAH6Cc(*m${7OJBFhNFP*=8o|p^BYm@}zWR`ov_wBm9n|WJ*7niP zf|sU7>IQ!cGLGoC>P^#IuD4rdhi*3GJC*+`YjoN51=T^Vy9@e^(>uO>W^`z7Y&z7$ zj1jw_`DEDcIgY8YaX-+g*BkJtm-gj`$&T6@mm4NKX{%mtnCz^rbh%-&i?;mbhRLql zGM5`ByJ<^aZkX(@Eq1wKvWGU`6mP)|mqBZ3CQNkHZkXt#4Vu3SI4 zc)v~5fjO5ulm$QJUJkhY24&2QV``&;;s=f|83&pTGQWdn0T&*aWZ?L{VWP8kqoDc$ zhKa7)0u$Y|`3nTq8ASzIZ+>df|9S~z7ieVa*?|WWy|q6~^wDl??5=NYZh6r#{{v$q zct`rf@GrgsO)&X}#=iQ7=7tB?FKJ)yzp~@}M8R$61tvOc%a0t!THT0eTcWDP>_u4sY4_qw2)P8<~1?Ly{1CuN`KQx|inCPnAUoi6$%r%0ILcayo z1%5U>=)d&%QlozDrG^L9mz*y-UCBN_Q7{v1BWQFd<@}XPAln-z+i06yX_#oE4Qg#C zf=B-ywE3pE3kHMi`4Djaz$K7uf3!i$SP&NWOt%mUg00~*C}(4KX^@xkx&PM7r0gUW@5i4NMJ z^vjHeUSye!bLwu2Z77 zSvfy!J%9H64ZYLn(c3CHjIS9RK;e*4agkx7ySBhY4{gwHXoU|7(>cF1ALwH|@BoxI zI6rtD0F|UM2S6bRN-3cSKshq@z}<_WnfA{Y8wLFia9-+AuKWx#ul+A*Od955kpCYv zKwRF?_)+JD)JG1GsVhHpJa{4Yk)`9yGe(vJ5O(B;&WXww^B5Te1UdWPzmWRD1yb4h z{on(LJm-f45AIw5iE)0}b{^uI$`7pu2S3cX*eIxRVBJMftN+NwM#0@+*+#*S=bIjI z9awa+QBWT0`kkL!4R(HS#@GYQG4;VjPwfvAy|h6w_n_gU&YJU$58j+#asjkbrRsdc zgJ&2acth``UNyx1t1alrp#qoC)3)QgC43_XBIPoQvQXoRGzhDL!09MXcE3ezWk z;4lzmRrtVn07OTA_|DievFXD9_wS|tb16;-t(sAoKJoiqmCI8=@|+(o>eyTW#V#a# zI+P)y_wxcM^!UM{r+Tqb@Bm8aF_Rp642=R0HiAQs^}>M%7ar7sLl0I;Etu%3yJYcL(yWf5TmiZO-8JB*9?H_G-*)Q?wa=9r3} zXKpgC1j$aGA3vd)V`{@>Uu_M2{emR@f(KJxXwIL&D5#q^T3?XQ(&S&rk=AgfvX{)}AogN1J1+UNmT@6+~Uq)S{^c^=0Y_ z^=0ZA@%8>G{H5{4psXlzFC8fqF$KzqPIIj13F^L>O2NF8WJnXh(# z`Es~;Lt}3RD5N0u6Z8Zbq?9Yr1U4xHw37?B8ko7&NanWu=Q#iiwWh|&uu`VE@d0R0 z7feSIl8#m)bTnjmBI#(G+E@VFrw5rCl+gET&TKY^s}Y3PtzM0pjpBcm4j^jVM0mIf zH3>Jt;=iSNYO})wNJ;C^49Ot^O`vsekX|=ve?${#{SmZI$8E}8EbHzdu6(AKrp)=p z>p%=+4!y#Gg?tBf%dLzPc{yvisz?d`-r6NRSVU=*D0GZ8ck*JQx)#reRDhaC@J z8hm68_@MCsv}$#Jyb`~$yq>r{`-RUlv{m)>3k)8B&e2Kv`q1PftH;;*b&i7C2PUN4 z)AQ5M)Nj>qh=^>S)tq^MR%2wNuP#U=`F@A;$`7BXY<;krZ=(!%yuANEf!*hkeaa7Q z2}5d;h6kU{&v?-BV9$9+1I-T;GF+59Ki$*2d4599J-ut^L95=EHEwT|oF+2~L<>Uc zNGKf$rDsCviBS3`l)eb1mq+jShnN7$(Gb@1D3BOi!}rDqy6>a@`-5_G!$e2z_P-nl zzT9gRKy$2JIv3!_#oaI5(fByrG7aK*Mfzx(H zgN5P89rqdq)xf$slr2BD8U%hsWKx;H0^)$y+*!dA0Q&VEu(bbQf4<>G!{k#ezizEM-~8YexR>^Z(P7#j#_k9A8D%GR zO?~;j=|N9(XM6L5zV^fipf=@?yN!Y@2O#MJwEy@VBipohcRQ3feg?^NgU1Y?odu2i zT+=_UuQ1U;Tg5=}10?l;R_nWThIXcPmUp^pyJ@>?&-~ojc=*m*{XP1B85t)qD7^f> zAAG`8mUJ~Y=;Wtf{W;)$Qu|LKpL+vpc|uHfgqjR%D}rob=@ji$>oo6V)MnCV)~@{A z*f{A9$Slw-C@5}WYNwup^~+#mn;^GZerSU4Sp}_{_``^5UgPJ+#?0o-JFr>-(uza0 zKQkL=h#P#!Y!Ug1rCjn9SF+WH@}>JfB(J0L|<+7zsd*hFfNDzwSW{F zCp>5Z`^oZ4+ii&598*CmVeGEkC-g5ofYo=98V+pA|GVcw{(E#DO|H@4!HM(8tI6Il zvft@Y_WaP%IN^c9L|1KtiEi4URcMCboqUi~0;=Jiv>S~$zjzHOQl*D2r0al2oa?RJAc%k4&errRC847WRb|J~~9{d4Qc zEkr)pcLrud%lY8j+wXw-z@Q#@NB7KbWSf%CZ~xD7fcZj`^ki<1shk&<&Y!@$W&Q-- zCG#72C&~({a7@%btu;jI$ZnFfM*%_^!*nkozh3{U6(b#s?>)E^<8NXn661>qOJdrdLhBn_f)0{sS~-a|}Gsfxcdd zW9pXkJr5^5+ISwcyQg8YjKYM;vI+|(%PDM_EU&;Z^*7@kM#xE(jsXDe~-Q%;_Z~{?C+e>tM@>snX_4{dHR2*0}T%*ykMN( z+dQxN9HaNNHH?|PRlT6{Snz^xV_akSU#|*@GDApw2)ZEzkf9JstmF6iEb$a;b%6(^?-1v=g^552p zlm9nP%m=SkS$eS5$npz9tkp>I%XY>I4?bLcaXwJTP)Ff`g3*dE-A0KYG`=(#1%7BY zD*VEIpx4OqLxZvB7sUjP14;=h391J)5|j@pBq|h zPwPbWe~lC48A0LcanVq~YRbn4{!)P)jv|39mEWHpXfYG~&}nA*^#`N+fA#|jjfIV% z9tg;X9AI9DdimdmsWbFJe)4~|MQ@YR^#7a(CQNOZS}-+nYQ2BI|9t-sFZOF`JurB% zgwgrp3cVE)P6t}e4ZqmG+pM=q2_&v^VCMUsdYhE`&31lJ_|jp@`C-ig-UAKhiXS@6 zIX^5rz;r<2;U=vu|F{pdJlLVdaX{ri=YeMr_Gz&l0JYy)4}jLbg47s2_`$gSAF3*zlx=8iFc$oxS;u)m=|9_n;wi;bSPnGlw^eX{D4wGHSNMR!f4&1z zI>jOpUxInUC5m;}p`otRKIcO56rI*$ksY5|4it+Bd@+|`JYcA!@?Q|7;_-wBI_=#T zbXt}E%N$Vr&wQZc>4XPN2Rfclc(9$32W&&*2gSck2O1tR9_W6g{F$QnO3Y6p#@2{oxSt3Fn0 z*LZ9AKxMyiJL5D^+lX~SVnBfdqri>t4O1sf1)Vnu5(SG*Koy0xjX>jk-HnZZnGf*4 zmwzvHpy@yF0lh~1#-7HxjiA~x<;#o4pN))@Uo`)0W;^hr^=E5?KIhaRaDpISaO zed?~MC%-dH2cJ+k6;#)7>9I`#&8V7BRR_x@@fXXt$WN7DAj>h8Rd4!lu`di$*e-Y zh;PYjscq?LnccFgWoOHYmirCw8vZu$G)gzFYTVg)j{l-8NcCGrj;RYDN$IVU-Yxx? zk@o=TG|+eQ|K%5nZ)ShO{*_(f!y@U;+)uc_a;M3c%Xi4nl$V;4`8{E3!BkKR0Qq@|fsqA7G;uI6FhUP<22mnl4kIIoVgyMsGJ@rqm>3wC7?_wKGy~{x ze+Cu?78Vv31_l-e4h{|m1_llg;@|+$3<3fS3<3-S0uUNv2FQFy21YPofCzz12iXMx D{)5Mu literal 20268 zcmbK_IA7)_aJK_29%f+RnX+0a^DqNL`e6o! z)WZx6$%h#j5)U&l#2;p0h&{}}5Pg_|A@VQ-L-=6^hETBjbfLh*3=IB<85n#IGcb4` zW?=9<%)sD&n1R9dFav}0VFm`r!wd}ehZz`b4>K@WA7)^%Jj}pgewcy5^e_X1@nHrA z!@~>=`iB`9bPqEyXdh-^&^*k*pnjNvLG>^LgYsbp2F1e+4DyE=7-SDKFi0O}V30h_ zz#x8@fkE^z1B38k1_r^y3=I5-85npEGca%;W?2(OJ;cE9`w#=e&qE9h-w!b`d_Ba#@c9tP&#A)i4>2&jJ;cE9`Va%d%R>wd&kr#$ zJUzs~@c0k|!^1-i4EGN)Fx)-Fz;OEz1H;Wj3=G!~F)&;`#K3U*5Cg--LktY(4>2&D zJ;cCp`Va%d$wLeb#}6?u96iLqaQF}d!@)xg4Eql;Fzh|Vz_9xe1H;Zk3=G>3F)(aB z#K5rm5Cg-;LktY-4>2&TJ;cDU`Va%d%0mnc%MURyEIq`)u=o%I!@@%h4D-S6WLBJg zh=C!EKaJmyKb*gSUxnX}-;v*fUsGhO@IK+A!k2~b2{Vh-3JZ!zh{%gHiZ+T)6%7zu zE_zhdRWuU}`DAWOS4o5LN$J(nRnm*3yQO8AeHcO++!!1g6d0TtTo{}g6c}6>QW z(;Y?zKYu@01|-nQ(#6uv(!sn2;2iz!WiwA}JDJ!LSX3DyRl4 zlon^^r7QS^x;cV)$@#ejnK`K`3gww4848YJLAvhF&I+o*42C8KmPRHFhQcUh4}}od2(*x9V8}BxG_VSH^aKTk zf}4MkLWHls3$o8o7#SE?h5C8>`G@-{IQ#qhI{LYwSaj0Jz|hLmFU--$(*>qLAvD<0 z9hM?b85tPC6$Cg2Ir_SWxCSAa5#|~c?CI}^B*MTT!t3ns=jQ2-5Det?;5Fh6^+dIu zfuWH%oHxkT(Z%1-ClaChDeq<8&;TEQMgj?ZYRKml8WMu+HFv&1J|8}4+5>5X;yAuY zK4%|SN91rx1KZ}|>JtD}1g5gUqCvsIo?tE#u>~xHBmiRys>ts<|NiX$`;YGJ7kISb z!G=e#UjBQ+bbxgN@1#YR8`*Du*Lt+*<%UO$2V^I$wcN!1@H_Jbo+;kyl?UoB@J+eE z-SD_!G9%lQOS~8Prp)7MzqsI9!lUbM=CMz&?JZ_k* z$aMC?!3TU(7V|uq_*&(|#5XFOQy)zHsPbXrCl$`A4HJ2|8vcJce_%2XSLsE*DTjFK zuQg1ZtkN)iD7I!Gs424-6jsVpM20 zZ04BS^l-uhwKqm^{!H~ogNdv&KQtLkWZn3oQ`_?UlNX;Jv`n1vU_Rs1^L>veJkWT7 zQ2pu|Oz!&mH&0;fi|6Gh@lWF4#y?3=<^TDHi4_dZ|G5ryJZP9)!O-!xWk1N@4Ge#$ z{yWexF@T{hpUF8YZ4$>_}*se1?%@D#ZL3&p$k9Y=-cCV_$ts^Mj`!9yB!e*EKXZ zG`80_G;>UCfAHYdhX+l~6;n8-A|NPqA-o3@|EYYK_+O>5dFrFi`5PDoRWgEV{aqgg zJm`2k(-v2G*PezuBjDlazYcwhf-aFr@zv6x)l5UvI zi2;S2Alqdgf$U|O$eK-ADv*nnA9$DqvCsVWhVkwBH;m8Eb4=x#a$T8YD#Xue%9bDA zFpBB(O}VbzIax5^=68rW98*CeFbvWG3ZXlUAX61Z4Ov%yOfo2Bo$&D&qhf#|rwYHR zJSaxQ4_t`7Gx>ahkAA=dFM~i~e;k07<0ACtt3*%?1Ny!GJsGEn&7|JsA! z&EUcphqszO&n7}cKsjZ!@k7 z+mBVfa&-r+a-I6K^jGWeR&SWRfU{xZLe4f&>GGsu@97lb3KdOip8Ke@lw1COib0*znix zK=0$u=B`Iw%?&TQo7-OXG%Gwbe>>p`D1;129!1?LVc_c#I24@4e3)cLRSdCG%_=k&h6-LH4x$sN5557+9czn!FK{4`n5 zypz>|vcS>B{fW_66h9Hl$EO!t8 zT=|8v8)X?q1z9;iFrNpdFHjx!f5Q6-_a~g6uz$k(3G*lPPpF@eKOues$5j1E_LKZ4 z;ZJ{{9H})Olv;Zj9YtFnM6f5a7P4}D=sSo=nXlj}^VQUg-&^>n$}f}OF5js0<-vTt zg*qE`G8rH0eAH=?n##3|YdcqG)2yb|O?#S7h}>j(#qyhl<4gTP%|@$6P-)8fCFvk6 zRoCf#e|ul=!4p5d4-e1lJ%4Mb_xWkO-jf%3dY@nD>uI)Iwfi>5HRm^1wC`l>)SIQZ zT5q?Ch5m9z59vV86!B7ajxVbjLFvi>DYPB1q;Z&70W^(gwpX=-^nv0&v$d)fmPSD0 zFtwn3gG&w+ySU^)=@6G3$bOJq!K5^{3uL+(ls7?UU~@A*yYb0^@(C_89Yq6KCw}2{2@_%Yg&Mw7n6!WsmrJM>BOq6U>QRt;Q>06| zL9q@>(V%<Bd7(iLVPFt&F_s5wBRK? z?i}bp!G41N1dgdEn{G9|Zu-+ya}K%m&t!BIRe2Bu&TkH1LFGNDEdt6(EYhOfYTV}B z2gEM2J!1RJw&8K{=4UjWYk4HG%o8m3N|I7wxOdc)*NDh(x_$~Qm2TG~w-}8QyZD{^HrD5W4l^+0Umm!d#Iq-UK=d&j z;^O^P9=MwYv7h|*h7q|R@`mxn`PGcDG?37!@F)q~Kg*1+@#mTHT^ZD_d&8Lir1$~f zly}OV+Alw*KP!H4juFD+{9=C~{RM)5@niZc1aIZX^fw4zTxuZy$xj01kq!fe5Bw8AH7>{0&Sufu zosA8XLG5=?%e^6Bwr|7ae<~9u|5w>^1ENacl)}WnDh3Zgy*>2;WA!HepN#ML|I5FR z|K&TOaiU<%0bDZvIAxr0%9!Gm(ZDGqjZ=mXrwro(j;W>RK|WK6{lloxEZD>`^$%l1 zR`2i%( zH|2@qKgN`aiqjGWzk}N{98*^_!u0G?Y4de8` zoCiRybI@20D_f6#)TIt($q$fN>d^<$4-Pj>oTAcbVEFOGhbDu_56uRaUm7MdC^QB% zOlDB%Q1<+|@N&t~hKU($t$%-=Z+Qq3ZGO-&d5X%^%NY>y|L>sUps|=KDxH^Ojv`EG z6uf_)Z%Pac-;{F-O<;Z3&+|>0tiU&=ltp0D6qO6-8y zb;WT;&Z#X}?1r?6Ii{{)On6lA0Ae2BlrGjD(YdUgpS#{XI}Z`NeO_VW9~DJG_5%u! zL23FAqhJ##G!#*Ie;5@T6$M!jG&D9EJAP;|7W@DTLxD+uR6wB!N*NGV|Kk}C-dyN= z#xb?y!K?@W!K?>wzC37b?5l5VhNKLC7LXov(J-*+%lBU%DK_d)R%q0ptVl$RDop&X zB0ougvfeXXDFqSxpt!n!2jn*pOZYB`C3hE=9vbh0Tm_QhzXy^Lz6X;j0n6}BVP*rV zK<&TQFrI&Z;Q{+g(FZ+`Zs_e`YWul96<;R0Y7g-ZNUT6Hl$a3I- z(M8t44|f>PGBQq^!{{^FaGK(Dmx+#opU+n^_P>82^@Hmt0EL0{>Y}C{C1sD zaJtN-)@PtxjcD6|+B=WV|6x>^sKBIa zi&PXQFH})^s4#h+is}P}$#Yc%CQVlnm^4F0VA4z#fl0Ge8YWLwnJ{^p3ddCS2MUuH zsi-`|uj>3{hlz_+0v`NgG@Sm@;3KQThXW6K^v_S^nEEK-zdz5EOl5_M3sfddT&SWc z&iUo;0fPsf`V$^7PS+5(Was>%a4_Q`s2l;6rvj4}sT_prZ8Ze7(>e?}zpxzywa_#V zf<$HemeNz_IZbivsD5n&QY1g2&&B#CeKzem^?@27vqEYU%m~^3KoW}j^Em#CQLh@ z3U?={qy*awj-`bv4il%V1WcTvk}z?mO2NcgDi0=3RrxS+nu@{;g9i-{r#|AGdO{!6 zdfa{>@d3=Q2@@BpAhQ#u!g((Wz`AbSdGPS-ql5>I6EpZ*A3d=A!G7^OObxn?4iWMG z`Tq6(4wI*=1WcZxk}!FuO2On=D%R&ov2i|V65F(J&a_U^#1LN}olV+<3Oq!!2 zFloL@Gc?Bbo=bu2?u3eMK8HwchtEOWBX_=G;v$tsgTfE(29aMHCeBrv|9%GlgvoPN zKqUys7SK39s`$6_4HM@<)y-3B6l6O9QU^+Hb5%H|B2vn?^N>;Q`LAd2&ob2bF#jcp zKJcX>NMYh)6@!UORP^l)StGuz1lL9mlNYN5OkSe$6Pf}c?Lhg798)K}oxwlLK;v`2 zspRJw`g7~&8vp#%Yq0V|hk@mXZo|m$0+SZ22uxa{^6Y%W#KkHTCN5E7n9lf_aeBk# z#VQjfFHyO5{=vk>Djy~;Q30iGfhL&xhKT~Ipp?1bKyQ7oG3S>#2Od8B`iSL#ys_a2 zS!2Zy?->Or3JU%>FVU3#vJ{*uA*Cbd7qf%8uTVv_4ko`r6_Gob`4&|~=wSXkR1vm= zsSnCfO#XEs`yr~xy90@jQAHjdNPmJVa_vCwQ&f>t2a=zoitIa(`2tmB(}Db#s3OY_ zq`pQKnROuh4XQ}rfy8&HB0&c_-W+)F@a>lePbT(>bAB;6@aR2^?Renv!>>?rivv#{ zL)eWUpFV}K96vsL4q-8V1dZySxYhS&%7de~&M0$!`F9Q$LqE@fN|LR&y5CHBu>IDj zbD-X~<0Gf}2N<2_Pv8|)=?j|e|LDBx1A_-&&Z|5yc<}MO@&khh@6IbdFnI9#yy63c z2QSVmzB79uFiAjF-dOUZtnthbg36K~I^P_8u=u<}yuJTVM%RfU6G3ApD?fwm`o+jO z_27f4=k?-{>^-mk#O%SY^NNqn9&A6a{m|^emh-9)%pPn!um8^U!MgLBZ%rSp zKCk@7^udbry01(hEIqIO()7Wi^BhwbJlgi4>4D(1p2>pKMW^*l7M=d!$&UvDiv$<- zKAQNTZSnNQ{qN_$Z&*HYdEry;*8n&t#6Nh?&a%$@3?_pZtGv!^3Hh z8YXX4nJ{^iO2bPKd%enp$s1GzCaqEtn6y$wVA4_*fk|ss1SYLh5ty_>1!R|SQ`^f4 z5875wU)}X^!h?qO6W2d@@)PU=kj)?$biQbA?t9SC{NT~I2SRQCC%&IJe`5bc{t5j1 z_$SCukU(;W{$%^f{*z&@nJ`g&(4Jm}zW(r%c%Qf0!#r7AO(4}P4X zKfPeO0p}Nw12gpJ6f}Np`rV=4@N?pWPW6V#%T*>!T%j^iu>Qb=iK|qmO$FuY<^u{Z zG_@5buTp84xK?Gt#C0l+(;6nPRhck(ol1MbO!ZFf!Y>adZdCa&ag)kT1;2+u!k1}NRUc^ZTNqe;nKo6!K;g@@si4|?+Eke9CxBhNS!LOIP%JGz-}4+{ z^P%$!4{FXM;vN*{pb%d_c|Rl#OkAci;X${-MAn9{e;8lJ{{y#J9!y-X@?qizm4?Pf z!8HdOo-|B$WmA~ATE$@E8hB_z+Alc=45vMqyk6zQbJ{cv$s;X1qBdc7j4{nabnyAf6i=sJ*icZc78$YLy8S*MQT(YLy9-*Qm^41oiHfwLz&$ zVd7d9gNf@@KrJWE56jMjX7QJ)EIp4L7FtkS+8;DbUZye~>Ml_2x=dvPl-C88>pU+o z$$?W~k{hSMBnA#p+;35-Ki~fx;m-=F`d~2a%69eqgvoAftDwBu=Rqy6Wh$xXLA~z> zPrf~9dC=4>)OFy+#RpB#`kFx{LF)sdX+4vLrZ+wanAS5nV0zPoplLmmgQiPOlbIwn zz4?LUw4TW`p3Z2V^>k+QgeMc5r!_Y=w>3X_@Z&-Mg9+f$qT|7Y2TjW-FK>R-*bHi! zpFaz-tzqJ3l@8^D9|R_CRspp;6xkXktFa|aT&q$rah(cioVD}IgNg4|K1}?e!Z{V@ z&y9B*CT>w_6x2EZGKpjAgNdJ2K1}?g0xD%Vr%w5=d|-YZ!*s{buskR*X|;;Lq%~l9 zY^4w=%$BKu%W78Q`Wb!XQwhD~*!3d5lCdf}%6@JbI*yWyvALL-}A($oZ1 zHodf|X;TwaA4L53&yP==npkj5U*W+eeZ>cd)DJY*$E)ibJWvrgWmovT4cv~ssM7KP z6g%5gCQRP00*d{uDxki8!{m!9O~^728zv)UKy4%3^Mjz?vL1MRwujMS;zbq6to#h{ z+7vysQC9R>AdacO7~jP~@?#C-MV;@A2O4Hx?NPnX*gLtF@$!^S4{r;7J)iKf;K2#T zrtLe|=aF!_v1 z!jpmroo}W*dUgfmqX`pFsVtayT4lq;Gb#;}&#FwAd`@M-2V+C?#O6iKo0~yp;6;^&M-v|0KL;ASYcsm|p~>{% zhXzy5j}u!+pUYt6eIxQHp7Fzr^?Vy;JQ!~<)=ubUynVS{^&4a3P(t4 zL4{Li+LUQiCaA2uG4Uz{N9!+@2 zaxP)w36&2I^T8wW4i5t!bi4+wlDfjGFmZ=U!^Ax*4O2D5Ilpuq*mil^gBj{S7$-E# zo!f93lqW%K39$YL5A)#qLF0FCSlQ3b1FHe$cu>4uI17ol8y6b|Ee=iq%YpQR;iU5uCLU7h6plM@Fmboa zgo*oACQP*y4nIF(;$am_;o$QQ6OX7&n0QoW!cZOH1MJB%~cJJjcCH)(IyR+xBE zMZAlwbuX140PL*CpC3RzUhRM5By!AuXA**_J ztGv*EF!jOYJt}W>LG)gg2Vnj_l_y|&ze>a811bk59aLeMd`QJ%@?jNdih3~N!R<4U zuzP#~6uy7XA;P!)fj=}{uR`Tu;Rp31$9dpq|esOiftGzxN`Z3LGnp!7BA%n!!IM&vXON~2d;A$3*a zg$hQ47mxWq$|OBprgwvJ&jh_o-Kswr8z=WOa_elGvO$GgXWNu*Q#PplyRdo6#$RVt z4*a;N^YOuXHCWxZYKr3bhL;l_#+~VG1eJ_djfTzIjY`dP8Yee5t2e24s<$+EJeu&p z?@Yquf(IgJ8y-)1unwN)d8S-p1+{V@Gee+}VS`3xb)!aQb>l{5b}G zI%s|ghCS3H)s^*))m79@)fY`&U!bM_O#C~$;P*-T&H59XL2EdhpG|)D>---^kl8D# zV)jbLQ1yn!2@hJtr?Lxz=XM+$10H}}(f9zgPHyMth6i8IJ3k9}0P@AF^XDgTn0Qs? zz{G1R4im4dESPvn<-^3wDi0=JQJJGZp-@|2v2K#OioQb8By}x)mC8x#`ufV{lhpO} zwTdUHTk0E4wJ)$#SJqdXsy0?m?4~yv0(C5 zl@F7zsXUl`UBzMYC6$25msJubUr_;#o`T|N!Nkiduk_y+e0cC6=D+WOiI-FkO+8<5 z;lY8J`@Ro4I~reTgFHPjc<7szP*JFs%h z`V1K$cQpJp(Er6~IC(uI$VI;y6({d!6q@$sk%w(OJLiYC^IsVo8)r6lsvl~Y)p%0v zq7GF;`G$|0?YIg6g0;gK_$dZw}3kO^2G8o6$oKv~rANDr{XM zsNeAl-0xt0DE{dCB}nP|{SmLBJo~}#d{YE?voCijdwwvOD5|b7QA{1Qo}$ZOB5THn z_{$y2f*(pRFSz^)rGEk{^Pa^0^S^i8Q1I>fhKb_pO$Hv{6EA~U4U+}bCtqopD4-6i zfi4~ZwZ=r$`KIvj-Z*byvGJSVWsuyFOWl_muADz_5MgAH@C~GI!bA!69^1zc=COm? zJJ1=)iIVDkQ?4-gFfvT%{IcV`!Q~x{pfx-PFScIVc-~NO{ds|j;_C9{Dwm_KJh{}N z{PMHF2QZK<&3N{M;7E~Ab+3+Cx(#1=S z`W}}W9=KiNy~K1S5aJ#K&JRB48y_eeaDHfb&@fp@{mOZPiGu146NS_}lnp-%B|JIb z{9xw!<_BHPU5`7P}Tw{s5o6=dgk|r2e(0O%8C7qjTisFKQDEk>x}4KR?ZK*&VPcJ zG%$bUFm^LGfc%|Neeu9VY4r;eWz-LdUu4(#09wNZYTdnH6nLO8-SVrTAkP8)1FZ%V zKOVW*C}?4w`JwJ&hcc*^zH`3$!L9R+4{n?Xxvl-L!2yKNAH@9kf6!n!t)cOw z&I_rJ917D{e&~4cLhK_;$CoxnmIDxWRu1THoTsvTgw*eK`-_5BBo@Zy--YQXqW z1g!GM1yE?cywE793042`{PXjmknT{H{M>4g_~H2lNN9m-cSH%vF|`>j7C_@V=xSi$ z+AvX8eZoXJ^*@Z5;kpnSt{NZskwUd)V%P=HnmFW8y{mG03M^bN>hN8tJI@0S*K#c3 z3M)AlOq5mMFi}o@ee{0+o{1A4G&N6dZfNYSY-mP~3xOuk*cz-Jug_ zsB=u!i?;WNsY{w#G_|0A+Njh@-~FmW0M;n9mv;8)_O%I6pvK+7RIhHwB^&)?R_^wvf>GYR+sn zhpQ2U*GFEBnT_Iq6%HV3s6@COLQTR=ur$!pJhj>30VFLuG#gG6Xli`GKLOH@0kwOY zKr=PaIu5r9_c2OINbl*JUYauJ7rO&Fj0_L1G0IF7RG#?p8l&K}w-f(N6q+tPt!JX} zbdhOuCQdTo_~LqC#zT*XpcN7UA2c2qJecrce!LRDvAmwRJ^O{vQ?wQJ^$QFhs2Lct z&iOjO?xD#?){3tk%8VZy4NiWUkn>K@Pd8J)QNQ4RhqB~H{`jrnkwkvMBj-W>LCwqO zCvZ%ikO5jt_D=7~`3WiS^!)TQ^&4I^^3QAzxIeS;*7+F^JRa;i-|*nkdC)qZWsTb# zC8x6l^ zpq$$_q;#}*HZ~@7g8K~|Q}wt1n9}s% z!JCf{n%ZAI{P5t(#077*Jh(OO&E#9tUxWF#r@fhcdpbykP+RxoS&#ba#isR6o-`Nf~R5WoMpYkK?t#P<_n^JeuE^C!knM4y2KwdWcIMGt_+ z%th4Cg6EJ4)BFcyJv&R|hd4e<=9f0p&Y{+3kO&4}e-54ULA=96;kW(i1s5 zwFSR4Jh*!v(n`M2XgK{qRIW!wpeg~DujYg5* z|J*jZn=nya9bywi&)M@0MjyXHR9yV_`Zf!+%wG6u^KDR>?R}d=-}APFzWePTdak$q zbs_zF$T)F@wu5${woi9#cV2gWx7qEEev{js{YJOD`W0{gy@PDatn*+StT;ccIKT6D z)ooCpwx{!N2VbXrr`GL$U5(of`f9fu^;K?n^eWx%>{Ynk)hl=V=`B$BLEL%u4A=xC z&JXS9XWTw_2iCXl=$_e)Y*Xra&>D8u3122Y(B+)6{XfeA<_k^Ilesyja$Z?SyiV=DSc2xzqK4P!=QWn)+4 z>_*TCW+UrFR>dzVk1F4GKb`(S_o4B7&}gdRWlzQ^#@UQ(7?;1=_~h{YY{nYKHSe~( zU&=UzamW2*eAne($o-W2{*UcIkY#8 z%yCTJe!l17ghyM>gI0PrOqNlYFj-b%!DKmw4U^>+IHvw)yu%1NzrZmdz~RPsh)C~5 z)(H)gi~=`5&*X-PfMh*BfX+E!P&oOW@qp|kkjMk5dZq)66L`TQAQRR-*zn-V!!M6M z9pdej>+J8G(X01Bra+z-(hZg(RK>eMX93)c(dFR7hbv z&|@a}MInRfK!=&*7i9M}3LZQ^Lw|nl)R4&r8ee$g<^BIZ{@KiXpxMmuL$i6|hh|gG z58($C5By+kXzXm}io|Fa)RXe?|5^+!N{;{fwI)XV=iOr4<*@{NAkCcWwZIS)*j+Ay_XYU0#-|9=1Z z{t6kJ^t2urJXpf$adCy-3JK=}t>&6v^y?s^ss}#l|E%Ay*Kc<4gT$8()5;HP4>Xud ze&{e){IKGHzP>`@CcQ2Hcn@^zwj}J(<2<19pXn1_1F%8+SjZH6doEpU^<}i z(CEPr#_j)5-N*)ZBWPwG|huC*8N|;UvJw#?gQGodi6_10={hd$8})S9}W<| zj`cv5jAJEcivUj`M)hf3^d~Q;Mgs9B9&StKj@l zJVhDQSNzX*AWElLMB+;@Pq;*}PO(S=G_-ZvXI?0tqSN~Ae6fhY7jp^51BN;({{;_h zX9UgJ=(KlT&}mirFLprjKl6c(rxPA99q4#I;lXxB9}t@|NVP@N$ZM)CG80T1^$1|-eEk=$aFw=BI^ZE$p9(` z)bv3r&0Ed?{ylHfYF=;BZr*D6pYwp(W21J9wERUa$0 zYrHjlpt9e%opBndJ;OR7F`&SKQQ*e+hN%;#_VLe`2Z@5kCZLMK+A|XRocgaByBiz- zGK1Z%aG>eGzyZI;_(q*Z+eT2?QuF0Su)aRVqsjc~4 zuhG5{wDw!C*}l0^e*$>V4X925tvy+#u3-@PQNghBXR?9xR(W zeQNvE@~P=lcTGL{onbn7ck@(G?ZKtTHU%`3WIk0LESJPzEZ-tORepgi$5d9m>A%Ik zFihdU5dN3-g6jqLKTH?gzHl4}nCdXqV5;I&dw+lbcz=$msJW5&9oMI%Z*zn8Tysv* z>agta=!kF0YpHGNX_?)!s%2-(iI)2f?;8F#@H9#{u4>%bc#i*~EJ*cRMvkcqA4%!0 zlHM)-my!1X=){P3^8e)*iEn0q!v2+A;lm>7&D>A8zjCL^m&JflWMqH=CWc@J7|(=(fuY8VmEjo!1A_^J0s{+!27@qz09bwtOalW0LthdE zvobI+FflNI<(-ll7#I{9z;crq7#Kj94JrpR|4K3g!z6_UFa{ZA&d0!jF3-Tw$N<8| z3=9k)43p12!objegn^;;2m?d&5eA0FBMc1nM;I7tk1#M)A7NmqJi@?GeuRO6`6vTJ z@eu}w!Xpd}`9~NSK>D(eFfe2uVPHrC85rIkW?*=In1SKtVFrfhhZz{29tQb&gZRV43=H=VGcepe%)oH_FayKQ z!wd}94>K@aJMFdRM1z;O651H-|? z3=I1ZGcfEu%)qewFayKR!wd}D4>K@qJkl(9tUb)Yu=+3q!^*=9 z49gEQFf2XHz_9o*1H;0@3=H!RGce3O%)l`FFayKP!wd}54>K@KJ#JZSu z3F}hU6|5^k`GJwq*DXHOCnU(x$J5;-gn@x!p~MY|PRU-$iIS5fpGbX|a$sO*VDfc~ zclL1%4)%18H}r-oGLz1f&XvxSHc|{$WME-oVD@#35AX>MHuR1+cLG@nGRYN15jz75 zl1U~olcJCn39vA*dItL&nwXdvJH`k5dAhlQ-GuINbkBioM8=_>F7ZK*elGsL$f5`~ zNZ!ZQEhOI4&pF7|*VPZ?d4x0rNInP@CO8y;F4MJVuP>_ zMsfj(B4e12cxQhFYKlU6W=V#EV_1-`yR)-`YA}PLsezG^F@vG8fu(^VgNdHGo)Lp;F#|O9sg^Q; zP_T|_FoTc3ql=TLAA_@xt78yI7)`*mR3SHvA*wY_1i2Vhf{r%iL-N7ye6Fq{> zg1LgBp6DU5Q*e@CkgKDMzn>3MbgKvn355oLtOIKX6Ba@s%Edq24_Vw6EE?n*?24Qt zoWP=?0q#MLE{M4E1&jK+`UZPOAw)r@MhJy^x?qSF2swp@gdlsZO=yx(H&is<$KMa) z!8t-Jgcb_xh6YyQj-H_MLcz^H zNFf5`VWi^Wgpq-PRj8l0pMSWYg0sJ`ucIGQFflMNoHQ~pwDR-|bM*0afhkZ34R(ZQ z##2THMsNiIjzNyTt|6{LVB4XDpo;vy^Y8CJy0`!Aet|~|9&C8@?!~8POb1ve@J?D} zxsmSNnjEq)1(IzCNnWjelTG&3sb{n1*VS24U-j_K3-^;=)usK&@kD9 z;m`xV1AJ2+2t1hhTjRsTKN_4<`KEaAKA8AbKm&o85pu!epEIvWL^0|(ZG<^^Mk?zg9i-{ zCOr7X*w8$&`6MI9RHcUo589qjLK2y&-e@q9b>W95gNdv=KXhtqet+`#(*u=>1`p0N zK0dGa*x*6OV`TNO9>Qd=oPYEFBUI(N^YWAUC-HCNpCqXA|GdQ1hKUsn&HuR$bUbL7 zT*1)swq-vkOd1&ePW^YFVPXJ7TSCL+0EUK%feelR|C|TWP5=L#7nl^rp!h&xaspU~ z!ej@A=C>0bH%wOJnlM?Ns|^&YTndw&8JeF>c+fDJi)F%OZkC40JS-C?^Rg&RW?)g6 z%*4_#@eE@}Lc`=Uj2u%T_P%)j;Xz|FgxCGBVR8cl$5c@G_tk^Kzxz$Y zhS5Jh-k(WdX#NLA;rSnU1y!Dh|MgFqm?+49;0DR`*2M1(5AIJq zKT&=n|3r?dcNl9XmMeFDP8WWE{uU$af!c}X%7LHDgkPLDoc5LxWWu-e8I6g856(B} zFS*}{q!VQO8^*+dLQassOdt6?vY7vY(GqUE%0wmQ#t(^xg{&DL?lCeSNH8p9b^M?^ z`7NX2G>|TpiHd?>&$k*(WL5kk(FAf4$5hYBAQ{GKx6X4+<(aZimt!i#mty*9%9@-Ef1DSZ|9!HxI}y_JI9x~jG)kQ{Gi8gFMo%zaboXekdJSE=a_n%ab4Jc-vi?geS9qu}IgL&EfdY~~g(nJ7oogA>)XUW! zu*!An&(dG5zgxXw@&e9=i3>T~KxNL8hRF*#8=!V#ih}$z;R(n+Fu4g(^^KDuzU=(o z@UUTWDjUaCP?}@7z;NO0_IukQVxV$Ajcvw*36oRVW<8uRIgxGtg9($DaSBXY&N<=D zgvm=eXFQxRc?oC3SvW{XZPRR z4@&La=lv(ePs*QEKdFDx{7LI4?Vogh()~&AC;guUE1wW4Aq$=ovZh}A4hmt02Oik#vJmtW{GkVwG?$uLxa!JqN;bJ}aw^Q_jpStR$ya>}Pevz){sUM}EtzWL*s%N49 zobiP8MNS@ZS$2*uFBlh0N@JUVlx{9e!c0pru>+GJX$hpq0gIjnEMg^k$f*iu5-2=j zsTU>&GX21$G`0;`Ou?ldl(Ipt2_RArHgiDnjqaBDj0)2mKj`q=$~#U3x!+;pLQc2; zf6jy4>M(HuCn {EqBmbQK_*(8WON-Tyy34{~wBqy?Pl@}TfT7c0P`4wu3qV&)(1J)k{`Cf>z@A;-cPtc;rxXC6V^|dKcRm@{e=7p z@e}+fL>|+hWIu^eiUj3T?dhNt+}o_F7s==-+VUWRJ(0DLmE%L}K}34}1y8TPre6Hs z!ar4hnf!KnP?`mmt}N1`+-ltB+^LKYbw28xY`WF-y6I07kEkrG9;-bo$Cs*uoQ+bA zU_X3`I;h)dqzg&u4<4S=`~G&n-h(Ii^gcXXulM}zJiX6P^Yxy*=+o0`w{G`qj&IIr zuWUEd@zjgb%hoGban-fZ-_DpJUC7BMF3!&J!Rz1-##gPsTS2ivYRZ4r{<|Hd&tTF5 zPLLU}bORCxr43Li3`#G!mi>d|rh*CBa?^u}3pt-b^VP>VpkpIxdK&G=vi*vW}PY35GP}%~g#t)az`8CEj zX0%qe-U8S5ptRZ9IIFRXf42NjMo`_pLVPFt&F_s5wBhAEsI7=A*V#|dpTIE{6gu0^ zaW+deYd708H=aYT2QnEQMO7XIf%BNdSM(eN%0IAtv*CkZSiJ8+k&7&zA8s+8;JYdJ zhp~5Ji79-xXM>K;%|UjWYOjRr42G#PMy2|dtk!1<-* zK#M`;$5sQ*FH;V*8E}5te4yQc^UJ0K9R{3VIu9&B^EIfyz^d7y%=u;UfsZHhg|Ckx}!*L?+D>jGR;No_{d$zs84&44M%2ATfoB zteQ&7iJyNko?~R1rWnw~KT%fkfs(S}2ZKh%2Zn+Q4-5kgnhmFcYTAY0Z{Rc`@)NoV zmS7X??KwXvJg|?4nKASGHXLRcK2Qwc__F-GvGUE&P5Kia{9t^+|5M(f(eQ!4J?94l zDBnNcp;<8?eiq|MQSANk9MK!M6tu zPnw!L9=3IZLYafD?LWtXhKZ9@8UwlvR(uecG)V;{K1rp^AmBrn!O8Ei9#CT=&wY@( z{`iK;AT==YhDL__PtJo{WQd-L&7(hz@A&`AKbrb!>WBJ&>JRGwslST+;}7kh7{U7| zM%el%9Vq=1OKAV(+W8J;$q$VN6F+cFO_X zzM$R=sJzhNx0HvJ7oheHsJ!5q+VFs5>f@JR9`(O(oIK;vV@pu4rTOKQM-7uFYfP9t zMWf-tlm`uyr)o@?JWT_X)~0Gqmwbx>LSf=m4TFi(G@j^xcyOOlXquL|HG9BEr2s=tJ!yMxg~?Mj3?@(0crbCY z#)pYhG#Z*6o98p?#oPNUOrES^FnNkbi+*E(i*nA9|BZ*^Gvy?>-;$2LBfNA2b~XQKH{0eV1UZ!Hh`pc`AMKsT|!?lK*GS_ zL&F392@o?lrgk>(yeTl5Q`1pD;K3|LC4OUhP_G|M$D8>oOy<%wn9QxoH{~d6#{Km- zIvX?e6XTj6*k5c!GDBe^r>4OJP`_Ngz*xOWAH@0zDLwc<%Y#ah=kecsCp1nJtT;eO zMLIzhVFXpU5>#PAP=zu<6+#46FdpET+8=Ls9@IMSkB9Vm-!T5T-w@l;ED0UE`NP=I zII(f2vfu|$o@)qJKi}{eRKkNs-x?-P*Jv{2{E~3s#D``>#*Z`fCj`wf;P~KsV8XXtP_8sg{IKC8sGrKpCNOEb2Iql> zi7ad_|LqTe#Mr=M5PgcDn+-j_G#IY@aNz^U1dw`=3C)H#KS1oP_yV(0@gvASj;SDZ zATvPf8U-OXb|~-s1hVPMd5}%5f8U-5sbXd0m0cyhvl!SjWfgzKTK(y zAq=W7rfY!685-ZAc^Nb+1{!6;oxMsp+G0lX@vYH8#Wi%5eD{Cf9R?ZXAiF^J zfb0O74>H?I^Tzq#j15ML9~ulhQEE!jX^6TqBcvLwt`tG5D>I|!NRE|n$`Y-n2Mv>FX{cREKiV)cgRS-NFQ|#l zU~!JAi4PkeWS>iT*!Uph9LT*qQ{1&7^iCc9_off*C+knvfYORkTH`fDT=9YaWcf++ zC-+b0o5H5oyM5kvo@u@N=k0HO#xYg-oy8-NUeyO?U^6h)a=_K{O*zflD9Ci6>kY@$ zO?O(Jf!aBR5BR3=uz^g1)rFwCX(71B(ZdL8@56cl=NK8MX)flRs=3hM!8-6*eZqsn z2PYW$ri8JzK3j;=6R)L%OIaih*VmB&*) z>b&9mE64Ca-~rzh8@BI^5BNXIH#Bda!mTUt0MyG`0Pm+9XXKpP@(jJV0~=Z4n7V>7 z;ZeZ@gqg<~`KHWZ>k*yH`teiOo5$x7GS|*4Ok~qk6l6c3@c0j-Lh~O+!6s0sD5CKG zFe)}G3bGz(Xlyig{Lo-5_yH7_0+ZM@L7@psJrGvg)0q#JT<7ERtOswt zJZNm}t8Z+Eq^B5GkREi=WU%Pt2R|PvHtJ7SXw;vqPejau;z@pz{$!fmoKeVCiGgZIJ6gYIh;2ZG6B3RonPL8LqYmu9oXA$Rwz_kGjFU zJ&X;H7T<-LTLxGA_Q`WqkgPnMr_fAV>FPJ`thP$>c_hu$#eJc6a$#t$iv%iyJ} z;)kv`5Oo^2TAo2zoloXI*ma=~$^-e}FxUsDZo@+4?JZD9^Gy+A2ho`MriStS`wI^Y zpB&aRdvICL=g}6uHpXp?4KG1`3{ZKm`0*QK%ft@l&JPETF0vMUxX#FY;DFIZR?iQ; zlWV~}eZ}cN7+WSb3Vu2NopIx&dPc?R-yWXlyC{Qd&ckot84afkG_``=3Tn|JMoT!R z{$W&@sKBIrK zsRqYX^#=-*XKUy@G9*In`N=2rCrq5JG1Y+cOUr==AEp~{e(^bw@Ks^rN{xnzb2K!> zIlsI)VDMnV1IFnZ;+E{3UqlXOJOq{BpgK%o(rk^!2j?epOr31N`6cGSjt>(aI80or zq5t0Cfr_*tXOsA3cFqs^2U;IAOa`fZb$*6{$S@bfVP&M$!njv5+%PlT&Zm^eoR z<~|TRVJe*WqToT#-l%s<~Sd8I}R)QuqDC`??YVK8yI#!tp4G2eU} znolw^PHULFOk=|2)#s@yJ1a;X-t?nUtJ0sfA+rn>K1>LjW%%JsLy*G6 zRT>5pS8M3o8?pv`fu#{pZ&P9NDh-3lt2Ge4QvQjMvII2S!7+7y%q#VMX-t^7T7zNw#ZQdW8z!&Pm@s*@ z#+CCACa%)>Fmbg8C{+qH!PGZQw9)KP&ivSK9Qm==*z@Dt$3Gvj9MCs5{Ge;B_@SOr zaiXH&kMrLd1)4xDi?)Y1^e)T`V7xeQ1CO9e@W6}bFt*2mmoH&# z`vb3DL)eucLH(ezTm27aJSe^;sLc5#>paBuoL^GUgIth&tLfp42dTH>&I?Sk(bPAd z`9asX@S~ElWV(!n`Z@WICOUl~iLeLfE=9~~b# z%|F2CJbwbOph{QVbpI3QRUQ~T_;OzPfx&~1=an89Ja~6r@qxjE*XKbqK`+jKWh{c5 znEB~ABjYrXi5=%TrY?B2?LpH6!D&5{1*eNn>zOP%z31_)M-7vAXiS*AQ={iKh`mc= z!sOi=0+Tjs2u#|bAuwr;hQOpP8UmBHY6whPukql?j|T#a1Q+!_n)sk?@$|+0@8`d7 zSUz!izNE)nNr`D09t{9Sdr5|dH&@0lmElzK`U2&JP>Yb zdpY4j+v@47yB(6D~u`Ug*bf^7oX0J5p`MRRlCgNEh@kG?$+YWqL&{lxhb`zP{G z;NQnTL4Jb7RD=!slVNsDn5e4&jT7dQ_JYI@6DDrd=#QT^wLiYo;Nf?eOC~gfT(C`J-}wm-CQOF- z3sfFYJ`ak`&F6cbBTT<=Ug1ICdE{`khlgat#I+ir84BM6D?WhcC29^Rd;TVI zbRB^C$9^KRk3jviA0I$-9AO7q3^KoiLbKuT_5%%18Ya83f$Gq;8jsF*8gPDzKG0?G z@|(aU2Tp-WZkz&>7&t)g-mY=^Jjk`d2O13uzx6)`m2;4g=mV|4;sBZB$_5IHwHo`* zgG`_Bq~UMNfeDjc+1jQyfa7YD#)OHR!Ev=oW5VRk8gm#yBW23koL|ZhC`{am*7eyv6el-Kp3Ve(py+VlO-5iTq{ z|6t-SjSmxdYcw=A3Yvla?8>Gvag&C@#Le(D1ZsgOelnc)VDc`F50iJpZ95OHpCS3O z5o|NWHQp$uvV%=^V`~T7Zwq#fE87n+?Z$TU{DjGFY}H_%E1L(neqXDh1s=nB@Z{Tr zmIqDELR|-5Tzt^*}%9c+j+b^77_Kjm@A|^RctA zzG%b5Z5kcQ2R{f*+NJ?&RVcDGOjcuKn7Bnl0F;+R1zBf)c`)&(#)pZ&G&rZiQo^#k z4HLI(Gzvx?0GS4A$%1-0w!tjHM?3y1Ya%ko}u6oq)h;wT4!?p)}Q`Yl8 znD|%Y!^D3YI~YOb9Ou*?#wq`84#?MmW*!Satzg7wP9xZycCa}NlecIHOa_&Jn=}L_ zZPoyphON{DrP;L_AQyvD?XvR%leTNX-0gUF+SK-`Fw8KW^UI#|4i7*jHmJV+>Z{Pm zq^C4hL6u2QZK~Q-1=R-;|NS9jzly&@)dPMW)mM0MNk8zxQS}4O{_!gM1`j}KhvV~1 zaNB*4256MLVKRv3n2MNlgslYXVf@25p|N4&9u3gEWAuTBFVl=xew<`F^CQRwCm9iI zXh327e*(u;(41t(muW_VA19eIew=E_`DMZZkpK2*fOI@N-)bQEJ>g-&gA zeV}0?8+cwa{{Seh?$PLa@Po0T8B|xDKi~2M#1?D<#rz%(g@*PgFx%UtJU=(NqnX=~mG^3lJCYhf6G})5# z!_M=PO;SzLO)^a#FFKo@A3#RyL35dWQ|_^WbT=4rerY_=V9xoW_xumWNsXP2GlVpK2Sp(9$$K;! z;eN?HpD=N+M!|zL{&IN`c6ks09y$5O)^Z-iPI&;DA7Y$_>od3c2u^|cUHbZb&?>PVe!GBSXFGc6`brCLccnERHJvK2}Y)Ad{e%$@q=|j-1YPtD6VqgI#thqn6y`; z^}+9R5c#WM`Iz$plOXBm*f~g_9Tsn(&;pqa2|ea%pj^W<GJB!goF;%1l~Cm5N*egMg5 zfaO6k_Kl5y0&E5cv>FwZ-uG#=fZNymH6~0xpaEJ#d{9GR(jjPm+o#d;1XSiD%Qilk zFp*Vrx&h~hh6fFk5h|OI&3V``8Py!n+!?-=YoIYVJ?L0o!^C~y+W6vuAK=b4{k8_Oa|q|i{LtY*@0ezfNwV#|4iVUVyx1y3QA=k8zAf( zjF48Q&@_Z>Q}buItnjp+$->h`kYrn$zrtlfZBtN6IKjB{YNO!HLwr+8R3<){q5gw$ zLNh1^_Gy4z(RUuyvT!=sV!-*K?L4~s{lM<`KG1B*`C;n8hKYwXKq=JZFf7HvN(xZv z0dnn}i4%-CzZ^O;!JP9${P`P<+%WKI_2@ z^&5*<>%HKZyV%fry;l_!5}@9J(6l=fYQZv1&6gW0z%r0H>zN2L`|m-J+4+YW zY&gHHKh$W$`Ni#UlMUw=&VvosoL|BZH-t4AaC}&P0FwK!T>;sA{vgN=J;f6mCzx@5 zaX*svxZpuFEwonD3%Y%7bH!d{gY%Kyg;b2+}Efr2D}OzK=4X z+zZOhpt0Y3Y;F$%9&BXYBagBs01rJ)@ z%y?9NyB(s21&zv>M}k!d}XMW%~R`!nJ6HBi23ZT{A93@jryt!J{>bn$6_ChP;tv^T3X zPMCN^LsJ|ynguD3K)GAs94x(qVjh%Voxthc{y>8%=NHcNGxR5fO)}v4vieYiao~pr zE5{EFHijP>Z4^H=*$94Uu)g>WVpa=0Pd`7~YRUP<|DeF6ec&4Y{#i(!2g&=O{C4eZ z*8@m>e(`L=#KRf}50k+&@UVL48{4*XHyCv$3r?Fe8IiJgpM|7>E0;krdG-J(4Kz$X ztkLtJVe&qWo@=l)46n+H;3sYC-iesQiK0KIyD# zQ@H5-go(#BI)(Gjf0%GWLjfF?J(EFfew|NKKB(~Pe4FxZ$_Ev(D?b=PEh~LpSlg;Y zrQyd!osAE=)jCugnmsVNg2xFyWL2s{ZSje=xp7(SJtez>kYM8y}oj>jCROt#RloC`B|kf0%F@P4|w= zKN#Pl=uT5f_)(~1_#j!WO|=19GAcYWc*qEjpA8SQ;qlY+2DFdk9-G3%Ga3yOFK9GO z1&xE=KXB&iG-w$TeD>H?SQ!h7i~DClas1(7KHLmQjXDilqrbV-p=|j12V-I*x*Ayf zW6h-uMuQii9KBHI2IHOyp;xB|!2V8n<2p69bnWh6Sy)}e$&xlUb0hity!s%z`K+Eo+OKsqE z32Jx6oq?p>@=G1cjUS-4Og^ju>ig}}(7y^wxu6;e6j~l<)WM+#Dvd#W2e3;)>qn4X z3Qo^PoL}aF-Klft2cuFW$c^e}lpDJmHH4MVs5EvrY6#1pQElvL)DV_FGog9&d59}a zE`joo?s>2olMicjKZrlqF!73phOq4U2NTa~G)%mx(J=Leu-N&AiB~mV2n(HWn0QWO z!o*7&6Q*_wbDy6u@tQ`bF#CCfiRU#YOuVcyVXCDt!}$pluWMKe|2gL{@rK5Pi8nPS zO!XB0dTzqRTN<9iAJ0vgcpEJ8=G+a&ITHn^{h0{bm*O)~XgZ{|y^Aqa-90uN!?hTVe&Z*Z~aj9H1OVu^BOPoA548P`GUq9T@Zay;{lj|N#hBazO2zO`HIGY zNmn%(CSTKVn0y`FHiML1ji(`DHtQlN%#6+>;x6jJSG^CD_GtuM0p&7Cd6ETH-3(SO z4X$Au1^L0cawcNtqHk=B&^XBg>$rFTWWLTs!Rb21Jrf(uIKSLE(Diu2gBZpQ54GWS z+w%wKu-0um4*Y)bp2E6~_X@Ff+mFkTS_@yj2CMzHTm;o^w@g)Fx z8U^2+X@u7tr%pja`|*Vi<%M`lgvA#?J(5kQ@b^d-odUHaLH(84jgy*n8kL(TtItrM zq&@}QUzvQWv$3HWB#W&#({gI|gO||I1m!+ROX1aNNL>cXnZ>89A3VlT;eI~halwNf zryCwmc%Td(A$h|HYJY&n*g<6u$gFeVRezvf38D=NYI%U32nS>3o%SzWUkqz_~+s4oTThk#nVkkSIw4*~UnIHo#GWYvV^ zHIOPu--Kf-Xcf5Q#|-{T`9F-x&y1frPIOWac<4I+0HdJF68#nGUHTIqMCiMygZ4VX zu!nl2y0X5px{A7~`l6}p3$)aqiGODo{60y)S${$^XjRl7#^z^}pZz=!GJPYJOkc?u zs@~8z;X#Y|RCdTpEXT%x2OxJeK5!BbX5aa_;lbDQe;A#g1v~)xcA{yrc19;$4jg6Ypuv(VtMLt*=-&NnJ%>p=gr2mcB~mBz1j#1Ddiq+$ zlhiHsji%ZcSgI@QgT_#l)hFpsn+gd%NJ$l=?X6ulHGOLMRQIWq)F&3q5KhQgF!{d5 zhsh5#9!!3y;V}7*M!@8|8VQr{X@F+DK(TmW;$4ji6YpuP)L&n);lYBq{l0JX-xqv% z@F4EL?}ceS6BRm}v>!~oqw#1eOjMz$^92_k9EiK`tFf?2d(zbT1uOM8JXjF5 z-*?W$PVE=^A09l2{O{Y)2#ICn)#)HR|1jQWe8o7ivEc#8tcJh62Mr!H{_QxZ@BlV` zPhI+g`g!=8CMrWhov^f(6r+2EK zY7m+>XQI&blWG@rKzk<281Jf_QMsYj(Ku&fr}_!4?nY3Xpi}*amcXOvdmQ>bx{U>b z_r6VeKIQt9<5L)v1wUj=`Tj#Np!0i2V~=V_b7y0(YG-p-W1nhQb9ZCEYBzZN7&00O zSp~!~RpCkWd4nfm=M|p3JZJFa$vK55<>w5Z6v20QoS*!Mv9a+`1FDM}8c%37H~!E% z@JRgLcE)9ljs=i5MvMB%yD;}04CwrR9y+smegb552*bS-`V9}Z-#w$u`NizOffqmS z-q3G&u>S6`sTTzgWPAkkRzP{Lz`TV}-eWLt7L<1f%$p45T?O-cpuBTnUhCZ+{kEwW z1sgIT<-vgmC&6{l{<|O-l-)g}eDTAH2Rp!O^T9e#By0rpGN8OwU|u5BoQ?#TIZw~y z8&k4jJk7{BJze|c$Ipz58V@vXY`om4rLS9Lqz@`bjo{^|k-phfUwuePTB4t(4r=v9 zYx`(t!Anykb%VbJ8AtS6^`_}9*W0bKLpPi8oyvceHM;Ejg6g2w-35Kd=^fubGdeUk zHXUkW#)w_ed@^kJ9LH4HxF2ZL>kW9+OZ#%eWJhg{%MFvAv{f%ROm@~*y4*0?MO*%I z!(>-&nad56-LxeyH%xZd7Q5Uq*+ZLeinri~%b>M16DB%pH%xTW2F+gu9oPUKG246q zH0v}2yx%73z?{n+%7PzqF9%$HgED5uF}2Y^@dL+~j04REncqRPfC~>yGI0FfFwt4N zQBeH=!$enYfr)O~`~`yQjG}_9H$OG#f4u~<3p6tI?7)MG-r64~`e-*ccGovHx4dYW z|ADa)yd(W#_!nP+CYXFfV_$tkbHjt{m$WbUU)gbfqTsgk0u!CJ<;#^Xw_mBh+@bvP zv%uuTEP{e%2SELC2km9&Cqzs#;P|lUJjg8*Cc0?%*eXAm#LoF8{lGd#*O++!go&=& zd{Zv6^e}?v8v4%vyR?I`d+nUH2QHRhYCk{0g7b^}fk_se9~#d$Omx-mFPM1=<{H69 zq2Ge)0zVrb^j~^>sZqc7Qp1DlOU{>^u4JE|D3}Sh5j47!a{kICknIhVZM03UG)%P7 z2DP>m!K42U+I&;o1%pBMd&NRD&ivpo`4r=0eVA&6|8LHNYH9m; zm}-yj2d2F^AHTog5@;+6)b^Ti;l;%t=Ncv+W&!Ph0gYlfXwN#|_~7?>r%U?hLFGcj zLTJ|$nCPiJVWOAzAIA65|NRvj|1ds? z`S0J*s3AV#WBtXw_rHVJws-N)mIa-qq59yGUau}F$0JHhP;TOwnt5^g{o2cog31RJ zrWbxznCPi(Fwsl6~Ah5A-n} zcmT>9oFBXnfJ)Ms1E3HDrIgSEpd1-{;O<4xO#A1Hje>p$I4^Z5SAGVW*ZvnYCJl2j z$o~%-ATDoc{HXIn>LUlp)RiAP9=s6y$kOrU86(R92s`pa=S1a;d5nw!f}H*DUr7Dn z0;%l$e((WAp7X-gCAyGY!uWuu2XD?Vxd2+J zQgy!J!842yyrFkeuNxYM*Df5G=&pTXqKEbY@r&#lA0V!*Kk$O_tP192h8{qqCr~&tG(yrzfQ@z+IcmO5zm`M&jhDL!08^NK+df~u>3lHkRp$99a7EJWi z-Z0TidwukN|DK5x9yB#iZfc=ZI zb4*3gGdCGmf@CMpkDt)YF|}c`ueOH1enFCc!GkF;H0MuX6jV`)Ht}_sc#I`r;&GPt zzd{ETCVOfdO!m?~&Db<`($op{Gt?XEXQ+clLK-G}YfqT$qs=i@FB-Jd3ZgD)YSGk! z`ZD!|`ZD#5_SSi!o z_yDx03#KCpNk=OYIvO%Ok#w|8Z7hK8(}Ty9<2L0kmUVX!S3c8A zQ|A2Qbs&bZhmj{<-v6V{RmPZ!p~@#eUS$-V_IBc*i9*wFFbYohnFyMNYck;Y;(TDn z!;Xh94L-64e9(9RTD3YqUWwmWUQgVf{le!N+N%2c1qKg5=jfz-eQ5HL)#K~@I!8h6 z0~1p2>G|nr>bL4QL_{{vYRWUf%zo!0z+N zKIMnDgdw#^!-G%fXFTY5u;;v^f#!z^87|75pYG}1JU=1lp5C?dpjGe78n-t}PLr7g zq6MLJB$N(>(lep-L@0d|N?(N1%cJ-ELrehWXb5Y06iAG%;d|o)-S<)d{Xx08VWOjU z`(KU&U+y&u@`6j_M!}!wIi_B|*C@z_#D9I3`5a`A-h+w9SUyZV&hjAYzyE>8i;W`B zz-hap!NTz4j(d%QYG7R*%9bBn4FW$Ra!%7rlS<39<9E30gaFOoi1GpfwthdYWS@?EDChsmT{IFMvW3vZJ7(vA?{b zSzwaAHmJ36e=_J?Cy}O>#>Rw}X1@y|7Y@9+@}Q%!zr3Tlqp=~Qqgh~*gSNmV8*PC} zcG?1yY_&TY8&W!&JsxB{X?T%$4@^JEy4TU#kkZlK+1QxS32u2q%(mbDW6FUy7au4+ z&}x765Y$du@Mg<{Thrc5zBToA;=%UTj+LnC&kdOM`H?_C4bD*rvv!CogIev2fah;IAq2&O^h0%+&fDHc%cu|v7=W6Ohv$)J{{qaa9K%YPB@j=NJV zpmrfF6b`d&gZTQz`@0a|zrL${`~SrE6ZcPC4_-4^KQVt|{6znWsB6_gZN5f9QScfU z2ko=qRa2)}K%vVw#YJ%Y`G$!nSla)uKi}}8Ve%=KU$<7BZ+`F!+)I1I=rHXMWA}sm zjIxuuroQ~%^q{A?v%UF2Uwh&MP@D3{-9|x{1CVq9+JAhGk!{+$yB*3KKZE4C!DEKc z&Vt5$uIV4wSD5Iatzw|~0g`$^tMy$vLp#$t%R61Q-L&1cXMS#MJbY)Z{vQ3mjEoZ) z6kdMc4?bZkOS+mHbn;WL{v7Z=sr{#r&%FV)JRv4KLQRIX6+t$zbc%MWb((iFYBOmw zYgc}5Y@BolWEN-^6co2GwNp>Q`em@OO^{nHKQzJjtb$fe{9!~jukmwZV`g*a9ayaZ zX~iMhpP7v_#0@@VHVfTRzn9tAD0uUHo4)g%h6h*Sr;6dX4K;i~wi(|6rxN)8VT1yEuUbxLDzTxxZyN!Zp&v!PTyxrM&@;sAhd(EdawllA@9vV9obW(lqN}#SL^o~FDl|jzPCiH~0oCwM+Kon>U%U@+d@w%HVAS~? zRAx6CWq#jtn*~4 z=XKY2Yv1nZ*Sy`?uYS9$U+nguI}l$%>|A@k$%yld$$@4g&JVlJLu>=}SXyqsxRWr^ zSsPjHbcnna=ZB@|OKxAh4eDF>bpGw&>y+>0xZSVIcDq5J<#wY!)9sF4hTEOJ|88~l z{<(GJ79t<)I|H+!<$Un%?RP+ZU{DXdqkCpIvQ0_nxBq83z zGJgW^lKBn16J-TeIHoR|zkzY{`~!@O=QCc|G{1niQC3i8qAbT$^wX8R zKwmG!F?GxNo`(}2Z9EU!-P15xMq$EaS%n3Yp@&IZc(*ec_ykHTK4eK6kc<}nczeisW@pj5}_IJ+c)q9}R%-Jl}JpDh@frbYY zUNBDYZJyVBj?sJC8ph1ts$NieEO^1UF|INEFV_M6MvGR^ECkP&S&TmzAMt;d7iiL( z_T<5{Lu(#vc<|!!zel?c)i7o=b}{~86l)T1YHn=&zw=;+O7oP7Iz4=I<-RjcZv4hL z`ETpQ$^RQC=7ZO&EIrt2WcdXl)@r2qWjo`92OloJI3K8EsH5;e!Dz*oZllBx8ebZW z0zWhx6@KA9&}(G*p~2Ymi(-Pt0i^_$1l0o?3Caf)5)}`q|5ZO=p>GguWl-@&?LXUr zUk~Ev8So0K1nUVO=z3rQW*h4%B=H>RGgADb_BZvQLJHe~9y7r&3K>iXI?NouAiEIM zE1RJ|HDt1Z#D@t%lMOV!fZCz|AOCFTJVz;xkJJIy1KSxJ9!+=(bi=? zP^H6opj1cYKktEmjIVe<$~H7M7z=*Utm8bO^q=iO@s#2zEC-tO+bTFe6i-q9D||rV zKi`2Uonn!QFTp(F62&^~&`{TDpL3yjicV{>$d1n}2Z}`mzL-le9x&8V`7a1k@p!@m zo%ZevI;~3oWezC*XFkyJbixCs10ByNJlM|21Gb^@gW_MN0}YQD4|G3L|J(Zr6jwzT zz_I#x!h_rkQB#(RocO$I$``OZw=;rjo}>#41-_jJt9dlxLG%TyDTV?+&j+0Q&ZyRC z-pF)7|GoYDlZ-mk9zEnf_~6aQ2g_TR|NVP@N$ZM)CG80T1^%DT-eEk=$aFw=BI^ZE zX#px5)bv3r&0Ed?{ylHfYF=;BZr*D6pYwp(W21J9wE zRUa$0YrHjlpt9e%opBndZNxeuF`&SKQQ*e+hN%;#g3g-+iGsx@po+rUMxb%N?#9Ny z%m?`2%fFX8(Da}8fL^10V^8DUMo?{;^5sS2&ql_{FPeWgvmJQR`m?n`pL1%bw&VA{ z#`%qm)B2j{H=h8P!JyiWW9l!)Rq7fBfgcqN8$Z67l0P}GJ}(}UR@eJ)d|-EB%LAJW z>HHP)o$|Bf7s`TWg}dY@$}W`6;xCkKlm)RAE^vOym|{Os>w(&QK@|f@gIL4K_r9HH zo|Gy1O5vqzkfULrte?i5bI?u@xe3J@UKIV<7B1_E5E-wzvaQQsne&n zPc5ICK6TgBliwMpgHNcN3aV?k^w_3=W>n3ms)OZ{_>1LRJxcx-YMzZ+@O>5IHzcJ zSax`H#JA+N)VB1r%x+oLva{tx%l(FT4SySW8l@XoHSTOY$A3{4r1~u*$JB+7r1Vxv z@0R|{$a?^E8t6Ou|MH8(H?u!s|H`iLVUhG^?kC(|xzps!I9MZ6P2Q1A_~LDFX|H$>73Z2KEAo>%w5pzyo41fYewp2*BBv z3?gv06@vtvZOtG9XWK9+z}dD8DsZ+P*exKg3xhp_4u}CZ-+{pZ&US>m&V|8=!2&Ms z%wPj&yD&Jw*{%$*gS}lC+!#FI;_eKvEWUvtt+*z}c}3OW^D{h81vjJi{6| zJAq*XoSn!3yD!FtA&FrJTs)a!51gICZ~)FuWjF$7r!ky>v(p*Qz}XoL7vStnhAVJ( z7Q+oVJDcGSoSnn)0M5>3cmikVF}#4Y^BLa2*#!(A;Os(%FK~7d!w)#SnBfncT>{BC z;CL)$U;*WGFuRO_1I{jI;DNI%7zE(#N@!65$`@4(5^(Wq1{pZJhCu<&u4Pbxv+Ec% z;Ou$^9XPvz!2r%~WH5oVn;0zM>}CcVIJ3GIC}=e1UP#p!xT7s7Q+lUdp5%yIC~Dm0yujv!xA`q9>WSa zdp^S&IC}xZ1~_{m!xlJu5yK8RdojZvIC}}h0XTap!x1=p8N&%UdpW}yIC}-d1vq;p z!xcDt6~hfUdo{xyIC~Al12}sv!xK1r9m5Madp*M&IC}%b2RM5p!xuPv6T=TUdo#ly zC>vBBgV>-tL51M}xb6UD4Ht&PAPS5@Y7q6p4Td|QdJddNZZh11vu`mxfV1x~Jc6_D zGCYB^?=w7uvo#p`IKjp8YvUsenVwl%{nxVR6) z95~yLVIG|A&#(Z_4rEvaX9qDXfwMyxmciL!3@f4;82A|xZjfh$)Rn8?YU~*hYzKxl zaB(Mwb#S&b!v;9pg<%t%?aHtP&URzi24{OP?0~a98Foc8Ftj7NVLH?ed*Etp84zqc zhJA2x2ZjT1wj;wKINOQg2%PQAa173NWjFz6yD^-Cv)viaz}X%Q=iqElh6`}E7sDku z+neDEobAhS4bJvwxB+JeGTZ{OnGj(szyt}~J0NjzT5@1OupJrh!Nr{!9>Ccy43FS! zSB58Wwj0AUINP1!1)S}{@CwfMWOxH-`!c+Pv;7%9z}bNepWy5uhA(h-FvB-EJB;B+ zGy_8=l3zNZeu1P^P+E0{F&SLoEfSD8;wl&y2FQgjAcded35W(^P@4oqgD|K~0-{0K z1>S-InS;381k?@z$%C*9yk!GYgSa}$1=`Aai{$3NP&faA`^%C6!M0-f0~hyZ_y=eE zGQb)}AbXjhjUhca-*Ffb%CBho-2Gb9aw+z!Gn@D?7({m9{i zxKjqyHUp^zVbm~z--g2gat}!UDw17KG3>GhDFI`!nb1Za$V?_U+n<32&JJK;gR=t} zINb zK-=>WHfkFlBnHBuHav(1VbrjNwUR;MjGQK6EoP87a+rI8i~wU723%>+A1n_dTo^FZ z9z;A8M1ipjLpYcQ5iSh5Ad2AtlHV`j^*gMG0CJ}hSTBe`^{+Wd2#itvZV46x5iSf? zAPS6K7_7lGh;V`TEpax3~P|wwg`VqPI6H^I2hPrA@Po7S7y{tzLWUqXyNDqK z&MsjHgR@H+BH-*YhA23@f*}UZZe)mqvzr(a;Ou6GBsjZ;AqCEEWk`dw+ZZz7>`sO( zIJ=u62hLv0ke9%~pvZNF&(H&BJ23RY+0G0T;A|I$NpQ9+!xT8%jbR#`?anYGfq{Xa9T9Hw?2vH#1XmNl zfM5qQe1VGxF?@rwgBgCn*&z(S;OtO_KX7&g!#_AXiUE9qCAe)9!@vZ(%o5CwV_<=^ z;~CiC>;wi5I6IMn3(ihr;DNJK82I4qR0aV!JDouY&dy*EfwQw1#Ng~~1_?Mjhd~O? z&Sj8+v-23_;Oqhh1vtBqK?%+-Vo-sziy745>=FhIIJ=BN3(hWQ(1Ein81&%mN(KWs zyNbaG&aPoFfwOBF%;4-g1`9a5k--YiZf3B7vs)PK;Otfg2ROTz!3oapXK;bDCos6d z*^?MN;OwakUU2p_1|K+k7K0z0J)0o_&Yr^%1ZU4>2!XTbF@(X{^BE%G>;()_aP~rm z7&v<=LmZsFj3EKeUe1sNXRlyLfwNaKq`}#%7&74O)eKp1_8Nv9ID0Ka9-O_7p#aWa z&rk$sZ(t~avo|x8!P#3GD&XvG3{`OUc7_@_dj~@uoV}Bw0nXmV&;)1iW@v%4_cFA> z+4~qe;OzYjU2ygRh8{Tk2tyy7eUxDWoPCU85}bX4VG5jml3^O0eTrcQoPC;M7My*C zVGf*qmSG;8eU4!PoPB{|5uAOIVF{dliD4O>eVJheoPC916`XyQVGW3_Uy@s(pPcMp z5#;M1rB}>QmYxq@R(Wo2p-upPy5lRGOKS zqMwzTmz|kctec%zT9Tn(o?nz*T#%TYs-IX^WTBg$SE>tAo1BrDnWtY|lnfHq&B;tk z)=w@fG1N~7k$S-l@$pHCDe;+kC8maU5Gc`&~@zyJ*w)J2)6yz3{6lLb6 z>*uECCKpu32j~SeKtrR@q#`*zh}QNNmlP%E79iW35@4C;97zXz^O6%wkS#7rcJ>T5 zpo_(*A#EC(;pCT3Ba4yZH@5&0yJcl20RhFdx3i!UVP|konxS(A&Fw5sEkW3sZ;~3~ z9YP~Jb2E#R^;1)eQsR?x@{_X>wt8ln1_g%G-qy;JRD`8P<;F=7hP1V`v>+uu3B^_q z^Zd$UW7^tUUW6XNu1O_DuI9A26~(LhE`G%kCN#1XUJ@6V6y@cl<{_6%i6Nnd6#+D| z7+OF;twkiKpaSneiwK%onv$8XUz$^rpBSH+SC(1?%Chdx&Q=NL-tje&t-2Nwea9|Hr!F{u0{E(Y)* z1Rpm8gBk+^g9$f8AJkazv?3FOnL5l|2X2UYPEgtfO1nX64=C-$&A`CMz`zgy1#7-2Jp1;5@`ko(AD9aq#3{izJH_{ zz*FfGG7LzAyAU}h2Hgah{TVWlaH)XO9Wo5yDd{&d3=B$)3=BMSpk)aR3?gz23}Orn z3>tC_@Tq%{e<0ywoene4N)F;a7dZw7DMki{IC)6C*2zP{=aD=Ec*?j>fdM>-c0z%H zVH3z8CCmch1!6vrDnz}QDkS_>R2jg_AS|HbPEhdxsCWugJP#^f z0~MbD6`utaUjY^00~J38r7x&L{PRGS0lYLqL=BQ}J=8!$l?)6WY7qBKQiG^lqy`Dc zRcZ|2r-B9p!vZD-hHY953}qmV zPz+kO!Nd@-6s8{}3`*BJ+6)Y0ObiTGx{!PU5(i<>auFs5p7qG;LE@kRX(k5#jWBT= zT}b}jrpv&P#K6EHp~nE8&Q8#0V0gsHz~E#E$uAoW85q)_Q<(^JQqRE55i*AOUkXYq z8AIHoV$8s>g^7XTgejzaeP_zRPzN#qiXr8Y<29H$Ic5wDa-j0j43dAhK>3%b869a=20|Ub{C)Dy2QVyoPf|<+W43STAMztT3AMd_~se9lIDJOGW zAn|v_g@M6^nSnvXgMlH8fq@~-gMncY0|Ubg4+iiu76VTPhHX&4fGE%e0TTo7N0@ma zu>j~)EUa962NGmpfG-08aUuGwf1v0CNiaal7ZB49M1aaXC=H?@^`gcT&6KG{NrbY)~hu>knjUbf|f9W>zP^sm^@4zV(u-tc%2UizAwLHA5)7Dp7&JW>L1~yhkD%s)D9~~sCI(wmxIY3I7(f#tMgfp? z8UUs9pma|F149u51H-=nNO^4*2${+23xtH<0Vw?`kbyypfq{W52-4135(M$zgkVU1 z1I;9Y(u7V31H&qiL!cOvuWg**?m-csi9`GwhB%}=33i5=b14MkpEn_pddDM_0ptXz z>5#ICiD7a8O#Q4-NPWH{6jBau31xsU83Jj7n9mmtQx6gYg&T;5CC_;<1_J|lc@-1G z>QtEezA#8Vd?O5!@3g`p`K>M-Q7(eYi8tYp^0p=dQXhfL?_ywJ*c5?iN5Jw8D7-=P zpf&}F2DSHKbU`E}Ulc_$FqA>l14s_y54%#ByFg+gPTkWc{$^du|{F42W=n zwJ$;829km;dxI?*gSF#ecry%+ih=5{9I#=F-Yz{~YBHn;Q{4Nf0tDV@*nT|vJ3l8zXUD(Z8heMouH@bRI zo@QdmfQvtgg5>|IXh^%hCK}p)i-xp^Kz;^cNO`<}56nEC7zX%qNre3EeK7g77zTzN z%pe&EhUiy00+XMW0Lf1fSq6q_e310dz`(+IhK+%NF`12lp%K&|fT@7eOpI(7*clj@ zH*qmAuvLNPa+w%8&apEvurRS^=9Mroi!(DYu+@O;btZOy&_Z4oR?xyH=9L@_3~Y6v z8E7UJb}x_w2kUo61_mY$c2_0_2IfD^3=Hhay$lQtte|OUX3z>D_LR9GK4^-Zjfs(g zfstK~aX$kC1ACYS0|UDPBd80=q|Cs;Va(3Jz^=#$N=lqe>}yy)gA|E!Ffg#MVSy@Q z2d(yna~T=9KOT!TUCCNVHD@SFzulTDC|fq{d48A}}_%&rx1V>r1O7}!@r zxs2>bIT;w(S3$W<>=JAY4D73+TxMR7JD8MN*dKy4t%VA+vD<@Gt%Gve88|>IR@v9H zfLz1L#D0(kRHU%aU}a!nKL}OCz+QpO1v~#B%UO`~ogIBZ>cGzL0+n5yOzcNkzJi=C z1PXy8a3h$JxnLuXuz(f_@r83UFt8tC0UH4_lYx_o{V0nC69WVLb5OJ#g&T1lnF}`J zC`&LC0|Q??$cINEMu5x&8F7rI8f3&#kkm1_5dt93!?<80j?a^bfXrlI^I&ISaA4oea)^b2f&HNh0|Wb3xG}Fm+-*=UBfBIh zAh$!gOza7uWVr*%WoF+5a@|fSmxWyuOBsVgzMa85lSORaqDq z1O!1okq~TUWMEJLt>0(R5S+usz+fQg#mT^6A*jH?z;J*;a0(j(!wCk#8*B^=7Z?OP zSQr>?FbEd1Ffcq|5DZ}kHD3imS>*$RAZSI-4+aJSRwj_GjI3E8TW^3`{erxl3=E8d zci0&im;|*L85o!u1UOhhs>E5lK&oDXDp5f`76t|uLC`W{HU@$1pph1K4c6@-c>#6? z1_r@cR*SwQaH$p~_30w>6g3<97f-i+*dtY1NjAA`y+!D*l!3WCd6K~^3I6|90L zTp;7WaxgHk3fh56VZk4u)C0;Jfo!rM=5kOT3uJ?pl!eG#Mo>u^$Y#L?${T(m4D5ky z;Bo?FCCG>%wgiw7pas0_L2x5xgNh#*7i>fjTQ$gt0M{S}_8^E6ATvQm1hXv$8KDcx zJi%}yI6x5!J1Dg>m0|OtsJ6jAWJ%Q^6Pq;C7^@xvcE9pbX;=8q2@Pce+Qf6b|_zAN871#zQCic0YB+JNgot=R}h)I~0BkmFh1A|CKH3I`j0;om6 zq|6{PlZSzUBN5adU{YojnWo3Uz>x%zV-}GDZ3#+-@K_j_LBnqxDHAyu7=)cT^FZsK zMU3(o7&r?+OpsZ5r3?(5MG*B4BA(_944lOfo+E=Oh@rsAz#!Jh!N6e8zziz;IZN(> zOl#pR^XFt>5cdxaVc@I)DPmG)5cl+B;H-pjoEVs$xfvKZtF$>87?>EDcCj-saI$k1 zGcE@emC{TM3|ys*pwSj4Wd`Sodw}> zGYGSA7f5n3Fo;H-o&b%pej}#lXN_53+(uS%86g4HE+ccN54k2}T~_ zgYCR^`#n z=4N0JF$N9R>wydcIjM<_fq_RKBmwex87Bh+k5MgX*j-srCBKZ7Kr6cdOm%?Q#x zgPVat226l>3{p%WL!_9RxfvK_89|nTB^jicmT)sLFtdX~z;O*11A_!3FWYZ!1_r@b z;2JIs6uN?EIYBkXZZ-x6MZscbP`zQo$-rPJSjNP_U?g~pg@NHeBLlNFI|Bo+=s}Qq zirfqgyt0Bk3=C3C;yfTLb$J*VWIzVX^m8yU$bekKAO~7>#w5kaET_QCz`$(7$Sj`% z+E1s&2=XJdoIL{r1B)ahv)lr61_o9eMrH*@Zcv|snGrNp2b$Vh#L2+GJV}9xF_D*n zK@nt!0Ve}P0I0I$Q#9jYU?~offZE9s3PCdx&fB;_CaGjHGBEJUv+;m9s*K&BPMjPgqblQXP=Zkfu`aPNFz_mZSS1_` z41zWwRvR+|gOC`AwG5O`TtTd0b_NE11rX~os2t)2u_lAcYIP9Hn~Q;gSsBCvt>Wbe zoA((M_F%Djpb}I7B-_o(z`(BrV#R?nvj&KDpP7My7cBM#lz?p+85!b0*@odJBfMv- z#0Tk_f_7Mf(gX-gv49F%M9-87SI?9QOV1Q{ca%99)FMK3N10PVEgx1;&SYa^e$EE& zih?R~=I3nXppjH%NJS3kGBR+0)ZJoWVBmE23t?b>&ejeZ^#kp|VPIooegW>)vV$se z<`-}yKovQh3pU~fn=GiO2dc=KUqFlinF%uDC7Ua#sRgRYnP0+<09E90F4%~dY@qFB z+@Ok_`6a{%keLiT;EJ62F&k*d7CWdSXMPGd22_zVKZ9}^c|raKRpg+qIH)2A*$k@4 z`9Kvp^DD3o(2ATdi=Tmk#TA_6`Mrc07#LZ%3o$V;2rLDqUx7RU1_mYp0|5pGW`S-Y z1_l;^X`u8haFdULflYvipMim0;ENCg1BbvzP@N?Z$;ZH;A`r*Rz@W+?$i(`=oQZ)! z2-Fy0{RAqKn3NfWK#c*`&k!CX1M^ZL1_st|AS>B~ScMq*K@Au~VFm_P5k`<^P}N(+ z&%nSc1}=7)l$qF%^Dr>5Nq7Tz-|vR$_C06 zWZ=sLskUcyVq#!m<7C~=*a!F6PPoT*g50_rY9AB(DUgZ#phmE;UkqYkU_Aikva-MA zW?*1F2<5V|bBi!AupWkT+1aH*9y<=@axn1S1MyEYN`oq8PS!7sGN86CI9$KMt?vMZ z+z+T8CU!wS1_sujP%bn3dJy*?l*I=BUYL5|u8mSR$7Vi4ZW$N=7AAp+jt$j1x{ zu>(wy)3P|xXFz^W^2s1G73%my}MG$0Ve{03Yz#s%lYwYi# zkt<{cDk(mI!iY(kNk|W5!DmQZGBYsCh%hj){{T6XjfGv7u?Ez+0c)3sCsnY11!!Vq zVqY)Jz`(8yp_DIDU%sfCo@Vlf*KrmLDHaO5~Nmu&VjfG;(~U( zOM!ZKj1Rgv7{Hsir9dS*<3mscg8Bi{pdmX@k3$*M^!yL9=MzXy>IKLJ;DSF8G=3t@ z!^OZL#Kpki4OjOKq3#KWl#dOb@HIZqs$3Xz0Cq5Y{JCAAb)^`fkD|A6#56D!ct5O49Yt} z5pV`70`fb989!+3e+o0ag;g#IX<@-8l0ebC1vG?(H1^MotA)i(QVWX(t%b#c)WSL^ z0XjEiGibRByMPP>!(2vo7HJ01?rn}K;tUL|EC*Q`85lT0Z4{Qn(B>ECa#;ojmLm`z zBj;r?1_qX+5FQifXAuSlmSYeeGp7?s<#7m)g@IWEw07(S$TGGcVjzoeScBSCm7rk+ z_J1;<@=g-8$cX)w45;Jv6{MVj?TZvh=`YZ(e0Cpk&~U~oF$M-E_AinQ3@q#lG7Jn{ z?4~jd3_R>7BtbK#T%e{CBa0kkC#XFKcDe#1#0{VxDrg=>kr8AX*L*Ps26h%xMjlYF z8LZG8rjQ%dN@KBrav8Z_f&66&-E3cVO}K??VRLrhl|6by0_ps+Fod4-)>l!1YpftM4kHiWSsq_!S(WD5Hh39xBP zr68uglLeWU%(xz;;;tmf+C&kMX&XRpW8gX`#lXP9Qp9Kq8mIt=ObOKe4BXxz&z3^D zjNFzWZW)xz#BB%SmP5JB+^<303MiL_`y+^33FWeKe+O}^pj9<3|!Yi!NW3zaSKQv zSm89NLI!RHkh^BpDb4*we)r7)00$Wf>SG*g2#a7-ZP>#2FYA*aM^)7*yDEWk9R5xX#Kl zFbJ^RX5<46EP=gq7iuvB_fC+#_n=%xi0|%0xlG(ipfGy?@fVdB#To!K7d8dc^3u-7Go%vg))CYE3}P=kdVG;_cb3^xKaa{%XpjR<6a8c@b% zgc}iw%mo|4$Z;9$3THATvQmFme0_86gd--@=g%mf+1%wY!_^j-&QC@{l~ScJ?48^O#G2|5YP+1Z(ag&AT5$V`wCEF6s>BQAiV zg#~Uz9VoxUxL_k#I6y;&g3it^3@j`VBS2_CAyg&F&ANTvqO9 zpkR6k<+5?V2XP-kx$N9uK%w>+%H`lb1d6dIP%bC;Y>;oBLb+VruR)3a8I;QnDRrJh zxzMWZ1(XXd&|gBie2_Bf6_m@*oeXmGYbaNMdl@Kz-$1#7+*?50w@|JS_Z1NL9h57~ z{RqT;59Nw*w}IUJ0m>ESZUdS85y}U{H*IfpR6e*MJ(m zU!hznZqRZ9mTyq5G&g8D0n2wNSB4w3oPgyAlq<^(T28?76Uvq21}!IG`32?5i-1Zp zCS?U~36R_WK!ugK)j-_8P_8n!35fd-%2nZZ0&)LCxvCFz+y_8h4k*`{`y7bN z3FVq_-vM#Cpj=ZCQ0`|^HWLA5VJ2k@5l}v4QnnHSWhN$N8xc^BU{bbY;5h+GI0E35 z&zlHt68dpC@-Z;5Zv;09d%=~(LQzn0zgZSkS#*LluxCnvDvJZ6pvvNdGy?-WJ0oZl z1G}&+Xx1`E8q|exlVV`tX1^i|YDhj3XJFuEHx&iVxbuoJFz_=#hkThJbGM=ak_-$? zj*QHr3d{@)Og4*) z$;ZGT>CeZ&01~~!#lXPm&mh6r2MVS*MvyAd&L6N!Wqt+*$p}6M29T%(sJETKAkGMy z)nLqE1gQe;0RpRJ=md3&89>8$&{cDwZ6BajbD$;8pk6ZwF9K~rLh3oQ;OaTE5ZiNx zhBqrCtMEn!1_n0pEGip#7L^S=i^>KXJz-`8&!Vz{XHnUZW>HzSK`ZdtRateb89__u zK;yr9AcL5c88|?*sI2-R2_|Jm4$v$rs}bnzHzs944$v$rt1*Np%mJE3Wi^BFL^&oh zGcd54LwMpGpjlK_3kXk=12l`uYPl7()=ycQ12l`uYIPjUljQ)-qOw{;c=8;eSyWco zEGh?R7L^q?i^>6-MP;=IExBP*R$<`mW@KOhVJ=VugP#GK__!H)m?nYxuHdn&^^6P* zd|(1Jp2NTc9@phzn#Bk@e+*2eGVY*#^R8F`pM zb_p=CGP1MjfQH_|)2wXZX;!wgplMb%@H8tMc$$?BJk81m8niKDL!M@37yZP@z`)AL zE*=Cjx>Gcd4AgN8Sm6+t73vKgQ$Xr??Skds?LOWZ)# z^MQ_@;{%OPF|aanNSp*2Hb)+0*kMJGVKs^j3`}f)3=EtM%sTQ63>>N;^9A$d85kHjg~97MlfY(zHX|{zd4tWo zE)Oy@SOH|FvLeXLSVfST@*sD!l_`L>X)uF~;8eQ;>c6vbiPSSQFmQ0IGca(8f*cA; zWvL1b3|wLm9wUc@E&~G>I7FC~nK()W7#O%DAnB2rgI$S%flCtP7$#*Fj!PhYQV^}E0ohXq+Fm6Ok^rUVa7_jVE``IOQc0Pafrkm? zFisG08PpjEr6YC*=2nmailDu1Li6Mp7??yEnT4{g85o!?7@37vDu71E89^lgXa^v; z6cBa+2?{cT1YAIq=%8Xu*bEd8LX02*(B43Z${!$=!i*pR&_+Rs;A4=W2qQ=Uv}+J7 zD6$TeCPcxB7$gYVMhKRe!NR~GdIl6jqM&rWjER9k>@UbFQBVqJOPkD?KADk0+!mxl zj1i;_wDS9eanbIpzV9o(?_c1dtDBT1_&0LVtYM=#q$qbD1KxIP^ zXt;G3Hv_{SZUzP$HUfsez4wK?P*7D&q@~i}o{udmfIvSeq}S7KmbvG$h=HH+Wi0~(a}FbT5}%O)R1z>TWN^Ue3EZIp3_Cv-6u^3*iG2bA4BjI^ z^hyj?rdrU_3P|IU4Hn|;jE$f$V+I$IAUA_{ID-zHVw46oYU06?pd#Imoq>TP4a@~4 zThQuQ4sfV4gB0!q$$~?b86*o@FV6`sURgoAc|AZYacn_)*+8-d91ILxpu>APk9smN zF!F%nVF75FF9R!+B4|9H71F?9%m-tZmx;3v zBs&qxW##})e=|>la#=Y4f)r1Na#=Y;K-?)%E*qyJNbgiAmz~4YkAZm_l*hpd8Xjey z4&`!kepO;%V4eZxa&c;aw9bTbxj8}Of6TL>Tpmu)AT#r9D3_O0R+)i;c@C7z#|au_ zW}XY>@^k(G88r{e72vc2DV`7I3UWq)xC@|MA#VG@t=3-M}U|?i^#CaXm=3S%=T8epB6*S?*Q?3k}BI4Pu1fC*-mb$!* zEW(1IRcYW35D&Nm!~^aC@qjx(Jm3xx54Z!wgVX_H(FQHLzWSPzQ*`9@OXnb$|pw)5Nct85jgXp~cT2#3;-J;);Na9nc84D3|~h77W7Rf=QU^ zGcyB&7$e9suq1;plL*KeNIf4GN6;o1UPe~7A{GV)9&k5@2i(o!0e5qFz}*}ka5sks z+|A(ucXN1hwfG1RyfkBXGu@VD=5YJ^51_oiCZe<1r z1s-QGd0Ux*L6OHmg@HkdXPF8EgE9}dDg%QGPmC%9gDMZB8UuqG&lM#G26YBzkOl1K z8K8X*Y#bt>6Dj#YT`CSyP@sU)EvQSyAqL?w@`Jim9N^GrQfA@@waz&tASs-gAJnDd zkOX<0NtuNo)TQE(g7BbSDh}x@AbX5CWb@e=82CY5Dh^neiXYUa;*bYPfbs{ZOU0o8 zYOgRUGcyP?fgC0PB3eN+HlUOV?NV_lg4)Cq;-GMXthZra%f`SU30euor~s-E7$nM6 z85kIy!L23cQ)~tq&%LHITWP) zf*S(^V?0O=gUmjVL^dOH3rGTNdp6j1@M4y1kaHnMW`qDahQvNK>=*h6_7A%-04bbdb^}kfYi_gS_gXi~$!4 zRE05hK%1W!lXNGrF);Y?F@UdIVDtd3kOt z3p0y>L7kVKfdM2c!Oy_J*sH0^&cFa#t)wM|@UALM-q3&@(p3gI(1@`Ov|(=@BPhH; zM+{v7jT=1VW?;|;g+&xU1H&Ycnft`J85mSyTu69ifL$8L&%jUyQsVKCi-7?-JV2s7 zAQ?n>XoE7`G=2sKA<$Z=1J^)?!nis&L1Vf-jNo`##?QcT2c$P*J~smcI9}jFfvPYj z)E(e>S;5Z$zP^Idqm3KY9Y^>X7;b>fLb!uL9n_0^2VVEcz`z)-30k!+!^6O!`Gk#u z!GMQ>K@}!x_=}B!!4-PKhA}9J7(q#s!H7{AlxjaPf`mYaGG&1ld=>CBFld8Hgg5~P zh6W)92FA~h{0t155*!Q+{=5tfn!Fqg45c6j69)ssWYDT=kje@n1_l!q4h9B8eGUeO z)w~Q0CRQ8_47#B5GDUy^e4hs63{B8cQJ(A!47#AC3laz2kHMI@kB5Q56ck+`AqG%a zKF~~piGcwUJdk9YA;7?30Fv@p%7Yp_+XNUGPJyBWDR{skS|Px|5CGDWa)Sq&Y=a@m z_LTqw!#|Lg)UTj010~yiybKHwNzlbiBA~^HX+j`>f+R13B*A$EB%uM4Ob2HJ1_lOQ zP$6F-2ie}K@l(1FD>;9 z;B=!S$iNT-GC%h^FEri2g#uM!OlZJ>)31Rb1A_}lhX=?D$mtg(8Ud0)3K+1K3PA>j z9*{&KXq_(9BVZYj=mL;T5jP(+$e^JD65RrlDF&5knxIfI2klNV1tr97f(#5ZKprXq zCqyq$7=RLDJRbvt*#;&C25=&52dQUZFa=e94FU`dCqO!88B7Ev2v9Kt5_Kz|6Sl~i|sxT%bSW>_~c_hfd@D1c%kE<}lpv4?WlnZ1Qda!5- zF)-MHBzjUfh6lSV3MHa#gLK{B#{P^Y=8zP0|SG3n-Bv7sHy-J zIB>+e$0wfe@ zR=|u}0t5*&Fm!;VJXQ%XFo09w93chfA0A)^4x=IpeU|0dt znDQ8=@hC_h9IqdQ85np(7#J8+LHQo6`4(J~PlSO%3nZB)3-T~1MZ5(`f{Ox>gd0dQ z9juE1w3r=I8l(v`FdP6`II~O$S{jH5Gcag^N&_7b15_IL2t!K)km?5@)dfv3OF+xl zA?1Oe2m?bM$dcT*g3yEy7YbB`F(C;*3GAUD5e9}dkPeTFFyj!x1d;$P^kGB|Ca}h3 zA`A?NKpG1{xdZH{Qjnj(k|2qDAju+ike5Iq(FvCXN&Esy7Q4VCLE9}Dz-7Zf5e9}I zAn!rShP@#FgUW_W!l0DH0xcV!feeF|4WI-M+BU(6R5pOb99S3_7;BfqtWXCnMS>KX zq6`c%pk!JlBn%BC9hgv{DvSvUq&%>93`7|iTtGTJzQK$`1QJLh0wjqgkg7x(7{F7% zb^0KWfWpBB><&;u14%3bX{-lDE;t1JL6YF)0+QGUl57A=B!MJAEf@xC#u89tP=pbj z^+DMlbo5~vC_F)l(+1pp6=4MB{hJ~T3^w4rF9OcUvZ4$OHsH(;>AS~^GBB7$u)uP^ zG+5CEQCMzQ0OxLXF$M-mZdU~J{l!4e0Cxo#MHm=tL0zx^%nWwc8Vn4Kav&$Lf*YLn zpuu+*XI)S%FxrF0-C5-qLpY#ucMfGx$BmKEfl*(Xfq~tgkx>-XH53JPY#A6ptI3%d zl6c@F!0*%{!-=4NDad{h76+~TMH&I7!b)+_JS+=%9+s5}bZQZFP?3!ZJgCT;JcogS zfgRLq;Q$XRvi7ip&cx#c4Jxwsu}_2yDsq7a6BI^_=myHWFsK`1M%4O&D^kZP12IX;Zfd&;>r$f1% zT%bWk))`PP7Z+$yk##1N%gqHERAik6hlq=4_4H{HrUB~REwA&VRWEAf*(AkK* zd(;>h1bCg)7#JjY4b>SK6nN{^7#K8o->5M#81P39oOSyWD}kR(hnZj;{}iF z@q)+oc){a(yx?&?UhudcFVeUkn|3;Anp~AlH-(vjK>#$a$EF7|h)J1205q=0rVo-} zQf3qYjq9-)l|jb!1VH0@Y{n3tumEUWkIf9i6BPiB>#>H zIUQ_@v;b&akIiZ&m?tX$8rNg9hVbMCK;wFBuyH*B(6}BOY+O$OG_J>HzaFelg+UOM zz)L{8Zb3oF&mhdm$^_y<$_9{YM8O28oxlK@aA0Ms0gvl}ECWk2urkdB8HY5k$L6>c zw0MA#o$WVh$vAjij~6_y#|s|U;{}iF@q)+oc){a(yx?&?UgU8-cF}{(3=DjX?Ba@` z@jdXk9xr%Yj~8iNk6oILg@FM)uE#EG&ceXJ%47>3*9!)X>w&Bn?T3%+@iB4;XMhYV zRA*pd;GGOgJ`Bt)>I@7VVj%T=j2sd>K=R;mKVI;-A1`>^j~6`d#|s|!;{}iV@q)+w zc){a-yx?&^UZin94%K271_sEuAEz)ID+2>Bc-)T{JnqK}9{1w~kNfe0$NhN0<9@v0 zaX()0xF0XlxF4t5VHO4kel{+VJkUlu&{!OoD9E9pv<4cB;}V1L7zIFMaa`aKV^U@k z0FA|QNkCF1vjAu;j!P2c7$#*F0nk_+mlT8t9gE|V76k2+Hs+FD1F{D+7RLn}ixU8i z#c|1lBtU5zG#1CDunDx)Pnns4l?mi9K@f3>m4QJBl$xMpaa@X(tPBhi25JlpOj?Z0 z&sZ54BtZ)Un6yACi$P)vNJ5Q~`9EAj4J;wW0*W0mMo`TLI?xxinSc@0m6Qf~pAqcg zt6~fcGP^3DDZGaJA2@3=C=#3=GO3K8i{PS+S0@!9Zkj>T-5S!gWHiJB= z2r>_3s|UztS0#1^2C$iVATvQ?C}ygH+!-X!zz_pc9jXL!BLjmh2P*>u=;mOEMJ6DN zKx_U%Az})$XsrYT1K8nv#2FaQfwUTfEja+P1jI+Ngh5t;m4V?S+~GKikV=CgSJ)81F1HII$WMbf`Q>SHv@ybj|2n5 zQxGFSf`Q>ZDBc7?7Rhozla@S#I^$%}Mz=ynP^f{4K7&OY zI2agYzJpRpCCC(3=1D3I3<^g<0#zUZSxE*4`56)n44@<^zX8f%&}0k-DVfR$G6-~Z zv?FL$AU7uigLD*V>B3adoJfHr1A{adXx@A(sEm9e35ihf8V>=`vCtN*3=A@AAcN+D zv_h9UXoD7VfXZIRB&`5e1_lN2@{I)`BUC^eWxz`v7JwWFZjZ4t334(p=zuh6FouE> z?j}Z%i$DiigT0u<$-tls+LO+>2~@r@X6T;RWME+21S%C6)AST185lrnK}lc_$ka&i zF^d|EOF<4h#t4!F9fl1y>mbO7V6%>a%(9ebV31Y=*?A1);ZzV8?BQb|*Y1{PV9@Ua z1H<1_o)cgD-)? zs8$9Nh*v-^eJI1gU1^rXlCO8m*(;eG8aLy$+-};f)gCzI-qDY1~u{7oVS6xYmCOACO*5o4!DVL3~J(Y zDTC?*Mn)6x>J%P6@O%rSDR?lOTZWO*l+hKmR!;-O0u3&5%Q7;WF{Z0CFz{xxfKOax z1jVQ*DCvoU5{D>gnFWJ6<6|`j2HtoU$Z8RY3`m-R;S4WmX=60#KnTbxgfkkDZo>i4 z;wDg^fq{X+M+tQm0!iHl@G1o6x?E68AM4?g(?N?Mp*@JnAXTvCB+woN=o(yb4+4Db zBx?%j5H@yDZsK5Kea;5D44V_QC5H7m+Z>Q?Wd=^rmKZn}bW|4WbGH8s&;z?zpR=t2 zwT3~fNEtYoSYNQIgSM)I&iP<{0XG74&Igr1#1pb=v@7i`2!Hqg0tyr6SFSYJYn0GY|a2R`S6^)cH?kTIb7eb%RNV?Z09 zSf4?;jQk+~g60iDjt0#Uf@}tz^C9pPbQq7-1a46Zfm@V9;1;D2 zxJ4-hZcz$>Ta-fJ7Nrn!i;_(gbOEy8U=U^mEsGTaSuZjRbeJ`$bYc)>WEWltG7Q{%5CZoeguuNAA#m?O2;6%R z0{0$-ka`d7+91w_eilo`c9y$5!qT2K>PSx^kr zdtf()@Px%cg$}zJgeNKnYB#Z)LwMq1pxy(!1%xLl2I@VqTh0TUA}t2$J+NDC0P|$U zK)nZcYY0zX4AgsIhxH!BK)nZcSnoj$)O%pJ2W589ssM3N;;v?9V34>9TI9?i$;iqC z;!1&61LMUx<2~f|1jY|a7CKm%WM!7^m4h6*=q%98N zF^WOj;-Iv~q|77+X^TVRm{|pfu%mhtqa>Gu$69XNGz?}$+E0CF> z+L=2El*XBqnZ-b--EpIycE_Ef1X||l#FMuWWEN;@ou>fA1cd|WkP#l(AtPd-Lq>Su zhm44W4BZHG8T615o)S>sL9~UZ>;b631R4x3JnGZCL=~>L3RcPInbIxCL>TtGswq+M&$$< zL9H*)O(x(*UO1>dF9u%G2`bSTGZa7($S4RZ*`Tc|1yCe1f*an9DGZ7kAX79MK_>J` zF)$pI1uahJU|>)Jo1zIa<*zIQgA&*rO^`X7atsVgU_&%P4#}5eU{D5~1)3wpz)%L- zqoaMAoq<7x6*O}z$H1Tp5(CZmsWGN8e`d^pss@QRfK==JfT_L&QVkM=ss=Y&)IqLd z4C7^BP=of+AgxdhM$kE5jAo1=dC<)*VE=0{f=&rzv}Oc}fbMYti)u3N0r}E_5mdr~ zL_s&ZfMwQzd260_L+>fBW4h%Ysb3q~jj39eJx5t3(x&oR8&17H<0-43Bz`($u$G8!s zE(Tn#g4BU-m;tNRVf+P>Nn`|xfbN?Ci-HcOQuHl|Hf{GvrM`3dI;fia;0A zfED&|!Xi)%6oFX^um}_b`Eoyq3ywfBPy{|zU|`Vqk!E06AkDx~4LZdR>^*6ae~dtz zOVmN;GQQ(rU{GVs0JZdV7(u7JF&Z#}BtW;{fGyp{$-rO$+7Ac{R6~$3SPz2{qYuc5 z72wbZ34`v*i2^OIF9xmN;MHPaV5|T!I~5ribTb(k!M(S)iVO_K2c#JoKt~Npb0MOi zsfR%gnv_|Y+dvIn<8x4DPPmj!11q}&RhEfM*)otagE!I)3?R=kurgJ0F))~bYC|2y zOCUeAF@oF6L=E)ij4Cb030S-_=vNBKAXkY-hc#3(TEgmLlyT|-7NEvqv4`}BBD5aUi z@-Q%1fI35robI6MX;x--%?1WbP+y7N8MH%)kBd8}P0PBf?Qm_apkAevX8*o=nAe)5|ls3W9 zB?4lBWko=pItE)tCk+M$fh?#JbZG`I&=MJjbD(4UApJQvO-O&v0Ccbev_JPz9koA) zZKnlk8v(%E@tC2VIMBcgd>RPa7hz{)5eA*#&jD`vbAVg^9N?Be2e{?W0dDzofLs0? zNG*RBZP4x)PE{6N(6KjMpq4+29>^djWd<%#%b!IbB*CQ2$OUTovlxMv=QAk_a)Da@ zEXEL?Fc+xh&teAQiE@Ej{w(GYo;Vk%<c* z=rbuZae?|h91@Te&ddes_i(_rSaN~-JshZ8EIFh>hthExbI5A4Ffed|`aSUVz+9ky z4~INR0+c^M{T>blebAzE@EiolVca0X9<-Vqlro|H9uCECpgAt^>9dSdjG(Fmbf+G; zZk`TW3l8EjcC#@sh(OzptjwI64Gbdi_5-NM5rNjmOdQ4x3_^^Spb=I%Mvzv}#e87H zK-U5YgLsUf9aKacCdya}GR%Y#l)pgQK{x!(0xj-|1NE(>K#L#2#qfJ&1_tpJG7Jol zWEdDEj)S%int_UEXB7qp$u%+z3>QGloG-~RFx&z$uE;PjfEG?jUXx*9cn4bK{6L0* z0n`Q;Va#AOW&n8uH2%h@!U(bvbe|yD8}nHi7^E{97*#=Lr>VfKQUh^8m*~lWR5F4* z%OJ}*ALMk%k%S;&(5`f_A##kIAekUWkO=5%Lhy2--yjbqfF(f1f2}G5gBZ9e1a9qa zR%Kw2l#yd#0J(rco>38`FdQ5#AQP-WdyGLlUY$T4BXF>UgP1o}85kt8L24sFPUKf( zV2}Z+g*cIw$pbXu11ho40K3@X`n79(K@~e(a#756pegQ!E%bKuaH( z`=MM$4$#sE<_SZ(`TLp<+5;qmOd~~hH_asKuaH(r$D)E9H6BS z%u}IUc6P{qDp060DRXdumOd~~he~pCfR;Wm&wz5dI6zAum}f${+#H~#56rWmTpkY4 z(g)_*P%bYAXz2s<94MEM<2@?_1M^%cm!AW)^nrOElq_s4xhE zBJl&Lvf==FhC!H-iwVSqEXV*2EQ*2&aKnlV+_2(e0FkTDlz2)JQ|Z9zs8VnN1cP!-O!6TBefJZR_Rvi z2iOt`P6{WlmulO*b)g&DF_cbEXye^4_+d{DZ2|~52$&iHiy3FhLM;0klK{6u;2s38!K^D+7c0cP<77MhQk{E;i8Bs3{;0s5X;0 z52}YGK%$bbK};!-C<7N0C^Jeif=&+cc6QH!Bwv`BWRkDF^&-=0=nfFEV`VH zfkEarD+2>av;eg0JE5G7fk76uXn~D+x<&)Te7P4OPsuL;)tCQRLEYJz8lWQp6hYeZ zpraYpz!UEIpd)1ufcB|@8w~lNJYb>Dz@VPV zz*qkJ>H*ojQk{W81?;mPu+P%u z1K1%Bn*ovrtz2YakY+RknY4isWD4kRWw1%opy4vGNgF^)tuz@J)UJV|c>~D1X&^4x zyBk1m-J{9CptB3q>;s){qzi4VLdG}r7~Mg}?`8y*B_QKL*E4?tnY5M@=GfgJEA+G& z7}UTav>Oycby^UY?ghy`(qdrHzoWpw;LgRs&!=MXq4TF{yFzCO6Dg#|K z26GCEGSFHZ27S;uBp}mn;xg?AXf#cqO%Y-#186A&HcKT~85kJ!MWD*maVY~WxM0v% zf-3XFr7Qw$ngLWL3nQa3c+iC_n}rdSf*3(zFA8Fbf?`{gA9Ogi33$|o3pQ#4 zkpW3FFzf}L%+9b1bmSVOg_)}jX<-V04|M?rCJM zi3iPQqnvjEol36&Nno2whYq^1Le}20B!gCcvVqbmc;=iX1#|`s8|cU+b|#kRZ1+G1 zU4UlJS)Q|jw*G?-J13MGTOE%E4pB$i>bC#EIBS16fa4y)0 zmu&SQBS4e9EH5EOfXrmz1<#zbJZ3u#I=%rkbI$SMS#$ zTu4iuWhRshX{oc!f^s1(b(YysE~KT-G6%|qwA5MVLb;HZI?FsL7t&H^nGfYcTIwtd zpj=2xon;}E3u&pdEP`?&Ep?W~P%fmU&awo`g|yUJmO{DW4E&&$I?FQl^Pur9$X#QC ztgLaMfn_1kq$?|I(iL*6NFpc&GbuAdZWVz|x(b0NU0G2lU0GAYL7VWM*z&G{+K8aJ zHnsu~6Lg3_Xr>15%?_ZINFo8u@GHjHN*04mYhf!B1+~pU5zJNrQpBXpAPTG zgvZSw$ih)@A7lV%?v`G8;TA4uzH22C;53&M2_sY=(GE9t-Ni-DHg!`byz`!7` zr^CR&C?283z`!KFSPOL4E%QzgN6G{=>kaOhaSAU6sRwt=#6j&HMse`ipE!8zPaHh< zCk`I_69 z9NaMz2Y1ZG!5uSkaK}s>+%Xdecg)1W9W!yHjv1%)G6Rz# zXeggSn(?VN0|TQHBdER6qzJuh3pA-MQ_R4q1Y)exW?+y7NijxoF)+wMYj;*=289L& zIcTc_G=0OsAkWkSYI}kVR%E;gGFOceq;ZuZ1H%IlSDc-J0c5Tk$XtFM1_q^M21a#| zdUG8H2IUp(3=B^}%}j9nP7@UCp*joL7kQh8r0`jW^H)2%|M4$R*ogzHDS?V9)?h3tLZNU|`sw!@!^co(HxD+5Ak0 zfk76emT@J9k;vYbgAOc0+HsnUpewH!D;PmK55R1aR08?lk&$r&I|G9jXnLQ~33S03 zgCZm7<}1cpMvzh_B?bl=(7bOd2Lprlban=Ydx{JUpdI0i&GsA&3_3SJ&66eU3=H17 z3=DeD6d4#m$5XO%pvMY>-X}!{hOb-<4Duj3#tcRyImR?bX9m4*ijc!9jUnPpJq!%` zAZr=bKJ8kK7#PyH85j)Wlo%KaK#U|M1_sc2 zLS3FyuaMtP=JoD2-$CWbL+-jJ=~4^*59bkjDd)Hepr8*)v6 zXa?U41nO~sYmfg7CRw1BBXT034l66Ojb;Ob320`KksDNKGD7mT38*Wumty4 zIqez2r?Z-Y%4RcAk;-7oxL=!rfm;ZCj14%6gU8z$Oc}+s85nr@AmX6(4iUFx`~h;* zY(_>8pHza{Nqysu|Oxt@+pE?+d#6{K`cFxt->G{ zJIEe>Mn+S{FdYU4j$Vk3pvxH{rdu;Mf^3|^$Oz#x1b_~bWHRM0WCI;4zlH_E1+7A5U&F!$IuH$d zvpQ%sEf1*u&AFtD!&yM_aFv-&!ay`a7!`$4E822N0q63zuX{~!x! z0-qatvpU%MZJ?9-I6yb6e*_r;Iw_9*2;2zh&FTl90=l_H0D7}J*a(oB3>=`F z)j=2ZaDq<7WIqZw0(!GLk`YH){FxXS1fVyogN*>02{Pgs3us)H6MC~cL=OX}0O)$E zV^9;pt~kar31kHHW_7R;ATvQm9B0`DI`|8EvpUQO=*{X7F4&0UELTBBKyOwD8v!yC zWW))UzaS$(N06|efLhDIc@K2UEsP5`;sgt*{|UQU9c%>1Oa@-q&FcF=mtlfV6=UBD zH|90uW_74bIH5PIL%2+w(3{mETxL$tfCu|ds9qLM&`l%kyP#ZFNYdF2<+5?6ffDo{ zD3_fR)X8Sw3*~Zff^HgN-v{M#a)NFeVc!qsa&dxg8eu;G<#O|Zk`t3M4=3nO5%xn+ zVaRcB?1!OTem+o&VNw?014TQNvJf9A?wFKC_&^cBq%6h<3PmPm2~N;a=PCff`HgKea4&DN#n-^@RtPBjCpiVve3%C)WPCc9pHsS>vXeW*U zs8i4W0%8QnOpp;T*+99L6I7_Mzl0kB>eR!zU?X0#O$Lphf;#o=FCj*N%!GF8*&nlA z2e|~)sb_x*HwM(HXMYCeGV+1^3+mK^91ZH!gKUO(>e*j`ZQx*H|HcNo<(6~39s>jW zH>hR?PCi2|07_Y=zH;;aJs>KByD%{c|+tKU#A4`&jH`v=P9h2)06P%bn#{DX4& zIYHMDu>Xg01vo*=4%r#lAqh#46Lbv$J0p}U#0k2FfSn1-73Kt8L%_}q<%)2Et|4G& zfpSGTLDvwlvqHIIoSC|44a_c)|Jsv0*n)i62Txj0ogL36LkAh-@AIeqWybR(BK)H&Xpvwu^1)*FePSE89>_Skk zGAHPA0(N02SA`RFIRU!}l&i}55M-1nl&i*h0u)DLP_8=Xe~_#=l&isc4J0c8%Qcn zTmw$fRS4_~P_7{-=qdzuMJU&Z6Lb{TuV*`5LXk*wc=C-akZdaYX*LGPzu&&2jxuI zL@wwyKo0OFfXwZB3=AAfr$OVxOcz0;$BbJ!85kad?ppyZ9b;fF(q~}cP<{he@CmK} z)N~gH5e%$M9H9HrLCr1ZR*+g1kYS=?9BPqV3=CqsvKbgS)Im(ps&hM#Z5jta7auDN zh?N*HFmPys>|#lJE^W|$JW*9H-Nm3=%|XlOxb#2k_c_zbdf zhRbLvXgnLbafZtn!h>v_;WC5pARA}6%pp9;#u+XP2oJJxhRgC8*c8ad87`|EU>;=S z43{;82iZ8oWef5old>Xs;|v$d#u+YqPsGO#k80iBo*x`my~@d+0LgCrw2n=PHoF)1_1dipW&RYEw>;Z43Oe$c(A?EJ-yExZg2;5{Y$@NrG>o)UiexF&c{ z2|s*X6TGK{A8lNdzn0OCmw`c4Kp+Kl8kiVpTvGrxt_j{#B9H+JGuWOIflLSwvZq8K z3&I2KDG@062D;20G_ENC8`lKyDG`8=Yl?CUo|G_EO74e}3Y zTvJq9Ajtuw2sExKkUaskRT8?VM4%pI1$8YrPM$icSr z*TN;Vz!C~_dJGKA(;1l+89{>vj6&eD3pAi{ONoJ@7&J7smydx#=`?8RwGgN{Gt^^X zP(Gu?!0;AyJ)-SPUIx`L*iv+6E(S&h21UkTkQOtr zc_6cjlo=QxLISYhFaw#lMW2B|1AL@`g&F8{^BzV`&_Y~BOHkRM<;};yV57{y-~(D4 zXw50Wz@QDfJcfB<)O;O~7;G&()5ItS2K5AxN+f47HNba7fLsMz9uHP54$9_k0t^h` z93;=6$oLQxXwF~dvj0jaG z&`mO`^OPAFKuaW91(9SB9%E(Z0IdsG=Tl)|ScdHPI=J7NI27Ps2Q6+;VRQ#2uqd!s zLEiKLof-{FJnPDf=Rv!@y|FesO)Ffg0|g@+2`Bv9zrfVF|Nw7@L+4cAr!(zY9< ztwDu>0n~V5P+!2nT5chs83Gwq9cf26Z7- z1_nM^M2Z3x2dFt%h4DQo-q(W71DT})Gj9#ZJh1E6g3Q|tGEYI3fk7Q)9%BZh0o7_9PgQ}J)1B0t91H%tt=ngAngBg@f zRN;l!6;QnG1Dgsm(FtZM=%hDDGS~-ls=NsUgSs6NUQY#OkfUJpKxPHN%mdvF2`S5u zg3NOTndgJ#bwgwq!ZIDG>;aXqnjk~ZfDHv1m;y8OFWl>AKwhslVPH@VgL?h52*m3s z1~VupAiSOriuG$?Q$Z%?!A$iPh2?;2Ag68wIW$HZeIdw|Pr#;vOq>8S^%uxg za2fIhLF_`DyfgI~> z%D|vLjR?Irfk$1H(2@OyP`qBgSQ*tjPy45oFp0m_uiROawmO zXbmz_0b(S`I1x1l26r=1b4LQ^Z3VC+Uz;&7D6^?S3sn=w6CmGdKs16hd8jck2%0l6 zFs6evf_5Q z0OepcNWHyR0#VAM>>>o+48)+C0#)_|mogJj^{!l`#=yV_a!-RAwC*!v6a}R#JBWKg zZkeP8E$}@h85oSgKC%P*sK2xcPa zG#iKyUBEuv1o9!Mv1};Ez%WS?)l>%Md1}y-*@zL`1ond%2{LXK%*d;7NBV&sdBcK% zK^b(Kou?cF1A__UcThx!Ks16hIjJ)+{Ig(SVB9MOi|7!r#tusc2GjkZ*bM{Aodxm1 zlhWbf?&ecV1_m?G#X3b&3=F2AxfjMLuqU{z7#Pfx85pA(K^=V~D+UG&(9ubz;HmUj zuwGXy1_o2`TzV{c77wI|fkE{aG}2~DA$-otJV61`EMux+U{F_5ha>@5V#ZX$z{+%3 zih)4{G|FK4UWb8!MGb5(^HV7X22J^V1_l;g@T|89;|fsf%Y%dmC@fZ~Gcfd8F)%QK zhOHp6od*sNacc$!s}oWT3@+*n3^PEdMinqxNHZ{4fR2>6zA44P5Ni#Z7E_+44$T}k zpmla!&i6p)f-~BH*4c5(>w!01ii3KRpj#@ztz=dP8_;|!Uu_KNP$Nbg(0nUj9cV_2 zk!!Ir@W+yEDN0oE*XL7IWVjxkD)fkAjP6C-H39V4h$BMd6!gh4AJz@tI- z3=ZHM%DCLYLo$q@;u0*u;0WHrB&Np5=mfsii_3$N(MN`X0b&5C`Oe?~zW7K)4jc)L z#VC@(U@ll0D^sNm1B0^*_>dn-=pjFL;5CM#@hlLhfg0mrd%*;Q1Nhz|5qXHophhob zv;kxuM1>RMc3lPrPJTv4P}^3x1T>@T#Q5HTfq_$ikrC9igorsZf+kg&Uo$c~f-mkA zmj|&xmvxFOfV>7e#fwLakrC7!L-Lvv`0y(p9Y#h_lL|bzfh6kyKD&xX7ZPTmHUdNi zsBmU*0xwjSaAafzRrW}_oWLu5C7c-`o7{?$7y3zy`MlRsP0=OX=htUyy!~nM{C?r7p zvBb0)89{{ zCUnw>CDx5$5L11Fh5)0gdf(R)Q=91sZ50|T4n7SObX?KVCrFEV2~F8Z+lVznGCA*_o+jhd7uej#e5b9hV9l242o4O3=G$-85opO zSQr@ISu-#wM}o{y0oN*w=8Pb1Utn6lvoJ8IHh?TOKh4O%0PPeosDP^*Mkhv)LIn+| zJu0j)#ZJhI)xb-I7`+)mSqY?g8))gL4Fdxs=kk~(v+M}SIxk?~6OtEEP&<2Tt)Iwa!qRGI(1KN&o z476ketZFq#6-W%BNbOh8pQv#)bR^~Y%fyG7) z42<9dWLcS4f&{>s9(=bXEAtAF01rq7Xz-7Lm3b~m;6KO=HBbq`$~+GwpaxQ*4iQ)e z5&)mcqyehJSeX}q1e!rAv_Sckm3fIq1A{22zPQD~z#s;yO`t0#*=tXM`UQ{`lk9b% zwgq&>Bzrw0C^a$)FtLMHOoFOn@QO+H21%&6JV+c=*+5rJLNtRbEk{nMHUAlmK`SPi zWDLQYj6uzNCRtEv4LTVUbPNk8bfIGfXgU{6G=uKfG_Bd`30L4s9gkVp)tRJ8v$ye!MR`~Ua*;hnpdC}8uJT?5g;=e*qNALvVpGg1@F~i zehD`M)Ix)E!A87fs{k1RYN0W|gct!b6WT&!e$2K97izVeesEOyqn&-#Fz#s@}Z?P7Dm`utHf}r*mE3CaG2x@P!!rNOypgbA}YTSU% zjDgOjvX+3hc?h(ymi2;KZ=m)TYXwLVsEq--f}j$@fws3;t1`ix(V2F!Gcd5TvlTNw zWr8-l*if5YY^cpHHq>Sp8(OoAt(I{k6pZ#SUwB34)qk>=~e-V^U@m z1U0+ZGa)=SK~S@cJqyC)W)NUuF97eP0X4hWVa+Zr@tD06Vk*bWRG$q5KTYkcA)eEDQ_+ij3<(0WIR0!oav54qAx*LMM-}HmF2HMmPluUL|=nKMMe#DSjiKR)O!$L`YDL{0Tc$Z((NE+e?h_w z3^LZN3=DGd@yQH~+>D@mMnLOYWFZ0qj7gwf=%CIl*s~yMVUTB;7{o!&0Tc57K_;I9 zM+&11XqyT@$oSJ>CfL@~AX^o{mYxP#3UTHc5K{(pR=YGPTp2Hb!c|rpJgjyBR3J)& zN7TSf1_qgLApd}(gYhaTI-m-#A{2s|3=Fc;pcrJl1&TqaqFV?>U?%7QT_z>a)*w*q z$!ma|yN?l+R2Wl1?gt0xK2U&y!utRyyrCu?MwoOMBn+Cp1Fd*xlw@QC#RaJHx6)-` zm}SSnz*x+|z@P+f-%5g8_O|v649dq?7#N;tGcbTuF={fZz}TvnSr`~*+A}by-eF;2 zSPNo2XJKIYZO_1<23q^5?!d*s0J>^Ym5G&sA=QC_K^3$NbGZX(LYs?$;XFG7gQ_Ge z1H&^11_q6ERt5$)9R`L5&{hN{M$JA}1_lmC1_sS$Rt5$w5CgP+GT4!UL2Ci%G{2dw z3=HZAxEL6sK*oG$WnidwWMELapu@m$Lx+Jum6?r!VX-3vgBl-bn3+NQg$@J5I~@jw z9(D!>9Z<^~x}RJHCZW2Om4RV5NC#-6KLdk`k}d;-nJ#Gfo|S>&vLge7Hb?}t#0^vy zs@`K|VE7GE{t~nbQx~LC58B;es)J+*eG?r9hDuHb20d6?uZn?z!2q;J$qVF8kXN}F zwKy0UG%Y}}=)}OF^?{3lLDiX!fx#2R;{aVU=*z~y@X(2YK{bMnfx*%loY4%Y=`b)% z=VV|ongeC{bAarDtbt%<<_GQZH3W?itmb53(BA=71al!Pvk*uD11JxJ_9ZY{GBSeV z*G3oGKonZS!oV<#gMk5@c~}{YWk5-8^J)&zUT4rce(^321_onrvuzJ3iLo-T(r921 z0#zy(5!y^Z!>X*c2f>Xp6VR|KYuzjc1_nk(6VR|KYyA(f3@g(=4h9Br?P~%WR%LAv z0JpDLnLwwRvw>w2lsxwV~TsxMVcIn!r0)xMV?PIU}PGD8GOX z)d%}SguxU%@Tyt@Qpw8f2+C1GoD2+R;2}0x#7noo$2XA2G(qd!;1tvty z0=!v{OOufi!e{so+9JyER2klO+X!vDf$m{tLb}*9+OzT0$LH5HkgVyCSIf52g3xK8% zn4CdrjFFKOr1t|O0|VHm{|tgljTso2xj+YfF|sn-Xf-e}1WAKVtX~OQCIJ~-)pLL} z-(P_Ct}#GBvKMOeoeg=z4svo}tHB&xMNJOO_Z=7**cz)rA;ZD$3Oei@bi5OLGHA|# z6;#@Tch|G0%mvjSpj^tv1UfK_U5;@-DC$8iTXqHT;rvXXTiuO8Z9GNBMWDSpfz}KR zjO;3m-$BjxC2k_l*`I~6=YNsl*`8M=fc3i-VEikvj0ua>dv( zFmQ3TIxsK@aBZ_-U=ZY*ZO_0U#Fb&fz#zagv-fWfs4VMfkBar z6*M%)wa1l#L78j19Rq_3*ICel!4(61DA*c1H)Ygt_Kzj4EGqgUOO=`+-KlAYr??rfPu^3 zo`K;Z1J`?V28KrrToz6Y438POE?6=!JYnGKaAjb4%E0Al$-wZ8forV|1H*F$t~e_O zh8GN6Z(SG|UNUeUw_#v-#lRJ9%E0iNf$NPu1H&5zE;lm6U!zTu=B~}a!pBcDV%@`QIFmO59GBA8);5u*0!0?TM z>!R*-7X9aKNz?s+b}TvWZ=>?WnlQlz;(!;f#Ej;*BlE5hCd8k3!NAk{xWdM zS~D>GW8kuOW?=Zwz!hZ9z|g?R)#b>*(8$QOz=eUKiIJ<=f`Or#kt@cHfuV(w%fXF- zp_P&Ar75U*;$pC8U}$IL5_4u?=wRe}>Bzv)$;jnk#lX;lfGB8|c=U6}W^PbFn0*qI%fb#iy^eh{ zl*`HvI=zm43Y5#n4m!P#eJYg8&JCKSmu!ByoW1kM?aeg-aJSO2xI!4s>V& zCz}IE)d_YNkgD|#AXPs=LR{fC3=B+M6>gxKG#6C(Gw?96|7OntRYc&eV!xr*GO&YY z{n%k#Mh0Gxx^{L320rjsvES^I7#JA%K^B0FVBlB}GGYrO0|Pq)2P{R*M&^QzVBk0f zG9th=2&4{d1jtN~5sVz4Kt|MnqJ$A{1n9mcb{H3I1S1FN#xg!tMATvQm zFmafIwzx{mFfgz)!Hr-==7No2;t1dXdBoWXqz-HZ$V`wC%p4UUBi6|>Ft9VjjaY=t z1slQ40lG$u&)L}-qz-HZ$V`wCEF8N*MqChKU|?r~8&M~L#049{!f_4a3Kx(%un{0L zK}K+MfZFHmYe0Iq;YKV$=7Npj<^T<*3fPM?FtBq&!UAL_$Os+|&>$-NQIN}d;6`Xj zGBB{ixL_lAIATB}rD_m$U{`?51R2500qPsDvw}7X@xqPxE6TvY4&#E2;N_SPG9m~R z&b$y;fXoCL!N+l&6Vw0!N%6sr_zemg7#C~=AIBq*5rUva9efZYKxTrB;OF4tVqjqZ z3-UZa+z4l6F4zcu4plA&1_5u7Rs0YmKxQ(q?Ga&MaA3d5&Imf$8@yldHawAo_v_t( zav9kRLBVqu%4K5b0-1FW%4KG60Lk8ma#`5HyH_7TxvcEqeR>a}TsC&_KD|d!E<5`d zP^dkIayi%!fnw|ll*`FJ8|0g(P%anyYfv6|2IWEvt>;iKw9tA1`wPmI7X+1LOv(!E;Qe}kpu$S*;Qe}kpgDXR&B$|ELa4M9+$!lbMv2r3zvlyw9_*_%mOj~%>& zjuo0D4cM1}QVScDYse1XLB|f|8nJ_S&~ZSy#_Zr7bevGG2|H+^4m%f=YbprJ{Y=Vc zf}kwSq--Gw%7;wKR)V0+#H4H^2+9#m%61GKCqM~D0G#r9nApuYOhIWJT#%bV4TBcs zFfKT&m~jN~g33R?5C(QLNLJwmon6nv#BR+|0WtzykXyrz02kyiF4zcbj>#Y+zy-NA z#0Zd?pbTrnu^VIrxFENI8v!oJVO+2gHXPSLMt}=)8;B7gGeJh!a{L1s0WQdG;YNT9 zau^qEge`|8AIKx1g4`Bj1jtN~5gr_ld<+bbBGdzJ1h@!=aluA-aK!L2FhGh>4~P*U zGeJgpa!joe@$Ov!|>IpFdWG2W6FOK6NBfv$d7u*PN5enmi zjqu`l1Tq3#gnB`Y0GY|aw#p2&*;s_*mLLNIJGk%?gBt@byu_hgXyGLR;iUlOLJKcNC>L6IDM7i=!b=&- zg%(~aP%gCaQiXD%g_jzX3oX3Vp3C7G63~F0}B{ zg>s>VmmZW0Exh!hTxj8C0OdjpFGDC7T6h^jxzNJP7|MkfUM5g3wD2;8a^(diK~UiZ%1BJgTI`^4RCYV4G97mCR$+T6 zSC<{URoDT_)nf;56?TMj^&thF6O;=r=$xTkXhG)!3K}x`0BTHdG0K5D{KB%J4nJu9DHoTU6axb{*A-FF zfC^}ZI4_r}C<6l@7q1v-Z!V`fs5#A^%rOsSTQ_KdE7y9^I09Fr8OWaHrXX^^F~}Y{ zD-b!s3S`@TXAoHm8ZzN3a|JbnIsb!)bgDRRgG|x}jfim_wgn9&+%achIKaSVUU@N&Iy0C}aw3G9^#vY>9jTn<-|8P`NWX2gMnxY}hv0S8)Q%gn&J-w~wh zAV)Sx)ojpkH`iH^1;Jb6*jASegy`aV&80|o{T*e+yI&>$#>{b8^^6$Y^)VFrc{ z5e5cvP?+&ENH9t=fw++C`<99@Fi3+5&D1_l{MkY!*=21%xkAmfk* zK{*_E3WKirV`bwPWnkcX#R3|b0&h;{0&h;{0&h;{0&h;{0&h;{0&h;{Lf)LrDtc7} zdaXCBtg0vjgCvu-D9C0{cA=#hG$?KWJX4JHg+;3M_8z(?wFfsfSV z0w1Zz)vXN52jC<1xWGs1aT%z9u3rKlsmBFAQjZIKq#hUeNIfo;BlY@485l&E7^M`% z7#Kw5T^Se{r9n(k3UUPTWFS0723Amn2{SUv7l<)1aBTwjmJ31iZd_b;prkDe>Me7L zgNIp#EJ6OeV-3p1vp}PjT=M3i>}F^V%5Jx;7#O%1m<>RhwN=F!800c785o!x7@4Pt zfj0O$gE%1D806+SFfcH?F*2_ON%We7IN-3BOE6<#VAW@2z5|i~-TlU@4~hVDI0Hn(30($;OCY0)!5SDq8h%+aFfjHrf)pp{GcbGv zX#m~Pt!@Dtub2o5fJ7Gt2KBwB3=H5Mnheb@3=A3x+zbpn5)2ILh9I{e1u1*s!oZ;E zlv%>Scnri%ab;l8YT#yIP`_i(z`%GNB(}kofkC|xG@fw>6a+Ux%cdB#Ku5)?M}yq4 z1*C|mPs%$=(K}& z;xK~eV;8$IFz7Uc+{Ofsh=U-_irgRp3r0p=#w1WUH83)Q4A@}E!0-cP$W{pk20f5T zZiWmDt3V5{ni=&$vW&c-y32rZI>>@{Mn;gB5NOY%I|BowofHFu2Iz1yV<`p(9nich zV=vgw0(S-m9Vd`)`@sAe?hFiupeO~c3p)ogzMD~8l7Ybp6sITLL6_cvlFJ=K28L%K z*(HpIprj~b#K52enuedq7!Oi?L5zXni#r2@@li1b2BTeK3=G^J3=Ae9C8pp_cnl1N zpp>d(#K2$&(l?cHGDzPKF$M-*4+aL~w_*$oCN@S445n<*6>^|0!C<>$j2IYlKzdd% zo(Aaw+2sn-1Gg&%WEV&Y*e*o|2D4p83=E*a_$$f4V4lgqI2RlNg&qtHS{Jw(7|i42 zOBfgzFoNpi37}~^28$1d3=E(UwFEiQL7IU<4zw+YF@w>}6nx;KRf!P;14!JIF@w<@ zBF3N(vIi0o*0U-Z7#L;!K}`ncZ5j;>tiMGW7_6UzCSG+@!J<1f8W<#*K(jm6`#{M> z4iVlbINJ?+bWS4y(Krs7b|W%c!r+zyLbDPa0GMNP`M) z28J8pMR6C^;S;Md?vPov4Lpz;H4s@Ch&roA(v}6(Sv4leR2sBt!O8?}YOpb~2=4;T znt@vw?BEs#JGh0x4sKzvgIgHv;1&iuQVWAcyB)MbPL)Ns1#|)&sD;6z2QmnB1Rkh` z!J-e6U{Yq}1hp_&jHZF+B9#R>K`jgxV+c=}6V$?BF@x|#IYHB`EaniNI47uu!D0d7 zNpgZ(7%Z0C!KO%af?60XR-iNFn3QEXZ?ZBluvkNQ@|>U+2K<^ZPEa`yzb1?m)WTq~ z2dz9~QdVK$0^Q9r1#~taC{yt>@G$Z+fw+)s!Zw2DQ^5qN{A1t+w=j5_=75&1F@h}P z2T3yUGVKL93aN#`;&>FamXMK^4YVkY9o)iT2e&ZT!7U7Sa0`PS+`?c7w=mejEev+l z7RE!+IWwSZo>^rLLHC+4nS+*=G5Ufo-T)cQ4?1rEase0{BcoXrXqr+Blxf*nJwRKrc_2yC@}8;T@DRe1}$=DN{4zEBqF#EWQG~U3?a~2&tNmm5N4Qx&3Fh_2GS^$333kj6iSG3 z79dd(zc42TCQDG2!63@G3{*rrGJ*;yDbO@D=!^qVMrV+y8zV?W2_f1C67^;TiKxIt z#TYd}qJiKN93*~0H~mfc*xAaAO*S`S;L!wL24Qk1A{Gy(aprb5bDjqAPrL~1G*X- zB*MTTtH8s+0NNKI_YdT#T96Z%dKl&RF+mJ<0PWaoOlDzVkov&Hz>w?Bz@YGyiGe}t z783(QBgpjgObiS&y%`u36L=UHWZ0M)7&dw{Fv$F7Vqm!A&A_1a!i0eVv{h!51aW*`R0 zw{bq8tE!_DNd>I=2s3d8{E4)SGSkcO!Q+Yb@}%@3O}Fcg?DFo0G_ z$vp>!csex1B|#ysX2QUb0x~=sR9JvRJj)k3#OpvdfI@s4$Of2laHy~IMGke4DR@I2 zq_>(Aw3`{SY>8=NIXu)2;Gu5Jz@YNQgn_}xl!2j@je$Y+0;p9p8I=BR`Z6%6F_i}EZOC42V1jv-y`F*Nzm$;*+`}de3@RY2HkdLn z7=Tu{fjtave*X7mU{IO?wGPE6kTwsa5d(wT6k|w$fKH#rrpAFmZI%hdIc4l`7%D^Dx$H2g-!@f$)4(re?hJgV`Kzr%Q0hM zXaTuGjT7byF|aG1`7tnP-2thDtaD_VSf%w4#FYZK@|Y%8s_B_QLTC{OS_nY{8rh9% zc2LFVkrhv@g1gZe9=C=JYJO0~e~=Y7VE2$x98@tp9w%19O|?KWl|c@)P?^ydROhiW z@6l*rkUI+UkUc1xSef@~G%#p`Rx`0UgZ2wDGHQc1L$k`Of$p?r)L|3>)js-+;Bbc2 zmY~v}L5Fd&5(5L9I3pt{gCQjN!LquH)gWyK;JS?wl)4cr7<3q;RTvo9Bp4Y%_oMKG z36L&`R$iuCpkj-a0g*Ed) z0R~zD#SYpl%Fn>T$Rd0dv>*!H?BfJC`#8bPK2C76j}zSN;{-SRI8mB?AVauRS#;-v znoW>qAIKmkWd?3YvkxS}q|C?-Y4(9~2a~cOH>BAI;R$m?ntc$SC^w|p2jPixLz;aM zo+LM<*>?%l!cvyzhBW&?mohLZ%W{KCau#a{Po5j4*~g92?Bj+s`(A-fQDI;M&76bQ z#z6xE)a(OsA*BJ`P4k*Zm;7z|B5RaI=r|FR0nZDdWk&z|0A10Z1LzrO(HUrW?1Zl)o$ZgfjM9%SWP}y4KEXD=auM2kYoiT^C7qq6(DJdrV5Y}1~JAW zP_wav5meZAfrg|(ZBcQ?wII<6j3ALMFwuX^3=G1c^u{<9l*<^z7!5!c%wz`1h->Xg93ei00V>63mygrEzlZ$aI;e#tc9tEQHGhBfk6c{*v8Aiz^KK@ zz{Pz!l8EAg9I5z#uEn%)nqC%)lTk!py)BAI!iYuffZ}py18Sz|bDdz@Xs3 z%)oFm7}OrMV_=X5ohpTBcq$<`JQexu7#K{D6--QqD==1KgIC84%An+%V9vl$0P1UR z$N@R(8E8LH2m^!cZBR2C#JB)zW`{5^sK8VzfcCM3f)%fk7>k zfzcVA2<>!Ly;q4CdhnHBpeK7V32QsMZ(Ka0tOrNwNf}VsI$Tu7*t?N!9fiY0d3Q;U|{%U z!N4$)9TNW<;P~GZ&cLAl$O01o45~hs3=9pH3=9{ciWY%eL>EAcf-E75)MH?b92lbv z%3zQ>!OOs~9JJ+mF(_kx0PD_(U|`S&_bxwz`C6Kwto#X_X=g+*Fz9%vRx&VtX8aF1 zCs7C7Ui<=03f$6{Kt;({D3@JT!is?bH0cD|@Bm823}9~@h+tq~P_?pRV2H9}V94fx zc##b(#}WyW%L6U9v|?arhsyDRoJ zq?eFo>lolsikwk3LCymy23>!r1UIS*rkJUU0iFQN7&Ji+1`V}?Zoz}8W@SF2(EvA{ ziNk?GGsTL50i+Cc3m!t*2^3`t44NP>P7-Ed0BtsfDPyWZ*bQ(5Y>^tQZ(RSTQg>2VFpz$-vkSj>n!z1_t#5R?t*&0mcALPJj!OS5OfK z8BjqXV9me)-XCSgsK&*>08YJkBB7;ML=-gjZir%FkZ0gyU;w9F5RZXDRl$aVLCTha z0d!{wD9R^*t>=hlV33mFV_=8|Z3qGn$W8(e$T~zbFfgdA*+3oUV8g($0aUo9z(nd` zB8y-m`(PrEU?P8@A`CL1O4-hqfgu5Od$%XkKF}3F8O#g}3{n+*3=C61wFo$|`+!|l z5)Di2zF;cf!4NdHUP%gXb7Y7Cg9!CZS8*WH~jscsw3*U|`TZ=D@%JO6-%k85rPE4^Ql% z-B_UXyB}E=DPf=_c98Qxir*qDMoMs~i5=u%P%0MTL0F6>u{$_I61z2uGK|EY_w7_=Nf1)&$Xv2{9z zfk8_S#PMHiMMt&SPd^IAYJhAO)Hgh+vZ4#>~KQJC=b#ZZ#++GiZJQH4KCq z7}oG2;)V%P3Ne~6sQ)l$V7M*Jz@Q0Q0=`d}f#C)YwGIsGJeE+k+bkIvKx$b)r~bl< zLnL#J7&PZuL6oTDP~yO#2`YbH3NtW(4$^|hbpr!~<{WDVhQGoL49VzvA;lacNUt@- z_%?JU(2~xGLH&X?)V0r`YB%9js|hLzKuP`vk`h+tGvJ~aZmD{JEyP6i7$`#%bZ`gA zrM#eHhmivUu1T}Y7UEI^bR}??YA&&b6xqS(N)V>3v4u2u%FvZSO>tn*EU|-FG!uss zBL?*@JE#Xh8$%(n4%KuHrzTC%ekV|5f5fRo-NON5u4aq_#0|2bW0R4?1L{m82F(@+ zNaQ*rDZvP8%|56>X-KM&Q!dCLM~GdWxRuO-Dp`YD$u>tw*q=vN0uOt|eV{wXkel;J zDIK&|3)JlawQ|7yX=VmC5T75klnyl5z{;S<7zk?XlrS-Z`Z3F#7#M!WGB7ZLP8ik) zH;PJ_K%E(lI0gm-(3%=XP(sWE9V845K+xHTu$BfRasyIx614c6hNPOQ2j0p+Qf$m% z2(lS$HY~3}#@yg0Bi8{8dW>11QmdYc5u}a9nSo(u90LPmr4R!H#L@L&M?Z{XU{KxR z#K7>(iGd+Sh=D=P$=R8Ku?^e`Q;la}(7XoPY9q|RUQB6Kmk^ zGl4f=3>g>{|3J-!OB=wBH3Z8FUSy~1V3bW5JY~9LmeU{=}Z(Nr+-0X zq>NmQpah=e4BaLT+SbPo9%bMHP3T$1gLVdhZlVOW4;bp>85lUghv9I8{B;n-1x*k# z@__Vxjb~us6me!?@Nxzz10@~sV3k(_$VXh@e8CM4VMZB7P%;78`T%A#NC0B949Mn; z1endB@hpaU2_PduOCIDvHa`Gy!8Xf-Y!*pmVBjorW?)zWw;6n%k53}VW+uo;9fJ;N zOD@A1M8H3T27Cfiz@JT^AmG7cv-l39k@sd`U<_acc{<01fgvlAfr0TDXvWwxkAX1& zl#m%S*nL5Y0zsUfL)oYi?)J{-;m0{!28ODfuYWwfnhpmb21OewX;D=`ObifhB+W6 z`xOv#E-2={q%tsYW-&0%1BokuHdF9#ac5w-;LgCn>0esHz_=GA;giO|Ah6AyfdLda z-~mO@z^xEt21^Ztp%eoHgD^NXae*@-<3&c0&(b^?7~<0y7#KmLraT59cU%PdZfhFM z$(KP+ew_yK&K;0F(di5f{5Bp83=tkM`$3lrFyyB*FmQqwNj(B7Yf5Ke5U}%rI7h(G zgMk6$90mpsaM{H83LF<8`(Jo4Fw9A3U|<9tYsY>EL4iMA&XVt zWic@Dr+6|j?DAw_5C>;%MX(RVvKbh}!FgMk5tJ^|K>Ph6%SJ(0Kg)m!7BI;VTO2Iw z3QE*+msmh&Rw#gOC@y4Gaug?4aHMo%-;KD%%HAQJoL~6{`@enL)$y5;}#& z8V;KCWVU2l2`Vb3d_ZI_NQf=i2joQdFTM;6j4YGifFzFkgUDY#3=E8H_Pz`ZOl&Ls zKx+f+{6U9CBzZG1u(B!pGBB{Qf#!4B*$Vv`7&sU>I9Qenf|fJ=%Vc0+Sq_R2&~hd( z5N`#9$HKt;(VKyRWhKZO4px@+jv)2m)2=o`R4{NJ@?l_L*#rt|&W13HtT!yB}n@yKSl9pLG5xSr!6 z!$3={xcwLySWbYHF)6b$a5L3_mJVI?Wnf@A31V_cv785;V!-JQvgsnkWel8PdoRPx zSS-N6z;XrT9VTT~&U+x0S3!Znq|C)RA7uVD2v3NCc{a%T*Fgu=acHsJ1sz?=c^aht zKFmi~LA(bLdzd)yf^geQ)A#}+6nSw0w}Cr%YhE>VrThy7Bm+IHvcokZU)XIkghKv3D8kb zJRnEh1%)r389pt3{Py_heK{hZjf@GMK8Tl(f zlFW?xpd+J{PqOhhg8aq?&dbco{p|ePLCV<~>%sC9*!iPD_H%%T$(WU|vGacfspn+u z2g~1JXW*I3#J~VDjThu1VFn(Mw?MkVd`<=)kZVDzp?qjFMqnez;XI5lKyxKBEHR8X znHd=P!NC{D2njz1{s$np#)I9)q%6e`4wwWeSDHa!HOOg+jElg<?yJFo>Q4Wmrv6bo1mhFo^yG6+c?DSQ!{v@);OJo`Yny7qBug zF!wxW5ETXK)d5As50K&$AjP_%L>O7Xz#z7OpMgPC7337qwJi+pg$xX$D?nTeP#W1< z$iN_ef}erm3h4Yt(3&2`;~;BuK_{z-zu;$Jc+CQ-UuJ?Vm5MW@4WMyCweFO3^ zI1TMBVqg$65MW>sxdk%&D=4~{dMqWcfE>dM4zD{!3=HBC0t^gxpk+&$42;ZRVew+n zwd|n41nnZ1f%g2^COS@GQnp}VU=S++-DZ@@z<3wr0Bw+J1_o}X63`SFNJO>{bYm#f zG-d_{9#HIp!VsJY7#X;kKmy!MptJ!_(i=dhgMktdJA)jf9Vis77{O@_WIYJm7lRJ7 zWMg2E2gjuqI9~S@GcYJpUa${E25L4E~c@QH1paF++C z&T>Xj@~kccE%*nyuYwU2%#3OBHJ~I`3FfUYV_*>L5P+QRRt=8A3m~Btpea{SF~V32 zwjuzuXq16LnUM#S)x#m-%%}niKn4cTsaZ@6lR-xlL(a-!41m;@9D*QcLGZ*p)Y_8r zRlUri0SpYxlR;S$e7YqI+F3a)$YI*ychy>qz&jK0yvkEfrE+V zIonfEX99E*0n2kX(0~9JX!QpJ8xzY5HeS%F1NoqZw=dvEfKIn$fpNh`ykOG+trG#A zZprcjVg$%ckP$E00zgJU&mRXRUXUw5r(3eTgqjF8;w4))$OzEsmMkwJMu5y@;CaTy zz`()sm<_aagB^6bCCgK&J_dHs89*%0pj<{?kbjw!nRr2tW>RM11=$Qb-IDJo0|Nug zE3ggFW(GeK>xbu{CBC5ZELlH+aw3y5g8-<8X9brCpn8OPsSpDL>$gLor6Nvjd8(il z8lVj(Yy}`DNIhte2^;JLO99XcmTd47ECoS^nu1#Apu?J=Cs?wTd;*!)!d8|7I@=O- zatB)lND-4VgRrL`16w7813kf#t;zv(Fw(^U1_q`g(ArB8rUoX^k&Ga-L5pU@Km>z0 zlSEV?0|O&d$3`Xw21%ztP#cyRBqDhZw6>f&h)B~B!AjJ^G zz`(@K$jA&@J|O)aq=%ak%>L}pz`(@A$j8jUAkzg>3|T(IAj<(dFC5h1W)NWlIYN%{ zc>n_gqZj1#I0goW8|4fPjD5@u4DulJ7`;HoL5oKPkg1H`AW8NL1_pUhurvBhW@cbu zOi={65t4&I{b!|DObiVA6$}i@_m~(MK*v~tMT$PM9e zH{@3^Fff8nh=jNy9K#I}AU9lsyCD+d2Kg7D!X^sLNkVl{9N0k|l~^6506LV6fkBQj z9^{N1xHCLJnI3Wa?p1hZg8e4GijxDa@Z4lNdBW;lc<~3sVOgTZJiP{>+#L zQJKQPpvhPUN(klPk`SZ~gs)dIFfg{W!rWU9a&KNW%)J#L_ih1k_k$c*2~zm0nt?&< zCCH>|P((P?FfeF;5MW@?G6RX#_pmZB#MLk`Xnh888$cykTMYw)4oX}%fzKZY#rL`z ztik)N2IM$h5CNJ3W{}MXodOH49|S?!X%Q;}gAgdQu`=j^&hBHYox}>-#GwZ|yN|67 zv=fApQ4e%>A6xxNu#5=Pc~%AnR#4fZ2Ravkt>Gb5{5eP*louH;34;0^w?WI6A%%Tn z5Tvk=5CXXbg0~f-7WS;T4n|`ocrY4t3kSG_XG;c^n26KR*it~{Gb)Glp_m z*rhBP7}!jpTvqmGkYZCPmyO*X)PgXBa@pBI7s<1kL%AI6po`?$ETCLY4rgB%1~yA5 zmkYe*p3Mr%_6V36Q;31eW8;!Xmsh~a)3#K54$eK?YVL76)`ih)6eJ1T;KL6w^+nt?%$+a;8N zL5tfkl7T^+y9%@fgj+d`fkBu1YA6GP9`~^*1_piZ(kKQ71Mc!L1_mQ;>2L-HWA5m1 z1_l#uk6;D{Q*N6m1_m?k6X6UD7Tnpv3=EdsrqK)xR^0ESL7SPmH-#`T9A@CY6~Vx8 zhJo8U1az<%H){;&ye|eGCbs8n+d;cPKs7ttb2eC})UKMu2K|I2UZh3pP<^1_tnT^lUF6Mu5x&8S#?M7Ia)3 zsAgw-2{!^%v%|SyBVMvafQ$gu>})R~Mu5y@U<23eY>(OIfQ$jv>}*fr#(-*ewr5Z- zqaet?Ov+4xAV)JPvj~E02G#7GpqicS71#zICbn;E7eHo#uA^uB2Gz{K4!VvW&ILQ^ z8{2D;lR($evwed&X$5E|nGJj$J=;4rP_l+3*AH-Gz{&L^l*FE^x!FP2(X;)Aa(UQ6*U_{6fpVd_=P#5CIem-mACwC@3xe%GlnXfvf{lS4 zl8_*0L9j7GxsbCU*qESP$XO6<%up`mEC@ChC>L@T1RE=q3popdjSb2b2Ong^#t!8| z&Vpd$fN~*cL9lT`xsbCU*tnov$XO6<+)ys$EC@CpC>L@T1RF1uD+fNvhK&!(m1hTC zN6*F&U zl&i)Lx{jVr49Zn!2VFL_Z1e*es3przgO%ck4oH42VF+&VJT?aAsnHA!9IIG3 z7#M^SLKqkrIX185U|`_>mjUYVJ`Dy{R$@U649whtAs{d9iw1cqAR6Q){t%Fte1aGl zIJv#T85p>@Gb0%oxVgO}K#RJClA=MzJvsw2?iXlzAom532)9Bss1+mZ#FY0Rd^?0SC55&>SdJ>kcZa=fnsuf6le>h z#Qrb_2Ig~&%#%487$iaW5HOzuF&U&l5g@%Tf`Ng>l992Boq>T_W=bRj14|VnBeU!j zP^$4~WMn?g$-p3|0aE492x2oxfs{&52W`n%$;fz*lYxO5I?^U<91Lo}F)=bTfL6$X zgNKm`#Ac8J#hSEe1Oo$;0aTOBDo|+71zENVWSBA|BeMlaAIObN%8Xz~%BX@mRT~%? znI&$6{Bezu8MM|9;*V=!CGx8y85o%FKwKg#2a0zEMn=YFE(Qh#yC4PzMkPqITy{Dr zk+?H5GJ=i|S5$}xwQwRJatsoBAYLsa<4!IH2BkM)3=E9*pzvXkSOzliJtN~?ki>ov z=OdWe2Wqx|0(px;ndvbX1A~f0JxKO8Bcl>G1B0*?<6SXs1_lvBP@cOF$|s;i0-F0~ zd;n6wq|C&iWDbhDhaW+Q)r*3RGU8@n5CbINEp=KmI9qm zpbYMOs`^HPu5M;zRQ&;RP#+_s8e3_5GM7#Mi#7#NJ5xEL6Icrh@5r;<8BH&UATb1^Vz zgC_JfKfnz91T|3e3uqS#cyvq~luiY_85lNzj7~bq$G~880%Y_tE(QkAItB)vi(Cv0 znIJo!a4|4^@Md600gdMUY35^KFoki=Kq-`|htU|6?tXYPFob~AJoDmXU@)=gW?*Qn zV_-0aiJN(WF40WY3FT&Bm{!NYU_OJBfdM4>%bS6L`HA^5P6h@L^ACvoR2@VG`7ki( z^D!{!Byuw_Y^`HpFnR!TV=gxX!+j9%2Z&e6&A?z%&%mJ5!p*>tQ4dO*3>Kh0RUq9U z2QmLO*~iJi&<2sx4D*46vq6Fn1A~Mh0|RIct|7E5&pdH|y&bHHv@wM$f>!T_!$_?L4_wM zA!L9e`m|;r)aRNrpt>~Icr!3;1cjHyJZ=VtE#3?ahd};&E7c>_sgGU`iLA9T@0JPv^Wv~K`Ixy8r3xGx) ztU#jWq<<*$yP~71ZC=f{NH`H!#>R z3W6%CqmUVSMq9>Q5ce=6BdAQU16M}&j1M9i7?`FpGBVmTUIbN#)nMlBa0UjZIZTX< zHjGok7#Nt6AeA7a1LLnS1_tg_sF7xZ3=DQ)0#sl#NP%h^d&X9fHJyy0yHJ~i85lTQ z!Gr6Jpwi9`RJ($$wgYh)q;drr7?hbn`WzU0qZk;t^O?X^93v=2AsOw&XbE!CSw==i zP_h9V!C=qW3=(VtJGoVdfq{pek&)4vv000Of#)a4@!vpRDuOzm0etQ}L!>!;!dof^ zGOCk-G^+EW4AdxKy8xOTXXH2sYG*($5M?6zo&y#}n;6if3?rx}s`G&^ykM*lHURm7BO$)Vql=c^aSYqeipP5D;A^?E6`j6 z`0Rer$OQ}P$OW7Wo(*`;b_;1v0yJ{L1sd7`O(?toUjx7n8o6LW9l3yW!A87blLbvE zK<6aDMu5x&8S#?M6*OiB8o6LW9l3yW!A87fO8^-G8o6MBj9hSm%tXvdECCq<8o6LW z9l2nEk6iGA{0o|s0Nq^xnv($83>vwB%}Ic4fOdEIotW}KixCCDtHZ=8eY z7!Zwf@EpT0Mg|6<4TxJwnMy#rSovF+$~0kf3``XuMbJ40rb-A0-Z*Ck4Woh^=WKqd zpy>s0<6IQnI2Q#s&PBnEb5U^PTolqc=jUKuyahBP0&3f^!n#BPpe_+BtV<*S>JqWS zxFm zC~8y=fqbb9x;2ZDmDygqfr0fpGpJYqUu32Nsu~zoKw;0w%Iv7!z@P%E9~ia4^#d!j zgLVUhD!hCbV_{%W0}%}1Dno-2Rt$nnWYh$=mDxKO85wfeKpn&fmhb}cF|^RQfmCSh zssuR$Tp)rA4a%3Qf`_@8(FzS_Rsq z3Jqq|LIchP8-Y}4FhhnrxuAsxGg6_!j9O^GxnLuZ3Jqq=LWB7+8z|<%qle6>g$6T` zg$DC0aIwV3#Qcp7v^kv}G~CIII@}58f}Qk@?K7wx0}XdFLxwxKKuMN?2Rz)#{EiJ& zn1Y8pnNf#3nNf#3nNf#3nNf#3nNf#3nc>5oydYP?hC7*2hdY^3hdY^3hdY^3hdY^3 zhdY^3hdY^3hdY^3hdY^3hdY^3hdY^3hdY^3hdY^3hdY^3hdY^3hdY^3hdY^3hdY^3 zhdY^3hdY^3hdY^3hdY^3hdY^3hdY^3hdY^3hdY^3hdY@Cq2q3l;ZA1M;ZA1M;ZA1M z;ZA1M;ZA1M;ZA1M;ZA1M;ZA1M;ZA1M;ZA00sH-5uoy@4ioy@4ioy@4ioy@4ioy@4i zoy@4ioy@4ioy@4ioy@4ioy@4ioy@4ioy@4ioy@4ioy@4ioy>^gPCn3ZC$ly?C}+a! zf0jJZJ#OIopQQlAgw_8nu)#TS{m%j)oCDYYM?uq`)vWNrIhK+pRt5(C7M8Lvpk-a4 zH3lpdAVtvnpQRGQf!6;lRTo$p7(^HaLA!M{;d9pDwKaku6I9t47=%FPvoeT+>Nu8K zQ8rKqM-)`Yu|PXGqM$mCrQQcDBgPcO#=yV|D(OT)bsS3r=#phdMlq%=kT}SChFy}N z`sSY%yuP^_3u%CZPJ##bq!}0(=2xTEHx%4Ag*>gwj#l5WBiA?VNc9anYJCIef{Imk zr22*(wZ36Ts&Cj)>l-*1Yy?t$!;V_tup`ws?5On(oC`JrslH*ytZ&$n>Kk^{`i7mz z`i31+-@p^;fHzV(Nok~VAR4LgaeHthl>?=b%7M~IFo`-PFfcHSx+XF(u!z2i2MuP6sDL%Zf#yC%bwS%&MGqu^ zG^_(_sEP$$HY2t(k%589myuB!v~m>ju? zI3=Mjgfl==@*u~HNHQ>Vfg1MU7QZ4)NCC`ckYMxxMFwQ)KB&dt;LE^pvWbC#F^d&? zE(^0Fh#A}rbw0Ba$VHtXE-09pl|jzG*v!Bn^&gZDRLfWy7{pr`7^FbXXI29%25~`= zzzlAeA8mp9=7|pjgMlyu1G9+?Xn{G%$udm73=CjTu=p}C=z+YY2NN-Xi5U4ZFn|@u z`7$to{3nwGWiZHsns;(crK}7LN^;P%{ zejADpOF>+O4~5&I(FgINe>>ENAiF#uJ_Iqrjs`KnJ_IqqJ_Io^Mc|6TJ_M-&F&HEm zuf&7S=|)Lm&Fu^fj56$S|A3gh9Vq^B25}Mo>Fz-B&qWXy;UCUU6#uw(BKZe&A_21r zYWjm`47h(VMd1Fi0L3cEKOhE!tRm=eIVK6l%0vurRdzBkFn&h$7IPPhx6(megtyjr zp?K>nh>P&n=M6LSv(1LJEBcr<}BR&NiAe-4AV z2>)>RqWC8e#6|dLCWwp3SXXf!Q5Y z))e$HKnoAJS1=PJrU+ayC{=<}1Bk&O!N`Rfk9~a%42+LK6Putdn2-WRq94WIH6Sj+ z-$(jU{LM81r9hbt;v)QgeFBod4?z5VLzsbK7AMFM(8LX{9QDWy8d1UD*hk^ zDJXG+@PvsB42&N z#(2!g-!Ykiff01>2>6sQNaQRG^9Y_09|2# zRyJXJ8B+u$5cY91FyIe_$4Dwz8yIRBWKaS@5EOr?DIshcDChIQQv#@f{xuCH5Dcb6 zTLh3QwPHF-AnXHi5h+1<21-ispMewz3RnUGv)sZI0R;j$!a?OSIKtB;85qv+U zxHHq^T;DxmgL)Eou|sl)^Z1{PIN<9N~>1_qS?5e9}cd<+ayxp52(EC!&G`y@y_ zLxh20DoETuo`C^!Ncg8Y3=GmH%nS@qd>I%TKpW6(Wi`P?MDIC43Mztor@ASo9Cj04f{Nl zu(6-Vz@Rcign%0S{9L>L%0@-r| zFfe|Eg$=7BsLarv4-FeuaJp%n4-FeuaJqRppMgQ;fd~V`4w(I{;BHUg0whoW5Mf|o zwE+7S(;J|q4VD5G4+#HUg`4LJitCgG82*6=4OpWDiZU=v0Er`#Y}jI`Z*}|`7%D_Txm-2HpMfF6pMjwkq!iS&V{rsE?eZ2w zn>Z|vpmciJO4|5{?N=QNnT3QcyU8v{AR1(1AM~T!b!#TZ6NhC;(LosNuL{DFXvzE$G4~ zL=kGb3?&?+mw|i-(h4pn)`Pf+aQwcEfkEYlC%XyrEwkQsx0M}p1z`!_L92#hl0({a+XrQrzE2JGOp@9aekQ7!i zFsNjRF)$>FLqiEtfOo7y3JuWxLwGABc~I&CwKOBdkpij#n!3Oh4m=~*!z}`r?8{bR zqz+I~2KG8wqXeT$B8EqIu3}(dtd>CWDAQ^bk7}$&@o2+p1_qS{Vhjx45-1)$u^P#v z2gC@}RB(?vN)YsD2HYaBN1v_6>QTtdeYXU3)dVYp8faF7sTSlpMn*NztOjh^mKtbQ zgQZCap~v=*ouWKf5%1OPRs8PypdgN~ufVgwI8 zGpfVadVyti;p+(?ZesY&1Dd@79Tdm{*%Zf?1ev{=ApuI55F9cIb@qk@c~cy-1TzBz zOSLa(Yc6C_6|*=kBps&~hKpU@GeixDg?seS$D9*oYTw#-Q1D(843u7Z4*rW-_obvA$%B z1{ncbc*Ob=ZUkt{6r2k-;w4)d$OzEFBi5G?BS2q^(ovK(3UCI zXHYI9FUY^3g-0MqgBBivY=$p9Vtoa+fsKjv8{0dOS)erptlyxTAzP;4T(FbAv2lX7 z(}C6yuzrI$=@@9P5VD4V^&ML)EA&!b)(>!FKwG9*KSH^XEmN$Ypj^n7Db~+WE@aCT z>lY{&vSo_(E0oL13vwlF4FT(Ss4!&96zdNt7qVrF^(T}I*)qlY3(AFTnPUA7d! zlndE1#mWNZLbgn?vO>9#EmN#)P%dQ46e~NF3)wQo$^qpsx2*)qk-1LZ=tOtJDpxsWYWtb9-|WXlvQKa>mEGQ}zYukS$ZJVo)w*%M`0PlndE1#VP^iLbgn?N=1OE@aCTt2~qo*)qkd0OdlqOtC6LxsWYW ztV&QWWXlw*GL#G1GR3L_%@Yl03(5y(ve?IsmClFY!+z$h>k#A5^% zt#er!7zA0_;+Q}a`xVs;3~ULYDuGFvK?rml0$U=e&}33(6awu>XG?;}F$+m?Ffgzs zLwGC<%wnLkmr@Rb%o1RCGh}065C$zZVD|tOPSB+W?4A$~2ZLY|yGt0zzAPOE26itH z6J+1*T+r3T5c?7sM0nX47}D4n7(_w7U}a#wk<7rr?gKJg47@&(!*3BA1A_o~eWCz( zeWCz(eWHL0X!DQ&czvP(WPPF_2j}9CAPYh36FFh)6NNzQ6FFg1ze1q(iJZ$J)-wr# z)+chVfbdv^K{o!=3C+GG=)HCK_J#? zihx4Ro*n8j=vfdlkld2qvqv566+<{wO*5+?(LBFNK>O(1nYS2HjueFuem3&>w; zYZw@m*g@H?1Eer%4FiMn-&6($#!d}R1_tQv3Y9<<31T!#zf=rtmbhJhaQ!N97h6_|olM&1Z zsgrWyW?)cZ0&Po@0+qt@jH)2N?_vb`nE_Omfx^C-n}NX)CZco>=j znZbCN5u{!RrsoJZ1A{782m=E+f6@KwILXI2ag=Kq?svIKTl8>XIzHbw{HYEz!$G=NP%>JHqL~1d6>xDF#bX;Qt7Vz-!3aF?xmU7`;Mvl6r;gh+ZKF zTCb1;saH5foPmLr;~)d5{{!kgaU6y;=NZ_S%Q7%<9D(o{*)NNM&Lf8KnAksyFfec& zgYcNyoj@v&LwGC<%o^eh3>+swJw}e>pc;WgfKe56s^ccm;kTSe(m=t(1wOciLzl$} z)S&_$+`^&H0x^Ms8+33BhXIt!$ejqX+7QZR;szbu!eIpEGIN6tZs9P7a#^@R2e)vT zK)I~kpo3dDOrcyhZqUIk9A;21J2&Wr3l4KAmxCL0a0`b8l*`EjI=F?y63XS`eyGC0 zz+naDa&v>absW}EE)VxnP6h@J8z`5TJB)*Yfx{Nc<>LnRQaS9PTz+oQ!7Uv2P_6(2 zFX-SF4hI%cC~<%fZsBldkp-R42tK%l6MS$BC-~qNPVm7koZy37I5|KEw{U_FZs7zU z+`Zy17)boWMlX zI=&Y)3c&#xg%C7j0iF2+-pRo6j_oTu0|O+v!bc$>$@L?&>&^&qFnkn(8+33B2YeKQ z8+33B2YeKQ8+33B2YeJl801POWj5|-pnM4*h2VY<;=)HExIqWEaKJ|)xIqWEaKJ|) zxIqWEaQuckhld+@~6atca;G+=S?^zibIN+lY+{uy*3>^QVdIh+bNrTR_h4u#p zxwnA0j8Lu+_Z1KqJ_^D82*ibtLU6Z%iYoXh1a}+AWcVlq_Y@EpJ_^CT2*ibtLU0Fz z%0T!i1os+t&^?1td!@L4gUSQ=CVU&HO0a`E;E0V9VxV^HDh>t)agfWP9dMQskY%DREM+%2Ku3;;hA^;H zfD|z)Ge~&)F|brZIM5C_OVw7;(JA182u?pyP6h@}@IVA7cp!okJP^UD0&0kJf(Ifv zAp;STpl&z|v>WaLT7C!WhO@MSn9`tbI19KNE)D92vp~AxGN4AYEbR1?G>{%pZ$4f?ggD@0wSb9N?9I&luChm>nsn!Oi=HOLIJm^#wHqfaoil9?j*!&q8na#Ku7?eP#vatCxg4hf) zAf?KTuAtqV$&8>*$Qw`~f_gx0pu;Un(+R|F0Uhh0lFiA$pb*Nypav4!rd|TNJT8=h!3@OR;m^&$pfMX%&S`+oj$qW7 z05VUb6+~)+bbyp;ZRBKN@X!Vw&!Wf+IsuM>L5DGeiL*h6F^!4CLx(Yi(Sku2q!J{p z16q8JEW^N{euNWZp$*8=-I*XuFLHubTBv{`2P6u1@LmShf3Q#hc?ui~YK+@J0cywy z^7yP!28NX&&wKMQFzA7fVPSLyg*s!h3Nsf2gHI>}gCEEaR~11n2r~f0b<>XsWnhR4 zWnlQl&A?y)T2sO32}+w%hM)sk7(GEL@y1351_u3%PzHv)PzDBN9+*NekV0vQLNAcQ z?;wTh(p(G-J)sN?eIN@W9C#QQj5N6z7`QeuFfbT{+{xGvI@H7jbj$%)97rD{qY3DQ z1Fk$!>Skm#0Ud6@RRQIIw#sq`)`PlfjI1Cr6HvF18`>=dXZwXb&}^T?VEPl3H1sEe zl(RCY=`}EjfwKN#mD(W=tPIok36w z$OP0=WNBam9ZJP$#>4?SgbGw{m^0o0WuC>1jOL7MQW+Rn7cnwgfX7c*rhs!Rqa`R` zAqWPBaxPE@;e<21TdAH7>70RBvFw{27}z zJ7^CsWd4jTpM43D^Jn1ZDwEAMkaBQyRRG*v6#zF^1;EW!0Z4OI$cZJ76Er;rX|95p zpcx*N=BhAia}_*aBng@b133rYTm@Ms)WTBc!N$NK2AXVRsQ@WrQf3eXH&-DXcym<+ zG`$3FuCn{J5Ib)Mo;89sSGTi4XN_1|K}_(h5u~{ao;70W04=bDoRB9joX)_&)XjL4 zje&s~L`ZCTkkk1_s3pb_RweAVw@Z1H%pwBM8b+f@x8%V`pGEvzdWGMJJ4bK?T&l15GP| z8^fyL#;_{5F{}nMA0({`Y78UGFfgctQUvH4^B9mD0>HtL5yrrf2jbd+`ZbCm&pZUX z_bD3#Lq!+^Lk&pMBo*Y|Z)^+t5r&udMia@oVrym1rC4>X5r&y~3 zLCQJU7M}-M4qC3k23xKH-l@+9Tdn~r#>6XPJK4iCPq=)Oa_K#Mp5Mq28I?!(NF0N46Tf!KQb5?{xdT0^Kb-!P6-#V1q}cP zfx5wvzX@H2A6JqJx9=wvc5a3mOk z&W}=NVBqKF@Z(`&U=RS!&2vP9uABmy3%b;fBN=2NlQItjGg}4&14kN2y96T-$b0J< zK?cBjpt4&S7#JJDd-uVTAg0e21_sb&jSQKb3=B!2OX#4JzDzw#(u`@0hLHV3j38-g zs1*2OUUrBqgKQfM1A`nB$Z_(Fhe77<2dysz+X+64M1gT3=mJ6TtuSEGwIF9q1??Qp z11Z-4Ib+^d1_tmZJdlbPEDQ`vH$j^8K|%IpD+2?Aa)cxU!(>*_gf>V5d}ZbLtqcrG z=^!)ag4A(sV_;C44~ocnpd2I%;?{x`&j)c$w=poNfbJ|~TmZ5g?B_Y03=HY43=A-j zF;y{0vn5PsOq|Tf)W9Ik7B`tOeljCd1?cE$1_lPuu3xaecbp6ioyhuNDkMO)iyGq! z4hDwAZAd->EsIjx3p$j+66DgdZ45|~2iRb~0_WCFkh{UY0%zAbATHQfB_MCCM>e(@ zq!aALN|4-fxEHHH$5MmWk;C1r%*DW9%ZB9F2B@zIz91@HvOyvyHY)O+D zlfi+2EoeZe#*(JF4iT;(&1#GXI2ah7Bl`-pTuNyZC|Y|!f%OLz0N}9e1#$VeGcYK< z07Yvbh^qwRf`gzR6a=Q*VX-{nCCG4cPrf1?3=B$OC#8a%)CqS|+FcH4n4`qXWp*U@VZ;i$ z>lss+DjB31lb9;7rd3dwV)ZpPeHd}^frEiz>vpIko4BA1kZZw-X(Cn;O;F-NN;nJ* z;Ny)znLrCvy?}BpgDi*z76-*QSR9n@k;Flv4;BZ-Kax1eO<-|QY(T|96%;GzXmXIL ztPI+qRvK&VR}N5HOdHfnV}%}Xqz!7NvDWK=+i!AAMx4-Anl`AF#@gTl754&(gK9Tz z&`K4~Xi$yD$f%9nGSmStb7Gy$1TIn;+c_B+biu@Q(BQFb59rKtrb(O(46>l29K85n zkI@=bAg_h!I1ADND(iGXIv@mC>=H-VVH~ z<$|5v%EQILpbI8Isu^TKgTQi3;#>?22KwNIcdVczTy?-3GPx#0mhCY*f;52%h$c|| zst;bg#|k=yRgZBRsOFgfaWp6m=%P6q?0kfy4Z&;LSc@1TI`qNIn^-{y&ocD$gT_U7 zdcYf}DmjpGQ4Vl13Q9K&440RoHcn9vGzITAV8&Qi!i;5I3G+(Oy2m=u#%=5y47)|G&cIR&l02k$muflcf~MoZybP-Bq=X}19jWS$?k+kgdWw*d=$o*z6~ z3g?22K-z7<0-5LMg6=k8LE3G=0-xsxkCwu@U?Y%r8?Zp;`MHpG8?YelHei9z^TV!Q zgREO2u-kwIvfBXOWMz%x1GV%(O;%QLp$BS$fSRnVu$9N)CMzpSla&><$;z5?7IcxC z6H}fK$ShEkm8k&41epaIT7fUc1s|D)Sc(fSJ7PdhR?z+hXp@zxL=w~nZDA_whBaB4 zDnN>$O;)B#2nX6^WvWUC9hnMUihB@rWGZ+mt|)jZt|)jZt|)jZt|(+Ft_XM(hRyF2 zNGW*Ikl^X6?28>i%{NeUm>s1#%#P9=W{0g_767eYW{0g_2A{6Vj=Fl8eHF-h$iY<{ zuC<`%Ffj*Lff~HvgGa@~au^u+I6r}IR~AkxO=IBv3}S);JU)wof%A(sXrxD(NuVr; zfr0ZYsA^+UW@Z=2W?XVNzz1$Vts(;ADex*(3@|OBguW84Xw%7?_kfB+^q$ z7&ti?-N0Nf_G2J(IT=B21vN}1nfO2wkoLC}*bLANj5J788pL9dWNHJQeZ?fo!oUDg z05S?D2U;s4VxGmoz{s_%7Ib6iBG5(5qIW?eq8(Wb3<{!$vKbf@MZL2b7?ebBWiv1+ zGl+D8Zb;?YI02-=G@F4zfq{*ktC;Z`3j+hYG!p{@S1DsI*yjxFpgZcg%D@XMnUq=B z|9~d8Dxq9f_Q@b_4V25q!1n}n`EM;F$Y6c}?i6LvP$Hxr;z^Z=i^I4_fI{3gIy^@N;wL<$@H= z16{#U39=BR=xjCv19vsZKcJh8`K7s&K=-DBy9nIbk3b==%pd^jB5>D(tYA_WU|?PY zTD;Z-GE4?`W*O){TV@&95oI7dnPp3|85o#+m>8L_ure^nfpe)36Nt?q4+=8{?<@ue zCJiQV05Z$4F)%2~gG98LK(dOeAhtGytqo%9K-h*Lwl0{>pu`xa!@$5;48DvPH2QWU zjDg|QcF=X*Yzz#_H8~*3C2R}~KSAxMEny4{y?hJ|>1+%Ps?cr-QxBsmxQC*00xH{z zBFhGmRRbB!2+|DG2=2ddLu47`SAvetVgiMn5@W6w0|Vm}a7=@AX@xT|MC|}2JJ7jK zU?)uhIjM681B3GVVg?4rsa)&~40m^cF7^v&VA##az@P@w#CV<$%^)+NHfKy`%$&@~{FyOL6?!!R^Jm5sRp=sjkgf6yL1$4h zEe8!j%7Y?ZiLp}ywC)=u$pA9yO*jLC+b#wMMk@|jgscQPX~ixE24zr^U|a=~`Lm0G zK@+q!Wmh-@!zIuG_8YZsgflQa31?tX=U`ya1|4p~xD}K&%yu&{sNV@^VEDtwz@UCF zoPmLzAGDwuq!Sc&>Mz0>7{owA@*w3pUqLxoj}cs8KpG3s0o`5>1_s?^&>_;G!1UbB zz@TRhI#W-d5mcI#?q*=n2dQ7n&cL9`n8y5>F@u3YiSZ1myx0%+AINVt5ey8gcQY_B zN^`>ew;$v`-aRl!9|5@{5yX81a>;2>PAS>Lz+kYNm4QJmf`MUzBm)EE39#=&A{ZFr zA{ZDLPpgAuz}`uSfO<780^(KmJg5kRA>$8F0%&IhxnffU1HvR2(Dl7S%vWWNaq$d`7gslsj_0|VoFE?7FS1E+)BeGCkyU;%kPJp3^vD%aRJC64o3JuNcw&T z21d~B7JA@9go6O3%G)G>|GKrzOOu?Q3j{)~*Eq*MgDVF9&hjuY*uc29uUQ!woDMQD z*nVeaV2A=SnAsQ@ia-p0HU@^SgA5Gn7ocfN{R)h61ID-mWiT*U?__0Qh>2og$ckcM zV6@ccWni#7&dR{B2xLNB6r|u%NrE!iKuen#Gnncb7*x`rVp34C1_lOwkRhOwP8GI` zrXiAnAs3V!_eC-=)PNYLBB6NzbRQTf>8t;PI!2u-3X&Pr*`lD?gCmN8p`D+B!CnmH zx-O7S(1-&U4(fVQP*V+H3Y|a-H)AODgDDJ%f)qFEc~Ix87r_{1Fh)fbq=0j10T~9e zUwr~h|0JkIj-aSxL@lZWLCtkdJ_ZIMP-C8z!3orXXQ~CoEhD27r~}UgUA^N3>cBJA z2k?Qq_L59te9(O!PM{7vQ$q$+JP#xeYU?|JI`BNvp!~$h=mhG(^FY@WIfFa!Op}?w zEe^)jd<+cIU;4j5^<{v^K>}|2G*+})!<$KY-m@Y zvmsxB&W3aaIveU0=x{Em2h4_a1v(q*73ge8SD>@O?mUODS^~}Bfi4Q?U}8hM0-X)@ z3UoH4E6~|scb>ynEg>0!bOkya<`w8{NLQe+F^!K;=YgLb`u*4wjv zgWjJG+4T?Sf&=Co+dt4j1fccyY~LWavV-ndhTa^&_KvLzw(Fnm1Kb$U_7Jv@P%dQG zKielL7qaW0?K6}M+4ax%1!0l}lndGQ&-M?>h3xug`w!(pcKx$4utO|@?D}V8 zgmNLf{@IwIT*$6}HfAVSgdMcro{a^{h3xugV})`dyZ+hOpj^nVe>Qd~7qaW0jRVSs zuUdjQ1G4L%jSDIZ+4axH4dp_1{j>2vxsYA|Y`jn|WY<3%ACwE(_0Pr+17G*FT#Ol&j1RT5r!L4CO+0{j-TcxvH>>QXy`J?D}UDgUUj7{j-TfxsYA| zY!XneChVeAh+fF9e>N$oEPT}xL>98^pG^iTs|&j*6(S4S_0J{;m4)p3XOo9=A-n$B z6rfzlu75T~C>OHppG^tMh3xugQ-*ROyZ+f!pj^nVe>PPp7qaW0O%2M0?D}U@hjJmi z{@FC3T*$6}HccoOvg@Bs3(AG=`e)N-2jxuIkeUFy+eT2o9<(Ni-2-%;IjCRn>BqqC z3E^-s@F%gmfYuKQLN?%om`utHf{+dPpb=aqN;d78HSo?Koh=c7mW`I}X@Pvmj`_IR|XmP7pNH%z-*=$C2_8bT@$$b6x?+EKu){ zxd6ljxdqf8Wd_e(F)2F;f>uN^gQu>TlpPs_KwYQ?&?+jB%b>${%q5_iDE=1avh|?l zO(5ShSAY~jea~D8;XsG&n5(+k7#JX9aa?|{LCdR%8;j#yYz5jQ3>u4rpCllNa*}`` z#^N|(Q`3TwlLR1g@RI~U*29O^pi|1?D{?{ip{g^rgN_QgmiXsAw(&1D9xdE&~HMgLt?fNQWi3|1B!z1Df5=1qq1;gKjor;OFEC zc>!{J2R{P?PZ%f=K_Tsz$H2f70g6s0Wk$iNxeN?EQLdm{&Xm~%|K%_+@IXhPI2icZ zdGa+m7#IXQKw1jj!HO6JuYvSNk%4RRtA0no*+Mv0iYRY zo*d9P0mucQ;Uu0ikkgoyIT@JufJ~?aStJ2ED1d1J_?|dsNzm95vo9kf$X;eC#wVcg zLCgRjILN@j_!KlPcK{St8X)GrL(ns@Ks`=R&^*dqe+C9de~{}~4l^*w>VmFy3IK(K z42WCf%fP@G2;%C4xcng5pbuOO3@(Qm800{Ptl?!~0G~p&otJ?@7_=<_+9GDEU{HW| zVVJ6*if{2k=lz}{pORX`pum{MRLY>hn8H+2uYi~v1`Q`Lb2BhR9ARgb!z^*m}IkOkU1-sfD#9e!sfk7GUY6}i-s6*xW7#MaVJG6`e=1@ihh+pja z7#KhswcrQU*1(l8H86qP*;uato3jOJhfili^f&S`Fo=N9J%-*jSq8Ox5okyTBmr8& zg%*IIRN?FfhH=MK*<+e{(xdi4OISs(iMXWhy@l0xf?7FiaCh5I%6a#t#*M^E+|q# z7~C(;;bvfv2B+69PR``+4+H2NVPIfX z;Dwnp17wcuQ3eLhNYK81kYNlA42*L%(~!9NE zM;RDoeLxOh3rcy-M;REj9)lEa1Z66PS7d(f{2N_IeV7$u9z@P^vK+(;h0;&Uaz#UFz zP=`~Wkrh;yZ)IfU?jE{kVL8SmR2oAouLZuqa zgjnGUN_-$?jEtZlhgbo26xa%VaL=3hFe4+V*a5qnK^Hvl%?F$Jz5=orOn^*ePyuPy z0e6v^L0x2Ha8H=I2vYqp8iTvm%t=tL3Ap>s4C;P^3JZt@I^ZrcGicUY7d%eDJedjN zM+bfe20btV@*abVD?bB+Dw8)q1A_{v9yVfZ%wu5SF98n&GJ=wz9>_Hi0<=J%!4y1d zzy}>Q(1SZ$4;)AgbHEEYFZjbd-Mw0|d3O2~3P1f=-M(A|}Q`Oi-H`)WXI)F&+q-7zcIn zp)G8t63_%A=q^#vQcCavUrZGsMevDn2nX82W~u^>ok3dI?0$QQpY3K_%nh6ErrP39 zkoBj->c_w-0Oj(stAP{?Lb-hGS|F2!z_u_c^FtO*NrH|^0L3Fe z1D_R0UYHT&LN;DbX~t~0b7Y|wLY*TA<+88~7cww#%0syv?3^GI6rdLJFz}rL@f8_W zSr{1jdAI_0urM$PfI1jl@P(?NrKwyYpwtXXw4jM=u22Y%O`xlQfq^R=RAn$Jb2ISk zaz(!e8L%HD91C(dD5WxicnKh7qRLv@LO{E34pr0pe_YhL^;w7 zHCGzQF`%^q%mN@2GC@X5zz!G##U-=kD$t$Opk2!@tPBj`-O^0Tj373HG{{jhtD+eg znC3DvGRvq2F)%P~U}R*LWxNE6W<<}!_!t8NBk0~dxo4o*)&Mb+jzOEiiJVYI0gO=% zW57k)U?Njtj8&ipJE)ju1gU0_zRJqLpvVOBrxN2gkR@J>Aoqh*fbceu3tZV47$7e2 z0=eMnG0=hq1_p+$pxw%B3=Ar;hIS953b-u^UVg_2l7>lvTbgVTSq8QBAdA|-7BS|s zF)*luz1IdZTmy6y1tVm~kLD*(aBN^?oCsI50ios;sIX#?Wn=;=ih{RV-HwAUJ>h`4 zI0~fU&~eZ)x2zx!F)(b9VqjpbxX#AFpluFX_I!c?N%90pvhoW|(hDT1;|bLX($83< z6O7EQMU|~bm2J=hg&j!W1CYVVx7isOv_Yp5Hk@E!(ETCBz@V4N#=x-R1T-o^YZsM4 z%0Z`lO=L$3+ByamXeW@-UIjWa&NQ){0j?T!Y8WiEnLw%`ZAp+CaC=jW3u=cci~+I? zECmu_V9*C0bOAaf&Oihdq8XrMaODI8gCQt}KyCtI#-cf(N%AT-28K^37#NH|Vj!#s zTFk(8l7T@-8aZ^fpmGm@t%KX^fZ-C52-rtnTnr2oIk5ZR7TNz`6G4d@>N}9(U=u31 z7#Q{;o6rDN0ro9e8%QmfF#*FNASnhxP;K;=gMmQ^RK~F~7(?cL-g1CucZ?zPKA?68 zBct&i4h9CMdKK^jO+_Xx&;m_RE7}+`?_&cMcLIrnsxo8HybpIYH~3CwW6-=0H?$RP z0&We0=0!l^&u9v6RDyl@Vtl#xQ)n^#0bekX5cm=c!~xT66WAi#uVJZ2G8hN zfZK?mxg@ZempK_2%)ta$q4W*V-Xx}boD2-opu*FVF&9*H9cE+%B|?Z{7T~MTc&r)0 zr8A=x7XyPim;mKLbI`6K25C^`Ck@(Gr3k){&lKFk1y2H*f)6HSn#Rb;Xa$}C0-Z2z z4Q^=iKpUDlAQQm^l8J>}pt1?HUERi-QN56XfvXqdVNiUTgEBUQ34G=W>@|i%pphd6 zj$nBERI3QmKFvUCpMutakljAT*C++GEs-0glR#%fgFFOol*0G6!*8L7H%dWGZ^#r6 z3)0?p7Sz4%EJ%CX;kVF3W{KcjaElUYZ#xU>eV;5yd)rxHJBlE)L~t(H2&4^0bh(tC zl@+nUh!r;M3*KPF3LEwnAfizU*j61qK~{iTam;5ydJ;g|#X)1XpgTT+djF1gO;L$8bkTh(|0Hh@Y zk!6rA0dFS)Ib4GACCFS?a5#Z11mR;KOGQ{27$m`#x`Hg#IK{vq35ozlH;_!tDFz04 z@S-zsP*@x~#lWEOk{P5Kf*FIrTQxve5P|2s4cHkNxR7`AfVTcXhq_Fpp)CVO1IYfQ zOwg)3SxL~UNG5q!1_oJB>?<)Y2Dvl>#iigu!!Ec>BS0>_dWwNT8SJ!Jkkc45RK7zU z79h>Qz?cYk7?=UF3)1i_0okg?SOBuc0^TswJk7wsco%Mi1;~bo)6j8jkoUl*G_x~6 zhNu};kUR-q6~Z9F*a9*#2PIzjfQ&5%t%?K(aSq7X*Qa4YoC}h%KZ72oC8$AM3AP&K z25=BhVrO6gHF{uC&eX#o4QqU11o1AAXJuXIPgSJ#_f(cMQ(u@Ne6%IBE zwC!3)HW|zYN$Mh+7ka1*M)cr~6R^uPz)c5kSknR2Ow|MvAXA`LfJ!u7M0HF(vL0Pz?w2C1^~EI}FtH10_+=m=bq5gvTbZyqJN3I}#Ee+zk9o z-0`PD1{?wjC&CPPU&O$`o$3hkgEAunKRhCzRv+Zrep-F(Ln>aOv;QPHUoGCx&nMmNdYmYR1NYhKNBN!8b}Xl zDFhQg6Nt?KUPrIU_zx6H$&4WTAO$M}!_+ej42+jG?i2DEhn z#YLCEF1i64!%}420SfJC|+~A zz`(%h1lnN?j?>*BuPwO%bMFC=dw+nq;0+7MK}nGNA_IdyCv*&H2B?{N1l8lm!5#o5 z05Ai^mv9jV1I8U7*Ob6ppIR58TPGlaTmo`QS7l{j*n5!y zN%90pvUw>?@-s+M12lRF3I-5nY}0Ur8U*IHqsn%o%65Sr3im@eET-ThAO<*yK`{Z# zO-wzY!wVU!K`H1O=C%pY5i=0aT?2Ve^Ab`(J^;D@K0I81fVj_49gzle1ZWDFL6I>T zWX*foUQ5l>V3obK2cTK2*-FoCQG}VJr9oWErn8!c? z#Gow%N*9u-CWAXai{U0qf=zw{H(45NveFf($zXHL7~MclWJTLY0GeJl2d8ybZ~+P( z88-*Jm<_y&2-=fikO$=@GsZ-adw9@{(cxxbfEdGrX$&ulF&2yyKn^iMGr@rIEGPmI za|u~j7#J8`d0>&J0gAlMR~Q)J<;X{F1_rIEAWgQQ2Ab(r1_n!ShFas_HQViM?%D@QAD3IPFc=R@u2R?dh1L=r?f`F0H2GS7&weJ}j zZ6F=78t|E$l1xpYGdDq_w>FTD*c7PvERZ;8kjDlzddm|HYPvBp+JM>~JkZfwTX?Sw zRF*Mb=V4%w1{0t{oIxIR?}H@MBOXxQ#Kgd0#|Rr~1=V8GU^VvO4jF9KzAR|<4X8ST ztl9^08RV5f*LgF6;>ZEf33Ej4ggGIGgh8PWG20Q|GXuNM5k7Vb<~krcV2-G(_MO3l zwxCt}4v67sTSm}@+q|$v4xq@BhP#x(5k8C!H5+t`2zcz8fmayR`U35pf!+<#SO)3b z1;~OTAA*gKqjv5{Is*#4gn+3I_Ywlo@_uH-@_v?NtlR8C9aL~XZ*-eIYCjKjZ6MNW z0?^z&rK<@b+w9p8+w9p;w%N16*6V_|*|Wjd>tfwz&j#IQ&xY7$&xX9so(*-IJsZ+C zd$tusZ?k77Wt%+*Vw*h&$~Jorlx_ALD5p+wz?Sxcx7l-`o;t;Ww9THAoNe|@J)j|0 zNG}TtIqboosLW_I`OYFN1l2}j)>QY5ifz~0M zuLNak5zbPOzGLq|(#d6D9cMrqxz2!Q+(kEmj=K<52ALsxuN<`En4t``;`mPm=q53K zHm+L+psrFwH3I|Joyj2gDKjuICxEzjK?d-1a6L@`srXRAz`*q!y2?R7s+@s=>ji|z z!oXZx$-uz%5>zbn>u`PK15M$B)qjSlV1TIq0^zX;+$m*X;Q9*TaR_9Ac;6sA9)X)6 z9_UUk1}0?zfpie>2SiRpK(LB|f$JxPCn0bO04F+aaknjG1mLRZ6aIrDgg0{MVoy!4T7{R~}_8%vd%fc=R@*fwJ%fa3ZvJ1B4 zgNOYwC}?0yJ_OivL5g8ZK13M!wt)EjjG!T5HWMy!M$lw5JJ>!+sEJVfq@Y}=ebP`a zWSIt+43x_Qu^zUjLjYnuY)yv<`xKCM3Q)xo?1w>qSA=q9*u6l0SAudCAZ}HLa#h$j zfPz~E%GF?h1~N(&%GF_yC}UvYQiF0082Ic#{#IuM9dyOU!==wSlZ}A^;xR+0BB;lV zpj@cOjGw1jIe_$f*N5D;|S&QFz^|J z9O=Zk6k?(mqb)nkQ9e*bP!oNjTo&*u7%o33mxFy5$V~xIE)N4A3n<6}8NY)}l;MhG z+ygf;8mb6tVhofEbz>})%OT;PnZm#o59RW(mx4k$0m>C%KLv`RL?~B;9kjNUD+$V# zVBqTkNhdRUvV(&tn-O&386=2up^Bi^=Rvtp>+_*pXb=@ZxjYPfb3yS|$an%|q6}9h zc&9kT#A>J_sEIXDF4V+YC>QFXdMFp_p#~@y>Y+v`7wVxVC|81k?;XfP&5WQ;By18~ z-Hf2=eu(wGP(@Jd`=DH?_5DyT)I$@XT&VSvpj@c+lc8J@20j^3ikQMUlY@bQUxGUT zbT&Kq^gV8r$usT{P^AhVfC`21pr>(!L3rE(#Z?Rp+!3IoNI<1iUNvZN3RHkHDGM?1 zw{gdU76S-GRWdMe$Ag%lai>M43=G^!pk12G$_?iLGl32`5N86V9&sj6o)l*SWessAP>vU80u@H$OrY{a z-VtP|1a#YLBsT+t0ytnKz=5Rb@0r5DD9H#G2YXS9F%G0g8ssc##$*s1>|Yu1aWx8H z56d!Ua5FG4$bq~i2l9{{C~fdz@YjHbkG6i3=HZwWEdDUn79}iazMNfARZqV1H;a13=A5eqiDel&{C3nAQ62o z1_m(0ii?4P_c{ZEhAZf}+8YcE8laMR1_q5ZE(V4@AO>jh2$)gB#lY|y zB+|~sz~Fp~fk9&u7Xw2hh%uLofngemu@cHq{RfU~1_lmU1_s9Kp!M=k84 zn0S|gL2WKK#9wL?xfvMtf<#)m85l(Gfed6|(1lP844{2Qdf=QF56XGI_n^m)+!lm7 z_n9CA!&+Ws2S`8;CgBtU-Ms-aM??r+ld=#4!y{~(96_247|(#RY!P^qH^=}GPP)gy zz*xe^z@P$7GDV;yGw~kO5k5i;4CZ{uj$qURj~|1_DL}HJD6(u2SwoP)j38-P@PWsk zxgoL)%8b3BwA=hXy#v1XGYQ#v>pj%oy82CBjC?f-I0Y2>-qhI&wmQfdOK~Mz9fO4;UCszysTx zz-7iM5T6y~fX(1?L*O9;gLyZIe~1y(SZ3;BM0GRBLa^sA3o$S}=0}Q~iM}w;GjZsk z`~I5{G)h6*_yv%()iI!}1*b4G#%xeAbp_Q=VGkJ?82`fkbOr3Edkn7Z1quK8F8irkU5}>MJ+%>S8NSMQ1J?oIB3zl1!U+7l%yFMEkJ!F z*ntz4j5`z<7b%_(f!*6$}q%1PwqLBMdL8Wnkz)8d1IuvV@7@u3=9lUq8J#eq8S+WJz`*BoB&$An_N=Cz^DUahCXIsV9Us4 zV6-=8U|{G5@pAH^ycZx|1(aj_1ho5%X&UIXMizE2CI$u$#&;k)0>O5G%&&=t9u4;p zZbu-VCYTu#pu2w?q9KzfFiot?G76wp zBRAtUkhUa7kn$NYEv}3V3_K6P5}+k}P>UFN?|_8DK`w{tmtX<~D`z}B&cx~%7&agU zYsCcy1}648(D{m>(v_L%Yb^r<6CX$*4P-P6WFH_C=ngUFs$d3?K^*7U85me0k-!3p z5*BD&K*EcKgY`QoW;obgLH2`&>sdhiLKxVC@UvpD45H`z|ABMav3Arb#?{@90F!3sb|!Q|{285sDO_!*=07#JAU!O}c23=C;83=GSjFfcHF1YNUG%)qD)_SZy4 z!8`^=^%e#OhT~5d7zEOCOBfi{L28&LvI+?&7BDbsnlUgih@>$vYJsd}>R}YgWMI?= zc@-L~qAoEE44{NA1{GlHVHAUQLs)twr!a}ZdLcd1Aa{d8UL52d3C7ww1_ssyCa^0R z!9L&x+06^Gl7YdM6_hrd5aGH=~1T_(pL3~i6kYfZTnb}Vn7=)4;7!?>nUZ3)efk7CQFBlcU{F%=g z7=$J385kIq!2FyS3=F~=Aigq~-}QolK?Ib?7*!Z|fmSp1Fp3tXmM}1$WO@_Nz#t}2 z&%nTF$Rs`)|z-hdYBj(B*A*K zz_JVyQLzjRGI0zH&Y;Vr3-U@B7&VzdLGlaaD^UJt)M5hN%Axd(I22%uhMDRZ7-YEOAZm~W86;HV7#IrT7#Qk6&aPl!3}FHtt`hr_fk7rGj)6f7 zyapON2mm@lA9B3`qZI>#L{S_A!?!pFhK-<=ddolo9LoesG1VZ=?=UqpFi3!ugW{tU zv~Lqs3Np5W{XHKPD2w7579 zOt2CLh5}IC!XS|ZFGz#y85k}g6{O`?Q43OL@(NN`aP7(T=@kP50~;u3GkpdzK|4S| zwI|aTP_Qs5GqHn838t^m5|RUydze_k9%E8w;RK}{CN?OSjT2ORGO;rXf&8G%!3nB8 znK&3h>rR-Ixi~59$1!#fr|-rY&^7t0B(z6m67(OL1Fqpq$U|{4=W?)nUg?qy*1_l9eNvQ@h_R1>; z2EiK%3=Bfhg((b-f{dzs!raV!(tM$8f{a0o0&ENnOezfA+;-f|d<+cCVhqfDR@~Oy zp27?aEKqR{1_oAB29OAwFe5V`H@6kHH7jWFfSnhjn$=U-0(A2@R5L3`DW@q;4RM+%BcrDRA zWFg`V3~~rj(5Sw=8aQbvz*3DOXu*~eLJcJ9l#vBM+9-}X)UafSg(U|(BEVq`ia1at zK|_fPE(^}dNKpvNX*|f0#S6CptQ3?(q1hLtlph*pU^xNgq#_877jUu=f+Q7TXqvIGXLfK&$^$E8c#(@9KI9UIAGO30fR#9cuo6cIQsM}Mf)W&_BB1gG zQsRh0N*pne2q@i%!)*r_H4=!@0Mv{DsgOj3HUoncBCHu0q!9%XNHGJ03_`a8*f?2G zB*<|yGBBWIZE&K5#e)LEd{8P>MB;*$-Xkmo$%5KOjDn2N1gL^k#;8KFJ_7?NUxR`k zT2QFVG9tING*}r7g=JV77&Ji)kdazo1{VW^HnK{P&vi@~48et;E=UH}Km*C>f%Je{ zp!#42Hv@wKh{3>M2-d>Jz+i-&^1%LurCwu{JY)jWz`$UNYy$&>86*vx!-`XoofgO@ zLenzLOiO4ev3d%FykrG34PEe}ahprRjCNkZFtAQ?rZbO83K5+s#Ea}fgr zN(Mq!%)p=qQVKFe9bU?FtMh=J3(C0+3>wHO04@%4pC*P3ES+kByuiSqjat|0KuTg= zB;SK>^nhh(eMl~V=6M5T!_l&VAw;DixWi`z<1jE7qo-aIWIuTdgQ{~=WFe4%8Qdap zu7T9==IDadtn%OqAJHQNC3{eWLen`h-Dz+u5Zuh>L#>neVXbZf@kZMO7o+rWSPzKsVfSMqS$PbX*B8Nx{ z;Hm@cC*A@NSkxiH(B!9q zoJ_#>Kym|0nujJ!kPOHMq*MIObUV&{kC83B+8$XgiQIi!&xcoG6B6h=vEB1nl)6dnkOravrR#84BsI3!Up zFi0Tc1(e<-5h+9pVh^askVZ{wG7v@3#4d|7<;fwt2kZx!Yfu_`(DVk&2nvuSrigGD zq%naqRsu>=%5dXZL9Gi=*rp@u< z%H>2ZNV#CGZEg^QfdSDB0jDE6HA4`EAfzM(b>l%U2DdvT5dqJ@AcY*3;3xz|6R1^> zD|yO*icaKauq?Rf(wOFn2)PB9ImasLTZypWt>sq>cg=c_23!AuNTYabvitNM)M|x*#P97?SMRAn6!3 zLNhk zg2r)0QCkCI$c3^vtWcIfZ9zz)Cv+)R`1lasG>lLNN`SH`sXz`X7082v6Vxq%6qbBGyy8TKz;`$H_+vnpez6`u@FfBWR)r?_ka>LWJnUxzJ@pfR2XZZrgBXjITR^D zLwl{T90syh2V_43gDyA=f|?I7^FflJ^owX4fD$kRWVp@{(U%8}#3ChMP-@0(KqLGH zsq;~q4X`TS3{nxAgNklM_Z2DqTOtQ4q=jvT>}gODkJe70G>3qq6r-m}L4%vv+yN?t z!TAYkbR3jbgg~tXNF!Mo5?msX0*b^YH*%(tf@KU5WEJZsgB*E307IKaP znV}7?SGX7$poKd)7r@G8P#)BSw2eS&^--%3*!T_Vcs8Q(3{JG5+zTFV2N_@t&8*Oo z6SSfntQ1y4m_l<4R4I6L2V?}OAq^@ypyC#goNI}Q70|F6NFjJY2b#&jCAu{%ciTXX zhPSnCL1(+!!9yMFZb;6umtbIEKpD4zzmZef9vx-uv)FfgFxKX9Ui=RRoq1yx&I3=AkOX|(LEj--^0fk6X3-)X|C z7zPF{q-?B>CgIS@cI!$kXDe(A@wG~ znh81Sf|4l6FjGj8iWt%XCu>R*FSsfhnC2Gpa15wIfu;{|g#zoL3d4G+pd}HYVg@?e zB8o`zVvr;+4hbF!c!33;+ffkg=V>qCbxge!F1A{6o7pQ?43=Ha^0u>bh z;1ml@ekf!AAO#Ez+7JUkDiLG;kaWqwpof&Aq3IJ;F&Ti8CCo^WPUx@;NDe;q2ogtX zJAs-~Cg=q=ta1RC;2;%V56}%@}PEs8hJ>|1|XG_B5J!&3DFz@=Sf)oft(4!7J&y+K}9-xPY1a~ z1{(ou7lG#7p)LVcSsI|+2uj(=9e6ed2H5y1B$qNU=s*(iS1~KFiL2IvwBa8;c z8fYLCl%YX^3tIdID!D=F5Y(UmMVAyPRzV7(3%|fKZ-(HRRFpY4SW*Suo&YifTKaZQ~QHOgCJwby82tYo8rhI6-3p$1c z8x{abf~K<(Hb6$8P$nE8wF)BZfQOYKf_k7PCi&$sC^axJu)$IbJ1n(uAg4G^SYgYB zTnd6pUT7eLOJ4e zsfgkU+)e`d4YY6oq!gOMAmtTu0s{@CLK7HxR0C8d!%`;bU_ns+fEfgu!h(${qo-(n zXy*s&7HF#a|p;LL6a0H8G_6r-<60$7!)<|H6U!zH~_hZi-Cb1)o~nHoC2$0 zK})Ydu@2J7#=yXZtQ5rxZX_$%z#AHnhh=yn{s(!E4`De213yHZfk6O~L=8ZTg2tOc85^ol8dl!Pz{)#W zsKKDH0ZoxW`dH*g9=uftE*}tWb+|aV9^ybQPtj{|_*f-aDR`a=RB!XZ+|CPgJ7~EX zD`+%eXjLXLiDqJ^atVblx&s^USR2Mruiq_6@lQH8{zIEVtd z02V1A)u0L-su~*fpfzcrLNr+eu5kYH3-%_1#uzk3!qEy(UXD_ z+}{W@VVM_fTS20(5H7`?E~1*87pX;1t=}RhR(pX4s3-Km?MiG!>~damIh(*3ra?y`;t+U zBzUS4R5XB^h0v)=P?ZfENQ0F{h(QMAB1RplEYg5TfGaTu25c)sU@n5ys2~@CYE)2y zXJ7yimcd*C^0O|a_?rw`ORWb@{NUjN(EJD$(h!BI9Si>UV?O+2JV83Th9B-y|gvx2iQXbMaQ+6@M$JO&2Xz$};xiWJxyC2-o4 zhbjiQC_uVlEAhaxilE^z&@>^abOBFYD1%ZxC_})OH9)FEP$EYgiUp+uculPiNrWKl zktasj7#KheHRx0xxVsEe0$$LH+)059Zm}^i=%RLv^^jX@Af4c4tqcs%))=JqXNZ)- zjUWlt7)c*EnoK~ARZyleg*cRf!3;DK2O8KhN3xQefx!YK%lxoiXGuaI5-9&ZAZi`2z(WaGu$+= zJ*Z=D*!$s#y>u+dn!)i3swGg(Kp(e5=%zwGA3F5~YVH?>l`LY=YzB@wP&N}s&)T4- z0z8)?T5sr8ffOkD!LkMegES;P%fJ$=ENWr}?NR|R^Z+Fld8B-x04bP3W4?+ICbZB; z%IuKNHzLC$CvQ;3K-r-JNqB0Iq^k}onGj13!QKX?VU(2tAb}B;IB;Ymq(&qp%*9}Z z?1%~-;<1j;;M z2?how(C8C5w=giMfU+eh&!G)oKr=WbmJ#dI;n@Qv$AGd2q74Qw$+aMPOdB~dfs`Uf z$)Lu8>_-_V1F0HnDGHt_z%4c6w%tNoe$Y0)2&|Kc*nSH)6kPWs6~(Y2UObBrAw?Uk z(FLw_LFGA8qYGpRsM&?I;TfsUltYd;XkQajo1!d0h3f#tBCJCPYHfo$bg1orq#_%X zs*$$qf=X!>SQ-W`T7fpSuuYkR+yJr*F@_8F8`vGNRzI|V0LmenNSOfKZbRK1!3OON zAaWOY-W=pUJ#byc#=xMDT$O>WMs2mh8e*V1NyOxbF>0PQ0dYZYg!Fw-rX)eh-3*cA zAx$vk^iN!qg_^3cH?*L0d*Jppz7q_C>f~N#Q2}TjtD^`LfOl45Q1SK97 z$WRfahpmc~FyRw|3=Hb1nFCaNKr0~7JUL2RNDG#vw6XPPbs%X-7d^QlHW-0hN2ndr zp^(aulMkqLg@y^JOeQ=uiJBAGB6ei3u}nx?Kmk#g!`ct9ja%SW3S!m+Txg;sNoCZgHK9@tI%on)g3yvp1C$&z zQ42mTL^=m;AciJDP${Z|>{PHrU=0hWQ3#3pF>Mqcf4yfr2N!g%=xBp12+M7VCE*Bf!)!xtRkJcMm|!>yW(cf-4Rr@%MjCx;3AB<347nom1(fl4eQ7vPTPRiY)}R0ybaZ4Xv`Ea{RJ{O+rdh zNb4WvEDneS)GRe5f!CfC_N%&=D+o!#g*KoC966gIn`-tOgph*>!*fb#t5pmQTxN!lJ z!QR0JB{4+z8k)dSy4Rr8I9hyzj?RK5LwfgWAdMerL66vU1TI`bi4i`)2phYE7WL3W zlL!{ph=z|kC^=}LCUWT5Bq#}?FaCj+^5EnLb_guR>p&Mzf;s`9#T!UXedPV!ps4@` zLt#W-KshQ2Y$B`{0~g^ig&?;e1~HLaG)VI*AVn1PXJB42M{+y3KLeZHLG7kkqIXk3 zTO|;)7uN9Vk%7SmQKmpLGGZwRI3yu83SvVnJO|sO`V^wh0l7g2>U|)##zIYFV4%*j z5a?V1c=R3XYz1A%X=yoZ0c#1N4_H9cJAAGI)-D4F3F_QCqq4#?dhlr>zSjAo0R^B}b( zN~Q$~fx-(V+d^zXZq!k8nsL-D$dU2brvMNu(^#On5VHzph1OiqDwNFxentyuG>#os zGGNAMJ_ZI>gkKT+OTk?q&@?irfPr>ZVF&F%xv=&3&>>nbXulT9MXbL^?B(QzWEeh> zBN!O?kv)l)9|e$tmWzQw5Q)piz#s%V>jAW>4(d3RO?9AffbWlBU=TwJR`^bESpOHA znUR~UNC5{87ku{zfP4Z9&H)NIu=~L!Agt&F1srJj0os~^1ss$s1Wlq)E+`0*6oa-c zfI<``%f-MT$^}W!tf0#+#JHd>O9lpU7!xEefhg-i=Wju^GcdppVFQ(FSmuX7DIRn@ z5wtdd)p)Sc5(V%`7&r31d2s%N6p4rq6gU7Nf++Lvpz@UbSVe8Lvq2L!G}(hP1t`#< zTv(=nCVNn(fCd6+yauu536TqUAh`g%v6O*<4@WLwVBkkh^stx(<$N{<2Ix*91_tDP zLJVS{t9=-3m_av;{O03gU}R(j-IB`aSWu9YnVeXXnV-ktoS%}K%#dsqQ&5zjUX+-t zkd~Q~TCAW^VPU2jlUS0QngbyfO7in_k~0!B^I{UqiYye;lapie5=%16Qe%wuO!SQO z3=Is7z*4&Dd8N7t)k&FoF?xFXIhjfN>B-6ZiDgClCVJ+2M*4bs2m}(%%uCKGO-UV0 zZUMQL0qjhlP&Y??m!izF)S_bj&|oKh=lr5n{Rm%IcSn6aJz~^A6ys8vlUQ7=?~+=U znVbp=73cii-26Nu6hq<<T%>ehLUIqgX14D3X zNl9j2dNITkKCUhhhHq+aeo-Za9h8`tk`MKzQ)x*_ejY>|be)|T=%RFHMotC>MrKA% zCNRl@K|;hKBt({pfsuuYnIEcy4M_)t4Ix<=7+DyZ^EufV7+IK^^}wo&IJv;0Ih-I_ z7UnuI&B)9G7H4Ia2lJVk^Fe%OMota}MrLLZ$->B-3X(%}C)`z>pxfLSr-8}@hWDTw z_!yB(hS72Wl=~nh6H=K3E(Zo8Y+z-go}NCq1cK3cN+M!a!pb9j>OnaYOR0oUOMX!* z0|UsdE~&-IMVSR9`9;N$f(2eYFrpL>kb)y6H4Rd51ec^B>qIF&-~|RNqHus07;Ko< zf=e$%slW~@-dLFyaWXJ4-)3ZFRtM+j1aNMt;}l|GWUdFZ6~QDEC_gf%fY}gnX)qfi zo(+~|;S>Pt0_8p?aK5bolMwadNa~Bh?0QfRWrnC^hN^_?0&(jY$~TRVaH0tmhfh%boXyMg#Z2)+l1FO1-Of%qb@!UEi=Vqj$o0EvnsR0V%)rLKw`<%AlMC&(vKYJav7+>$i=|O4AGSfQVGuXydV}c8(1AX zm<>@4slM{TW{H8#0%c}KX0YjSS4;3PFfi|Dgq3ZOGKCkcsTfQ$bMk>p9VRwr22eH1 z#>@=13St<k*C zKrw?EY!ZazWC2wXPM}hlVawnSLuhjkBMd>|wuXm+L5P_Z?0+V3f~^3hF-X4%oTR}i z3Csffo`H#l8I<~XzzLC=4N|XzL?OK=D2oLm&0GO8lYxl^oMJf`7}=m94$crTad@Hz z+rV57c7YH`Co^iC81OPMFw27S2NT$Q5K9Wm0_z346I|#`V?xrw46~Jq8D=XJB&C4#FoSJnmIPVDTm$wQq=f=b zMf15pH-|3(<;Ovr69-YL0B*k`Rgj=ModG&5fsx3O2343ahe8-&RU|V}RU|0K>;a|0 zT$q;N7 zB=JJbWv;>@t^^jh0h172vmoUrxYY|c0@Nyh!~j+`111j|*#YMdNNK_R7$QF%*0)2K z$L0i(xsVDQLe_yj0nXRZu^b4y1{{X>89?}6JvkC|b?0&*#G zhX_*WD1ueKgt)67)DVFu8#w_62IddoAW~ppWL{j)38FS4`yX6nF+;lgkP!IK^E4!;w?cSlz=NI8$`v!-t-$df1a>BQUNivfg?Mop zt-W{?5+#tqBZvnfekuiL`bXf*4fiZ4v4B%6JT0#gVqjqY2`-~ez^!yps~)U`nF*W= zC)RVyfgAdu(tvOpmjaJMgBtvhw)Dn&P7!dK3bGm!CZwlvP=OCm;~)+bs854d2&0Rm zrEzp=Seii>ho^Cn1bGPnmc~IQz|%O0LyWU=xeJ&0MM$I{f~4wwkh1u29k_&pa3JXc zq6|{D(I}0B3Q}Ss7v>d6l7IvZh>c4ePZ|el`wA&p3qfTxvoM&1G=$SpZ=+Zx>STT>5en}fQnkTGU(rw!7#V`2t3fmoQB1;81s29)+$7@3to zI+%UIVg_Iml3O694P?v*+}3AdVvYmlDHcX%$Ycm4yYgVs1FAe=dcegAXipZ{9&jE6 zI~Cm7MXA=HI|ZB7zBoW;P(Bqqtgz`Ti(k(nFpJ|<2j z21ZULQ1QjU%9H|X9GBxKw8Ve zUI33^K%ENd>_NmCIb~oY^$Wp;W)x`N7^TpJFD4j7CBmZEykix)8{OFlYdR z2sIGJL@ZDN&8I^K?TAo}O9^CBIX@jTkqk?6q!jXyMIsDXOM7S?0xq?2%qJi%U}3|u zfCXu>3dFC_#VXK6E${^_oXCq*xEL5P>xcv?1_oxNX^12cUlTOQ&j6ky-~eT87Dnc3 zaA68*K7zZo@cu#{NQW7yZ4YTrO#tz&5&TIY{sC|S04WMV-3CYrQUxvyAjKb~mH-#e z@Npqf^#m>|;FcW%8FqmIGGBhX=2YOxtXgC~&O!@$bKBgeqNd={LcA>{`Pto_5l$|M4kya<*A<$Ort z3(n_|MRg3UOd231*T70Z1p*{EATv_njy=Spr{Gl&#-rJkxD~fKF zjRcGwiqxq@>u!RSgL4@A0tfh_1{TyA8=Pwym>?ZVD^M!C0ZwJ03<+EP;{p=C$H2(E zw;r5nfLP2o$ge2KKaP7$hCLtn_xf)3C2O^RNt`&K}y)uYMF<8AkxcaFA zn+Xw51B;u1>t!z}8`Mxp0JHhQ_U3>|hfWLl8^A6DROoSqD=19$sbBvfK6uWK|C%BQr0k|IG|(`hc@OGsJ7uV#8Ks zfJ!1rFha^zi2uQhiJ4izWgD#1*r&k2z`Oz0;(+v?p?zJ5qriio@J{0ikn-I~oyG!i zNP~(sNaqkzxIt`1?KDcj3e73tg6=a$K?iHW4@gH1GQb8Q2YQ$d;tB|f6u7o-ogh!=Is1CnC+`g%}13b#vfSqtAhfwWLR8MK`MmNGE= zc1YzbGolNIy1#(X0%6!L19*pwodH~!gSQqS77BARFhuy~r-1i7fVVj0<|gK)_+;jR z){`-U`*6rlbQftphliVO_Qil8PEayi`u5>*8?@j+|*nV301 zWhx6Ja|N{2<6;11Vn}ae6-cc$$OKRy1Xj{-1BrtAAmA+t@HW!{knmq{HU*WyknRCw z_!~0C;0P|&AN#GI-6n?P5ybh4?3=H8u zknnuCFl_PZG?4I8RN;-_MJi#S(h2)u7AzTp@&QuqPdGUvX&mu|8?5;>5KT8okqRNv z3s$5!(npG1{3RK@JSCV0Kxu|HWiFm_7THfQHfXR5TylXnU@$T;Ao&%tVJkG)2}?P~ z%)sD?x(AE}-2a5{-zqLif%HY$P&RUa2Ep>7_JOyCp_ZY@%YwlLBxFdA1F7kYx>Jl3 zQOYBiv9K~6KG4RE*bD+M*LlE&G;}u@FH$9w!N3RcOuk+Q185rwc%vPp7C{<~V@KIC z#)4F`gWBxi?PDzP1)bnMD)4C_=w#14P_ZKfD!4%%NmfohaIp+3+QG}@7+9HZfmF!A zR4{|uYRurG8PZ8)U}a)cW?*1eg{gqFB_XY@YH*ne>3hP=lK`pKhp7fP=HVu(faJ_T zJ$MoDFk&94kY{0J76UirS-^u|LeSoR5lHP}@X#D+T>-d;08ib%1T4^&hb7?^K?!vqvQVAnzy07F`{;Ki2E#hhRf zxL-U#TA#zULTWb1WD8_Y4IC`YkfqR&Y6#N41y@yYV+ugVe1jVU_9k4i3MBalhhz&# zvWXG2Sr4=^5VUy@dBg+NwX;Bqd%=piK~*RVBXc>@@Cd5n4IstvnvEGe=>u7i1b5j3 zkP>(;$IJvyHsG;MxDp;!1_tJ3uo@2%s&Gj$kmOnoYO1G93d+_TiAc0Fs;rULOI{ z37Lt+9Y+s9$``FMbsD=m{)+6fO?ZGpo|Jlb+AU12S~|AxDv=9G^E1~ zvl^rolJg)_2e3hJkT^T2xPo`bJ3xl*0~-eN0cy^h1d==gmn7u9MIhzp;L5>`T6hv% z1(Li14oA?8J7m0{7u?DQkNSg4HSiujP^ku+M`r+KPv~lB=$t5|6oJe=Kw8z{vIIKR z4;dK|02if@6e9*LN}bdh7?|HNF|x2Q?}X?E=TwySrQo8Eg^~FH6L@Va3%IZZD`R0{ z-dzhSs39TO0-k|w9qmk$c%Z-#=uG2j*ui?DB=wGwTV6<0mq_g^c#8_u27*pg!dp~G z`|;r|Dt6=+6$fM-auq0fYr|R`kjxLR&>(BYnZW~l@UG-OkZN;;YEZ!d$ykug1e#(4 zm4^aIi^0Bt^c(`0SfHW;w?YLC1_tKSV1=NruQ8}a!z>2skFqc^&jByvWnpA~4bI!l zkagb>_kM;f%aZ|@3QXW>ig%DD#a|#Y9gqeFcy|*sR5iqtka2zRupX!+0hJ*vpoJd| zFkeBo|K9+c!@|h?A7Z-(C`&_|MqXexxX@sREQSLc$1DKqAG0tqe}L(o0-nlbVPbw$ z2bN-Fo(gdnq@-YCeg$4a%fiUK94x}z4Jqv)PJu4ohWL06LWS+2fz|g$NGUCYX~NNz$8DI1UFh)n3(_6f#yP47@6B)j{OO9EHn_oPGezW{tk0& zH&}#O2BeXB70h9vl);3ks92alQX1g%5EQ^R!n_WO>Q-=~Kz4f{#8B`C6}UKjozONd z1_tIk;I-kPBqab!Bg{C^hYZmiuLCKAn4tw4Hei@FS`Lq_au`%P z!bSnXg)w}3mIz+!86eLN1*NO zI@$~j%rn3ZCJAugjS*CCfp@b(iXlkr4KidW3MxiHWgBxcsBr>W)B!FMz+2@0|bASA@0vS5Rv zz_O4s15#Y7fXe}hE=c1JA`V`C$t;BEazUGinjrP?R;QIN0|WC;CQxC^z{q$Tw4ajU zDu_fGY8*s^Vvrs7py4mbVNi&Je87X>r~^0P^#>`b$$H74l+M7#4q8k70Asr!#3V2Y zHyAW9hBO8Rw-$X6ZZHMSAaV=19n0Vu>~CmdVq&aoCYMg@H z2brqS0$UC-7}5s@?=FVVt3oV?43&X*8AJM)%%GknWXCTvWcC$Ylrn<61lg&~%mQXZ z)`7D@OG}U!7eIFEKzsz*mk%jkA^wH!lmIyqQu;v}sIZa^G}i)A4{1g1_tJTjG#4cphb4S7{Gh%+8`@^WT34lP#{36 z6^M&s!DhdQG%g_?fsl}JgedBU6!V;5yCKO5<`YmbKop6BO@e5HsE4p2B%~&QgbTQN z$_xoeIk3C-LiTDx41zfiR3DuLuU&+s6DSE;fd^3vA!k9XgE;IoL>CS2CISho}3IB7?}SvF*5H04++4xiGpGk z+|PnmuMj`ONJMx+f*F#?A#6yJhLA8{f>v@t^lpMA0C1BW?uZQ_N3=16`f#9_1*>FX zV%`C95;&4r7@3blv_b|pSePf(f;`2-$UFhEjuB!zL=B{|0ZDfOp!jBCWu8|HO8+d3 z%#XqQ+gMnbdul-e!otY>6SBb=6339kB*3A>!phtZ)Ab9i3)-;(yAU2$5Z{4F$O2MG z&Va0>r~z34Zt5g}QWhIC1IQJS77sXyfSAnS)D32VeF0|Gf|^EkXnB1$jmYR7*4XW~L<;rH1B|6eZ?lre~BuY8ZHxW9$g2XOLUI=xdtbH4QV;>OyFf zRLGctf%zb~lMZTSH1Zi({k~TP#L7Jf~jLecC>sXkW zGeMTHFfy+OI~(F!C@*f8<|SYsK`jP*6XH@R39d(37?~eIq64A;67=9=2O0!m)0joUodig!!33&^ zpkqvs0b+<=$c7$>31AV(z$pVO(+N`s2IhY7NHC;G1Qi015*%z5yz%}Hq!2W^4k<+- zK@DSrstC~fS5Wx}Sw;>Ts{%Jr+BrcvUt@^peDD#RnV_~kBLkwPNlCU3f}N_#%)sDW zR9R4xZwM(vK+9ut%orG$5vL)+5-TKbKocUc6(3z7g%jYDE657LH9fpdw*{ndCRT-D zP4EP938Zi#Od)*5$t{rZGDbw1a|a}_8hpwUXtanCG*HFD#Jm=~0h@)9c?P6L-CYA7 zt^!wZEKJNh!3_)+M&>h+ov+};2+s$g6j%z*K-0k*n3*^u7#Nvl!6g`EY6a|A=40Sx zjLf$gKr$>$%n!kvhFKVy7eP`XEbT*D8Uo;k`5N#D96eOU-Oi#hoZwE^;cY^Z|xFY-mZdZbt z-~m@?a~4uQuz?HHKFG!eNOKe7e8@UfUT}EahLi+I?Ga`c1{Fih++ekk zHLJ)ZKUf^>F=j{+0rnEKeGNV22htFPia}~ zw{#&<2O%L-X5ggA{1DvSfjR)<(N2h)AcZ~?rx^ny^CU>5T!nae9XJq~r-LgY7AEG+ z;3!~WWWE52XhE>gbU;A}YNCJ|C*YB0u(_BbC@F0F_5MqCNtSOgchIScL*A4eB|Kz|8|>HmER07H0;lff&32V%%(q`~QNEJ7V4eK3)xK zIy9EnGJ<^wUfIA59<^p}0*5_wBe-?~CuXqkpe*PvCx|Ivv06?Y@UaXaZ+!y?3}gg~ zg^77Gp}YvGT(5(pk%ftQHCQ{O zgw#)StZE{HNfY^zRg!FL{dz15&nf!bvTBtJm%9W!{E9TFN3AnEl@EjV}~T~&xs zDqCmcdsDp$jG6`133_B?g5maQUVPRz63UT)LI&eb_VrvRGQO<;< zmOJ2Jhu5$vP7DmpU%&^Vf}9DPHV4H9q_l$!wLk)$1ysX94iken#g>5#_zyM!qzO_U zKstbsyG!Mek3#d?nwo)~NbJOYzIw#vY4 zg)Ae6WHX9w1W|6ZgWKTaN?qK2|U69HSk`*B&Oav6~kTQ=O9Gb8+0MZ31h9O&Q zz^9@>%U{T#C(L}1doW!BmWAig92d|KAOq-(0)%q#Oer&@T7b2}AO$f*4WwcM9nJvj z|6c(a16ti2X7e9d1KyoRVU~N>$St(qgp(x181qN28G>~PW z0~I;Jfk1m94Hm0uz^Oeeq+?FSg)G^?*aoYOvuk0R9jpaJUm?j z5{rsciy*_+$gL<3PZ#jm7R1?*5h#Rm@NNZALkqlSLKW8JVFk}|g11;f?|y+Cs}CXb zz_QCA(kx(38JG+LlYNjqxX&T-YwN&*5M>bkwO|oRFbNT72D2d~MC3F?H$(_xAXqcF z)zk_x^FKrlm;{UOgDBJon-&TtHNa#9n1q-NR*uD2VB?t=fQ<$hClA3Y!Ayv`5XW$W z&4Q?gh(OqwBt#ZM27+~!gGq=8*mTf(Fi^`DSx5=22qImLgKY~I=Kzz)7DLQ|=z_>X zL?EUitAwzRA-uaAtOmoo>mhyzOENHpC!^EQCb18X^KF!NGF_%!H=3e6Ycg5RnG6r$NjV0dpWGUxs-43B+{} zF*UF}#9bC(_6LYG#4LM|5GQPr6F4952A8Mk=?db~8jx~k9xw@U9>f;NvIa<+;m44L zsH_5uLoxtFBo{1F0VcuDL3PL-JPu(4Yl2t~DN!JnV>%6D6~uCgnj(;1RI7e6fwq-` z{0uP?5=8W2LlQN_nUL^>h=AD;XDWi{NB@I5=qQV!u+}r6L!SoIWa%Js3wS9Iu0TWD zsR+HO3FmE55T&4ff}llS$oDRRJFSqpU1VW!O^IBwA}t_dW?&%p@+Np)dj_%u5mGp? zFfkv1Bp;+QiiMGRA0!onb1ozuF|dMHB!M=Nfr}WhE*2){O<)Eys`fJw?U2L>$qHaL zs!^chAt1UTN+2YpY=Ve`*{GU+LY)tG8syR)7AEF?h?>L(muxXflDB(*V3P6x5%A zbcZ2bU<2@?ScnLu!vX0wdV@PFJfPuSP)-F6^09&TNVGt-K?bQIqm_{HW$;)g3lp;) zxR25a=?8a#=iylxnVmp=7U;SIhy{KJuPnVxD$Aj8Z%@y7GxF`#l^3{{bLp;<{#h_yIB~Sdmw8kz`ZgSCgvj$ ze}lW!kWvd0NT8nB3dpn!#Fd6%uYuhMU8V$KL%L`XKR~Y|cnx+ud;|bAgaA?d4YuwX zG=>`j4i(5qAH{H164tTpN zNH=t`BJ@mt$ayc|p#`Yp3czlFI364X5dHAD0)+)c9Bdgx7YhsX4e;bPGZ&~W133UvKmeo!MJ~+2=LUchO&uuF=rJ-2fO8V~L@O31<_F+Z z&cevN3X%sQ1s$YtD+H^A3=4wi`k_f2NgT4)@*${+%y1M$5|z*(RsCR!y20cY;*t?0 z4B^csI0Kd*pp_&zjlt6s&b>cS)!?%sK#2w1CDjD290M(V1b0+7ih)Mm9uZxdKpaSH znSyXXuF?r&o_HK}Zi2(gB0@E-!&k3puWV7(A~A)W?18R9?|W(HQK6`rxf=DFZD zHVZTJQ}9A{XoC#W2!l=eg63x-i)YipO<{;EC%Co(@4SPU18E0B%@GE-xWR@qXM$CV zf<+)M$pEhm0bfM`X`_MN3`z*hU^jz86%rwk7AVB;;2?#Ll!8YJS(upDfu$hs2k8QH zp=yx2*wD~UM+!H{5FL2P5aNE&5!&Ez0GT5URtd2YLS}+RM8PB^5D!obSZ;LE_k ztORP*fcB6=YD4g1YliifJDGLk>wyNAY?K~1v7Y(8xnS) zwh1`wK%P+m%R=VvwLolW>w^{6G*v>G<^$UV_5+v&@dv~nOcLy77A9uMv@8oNXq*CM zCqyO0{SXpdGO{o+UxskOBnvC^8c2H=+-?Kg2Wj&{^dpmyS_Lvs9S!mY^e}%pFgp!Q zN`Xo6a32;wf~`c3b+CP4A0UgOupzRLxfO_OAf|wAg-~><8em`BSFXsHGctHD=xfKnW+^u@@rAU6;Fau?(aX2{?GB)zshMex5R{}ZG8)fr0q} zc!w&eB@Mnc6Egh`KkwQIqy+iUYCfc!v;shq@ar6y!TKTdfDEimc_2y1r4FE(Bk+1{ z23DpXkZ=?DqBxM9khwX@tVPeE_7% z3fiQCdIn|%sH=@l&nJ)`@Qq}kAc5EeUJn7;LB_z!#1+KAz`P2)?H@Ge4QaoEl`w<5 zuaLzCkk&6Vcv%W)S2(DShaTAkI=u;ckP~D}Eps_|;RCq0jI0}SAPnd(L6DV@Grd9A zF@cY=fu0luS;_(K?=wR-Yk(WyEKJPDAjb+Vg)DyoI|LFw%#h_Scfn10X2_9GkS(H+ z#r}|B;Rf}|nVCTQ*I5{u7l2PAV1_jBxxou^Kr0v;_E;Vn{&2gNPx7fr0rjI93>-E9!Vay$;CU zbWkgcxdb$V0pTV92 zhcOp`Jpfr60NHED2No{@i}Qflu(SZW+6BBB4)@9va%6bH2bCUYVqjnz3{^D|RmSK- z#PsB3P>ro`qGzsW1Zv#Cg9QB+6H+QuY!`iiYgB9!;B)^lt5viL8C=zd20MA?m82FG zl@^pBSHbW_jChY5gxH~%!2qvwQJ2}E968Mn>btTsT>|Cv$MCuYlC_zbjlub;2V9b~ zFft!Q-HQGOr0E@avn^=s0&?UXgoGKe3e13%ODv4c_rM0AY=Z;Wtt`yU7NBuW78Yh> zP%#6km{?eu&w@{lU}1uuSHi-`90!tzmz^G=3=GWnj4W)-zrlqJbSMmS5gsG+A@Jlk z{LnJUep%4YK*+2tq_zcb*<)d2{tGb;b@^NaWP}bpHUv2)2~tk-fD42jgQY+KC2z>e z$uiP$$H*lB?sX;bTn}GQf|~2u zkQ>;b%eGDVPh(+X22Yu= zFfwO@3IRx0fQ6a)7fe|f#84K{GGx%)4Y;Yw!U$S_3!2sew+mUAnZLmt`U%{;hc!h( zN7*s4F@w*OV_{?th1vn~0Tc5f@QPs;M&=C=JCGdb3|1%s@&_cu)`QD~2gH>J;BB9f z$Qw-k+ri`(P|b}!?;!;qG^abmuRsLlLadcJ0ZowXPPBb!ra`J`qIH8dV=*|Erex-W z_t8Sq0c2kTJgehe3km6qV>BQj`xsCcnXxb+*#dDRq_>V?cLwOXNR$OIYKkTpQqkbS}sHbf1wH4qVqEQExJ@PeHM5kV#)vY6|v zc0e2lQ3_E+gf)h3Pyq?LZV+??CNWp- zpxpGpju^Itn2GFa(8BV*Fa`$Z&)^;rXmkTMMh5EWK>9S0u?a5lwkPm_4&>N&=;^B9 zQ@9}A0|r*68z94`f(uDdLj-*07N}@q2JdcQW(IGUf^<0;K`T>`dlw9>Oj_X#49p9_ z+CkkGWbGh6s&3|!WphYT7%#d0Fq6=Kxu`n`6g6aTxAZ`M= z{WI8F$l3$MB_rUVgSeZ8i5YTaCwK&ug^{@coTREi4OA8;X2=3#m|QVvG!GimkikjV z2pcG+gVQw&6EhEJ$P>~y=ad4SYyyjT&~~_`si4tTX2`WJ=3u>$V-b;6 zg1cJKi)7qE*%5MADmZ8%DIYwT&%(q!6_)!!79d&A!pQs*G6s$$2uX?1@gqO5J7f^1 zGb6hIG71mbyj2KN3CU$D;Ing%jJ8N}71AspPI5+K zW?oEUS&@Z8dUA41USdgRS!#^2o{653o}qz(5m-t$J+D+3p*jiI4O4^lW@(bUailb6 z;LTE^G?CL-f}N6t+`EIYksBSbCJwR~sEGrfbA`;mLav9#*iwXjv>7zUlb2GE4{3ja zZeB*;k_jIlhKv=%oC)!w9{4h8m>9&lkOQ6&okOInq%j*&#U(|VdFhZH_n-z9xTx1) zWWEpS*DV6K51w3nFk?45?L6$h8plvfzpZtQ;y0VM9n{&B!8< zT}qJNDbjHgt zh4>3XLR5n*U{ILCd*KjSWD=|fVh0NoGk7r&3nQdC1k%Zz1#%;_RRCU&3)$KO@nAOi zSdagt54Mq9sDS!Pqdix$=FiZ2oZur-ic)D`^7!QMoNTd}pkWvw%2i-03VwR180bLGm7HNG}SP_eq^_U^2fq~b}LNY2OqoHJD zq+$)6;UM~vNk{<+&U}z;2kQWw0{4(XWd|fjLo`9ykg^p#+6T?OU^c1&h|B6B{U31l zhq@86PXufj=yC{%+2GQGg^~FpxM*TwVqSwPeiYJW$mvkdSN!D_(EFi&sc~1UDIRm3h#z3ZfD++5)kG33Pik zXq6-Qd<>Y`7O+)-kO32L;STj8#0aovX0Y2(U4>ZK2vG>}9C)oiWMLR+K#P%iDOf9{ z)%QS8!cf*OPJKM%;Z#1vm4rAWMBv=$^ ztzidiC?YrJKpk`F+yk{o*ALUrjictAm#u8^s8a6mzHvoJC1f&Bp1%nS)0 zn6tpgO|vjD>wr~&MIpsFY%&AYviESyASn;*X7EG=vR@&mv4H0bSeTf_5k|8xLc9Wv zI7mQ(PalB{12BVYIu<4<5A0x62P{TAy%*wQutIQm2W%;{aSb*M+a$$ISQ3N;5HziV z102=1Hn>8t4XBd6_$0S5fplP71OXCfgd`Vc6L8S@gGq=_zyS(%7MKn86*%oMgF9|4 zOw3mxO2G!PFfy-&bPd28rJ=zKuD+2?fw0ldVon6xtO_QOBjdEkUSlhV?kN?7tdgf<^-sE2amf$mM}oZ-3csVfHf1~ z>Yv> z4&dVzm?6jDLqs6C8C+;UbNNL`B?>ux03r<`p(pf1R#!m^X@~?wH^e*$8$v>4!PO}9 zLx`!6h77VabWIb)JO~Lf2|7pM04|1*bwJoIU~x?IAeKVZ5KlsML5Afaj(~_jOn`{Y zhj5-kid_f^DFz|(5NTwx5bQ>1Qvf3I5TXw<67~cVDBvoF`8q@fq72#gBM?=0ArwUM zGDv+5z2pF*6B1I^U^^kIz-Rk2Z-l6YDAEK=L)g%uhj5M|8xI}Uf>i$yw}4xB%wTgN z1wO0=`3c@8f+&P|0761UAT1C`y$gw3NPvNBC{)AR;4KMA%MLR44>kr=O`%OOK)SVH zSx8leYS>cnee0km2zclZWB{Zo0cJr$1zdYVQa-BY&2Y^SCxdq_gEgjrf)LC?HUh~N z5aXbgIkGr}4KWYGMhYfW>#s4xS_2T};NSpT3LfYMvoNiPBu8YUAr?SL3~`8+W6W zn8ll!=qF|7fjam(nMwMnd$eE;AIhD868bP>8H)1?Kw}AM@dc3ZFD^+*ECNkeL#lkp ztU2jy;_PYeSCvpVAf9YY-*Yn?KWc}y$}jEte6MlQJcL){)oWsks;5mjOd zYY3Ucyt@^Xqgo;qRj zVRG_1x^nV5a`Fbu+ZgLXB{`cro0SeTmt|9wg+UQmK-&^D4x$Yr*h2KI6fi}@Kyt21 z)*zZuI&%(Kn=G3gh&E&9bO+IF+H5*t8e|$%AxH;X1BkTJDbi)GEM(@9)v?l1us)@y zW2?hlV(Dn73%1Atq{$O>{+A|*h-Bu`*3r=g34%;CvDQ`8Nzv1>wo=g1lhN@>0ZC}u zgGe@Qh?C`YQmjDsuobfDSZnFX=|n=D2~uMSBKqth0uIdgYuuR^F>5oif_lZEf{)=b zy~=0WWh{oYg3^*?M7o2gsT6n;1Qjo{5*Qem)fiK)taXagQ=*vIKw$tnKL7v!|Nj{o znCew{6quGUGBEHkKme!}(8It0K4Kr68WjcxhDDqV3{5!HNH8!kcrY+9sBl5dbmU`h zWOC$VX<&x%L2?FMpp60uz7ZD#LmLBvzk`c`fe(p)3~Cn0jUfG(xEL60kmUKe85q=% z_$J&CvvB$I1p@k45$5xOZ+d$#k z&g#g=-ofU`$I;2|$j8~m;mF6;&FRR;-NWU`$J5L0$j95q-R^VbM5Fmy44&2Ivk-wZOp1!R6J$ow{t`RyR{J3!`lg3Rv%ncodE zzXxP~FUb5pkoo-}^Cy7JpD5_aCp<^Ukxyi3?RQb@-d^B0aM=xRS)A&K;uu6LZm^E zd55GJ7_^{n2JzoWF)(l;@xMtiFgPIb&7>I^@{ssTq#@x23LlXEP12C?Le94^xBQWY zq-9V!08%R zgVeo|VPH^z)(;>)j~oL72Q;ohd=WVY1`&w+P~sXSry<9{AcUiy0J*Dxje)^R4iT0h zzKa|KgA~+05I;_yfdLd2ps)k+>*V3?MzIeh_eh?BVGY#nAby_$1A`T`Yyk03C@?T= zfVdUe&p7Kk0d@w43Pp(fK=y<9O^OT*8W1y3><7uMQiRkyAish5+tBnLP-I|m!l9Q* ziGiU3>UNOcCM8JO3^S_(jo+sPi3gbcG$D~BOiw|AEzT9mlGeiBOi|=AFm@HpF1BD*q?XU85nLULGlx_J}0m~N3cGST97+H zYT1+_aSr24C_};o6lNfK6=g{N$5yXFiy3fU0;w%hW?Iao=6F_C@L{M2e2UM2Mxi{1zKi-^m(X3%4>u^NE!vnb*Q0+`y@4p zJ7M9xNDY$jKC54JoFa?b{C28LDY zh;#tr?^8##D?$7(>X0-CDx*Ps1q}vTXx zz-bVqCqbWq;Sp9nlR6r&Ad**Y3>IaZMCqqcxkDRtZ^%qEPgCPS$62wfR z>+&hQ3=BfXkTeI10uWycjjv=32}5xB@G>x{7&9;|fy4`r_8cEKC=S4G=4D_wVG8L# zA-fq=W`XQ_XUf1(2MKEoH#>q`){y*x-nIm}HGq$SA;%2Tr-1Rh%n)rUko*=j`AcR9 zzk=j%nL+#(!N9-(;@>f2VCdimw^iFfao-L~a~+_#>;%P27bsr3LGjW9ikDtcozMqr zU-yIB*AqbP>xrQD^&C+9dM-b>vXBFX1IX+YC(Qa8)TRW_!$@;I79kK;JAR6Ss?Ko7f3k)7I)-h0rmAjFWTc<4#aI?gFLbZcsYz0j1+!P&)1d#aTZn9ZvwILT^?}^d4|2-{kXt5#+%gB`mbvVZItxub z_VNWZzQVx3fTk8vNA!Tq?gg3M2Qs@KOX8@2Fi;(!VCFEW8u}= z=O%#i+(b~Gn*%Ca=JGJ$HK!YtUVA|4m7qDGG7{t-&_ygxkaiCu-D8YVA<9TB`GsKG z2bEhhX*@fi(Ar)5G$~{n78v?3;0vH&KpnYf% zA9Ua{Xq*`)4?1HRnGZTv8JQ0{Pq_$5Kj>g&*qAWLJka^ap!OlmJkX)W$o7HGD@Nvn z&LRdm3p6eO(hoX$cow9*L>?D%?fez{g zwO3$#(D}NcvYwe9)Pipz&^Sy#;M6g8U1T z108k=ZS%p~0l4B$K#G9@bfh0_E(XM35en%mgW7i>KIrJaTM+l6^{v4Dq$!}XW-6$x znFcCrri03w8KAOeCaA2L1!~942DQiMf!gEq`LWm8Ah*u}c@Ua8ko^S;M`XDK1_lOX zz9S!VE2!RV1J#@Dpt7q2RCaZO+|>ngS2xIAJs@}Wg51>ya#ugdT@yg=nh0{&9MCxY zTmdIO5l~FxcB6wd0|V&DAJAAhvKv9}2g!j>@IeoIP~3y$K*#fd!qkzE8E?4-YX5-L zgU;gtjWJ^zM}s9?P}qRfLW2!Fo(JNC&e53wi8G8c52hF9X3$YLpm{1}|Dc--Qwus; zW*@{{c-n%=!Q6n)9GKsb)MB^~+_vL`q(P8hU~19b1mlAaT>-W8U}hIZGB8*{%5t1- zS8VwKG@qd$3$qQ}|D@{tkrSUNIB|j8jcgAnJtOn!nVtneg)r31$nge>Q(SVOx*JUn zPkIIoI%DrcgY1}q!+ua)qRC;T6IeP1g(tFFeCFbl!P_UK0fZ&pLH7KDGGd(9I#0PfQqLixZGO&^!+;RC3bxu2&85rD}n3|beSXx=z*xK1UI667IxVpJ} zczSvJ`1<)L2uu{5BQ#f-M@9jgS)epN2lNmyToe(#9ha@KDq{f#pI2IJ-WF{w;Waj6EBo=48mF6X*i!oprX9zYg#ML)| zAtbdZH#09W2c#LMu!OKYJVTvAk;T*6S4nx0u)l3HYF77yYSrxul^ro&e`8L zfWap}9TH;6pi`xs^YhX&(@TrMp$Rh@5eZ-y2Dk=!FgW}Bxp}(B`?|#k|Fi;Kab=Ij^Z z19k*>dx>XWT7EppSCIW1ptOk|$HqpW0CCPpEON^)%1wm$5h;S;k%JLt#vqNQnRzAP zG!R@_T#}j_oRgYb;F<@@2(Z9{Miw}vU@6-pF)t-26-`Ber=KC%OlTSfd*0K}%^&Rh zAlG2m5C-4W-29?S&%8{OTo#mCoLU0$K5}vaD?>>@uAnRc4Q*%tP`?lcXAi?5*I*9@ zpZxTY%;an+--iJbU?KS)`Ng304N2@4@g)qPH0l9%IZ_~5Koc-V7=Z&9R7gO~3oc14 zNrfd6w} zm_Xe45|Ed{Ap}liz5yYTU|*FWg5BNK&o#)?nISl}q$D#hz1Sx|F$Js!$>-o`#dH(M zNg%I5OAF}TOyD!<(-M377 z7?>f-M{tBW`uH#uXI7<_R2D!|6iN|hXa+J3S-&HSX->!)DLAzxG&2R9kdSq_F*xU^ zq$Y!kW3XIqVrCwLvxgBl;duImxcNA`2QxT(7=s0nb(%s&eNgN)2L~cb`C|ZbC2Dc5 zmyDvxk^viv|7HA%XL=8%anj+F6G|77Ug&2l`Yz8GlPd`|)gH{;egyx!8Qd9}feW0`gO%<@x z0PINDFz1jU)NryujvIGG+(3#Nur82kD6X>rxdSN*3>_Kbo$~W@ki*i@nE_t>CTAoT z!NLGhtb=MSbc5U&oIMP{F${@mDA$L}+uA{!gUmoUKX1J?(zSc!*KN~mQp!tb7bA+AAwjy@p&V+60E5!hQGag-`P*wfG5 z$JN!(#nlC*50W{+B?+wdatsaefYw~-Eh%%57Lbw9^c3do?BW>)F73b>59C8|#zQI8 zVEzD=W}v)LQk0(qs=UEvY%#2m^>vGf)u|@l44!@=;8X@G^1wMF2%00DeFHogAb|+7 zjltPBzz0-7g7Q2{(s5$&4UGVs0dlaj2ckU$FQE)w7=l9_LqdZwW8Dng%z#9*C+JKG z&}BOi3&HgeIK;pXgGRZthohgns|%8ELVZGl9DO|9Jwg~j+07}l1WVcjr!7!I0M%HK zIx{%4DivC2p)?*qwu1vV*xAt!l2YJ}JResVaFPm0EXpjY3;`9eD1{JMB*@hb93Iei z8(0ifN&0{y1<`i%bV03v0unQeK-DQYPeGG1*fLO!8;h2gEx%`v#XL zC4&wt0v&)>l3D~e3|c9n_%OJn2;zeH_{5ZyB11EtkN!!RZOr6q7RATfk< z<2_OnQ$S&k%Wh}K08g;xSY75@np2YLoROH9mzu-i0*zS|s}Mep2Rj=UaREj7CHcwu zIiNrR>x1ip7y}71hVrn)oYGW=ko=Ow9Mnh!X9Z9x1WFNp`JfnsnaL0zUzA#0no|OH zI5;-b4pT+@)Ao@q0J)(pHMePgp-T)lEFq`^*iV^Q)nj- z?sa%N1ZzVIW_T1jd&VOafyzRJZSg1`j4y%s8Wt|aU?ahvaSQ=%@J`H2f%^kF%mPaj zb28I1@kOd*h%eO1{v{cyMGV2EN#MuSKRFZP5U>^4a+^zLQEGAts1|~T5j5MQl?0F?1!M|1PW4G>L?saGYAu@JmUOH|=;3cVlfp30FYB57VeojtiUOG4c$`W&YA$?n< zBnRqL$CQ+!)M7|dN4PS$GzpaWilOlibqOrI;jRHC9E2vc+yp7-peA5- zvvYnasDTSrNL1Bnd(G?XYUMlbBafeo(MFzNwVI)@i}aJ8_a+tUTzIJm=M zno+_CTLOls0#GnR(=gm3a3nMMB<7`;CZ?xCq91oeK`e*J<0-j7l^HB{u!gNGsF=x1 zEdlieeViPfz2iZV<(^uCh%W}X6A{%{VnJe3W=>{FW@<4*P-;$UVlk}O39b;}I*OrP zeI(O@Q;RYabNotk;iiS=WhUpRz`YC}WN<7gDauSLElGvMA}BW_%s{HuA>j~T!VvBf z5+C3i6mMqY?Bfk;@*;OrEE)WRo#TU?jg5SrgIwL>Bm9G%jg7#{K>cWVTRz^!GYrzF z1*vxn3Jd}@5aTUF{2|>kRK@;oZXk<7oDE>@R3Cq5Zzs=?U*CucJt z^usz2pa3rcwfO^rJkg{fy)T3okn_N<0O^C?F#P ze0)I0gZVCQK0ct-?db>73099t>qam?2e<|~g}O2Lg@Ky5ATyyZ4D|_sIUg2SU{eEp zJwXFwuu!!CX-P*J5iv9c+XeM>P;dx%9L*)jfB_VehDdP)P1hjjxq$`|K|X-z97CfJ ze@KQxO%34Tc#y3y&jooy=e?aBQHMT^k>ka{1fQebGn0P+<~8K^BC z66E8G94dxpC_Hl%o(0(NU{8aK)6ih2V1IB~2yzTG?ICgkDEbhJK`d~|i=;Nl8KfpX z8JE;V1WY(Z1f7-7c$xg zicC;$LH4gPitmk4V#XN7uf`}bV+<)(VF?Cf)1y2@6A^zYobdVs}pWxC1Y&@!O!Gq)|jd{If z2B*-F5P!dTM`!TVW^jmqkZZiJt1p^(kgKz!j}I1!P)`@|d}zFjt8(Uk&sQ@*+VQ@b z#kq+k$r-3B+*3<@GK)*lJOFZM5NHH4-qR1}P#;&9cxQhXSLgVU2YTXVIv@513<=yxCZ%pf(E9Y{r&tvgR`K1Dp(dZ z+`;o|s6x(>&OWa3!LA`8o__AZ3{I6LsZOP7X{kjZi(umMkik}l0_ZKKsVR{71y8l0 znuiDhL{x#sl)*6rb0dd zm;qeDLrjHu3OX$xoLb^k>6rpD5R|I@gCe0p>4Iz|!bu>1!vZNjC?X^RtP_%Yf+FD4 zjo>*Wuum}qAGB-$DfMAG2OMecIr&M6Ij}&(mWmzyT>O0znaUqDtAdh=A>j^6FyKBu z$fZH4;3-1zFb8DHz&*7Dnw%hfy=3TI0!X3~G~=6*SOn1z8hy*p(@SRXNUiY90}Y*k z%q|9TL3zM8u>v#|59UKMW=KBNXb2UO?~z&ok%3Nz2c;&aIDvaW;BfVKclU8+2=MeX z1{Z{(!Hz*8@y_6c=^GpXt|UQ=SHO}W4Ng9ue%|pG5e#lQiNzT(OCWOwpk9E1uVb(` z1K0xC=mA7Bv;frh1xqjlx%xT=K-~kn`Xm(;P9a5^>7X%r(7ZmHb%qfP0g36U5U&S# z`Wb=c!7hLp4)-;(`#pnPz%%1;XEQ)#p#?dF1M#Y3aHOBJN07gte`qkMG65SMUX%&X z_YiBGb5au_WdI}?j3O9<13VES8sO}y;|S!6*}w=CIVNCJ{X;`Q&31@eAg+T)Bq%9DBwX^#^AJG|_6f*^3<3T@ zpgs>oQBZ1fVonZ{ttQYI1se+zhmskoWO-7 zEXMsqLqP38m*Ns|9pvf)^_pn}$TMajtqlI5AtCNQpd@1mNivlssl`62X(bScLL!1djL0t{A817rptX^qx5OmcMgNtVn$TG0BXR%XhaV0}=YGG+= zUUDiZ2Em?&Bu$Vf{rsVIG9;11N{dub8ibA;Bcc^88nucT8hE(!5;oWAy5sVDgm5~QB?T&`?*6Ez)f_j1iK_OGX+wvF@$7f z7DN0EN>8Z>$AdlU=;s3SDMXQ8GD84pOc^vU2`;`t4Tk)5_tX+l(*x{Y*cyi5)I3-z zoS*KSnhQ?&&?!+!4uyCvu_PY6#4Q+N2GoU6h5l)2pmq(YLWY?OU+e<509==VrZ2#k z6vV^De86@>N;A+XJ2-EF#oUTgQ$c2eoRkl*DDu-mB^2Bz2v>mo1xXALBcTStUF(?w zub!cyT$T#e4U1c7YQ_{#EK7xJ)=Opp*Apo)T`(C?)`5!o6~P3Hk<9c=VTg}UO)W2q zPXd*d@fF5Ki6*6Rl}N6Fsw_%DRq5mE5|o+(NvI5h$($P6cFngX=y0oq<=fEyJGGs@G?9g%=QYtO*>1~OC) zy5=H2C^b1X6BJb?si+E341*a5a#?rfV1e>fWh6e-4IiO}C12&rxODsSWsOhOG44@S;;Q>%DgC=s45|gt* zr6vQ?fQOL*3J+ztz{rdNc@dd=DrgBLe0__N1uWJ<^#Q1y$WKWHjc^)(2vmcdQ7mym z;h~J?8G#nrfs+=Z*$+)yAX^|s8&n`TwFJ}v^3Tfwb!fqwf>TRC4oS_0In6z_B&fJJ z6B-E6WR7gTG0K3Uu?318Xt5pGTu=iZyvhp6T%XhwaCrbuT+n6>D3QCQmL!5Z&|saQ zP7zoqs5i#|@&l-VK{5vJ1^A(`0Z6it3J9zhw!+X6)Nq0Z0n9vbtin>VK2#F4^uRSB z05sMD6#*&tNlgh#O+ogi5lRpkS)$0HER!^HV(>35@l7o*PE1dQxe{b3B+-Hzec(lq zj-X~G)K1XY0mMqE07yMFlEAKmnFDRQKvlV?mOu@K3P8(Puuq{v&~g@82xNF@L3&YQ zN-DB9jLl%SKvM`Psrr|e1SA$E!qW;!FH(3zErHYpP!33mM`}(1%rtP(4V80GEeT64 z0<9Z>$wGVtZdoGK_@?F}i@?(dgJ&L!Yl2ftpcNpfQUfO%(1ZreY>-R99dTp^7=5>)WOB}x)YN{c;Hz@ZL~Ko6Ld zJHpAJj8Fm-2e}o}O+*%f1T{JiW|n|f_dp|^0c1B+7HmC~4Ng`JpvH7*F(ku)(gIi$w6uU1YM>?qsN#c1 zJXjStH9-w?%P-AKVJLuw9JI~uk_wu7hbmzxfaDdJ8d#ABG91)K0Ik!8>I091>4QnV zWYBPaxI1_h#3eYyAKdwZ>}LrE3kC!`hPi@zC}8yv6F|AeH7qzXINsUAH#8zX#M#v_ z-q{&E1Oe`jdHRJIfacA?Js(t+&LEZGttP>Vxdl0?0hxIW$SNG2o#MkG8)BS2ApK`& z4}2>p2II76AsDIH(Zv}Qbl^Pg z>;V~BLbfZ!*~Ks(ODrJ*2t4fz&vaN*6*$XbBuhuI&ES9l&1E?|LYMtO;u+ZyAPR*f?WtIaRNb;Lg~pE(E<)pumwS>pdB@tdFf7| z#q8jS3$bG)0QkB_Gxcx44#FP3^9tk>BYYb^*4 zbcmJ^ zpbkWOGH9m??hwZC3Ao0E7E9?Q2y6ihPfSJzCg8FcR_+Cd zfF=#l>N=>9Ap>Z$q;Gx-sA-%EZsej`=7OW(axs9__bAq&1Rk^@icyR~3nXy*bM`O> zC1Fq$!z*;i5*cK7fSRGusvlVxTnRz5h)-g133|DUsEnZd!H_kBtOQ3b*d53+(6kFK zzL3R1I>5y*M%sn8Krws@(gDtE;CMwg3slKL8`j|HhLqzNsSIQQIJLW2Ca5S)&ue>v~vJilL&4UK}YH#GaDd>g6alW7k5{1YZzHS z$id)v0_P^sW-&7p(8du&a~@oDf|P-M9OMaVcY>-JP|=*3m;>5HgKQu)w?l+V7(i|Y z_kB>(E;NmTCH$MgLM`sUHP>Kx(ErbHgKsqgu2n44kP}|SY48=G^N(7q-u^ZA| z134TVArQUJpq`8;WT7)g zf`vagS0KxP^8mEaM-~U=BXHWlQaXcs5g*g9UI z!4as-kSzcSJNtsikx-H!q>e?(C(tP;9HkayK`64ph-3g+l@9VFxcv2T4RZyrKu1yS z9~1)4p5VwqPB5M>kPb6soDj4mG0YV-^j45q0$v>fTKfQ7W#Q!PY{=l`>}Fh7JNiKnf`Zh%6z3pkM+~Ko1qHAmKsVg6pa4>eAO)8` zx+1+~2Dmlg;Y(b$fcyUFx*ZD&K(!UZ2*?&K==djSp}S*9e0Y#&h$};AW{R^9gfv8` z4^PZa4K08O8$q>!f)>gQa&>fxG(_gW6nQxMgfKWK7NrEG78m5_6{j+QCVWzh;9Q7P z!Fwk&lcC`ZQXlN-4cWMgq5$d<(77;0l?5gFhK{8r84S)4wqIsaQcfy^cWR}7T3T^x z2{aNQ2jM_^saDfjShlBqApOK=qd>6$a{@#SBzb|ytsyEP!ibfl&}j*nE)*v~a~jnB!Ko#s z1q|`#PNAMI&`5^Hi(^3nI0GO@94z1H8iSgj&YLuCJUm_E0~~{bUE@9Tic8Z#2Uw-%l{n|;fDTd0 z%+Cu*EXgPat3nk63k9VX5>z>;*8o-+N&{+X^?h*&hg5>Avdw9A8Bo-B?7U@AwAPY_{@$htk zy00WP7i15T)gW$s34?1zL4F>n7vYpy0xc(C0RUPdl$o5E0|_0N^Gi~5{YsJJ#lzDj zxFj(-+rKQeC@m+y9HJbw+y&%2u#J!i1P3xm9Ig`NSBMeezvXeX>TCl*w3G7-_ji57Aic-rm z^Gk~%85QhkP(a7K78T_efjV`dt*Q`9A+i|h72;M;7f{d^gE~RJu!S$~1Y)TqH5cSX zkPRSo%a4bV}6{%Hu6;In!PNFy!6eB?@ zv6_qN7Qg%w$ow-rtAo~lmVv6dVo>db)g=r;u7UBO1uD>z8@6;S9^7mICBTsU^z@um zaGa&)m4Hg6(qfn{NWy_`qQITLAbCExBrz`q+?*@~)yUv2>Yz1Ypb{Fo0uHj%9OPmK z7uPUPXV-X0O9N(4Y6>`^K+FRz9z-l1gB(u)-iGMx>k{u8JPAb-djg1nRhP*BE$`Ze(uaMj?U5|D48?nd$>%pyqg0tW;v z&S3!!IT{7VgC14}HW%t4T3=;q@X z?17OA!NCVjp-6!O(E{2+9}hZD0W_ipGY#TBhyoN(!W2NH&;t}E3(*cb@e|29h#=G% z=z$jRS?uWtiiS$m2oB9lECH=aM9ui%xmD2WUuX(NPD7BRJ0UR#lZJ(0JR}=K6JR`~ z$AFxrK{FPxyzCU}=H?1s^N*(80-W$+c^Guo2|VRMf(6Zwpn>W5qEygXtZfX-3_H@08_3642jp$rONXxV~lE~JbOE&;7{L`pND#z1ObNls;OYEBw> zS{ga2c@{%LE`9iRH7~s+137WP7v90j zyQEyG1HkQ);LLPT8iXYqn6VIVq2?{5aK$J@p;an4O2Nq^32F(f5`}vV5!Mhd!p;#u zGTpNn>YU)z5_mv^(<#J3SduBY7y<9;N=yc?Q*m>33<(Vatt0dSHQ>O7o=0L1Xfv1- zs1`+Df)DdFIO&0c5D(gFt0$X8K?wk-2kRxPNl_&G>y=hm{}5JgafQl)TnbNl`FWsH0V)#|j@qe#>xTpZtU^UH z2$WzTVGFKB;(eTb&;t&p3u*_l?I7>N3Z{6NsXnd<6QFu!B|vPdVDSYG zF=(iOEJx^u`pYvfIUlr+wZB-Kc^!$Jg9+&CuX7nOhl3?(RFwn2l$$rU_M z3*n)=3>Gy6Qy@qIM!>?B)Z=hCNDqq3Aa0097Ka711;S;1r8zn9V2A1VECxk0IA9!e za`MYlQy@hIv}1)F2w+9;*VWfDWO}4ol1d4>o{C z9>HxwXm=bDC@3Wxj?x6)&4+1Ya1DTn`GSTZp&{)X3>wXF4FHWBfEFBs&c{Qf4bXHJ zXlFt^R5d(E(Om>FxU?u0W?6hdP#9cwJhD1f9wVDpp~!;S>rvgbyqRO(I~&fLaikcA-~apgne=Ba9JV21jQ|zH0zz zL=GI{Afq8}1T|bxA{NsEl(GP%6XsB7f4`6*fAGvNvM{`x4O8bC?2mln0fCeX%KPwC zNrFQgp!8f?Vwg?uUZgYoKO1Kd)udhl2TSP0yw0a=S=1XvcV4rD;EzndqVgA!Dwxv3Bd&Gjp&hk$K zr)7vs{6gYA5{vzllR*vA6e40090(w{!y^*D&eqV#6mBS@M~&eK)X)M)GH4wY*gUBb)`^2Mf0a#c*hy22EnnE)ts2nR%JHrMZxF3UUGJ&>K`Mk{*zQ!F#qCP^`iz z(u)yBLb5^%sv*9K6<~`I9zpbHK>HLkL4g2@BXCNAxGXIn$qZ1qK+V7xw6IKz2w9M! zu;@bSk3qZxj#g+$fx4Y2&I8@A1PUxj^8Lo3Zo2aQl5ou3WX3Q3{yNR9>Va)%~V(55%oRYl0ELESNE^nsLsyAY7Q z;S8lIi6x21YTa^5i!;CiAVa~mW^!UdacNFs323qnx^x9(Dby+HsU@KExxojIf%QSf zor_XIS0I5F8D!?AL&6Cx@8=)l=@t(en*uupEDEv>GM)tLD8Ze{0PA&t!V^)qLfT`H zkOH{{9HPjFje{Z#BmprtFU2(v;S12Dd177)+*;7)*i6JFPjGQiusIc_CT4?g^l&T9 z$pK42{Z~*5@i)j8s1P(L;=zkQK!oWV|q7@(KT5FekG37Q^qafYQ!kjIN* zp}>#^o|JWVaYoGxNREJnJ2bpOlfR%Ka8E6P9SRPfScTXJD#&qn^pT554^J0VcY?+t zpp&G2kVQYBRu0%~kbS|aC7z%Qoxt&13`uJ#3?QL^)S}G%6xW=@g5uN^2FPJ#usK>k zxEWCQVJS*rJ_<(i5y)KVLXD!-GE`@Qodk9}QdS1labPiUsSPp`YGDbu*$uAEK^ycf;k#i6u{Mi%XH8bH#qdbjrGLL zJW%2Sg8?m06%*fZGT1X^PfSk*M>)jFddVQ?LnFdBvBD?R4nvW(AX;6gf;21%X4#-F>PK6A!Ashti^m^tYy8vV?ln;pjWGA5( zGzep`CTAZ0u3O)t|vNQyt6XZmwb?|ZxbemgHn5zqTT)~*Z*VDxlQprI^ zKtPuYfP|p&150mUWl%AwQQ(>pq6uOOR2ovRfm~<^7Dx3KYJq@kYzbI3EHXiv0hbLp z0>lV=6Bv}PVGU4_eW+;@YzIR?kY5PQW~lc-wE>DaNB~hic)GfRhIlgb(tT3%AnL#d zLz6J5Rzx-wS64?|i9!Hi2Spo`o6iZ;WC$d6F2?edW zP-6sHSqXYGz|agd{DZ6n9DIH8d;b?CkVi*pxHhkzX-Mf11=n#pH_n8L#Rqf z$auP-cmbof2O9!W8V{93(EthvBxj(eKxEC3w2CYO2^w&5foMz-Ec&1^22KGGcY#*x zA|)zVJ__=4@q`yxSfVqqG_|NQ-aj*i0d%ee`i4fGq<}<$_xS{{Bv&!~?AhpDvn|_+*i#(N|d zrIaTYr9z6$c;}pa&>}gg*T5bD)ocYhsU@I$U?HybPE9Rv%*iZEMV11q1$mUg(G9fP z4(xY`dPsX2<~+x;#LOJ<>F5NbAFLf5FOWdiOJ)cRbq$IHjj=#hpd-a5%zUWZAv$0c zA;cue90qE%BRm5Y2bI*2V}YWH-=sZ7IJ;W)L^g>cCWZ^1ANoZbXUS>%qcynS3G;PD3kP0^e zUK%BqB*r7;Q=qvKnkXPff;^H6awo*Luw>}PiGHQI(4xaN2YeS1=$;u!e;JaoQxXeG zQj3C13qZ~J)D(YD7f?-7_- z8rJtFPBl{Jfdn7GTcE^Qg50nmP6s%JlHj1=lFXbO&s@V$hg*N`5?81VqFaF~rA%Y%Iyl zi!V!z&jFo;A0MBdSDFmx(#VCG`TFov0Sok!8OqWMK&|mK&>6C+iMb4Ep!PIFUVeN* zdTue~X35f=lKe!5q{QM>2HH6a<_^7NhNRLo@RgVh<(VlZ86bzn=M*HSFccJ}CNq?P z)`b_B6y@cl=EVmv#K(hO7oV9|mReK-QVWuxp*z9hqnFIEh?9X~2PXpq8$-rq#>~l# zAoeLv1_l;}&x{%KL99zivLN;yxGacu4@nlp{sor>v6#3JCWF{2TriUvpa5n+BSR+4 zGDe0>n8}O`nJ{A*88V?-;BIDQ$iVJgMurURE@foM!0t#!h78>9JHW}nz{FrMA4H!( z@-K)Dax@b|9|MR6*$GkyqHiIo1F=Cq0;vPh@1W*^Y~(@;ArPB~3uIRx%&TC(g6svE z3!*{xurVY}W=x*U2x5cm0?C1Bkl8Rf5c?a{9uN%*MwlFk4YHe=fx~V-hyk(`CJADT zfE{5lA4E%l9SE@y#8!aHfoM>4!t}vh{DqT&0b~IqLlR6#h>L*%q!mdBq*INHfq|J} zk^&Qmp#kMEgBS)-4hzf#FKz|~KW;=?0ZvHv|F+y-Lb1M6t1pATYi z@gN)yVsnE{XsMqMVt|Z;Y zhr|c5KY;mJlNqxoGlJMZ!2F!ajJcB;|8O%faDbf$kq5Dbzzj2C@%i4-H_i!^X90A8d8b}!n4=6&?V6q^efJ}h-1jIhW&A`CV(8$2?U#f{gj=7VG zfkA0LNbnX|qNyG%1(N^?f(+(iXsYK>g^7YhK)!{U3u1#p48vTQL(rTFQqRZ$cP5An z2`ET_BLWJ-hnWIX$H}*T#E;ksSqjCf`@@21gsYlFd%jW*kgV5^Fa)VK@drpL3KO~3=LpK zlN6Xhj3y|D8N_ITa#%o&IZzHOvfduBg^)l3u|bMZGZDy!Hb`WED3Bs%hPHZmhJp#g zs=Wz33=C7irlJPT8Xg9QbxU zlQJK~0@=vM08tHMgG`0UBAa;vY$l}82eCosfK(+RnE{c7>Dt7@zyPuxW;VKA$m&3* zfl7=|JPZsB;Lw1$2c`!k2U8DHdjlMiIUwp6IQjK4fM}3bCWgLxCSC>xFs`habLggJ=4hZnu>K&V0uVUV~9SU1FtAT~%hEQDdU81XVNfJ}xZs3=|r zh9a;&NX#zbWnkEX#7EZ$@^c(q479r^dvDZMPK-31Xj;?x`8$e<30IVDm zsv!0oj8Fxsx&l@O2|W<|9yrr9A@brOUIqq`cJv@ch(oM+!pp$$3Tzl8NMTL^S-K&n{4svsT!u|eiBGaz{YqzGgw zEbd_r`^3w@pbXZG>R^yH8hnuWgQ@l5V_-PJ$H2e?ZHJ@k_`=7)@C)n(uK&z%#|iK= zFevbYJPz?F%q)2g{5d>!2?l*0jH=s`K0Acg^y!v$g(K{?zYh6$9z17es#IlLf-1(d@F zVpu^r{2+!6lp_FQ*g-jhAjTRYP)JNt5P}6+m;eJqivTFCaWSyW&l6%`m?Q*>poGbc ziHK$!Sd|d2$gU7#U}y#FLe2IQ1R&y!49PI-UI{QTED{10eGxDr20;dfC19a&n2?Sj z14AF!K-9_&Bo49&$v}|MEGBALYGBflb@-|2iWCkoT zfY=~K=)DF)>Ogu9fZYLc7l?gC5ES@*_47dtP@usqf%#iY2qSdtgfKz}6o>1e@yG;X zY=Cl@L5xjM4hx8}1aRkcY1u>36IeZ|-2`Gmj#5e`z2!I%8pd3LE;~bPD1Y%r(a)d#QD^QLIh;dB_ zl(~CEK(v_{m@N+rJW#N_0w)?ssS09))PR}+8StDBQdJ=gO39G&5mJ_dM1F{Z%$t}F zqSeGeIpQ;8%6t$@2W->CbPx?Pkq6owf#^lH-$ode5+NxM#0Htm#sJAnAoc@@9Z5*0 zCc#W)V~Co}7>&qt?}Qi_U+!i6Y_##0FW;#4s@%rm01k zf#HcLsAx(CQ6On%2CfC1FsqOXohiZ$3^Tw{jhY1J2s1E1^l@H?r??GJK~RGUX4e&{ z7&8M$FkImWs30RlC`=un2*f}}h7g#L7E}n?I4`Ie8w09)K;j_3FfyQe31${Z9^_u+ zVCaIH#mvCj0(aUns35YXhp>p<6Tu#aFbjW)Ffj0lf=WT8t_?^K-4!4)kV25lKr|mX z@*qVih%E#*q_2KHh@pWb39~6h6cTdG44lnyZ&X1AkwUl+E(8zZMNlDR&w{eOg&4@; zlN6Xh3@a#y8N{%Ga#%nNJ1B=0#BhLe*gy;?D2E-y*Z}3g8!sR$8pJ?p6q3+E>{-xq zC}Tc|wFpTT#0D9GTDpPEC=vr@7Ua?mBm&Y8Qkw!c38WKyDF!mZ4{Q&lcmc6N`q>y_ zCNsuPW(2Y8z)r8J2OBjHtQaB*VlRL?IcYwKwGK%Z#0FUmaz+w7P6EUj7!t%l1q8I1 z192vR{QxN#AnpK(fcyY1!#*>n$bc;eS%JL_%M)W@0EHl|i3?(PfgJ-$M6h%M@()N3 z)(wP-gB-dE?9WLGOd!S8+805g=WH=v0n}N+uwvu3A0NIaJ9LvCk z;3K#or-M{6Gfa$vCp8ao28KAW<%aXK#2FYsL4`ELi;zZ)7J-5pqzuKJbK(pPSD@yA z=r>?bB!2=4K^zH-*Gq6AxXVD%01A5)6T8G27#4ukG8oQZC(ghCQiS9(gfzlsAXkBu zp_r2+!N5=gj*Simh4~E<3=A!B9?VUfBp4XBfTA2Uk_}>PgL0Tb3^7SaAqO8J0x3Tr zfhd+h>=$4@q-_pje*p6#4FVAR6POQ?2eJQw`4D*!n@bX89z>o;l7RtaDf$>6$lg6* zeULg0#D=JY@L}Eoi5~(d6GYhDkYHf=0@e%3>>&0JurK@S=Ytp!gCLSHgFs>`l8~ec zqBX#5!}%au2h28_526jgY~%SL+62rtnGd2Zz--g`Ale4ZHk%Kk9l&h!`5@W}%(j>h zqTRr3gZUuZ3(Pj052F3RY@_)gIta`*o)4nKz-*KGAUX=nHk}Wm77 zqEo{1Z?gjH9VFqG@w1F~r+I$de z7FZUd8pH+}h~B*cnF`VgD{Db)kY11}DPU6|x*&BI%q<|XdC*kJ1Y#_Ja+pDkMNke4 zh>;)#Nxbl}SCHN{5U+tKJt>g)6G4=L6wLb|mK{U_L^;4EKrE1nj0}m$ZdrxoQxIE6 z3XzyWY>;^%AEnI)v22iJL2Qtr5LpllWITGpUna@Gumv1<2J=Dm5ir|uK8U^qW*f~1 z(GS3EiiX&F6z?kRL&I!NM>} zih&^o8c|FjMjDjE3}R$JIV>PXACv=+Pmtasa9m}8s8TR94Mc&Ig2EM1)qvFIfkPjX zDnaZnFdtIzfY`lYKBT<`V#7>9jHiK20h!OpkOHE5z&0j=D3E$ahBOcb)0P6yY&lX4 z3?LVRX7;2Q7(iMX8E`nXOp1X4WFR90VRI)*F)(aEax{p&51wK{tOH20Aod}+EGz;* zW-O9IZzO_5K>9&}m@*&40_nuwNQ9XH8x#TQT?dY}Oy; zB!7X}FW~+Mu|6Tmg4kc+vLF`70`#(QhcpAj5pd8N%m>kzz-+_$AR1&M6NAxw5d8`) zZZIEY&JQr#a6X6znF&$@^CE~ZE&~dEh?_xd2^sV_0;%EvtAfN4hz(K+tG7UGm@Y(| zfkdQapuq=X$Ur&FAch>2!vbO`Ksl@+Mh27vpPvUAqz|?p;z$rX0nCR4EQp;B=0oH` zY>*+KoQo*_K&I$`RY5!fVyA%lkZu)-4blno6o?Ho1>q?*83qO$8Bi`Vm=B^uz-+_$ zAR43^IdD5<7#O;so?!wpdY~L;5Tg&uVF58FKsl@+#uO-r4a9f@wx9IBGVt;nBqkvX z^0zsP*dG}N237`UPR#}e5R*X`h*|(@iL{bBZ=zz_FBx?}c63mCx2OzeU9C}^_ zsWJgOvm;Xg9(hC% zg4kQYd`J+2*n7ZyNPh{$-UsGGNv+iX6FHUYEE=YwdF6F`ks5FG>-H=GZm!@z8#`5-z9%r>46qT|49 zlldSz3CuQ~52Dk+Y_s_wIt$D;pAVvQz-){8Ai4m|Hkc2hOTcWy`5?Li%r=@2qHDlx zxx zVaX1}ih@Xhs2I2ehy^kcsRIZy?;4U%L2M62P&h$yABYVy59Fh?`5;yVk}QY~G87^U zVu6fD Lb7#JRa``5>B05tROo=YwboFxzB4h*kr$P3MDX z6ENFsK8OanhKa!(>?%L7xWRmo8xp{5!}%aO1@527=`Y~%SLItR=)nGd21z--g` zAi4z1Hk%KkL4E<54@*NJejV8NkOCdVZUplosRYDsf(JHC7f7T98jVaKMjMpF3}UQ; za^S@&NO>37P>3ZU_6jf`5+N{S`xF@%W`ZL*ZGj>K1IQet)pH=DCxLZAOaZY$s$mIu zjv@oYJg_{(R1h0v1WX=g3rru9(I91;z*-?jgVY1j!umuzR7%!0-WV3B+k2HiHr(F~fW{Pl1a#%o&S5OWsi17}}VFNKfKsoFn#wRF;1H||O<#2)+Ov;dm-~ut&pd7e+K`!}@ z$D2ENisDpCYL5v0{hXcfDf^s-Pj20+|3&iMva=1Z^E{I>a zL9~hr*pJ$#2jRnP zTcpgu05TEO7CNTPz;HnsRGCFfs4y^qj0Fk9l!EvcDu~npVq1avkm?)6b_4Sv4hOM4 zz`;N^HYN~b50t|UVjO~USU`*;P!21IaRSO=12IlPIqV?D87PMX z#5f1#aDo_jpd2m`;{lWd&($E8Ttsp&hz(MNn&d$u&tO_Xj2BQ2Gl=mH%3%R9K0rCF zAjTIchYiH|2Ia7W7(bvK4iMuPl*0*PaHvAUg$u;sfpXyP1-axel6ygHkRnv~fAa($TE|5qFSQW%<5IYpihv)*aQ!sRaL^8puAi6;8JPcJJ zkuoGzAa*&J4>23WuEEd+5@`Udf|w0rH-h;PT_E-Z3|%0RsbEzQT_E->3{@bJMM$bZ z?8RU{#B30I1%@t=$QrOJh}j_aS}-4?3&h@op$jB(5UdKK3&cK#p$a5&8c7w1eE~xi zNaP}tDiHethANQAGgzVrF7k}42; z5r!&|$WkO#AoeN@RUnZyP>(Z#80(-MW)Ncol*0mIY=UxFL5wX>4jYKE4a#8$F?K*X z93aLnD2Efo*aPKoff!EekTlE<^A*S?*O1%`Vymfx5^LOK#`wvMAhs4*Q(gUh5Cdca zdVlGh8UuqJSQBbfXP+7a14xdUf#d&t5W@(p2ojGl7u-{0VE6!b0Yo#1Edf>sX??-e zJyK&}kW&Y>l`>#L*tGrw8wJq{Vl#k^g0^$i85pn`4f0bR*prhKm_UpMD2ExuXoGTC zK#UG3hZV#Ct^5J)BxD0I`k*rGAjSkJhXcfz1m$po7z>~rE)ZiClmjm-KrV>@yBLxb zLF}nuKEwwg_7Zhi;s>!nMxe(>iaG;BhB^a-5JT6YIw1!Y12GW?6>SYh1~K9JAn_b^ z1_nWfE(SCykZ~)pOTj`MWZMRHQ1jVf{uXrxhJC0J0uw@a5KJ300|#QzT0w(>K}iFW z9+^OlZCVfxGt4%S3I`2vl!K@gFf%7ZgMpy~%*+5$6Tr+I5H$h3GBC)2g)%^t zBA5x6P0?gvNYey4!4>X=8mRY}7!c0d0Ww7kq|Oko?vN$}!&yjpg6xO6>zpP7!xdC# zfw;F(Eq#BhLexIqjTD2E5cu+jyE2xv1Q z#Pc90hG>HlMh1u~gE0HF85s6Km>}vL*o01l`5?v%h&YH6(*gOd(_lV`0Wul2GUU@? zU;xP=_d}m(Gcb7RfZSj(A4Koc0ok1hqV_?BLG(K?+i*UJR?-D40Z|}3kdqnAG-d|Q z6JX<}fQ`!l8FvQkIL;IEFX%8ZJb`gu=rAyV3K>T>H_+HXSFfYXz+j{c3T=qFAT}sG(ABBw zGB9X?)j`Y!u_3;$5`sq^D49Xi1;|gB5e{<=NMRT_;Tg;a(Me#o;d~IC2WA`12hmkv zw()!r-3Dfx%m>jROPCl;!HM=0Slo0zC|z-Z^PI_i5G?>^8_x&PVqmt>d=M=IW*g22 z(V);q&NERu3=AtB&FVbOPC_&=a=`b)fAo06&7#Mnx_%Qzl=rAyV%w}ZB z0~rr8mXRS3WHQJ^Mut3)p&-K;8S+5pfy`lK$O9QQ6`W-AK;a2;Eh9r7%+PJR3=BKK zxo46B6Ns@3%3%gE4na9AAjT0WhZV#)2Ia7U7$=|{b`V2C50n=tDZtmog9N0Yf=nQW z43xtRVyHklEFgv&l*0;QXh1n^Achu{!wzETKsg*BMuI-XK2DgI4D=Wn%=AE&Sto<3 z)O--rLl0CY!H@GW(PLn+1FPs@FjSfEpvS1L$G{K;HmZZcMruBY83#5h6GVY5Vr2l!fS6nK7#O%9 z`lm43NX>^C4^;xP!cQMnNsK-N1ISurZOC>f=|PHZ5DhY(ks%Xgs+B%O7({!3JrD?@ zK&CS?WWo$ZI{TzVkAa~M?C=Z_1u-fKp%C6CpQ6XWFhdVf3V_%k)vOH6TaX$RV)_gW zMqrEKI%V`37!1Hd@F)WLED0L3Odv)Il*0^SQVX+<3=sabGGt(|F+}h| zY><(x49uI5{0$Ovf!f3bVz@y$%pk@FCOpEi>USA2Fn}BZV#CY^$%E`y z9ff8fOqiL0LlJHZ$lyyx5QnlELmbD*kOH&fg%Jb8CnHb{!z*tUV+IB_XgD%~7#dIx zGl-!D<* zB!)oj3}aZ20mK5CfIbTWG9>`43o=j#Qa1sK4`MHanvynun=u2!J|tNX`;;-rT@Ld> z^d}@a5c>~YCx|6y0&*?H9uPal1me21`5;z-3CJ9e`5?LsF4JVfz%U2S1F@DMnF3n4q;WW?%pXG9yDKD10XygVIeVC@?{R#K@2d3LRAwuqeojt07E~AO1s_ zAUDREf)#)qG#$bO*}fgZgr!Rls8!4i94_#*3=?Ey`1I^NOeF&Y140~9Yl2ysj^wt*v~fe}O>0(&F_L_LQJ!>m&?VPF8oIxKCX8);<9zyJyWm^@5h zo-qSM4LFN%xXcHI8_3Nl9*3!bIU1%2#z!{^W&=VUs;59{928ezOF*`PoCfBA+y{zy zFb8HVOgYRtm<|{prU}N!)CaL1p%21G=!5WK`an(t1tf|iV1nqDAjDA(fyD-L9~UNu zZU#ae(+mS>EQ4qpNaTa4WT-IA%|A>S7(k)O$Pf<`3NvM30Htyyp$Vo844~AGBm@fW zQ{X%dS|4P}z;Fi2VFoeYK{@c65v2SkIHy92OAz}Nm=76V1hLeTq16au<1tt*V6O_XYVtj#eSU`+#P!21I@dL_X12O(UIUFEHjv1)TL!4v*vVqAA zR1`rR31Vk~`H=7hu|axJ-F3%|f#IGRs5G0TzyxAEfO42Yj7Lxo3yARq%3%dDoAjQJqeHd~Nth%AWx z&lV;NVy&=8$b#5v4lr2|tH=={3u4ze!el`#klSDd1+x28!0v%mZy*;;N8*FnJQfgB z(&mF$9u^=wAgV#^C2&~~Yl8*I{~q%}^cf_TAodNgoWpz&eFsSn#1^xJ*#Tl%SR(B3 zv1DKfMB;+avF&{*)fXjeb8<6yY*lp0XkTxI0>T*Ds3Sxs&0L0EIjtmSlz$pb1iy-zrXi7<& z4`MxW1Z7GNjrkzPAGj2V#pDE)0x_hVU@ir*6kt*y1}L#Xtb-*rAv*?!2s?07;D{pw z!xcv`6GVY*VP#-Gh}3<6DQ08%wC)xI0|Q70NEwWeZYV5WBh*215VATsa7Z>Vf@nRk zLoz@V$W2TP4U8bI$H0!t08t>@K*BH+LM#{=o%W{`29 zfPl%v%taCU!#EmEQYKWB!}*6kQoqhh+Q!C^UN6-)|rFS zi{X3_y$8%Tnh&DSfZ4|LLG&#!+hjh7egS5i&Ii$7z-+VmYPJjvQMMp+%;xjhGcbV4 z7SQN5tV{v1VRkB5FfjOob2G$0pp>~C91ajZvN}lkL1Gl74ia7vJ}A5);RWGi>Vx6y`Hf#sY;TjE`wQ#AgU|Abf;55I({j2p?w78w&;oP$k63 z5DP2w85v?>vJsXH3~832tYJ7GL>GbCM)N^*1DI_*A4G#HCQx#NRR$n7C`)C5vz5vG zCR+vukc&X#pkf4+tU+v0V1u$8hz-hiprRba28Fg6xN%`JKf;NDAr8uhx$BT61H&^* zP>RU_Q7A0+Fo4_$8#ITR597nkm9S!9kh22$*I+(~ zRspjO=Ywc1FxzN8h&BMTjpu`Ckhvf?!_2Um57};zxv*RSG7qF5 z#s}#I71uC6DD8mK4U7*;KcG4q#>X@lk}DAALih-CA$)|n5I(|O2p?u{oDBoR92-zN zGMo>h?||7x^Fg!}I8PYQ2hr$ZY-hv3kYoc&*YPzr3=9h(%sn;?3=bg8U(kp_>S4`u zU|=}v0Me5La}Lt!6x$pa7$6}7Il#)viGcwUG7vt@#a|p47=Af`Tx>8OL^C*o*oN~# zG#i+0G#^CsfZ4|LK{Uu* z85l0vf&wfWCIsSw$|pt!xKNor14ETPC=d+hPqSxWcxI2jDH~)hsGW&@8}=M~28K2E z3=Dh>eW0U=EmWF7l;V7ln2ZC+EJ)`u3w)F^!YpJ_nDanx0rh`itt${4R9u3ZoEh_B zdLcYyJs>q~44)hxGe8mn$h9y&OdZIbP;~)l>cD)Mx+C@s44CeQ$$~Oh8n{I~Nr4H( z$bfQ~L5yWk4!oNWQl94oYO+JT3t~5b`H*fth}{h4L*zm17HIQ3V?Kzr2rLUx4Pq|^ zThUQFAH)FJhZ-6nkriMilN6Xhj8#w$Gl;PU%3%R9Hb6P7AO?#wCb+XFf03FHot7Kkjetsp(H)0{x;Ft9F&>p*OfPG*KaMzF0Q=ff0(*dQa(r<28; z85mTYL76lKM7e>PSuiU>I*PznK%xP}z5)*}5bFVwEV3?;PFV1O*g3G^0Wmgv)CC&^CO<-@QfT$&4 zCOiZ{Iv#=DK1qQI#K>_0#q%Tu_%bVy;4^UYHJA^gUx8iP&A|CkYCeel&Y6LMo1urn zK?*FUI3FbN$r-eU3?bOUz@Z?eJ|86f&6$Bg97#P`s*8bhij<=Ie2}D!3j>2J4h8)T z9K}-V^Fc~fTtKm!38Hks%w!N{0A?nEC@&XKKImjr`lN=0942G&8 zNmvMjG}*a;irOAf8Ec`^4Wbn1gTx$MKues!0-#fjJzN+V0$f0)FJv1dWJ~~N5XksE zXgD%~7zI!cGl+2o%7K?+Ai)wB(1JYXJD|fR7)?|;{!1|{C^RrAfy7t1Fff=hV9HHl z>|wB%0x2~BDV@To*uwzP>Hy`>2Wj2n!oXmURXg)tuyv?rKn2kZ0vWQ+g@Hksp@X3l zYD)sl7Lddd7X}6ih7Jbidtfsm+Tki-Ap`RJHK_lYK#Utu4l{^x3(8>uG44P)tRTic zD2ENicmUg=sI^0+h{(B z-UMbF&j-;U_k*T_z_xin)UbFkFo5g;Ez|;}k}9 zj{i~?Dm@HS7`qrCJjMAS6~Ej;nFg|!7qW&JX2v#G28MG`w@z|nU|0oqtHJy{cLoNK zTafKTsI{1nP-}st7I7rj4tEBIPwt?yA^~O<$oXQ>)WHN|NI*HvAcho_!vbQ+Ksl@+ zh8&c`24bW^Iqb-$DuJUKlDt4{8!#V|yg+P_CQuY2rWq7G7#Kh*g%~B59K7-|>{r8*eY;nRyCFJwUd&IDp)K{?DI#tSG1Ubuk-E5OOf zU_OYh0xRHbm=9vy0$Z8`qMm@686XN|2D0-&Mu1d<#IVWdc`z^(K(vD>kWxm5oH`E% zh6aczi0T0|b3s%en3(~hW`UWxAZiYnnE|3!fSI` zxghEon3(~hE`gc3AnFR3nE|36fSI`l~G4Sg&b zW(ugJMzANk!r17Cv7@(FnHZ4OLYg8ly{K}K-X}~BMzb+QOlFKkq+2G2i9s+qCWeXd z6Sa}uhwevYb(nI9Gl&r8BE*o6*+5~!&+9}Hg>T+KI?n}(3A2EM!C?Mm77&Js2rz_9 zW(=Lo2q~y1x=)6eTx<-JS&;d-Rq~;jfiQuOVKNK0CNFOF$ZkP4hct1R-;h=^A~Bg5 zCc+muk}Zs+5oQ|?)^_LM6@|GQ{p?EQ%z?~?sYg!m$ZTx#j0}-5VHnNG0Pl}*FicFD z!pQkY3SLMcNg^>}T0z|~7#l`o69d&=bg!CW4noi8=zP>R5V|bFlm<|v1RgNV3=N1q zf@}<^lIVPdA*e+gdQ7A9Vfv866ni5GSp_m1X2O8P0LW5O8%Hn)qsId}AE6Gtf`^QL z;F3p(qjpD`8S0SZ6IBwS3ANfnui{|pkYfP*jRDw2k@dmMLiaceL*K>*;3>aHklX@_gW#(ih;HvA6FM_P z-$Z!R8;j&_oRT~YEiaf2Rr(l|xXv@n;4&ZGNSHcM3MHaof+>d$v?KVaiH)#0dSXRQ zPcZ#NIt!$X)UFK73QVt{CV5c0K`bRl=t5P65JzuTV-FaRi-`ztkTN1XhOiyd%SG@Z zqmeK^$S;V2F7y-dFf$nFZfBTY7>yZTs6GbSfe0`3t^>MmRMjv$kg_e(d^kugA_pT$ zASp*xgD?-iO9Z3c5o#_5jRn1c4mB}>7_XolW)R~Il*0mIyn}LBL5xpO4jYK^1w3%n!v>;jd_Y4Z zJ%?ZpVEEz5!0->O0MYL<^I~8K@dAw{X6AV@Ff4>HpLj7ayoWG3ycrm{yuk|GycrlG zA!&V6MkT(OvF$nXPHv_{P2oq-i3@-+TTVO*IDts6iK+Z#I^}h3B zU;x?0$dCxq_W`UI-uwH3R~F;}kn5QkCRW;bGcbT03Sz@-HiC+wC-ooR3=ApYP@3on zuSNfOGcbtxfX3e}=7Z=^ACTwa!)XX7*bZ1_p>qc&WhQ!@!^bmdyiE zN?>LNh%y2*^UQo07#tu>C%8#@AOi!yq8T6xVkmrlwrb z>1JbSuIKoV=w^T%A^|oL*-BX8AY2X~ZVK{dV94?Y1%bhQ5DkiLMutRCoZf>9gJ@7Z zA@#ZoycrlkD%l{{X~P4w&WC}a0UXMpQ|84@rX{Hb@gFg(50>gf2*^ zgLFLs>w@G59bX296kkw51L4>BGBAKlL61FzIgn}{WR410AEb%|u|Z~mY)_dFVnIxS z$iiaafDZ!$NGB|Jg4haRQy_i->5D<)gV=H4fM}?n4`O5?NrKopFi8*tVk5*PWE(;L z1;r`IbdX;`>>^(V29RH2O$HDfq#q;)(|ZI|Ap3%Iy6Hp-0UNvWL`^h#F#`*hQp7nEMA; z+QQ6DsD2EQ~?1R>h!%6l>@u8+syv#T#-0MP|dguh`VV#IQFMv5Ug= z4CZt)+I*x^^ASC#fOdqyJH?>XiCpTSYk;K|6hQ1fU_K=Af!N#pV7uu+tbKlG_=F7lv88Yx6;>W-c>j#<+$SCq-U?_tyVG2R+fVdxZ zP`bsBfuRRgDNGBfT%bpH6lNcKl>~|eV#Zq`5dt#>Idm|)kf>^5deCRs2=QV1knKWV zZim!(MOFgShSc%F&V(t%RYxJ|f+?k8WWlUJk012VMU5}~vIsLF84*<83k!i8ehdu%z-GoyW{jE42x3Fbj05u#=0M7JggFrP$mW3bfyyL=I}GQyLEXW~ z5DU`^QUcS)=g+_(?GLV4Ciyck%!V*G_%kqUfiPhT5$-^Bf1E!9LyA8rIP2=?gBS&1 zPeL3EVpqW=VJ2nxGcaVL8h*&1f#DRY5KJ}2*$HF-d?hl7gMA1eW*@n^4mDJegBZQA zL@(wLHbVl9SUyZ0vR(A7sKED%z#M^IrlLr~6yYxbV5&fIM31Hk$R2ou6lVEAMn7tX z28U=2V(T23ACJsORS)yQKqUt(kqZi8dc-8m>jN2iLo4snH?k;=A4m;~FoiNc!kqZY zjB&^r3bhPJFQ+m2`1Ql=K?-XmCKg$k5XIRBW)Qjgfm-29YIvfmhxr02(2$r|WP1V_ z7W z_K20wO9B`ejs<|)eUPnzAU4PfRt9EIsBJfpq(N+uDJ%?4`w-(lTtN&BJVBs_(L-}PU`k+om_tG87{Govn9mf05ax*x1_qEFj12JI9w0+oLO@XhDU?C%DPTS%5rf#vzctHi3Knx!!hZ)3}1?9k%$AvO5YEm3yHK3>9IZKrou$6~@2-Qh>Y{_*p0eLk3vh7)c(nKloiJ0|OgWJ|Yai zT97)B8st62d|?a>W?=n@8&2imVu-z9DsVBx#j6N0#93=6{XF;BVc^noP zAU-G%kT*IvgfTFni^0?r*~Wq?M{h}?_vumV5Oi5)hK@@3#5Sr@m<2?-2c!&M`hYlt z`5+|t5l6_!9l<<|8KS6Du&BX=zSab03Q|dl5Q0~22qE}cB`_iM8U`lL#4s_J5E~}X z%+P^o&cOtUbx}A>1B^yLDhDQx%SAAG9IhZH5U{uvmu<-6q}q(E7Z)3=nV=GF0<_p; z0x>2*Im{r&4JZd*L4cG`3j@`akh%=S-UsGG>P8UzKp3PEmoXp2x`reRVqXUv*-<(l z!~mI(nhHT8x4=p!DKLQ;cc2_*5JM{*Qb5Dq15*A9Yy-qSAod5i{a{u&!nG{n3=FJb zK4c>>hz&9l(+MCM*vR};TnCBhK%K(`V(39R%pisVl*0mI7(qF#AchH)!vN${^AQ_nFKACv3y2Lf1<|1ai8Mex%>-gJ zK{?DIMhld~0%Ej5IjkT?2b9AGV)Q^c>>$RQa8O;1=&ONjm*ks%G)xU~5o<3L&%8PY%$OeZ4L?u9cjJP8N2uHbt{VR;g% z*Nt>s7OKTCwXi@%@FC8H@jhpHN6%ND3-m_Uqe zP!2PQQ4k3U0Jt|n$}b@~6vVy^=0ids#0F_Xwd6ts0|N)xD9-=$K@6QpQ1n7V2E^6_ z^C5n>iezALfGGwsV!)CR#UM7wd}apD|L~}Sg$t;0Ma0-OOgUyiLF|CZqxu28fru&# z(}UhdLFXgXK|G7#L&6WnC)RXyQy_y|FjLTd2oonVpg_v7w_KSRdf=^CCWan9n87d_ z-D31{SXA$!%N9j4FqD8(z$67G5TgvrVFocOpd1zuqYBDl1u<%%95xVRO%x>Q!pGS_ zrq+X#5+u+->{(zwB-%mjMUk*#2E^ivLZngxAP#D>W;Gc+O$MH;(A5r-+} zVyNMm!pQMo3d=4m%y1*7Fa#xt;g;4&?0!QU$FLwqPhP09FjY(p6Z5gLVPfbt7INV4CIgsJm}w1C2E*jh0}-DrOb=b1 zz|7E51uvCRT}z^SK+Yzo6oxOrU}ETjvtf2)hA(POf$C!PnjdBg(tt1%LjzJ%1Hs0j z1iK0F!@5y*!G&SE(A|U1hpA&?m{?AT4UUq z^vA@2=zrt#0(z=~w3HC4iK$O8yTO<#7tsyI6>mtfjj$foIn;10U85X5!Jv8o=1mHn zglZ_dmH0ccFehL}A!f=(jzY+iP=sz&)i7}iJ%*lv&^?N3DfO}!%=zd+iEck?;v_Gi zL1rQX7G^V%0S8isy&i%YL=P{ZM-w(XF}(;Iutc~Nwa`FMk)VJ=3|PW+fkJ?Y0vx0a z9#BjSh}#8W=3sL(Vhjvjmbj=!8$Lt?0Zs{+Yp@iBNJ41Z5zd5ZM-Mt|&PBKerVA8C zqy{BO54?>5;=p^L^s0N1!Ug6L9K(_@X^=CC@Fz?;X56C|JD_xlhywJyfL|772TI!t zF+PMt7`rZbiwsp4To|Sc-9P9qB&SfLI7o?UWuOdPqK7lOukb2Hk%WZ{#eN_^S-_lt z-bqB~Bh---N$94b2N@xGnC(Oc6i6Ao$OUoW_z6e-Zft{KV*r6`gx2cig~ z>%giAMF$E8rX1G|6g?{VRgkNXiDBSOhWUt_p+|>JnWKk62`R+sCJ1u{<`qk*2Xr$t z^dQzdp)1BKNs?l`Cc)f_yu1s&Q;ICd#DG{oi7Jj*3dYR9kps^X$cpe8408xd8ph3m zDd%B;6#u9pi<$-rsX$f@Gna#*1ugjyBLdTn;%>ZxYz&{$HX^l42=QTtp{D?JKHf;j zD@i?*U~Xk%=+U4C8)gRGGBQ?+V6Gsyd?Z&Naw^4c26j=x`UtCl`5C({=YIp~8^a6D{4rB*n z^a6dOD8gls^>7G2YEvI%3Su}3y_SaQ0tE&|X$)il_MipHz-Q%|7&h+z@K zz`)MX!8(OWnQ=ad;|vz)fe66t1X)o4);39j3B&;1BFV(iqkycS4#^%68>9xkNC6qt z16BtKFA&=<7UVuiNI8KH4NpMuk+U zNI^1);sFOjN5Fg#Lj)o&70bY21ZHM{!Z#1X1W}-nVqxff$}qn!mVsdoL;^(3j|C+= zki@!J28J^b2@rK2E+G@gz>pmWvN)q4j)9>F%!~q2YrxEm4RH(%2O!L2aSRNnAk0s3 z3=9GBAZ<|~DhSLB1yOgv%&0f<3=ChuOnAmP6vMy(auFj#5-9H0fSr>BqCl==WC#LL zAeS*RBwdMRV7LWQ0HQ#yWMl{eQGQ?tB!MW9D;XK0K~xPy6ht+Fnb9Ds1I$bUQUAcq zXb{B%c2*LI;)@5Rk7@?ae^T>7YypTAh!O)cqd`;zn31u4-$%wu2xC7vyi6az{;APbO& z`+H&;7(ihNTlKXkmVp5jWH3I=ltplLkSl>N!PPOB zpxj%|I3L7tfQUQAGcbU{j*%f8L_wk|7(_u5B7C3CqId>|HDCic6y}2%TfhdueKsqB zfniPp$bv}=0$lh(%6|}h1DFpf6F}@u z380J#y0Z|(dWIwmVuOrCtw=#;t^uop6u2NZNGGhj0%BiBk_WNhfccQ>8N`N}ifF;a za569?a56B|a56AVfVZ|77{oXk7#1P%L2MPI)j1%x0T%-U2pe%RFo5t5E(Qh=KE}ns z0K%8J7#Kj9kDGx3giW{^7(mzoeyI=x!y;}5hBMp@4EI24;7tt%1~ncAh7=wKh8!LS zhB72^3mygrD;@@h2p$H8C?s)^nNHjc3?S^n&An}Gp@C3qMZKp5G65W9khfdPc;co-N!cn%K(0|>7{ za?d3m28K@{J}(1<5`6zT1A`AQ149BY1H%Mf28LBg;vl^SybKH=ya!3#kB@;Nh>w9G zjE{jK3u#^S3VsHLHT(<=8~7O*j_|`W76U_y00Tpf00YB30R{#gK~(VysQ5Yf{!xf} zQp7U^7#Io!7#Kql_f#HWJ1A~qj1B00u zLcNDD0|SRB0|SpJ1H&n#6}f)G3=C<)3=A`b85sQF4KxM@ka!YQ{Dd&V98$%Dgc%s3 zgc%s(gc%q>=FJgiVAz0U9!Lyi{}o{dh7U;MAh9f{n_%wNL2@@tzDtCGVHuLU|A{a# zut5E(futUnILM9)VFm_}*}IU`!^BfW85pXN!~?__80y3r7#hSF7`nt57-oqvFf2d{ zXHXh{!^^+`!YX_W3?OX6$G`x>3j7QVAS@@qzyQK)gcuk=7!*$+yaCA^CUFJ^4RHpB zdEyKV3&auO4-zvIXJBBHU|{f)K!}6HV#FC3;=~ykDv;E}#P*0YFfbvh2dROX4U&VI zbU=cEfkl#mfk%>oK}-@R%D`|#f`Q?d1Ovkl2?mB=Naldt93{cP0Kyp(3=AN=NrHg^ zghBd2I7O0y0fgsBGBAK}f)v8sc~T4v>!cVMHb^lr>_QR;sY#MzU;yDhDFy}*o*>1* z0K$``7#KkKkQ4(02)~hHU;yE7QVa|rY$naX0K!Y885lr#lQaVZ2>+30U;tqW83qOr z&Vb*~%)kI*SI96hfN+Nl0|N-Zkzrr}VIDaK1`rmJV_*Pb4LJq|5Vn#-_`^kxfgw+h zfuTu`fnk{(1H%_N28Mrf3=Dko3=B&03=9tP3=DDd({z0CB!9;<9!B2sKp%31vVqgG;0m$zl4Dufc*U2+5 zfH25h5C*9S;S&lB3?N*g2y-n1Lz^N4L!Tl8!z@Jxh6PCC_Y@fz{($&O3=B+42=%zc zL25*l7#O6K7#K2?7#MPt7#Nz6^nvVbQexmxl@gS;gK2x1A{sP0}GP4 zi#h{CjXDFv5_JZKRYZt`?7F4IzyQK*$_xx3ETPQ60KzKD3=AM#q|Cqo!YV2Z3?S^G z!oUE+1u6^-AY7%wzyQK6Dhv!DJWGXv0faZGFff4d0~H1a5av;3U;tq;RR#tSR#9bO z0AUMN1_lszQe|KO;Q&WU;yC>stgPuJWG{<0fbkmGBAMf z9#sYg5I&~LzyQJ*R2djR_<ap+tv)p-P8=p+Sd%p-qQ@ zp$Ewx(2N}jgTe&lZxFUY@_(2f1H%?Q1_ld#1_nQU28I}Y28INEm}?jq@}TnQ;s6dz;MKof#HcGro50H149BC@@5tc3>z#M7*^OZFnqFu zn62Q1Fh9hCfnkXSM4X8T@jXy;Kx&cA!6|OZz%b2^!ij+)4#^$?YX$}d zYX*jS)(i~GtP$?QC9Y$`z+h*?z~E-Xzz}A`z>sCbz))kuz|dmDz%a#zfnk*m1H&F0 z28JUx3=CIn7#LpIFfjbGVPIggWnd7pMVN1A%fR4g%fP^6&%jV-j}YHt%fPVBmVsf4 z0|P^mBLjmIlABYI+*) zc;SIi|HgxXLCuqaLC2GU!N3zC4$_ zuja$RpyR{90J@JIrXF>lJdn0ineMh+hk8+2VeOdfP?dxsALLyr#w!yF$5hIu{=3`=|%7?$}!ZgD479ms6Z zCDAZ_=Q!)SDM#EOG1bN=H4xs5r<7iJ1*5F8c5WMJmP=;1C7y4wPDHN^ry1_scD z7BK&U?%4p{PXQ9&Mt7G5wKrUS-@(X!9P(@A)$@fDT!Q zxeIg_Jm?H~koX6Gm?-3oc+h$3=;AQ@U^Gkzj1QxSx;VN1AXgu#YyjO31Jh3_4KfRK z7XU7EKyskl18~Wsi^Jj*bcpB~=s}`U!3+#V&_g$2@}Pq}U7&}H;*tlQt|=7Ez<^I3 z=tNGCI?y4dFmpgBgTm|~Bo90GazO|K!=ezFE(QkBVU-{;*eQ{)BO*bEP96whV1OMq z3DW^m?-jzpFd>A2VH%P-ps+IvU|;~@fB*&t5Y7u=U;tszxxF9^I#3sc%>o%1K)5fE zfdPaM1Trvy@TWiq1`r0FTnoaWb6r6gbd)FvGl1+1VPF6q{|UmNLoZ?O0IlgAam=;AOwOrKf=1A`CrBq7ilKrnHbIv7nz z{8j`514ASO1MGksn0nA@ISP>s41Q2Km^jGopu@^Q7<2{~2!l?N0%6brN-%ptY>>M^ z7<70KOdP}p9i#)}6QV(CK_{qyFzECVm^*Ok!zE8GahScNnn$TVn0^>ds{MmaJQY%Ur^imQ_5*hT8ii;WaQd0|x z@^e8-AsP~sic5+Z^pf*)b5rv`N>h_c)8iA167$kiiy8D%z}(Edw0sylF)67iwG76~ z$;?ZIvD1nYbKxAYsSw>c`N=RPP-EdPC(Mv$fHb;c^X^+17#RBC=O%;JQbEiBjgNx@ zo*BedXkc(kW?+~EVnZ=V4#WhFGlN!kg49h?XkfUK%)nrdH0cUc2O9qau|et>7#hLq zkjAbUKyo1SKr2IGY!II#g@Iv(C}_C}hzFYf2Q7kQV6b8UtvP^*fyfP&3=AFc1(Fay zg2X}N5FqmmKpX}J28%`p2Bfh>u)QF8A85Ehl`*6@GB7kCO)7)bfaE~w3dRQUpZ75^ z%s7e=fw9uj%&QM!V&H_Ir;Ko4DVn;D?Mw{S*FYviFwDG0G<7U}%nU5b5H%nYc03&D z{ArLLn14AoGBa$g2dRKykQ@llL^E%%0SklHYls>U2~q>1m!PS8F3rmDKo%qe!7z28 z`DRGmLd1_-vNCLfFu^2D9f*c6gk@l0D6wT_P%vj;0L?RhV}!&nXbv2-jsn@dDJ857 zT}YEdAalS5;~|*AvCF^!x*`{(jF|yqGbo)x_%Itlp$ke+uuufag81KgT z^TT`yQqI7_@bN!rp4$%00}&tpgXSR-V}Kw3t1>V!AjT9w{?}t*U;yPgkZJ~okN=Uz ze;Gi0(6}NZtUvxo>W|UIKG0nNpoJ=+m}6pqY)J+!Sb_0t86XQ+V0=&+1zNxY!l z=pd<2W@2D4K~kT?#K2&M-9Ek8+ z1PUJ{{%SP$?f``^yjoynIK#xiz=p)XkEWj1<@pCX+xL^s_A$Y#cm_}rMEm-Yo6h!$ zFf%ZK+cPYn{L9QBO=tVn=xm=MGXsOP0<8RHVsNIj{XWc)#WkRHfuQ;=m6?HIHd1|% z&CI|s2Z>+D%)l@giQmc0z%UP~JekJKz_380fdNv5Ff%M>W?)!?B)@@~fng<*eo%R| z3`zb7GXuj4B>A&+4v*W+3=E)!5>?Rp`WZ6=!ww|(ePw1~*oDMrWnp00h~!=&76yh5 zNPI;W28K0Ad;=B+hAl|?Em;^C)+5QgvM?~LL*o0gFfgn|;zzMCFlC+O%Zb#bqep*9n3aJ6w4k8} znm^=O85r(sG%$d&DaikttPBiykoZQd3=9ei4WO}n21W)Z1}jzuh605K22j@*#CN2# z`$Oq$UmTt7%b>G;^>nsx0-fz!MrZqW)7ic=bhhs@D+2>)pnDFq{J71^z#yXlYcDV{ zJfO3C-qP7VP+t~WJ=3MXhdjgwsvmgS7#NNu!d$?}AjihQa0Q94&&I&;2#N0i8d!oV z2kG}?V_?XEkFPT_#IZ3j1R?PY(9~D3F);KX$+x4))4D&{PiOmP)7ifDbhhsxo$b3o zXZ!Bb*}e~Sw(l>U?Gr$nQUH}7w9fB}bhgim&i47x*}g`Zb)84bh-^T#)@cIUyTvLDwvS z_~$tx8!kcK1o6LeGBAJ^DuUKEg82V9AseCU7$EKyX5SVr$N>wW znSYRa&><0GNs#$akpJ&+F))A@T!OCZ1v z8?x~hv{C`2-w;jSmK(C+Ee#rfQqRW# z9$y5>v+*!6+yO;414xXKL5c^mA+rn`KdL+o3~71|44|bsAorT{Al5^H!q*OTU`03s z15AAo4`f3uXl)C~`~)5b2GGWhC!l#h21bTP9@OydL*vf^MFc}518D7&AOj1-N*)FV z&_-MvsC#zvKsL65#z#TspW%UQRs?wg#D9Wj-UpC-6&S$lp+NGCphGegA#0>Sd|_Tx z_sH`?7Q5|%+NXymZ-vHpz;Fk2 z?itiSQ}`GdKnr|lK>172+_RC7fk6S3xWMV}%fMg(HSZ%I zJUc%FgNh?7LCK=_Ymmd70@DesQ)hWqvp@2{0t0Y2@DLd^71E|`K$tvjpLy5 zA7s9m0IL6$(fE1-kOL%O<)@_pWP>`ae)183Yy^jeZ=3++U>aEd%S1D;42|C;z`)?C z4O!0uijO%0kOlal^BX|!TPFZHh@*=cl3ou8KsKtw?7NI+-hBb&^5^6Kj{>OS^H%_} zfga{QK0yYCM;Z+bpmkj!`;`P47*6UnfSLjf0u0RH18p3T>K7Y928JC`3=AOugYuJy zAZqx92r@A2iDm%LH-Ow9hbEsT2s!Ad1sZ>iX!5;i{F#D~12$mkVWA*oqdhD=ZbDNJ zI=lw7(K8Hc{wYBQ2GB+X(D*0FJud|z2MB@YLqPnWX!==&Q2iq)1le4=4QigO5CcO? z0>u9y{i;F?44{n-p!G%|zO4{s!z;|aK|%}+poROe@;OzAfdRDOALhPlAqEB;r0|`E zX8$sfejmtsB~X2~PY7~Q2xwg%$iDMJi1-DyudWF}4om>8mj%hcKr`=)5Cg+1r1I~t z5M;wGti2)tI&emtfk6yfAE^tYhKI2*1Na~YSo(7nh8$1=OHZIfb&%V8pu=@Q2d}{D z-%Mc!1}P?pe*_sA8ES+f2SLEh>l0>R04>OdwLhk!*}o8tzZQ+ZQ<#APwDA!Z{-6Vb zKpR#->wQ7t@d!yC6rR7)^s|XTHVnH!^P8{;WTQSTe$_-67(fS#NI~l_JrM>5&;cH> z_Ku?n0|RJd$`fdM0Uca~93D|34B&%yKnw6d?nxD4VED%YYFmIXBSVP@14ABC`l=H_ z4gYQt1_p1W@?trf{ALjb24e=udQ<@h7KQ_8@@LTaH_`adL>L%A8-0qP?gt%C1X>sm z^B=P)1NeXnSo-1WfD#vI{9O=(94rD_mkUyV zPmF;9bnqFh{QV%tz+j_=Xb=2Bv!6p8a-bZn{E`ue983d?Pfc-D|9}pALUyl{I0FM{ zqcE)g_7g{xSD^R=9RdZ~2(}99-V$-hflRRWOBb5?)6n>f#2FYs2U~&GcY^%42~B>V zIOMP>Sow2FoPps52c-N4+5b=+a)1piJ%18sU;rIx0E<6P2?p@NHJ}SSK<3Lxp!!!6 zjc+P}oPL-Y96^UxIWsW8;x|-+fq_%A0os0NW=N5M9Q+5XpE4yN8&E*?E6BclH1n&` z_#J5c$!Prf5|D$Ul%VC+S_#NOQn2*83#49+fdQ62PD?N__#&mJmlBYJtU%}0fZX#H zq#mh1&nO8wPzlz56p%y>A6ZG%{AnV|z~HFe0AAk-YHzrssSiQpCmjS4%<;LTrPkpEgO<{@*%D$U%cJ{~bm%|C}V`kf}9L{ddviUq~`AfHnhx_7{Ns z|4|Zh&=4&A*rXU3G!hsX+@Sg;r632Q!1AYo6y)F`Sb5|u1vxln3$%WXlY$&bu?VU^ zOA0mo%Fy^tXnfG&W1s`TVCC5oG6tpLPR-1TzD;Kk!fr zav&mTy$Q&_pFszi`7tnrK+}(?G^+a)(fGR3ki&K!LDgGILpDgk%1?VV_1@A93>%^t zz&jg2`7vA?a*!3wKjqSpgQZ~Z?LgB%1$2O#1Oo#s{jHEjEnl`tLk@_7mA_}uWgv$)!Ro(Q8RYVVi6I3|eE}N3Mh0@Q$~$gI|6qy?YWsbr4CFw+NznAR6ixpo zH2z*R{z)0gMqpTZcvA*7e|?dGY!HUYv&y3SS5OvmfEKL$SC)kwdlk>R^6~;=|>)ouMIl*PXX3HWn!?9 zhaB7o8&C6;ha89tYoCRp=}&~}2km1NWME<_kcS+!wg4Q5j0{a^>igsw7%Z3=7(jcX zK>Zca0fe9f7GdSlK9G3{knvVG~3$iYgm`d3wff#FFa z0|V%sF;M(lC@?U9Hl*%=_E#K1`sE<)8<2Y<6&M&C*%%nkF+$Q$8b}@~y%j4kFn~6L zgZf(_^Xe5Khe5*n#|%E9ZjLUg#mPmP1ts}K#d^sM@$ta{@gDK<5QYzg5#;I)W;i*oEO9B#&8>uRLlTR# zAza6Tf}G4`uv&x~B*CE6;#8peDc%v zk{NvR)7?t*lKs=tV9b!zqTI~9#2gUcH#HYZ1(Xy)Sw5+0B_Jk9n{R4veo-Ze=bN9B z3Nbf6K3UJq*u;{-$JIqInZYS1GcOzDrsTvNkYkKYOhGar-4ON8`MJ4?c`1;nP1Z9r zF|%L*n_*&R24k4O7)DTrxiOSsX$WDM8bWoM8bPH@&CQ`w=B6+POv(akj;RGqjfEvd zjhUe(1Jp%6nR%%o50s{*r51UnR4@dWB$kvGLtG7Zp`j7fg@#5J4Drc1sfk7LNyWu_ zpxx2=2!4EVNn#ObGc~eUPJVs?gL6h=ZfZ_yex9yxW?rUVGDC1>aY<^fUNS>aVqQu< zhyij8IIbaKt(VLIVK4-zmXu`XrGvr^7G-+L3@|1*!KUUURx(6@q6TbIVotJiMrv|) zacQnza(-TMNkLJ5ft~@_U#SevrA0-lc_nV3ZQFjOxk;%-3_+~CmdVq&aoVm!uXk1SjSe#YDH!VLwqS*0Bit)8=qRh z5RW7s56+PBAYEXU#U=R#@dZWs=|zdTkOZoi%;4ea5|CI_oLU5m2XI}2S~q#*7nh)h zHN^MuKmjR$a{@98Qqck&Bm|dtEKSMGM-4*{PZv}H-^AkL;FA2J#Pn1&2~QVKRFMEs zNT(K|3I_SPcm|^iIp(Dl4kiq9 z8;4p`y-?K0Z#4&ff80hs8rf+dZ`;IJE?pcms;^3sQ?p zDjDF4eS={tgPnstK_zTrUJ9(}LMZd_bb+aZ*54kUEN1!mW}x~pHMP7bzR1ubzQWij(WDfV zZE{O!qO72gmkL1ah<6vN$9OMEhmOBkG8oY5^$ zg#}$Ptm+R2Cm>Mu3KIc^pG$suUQT`@)PcnyCuSz*WLBl7Ae>}ugla8F5kq`@YC&dB zetKzYd{Js~Nq$jkaeO@3o8Tycrx$3g@19!XR9TV=Z47{AK_x5HC}=E!8#OStA*e}( zDsO2BuR$Ea&0J7PkL-JBl7<%NL8*nMsl_EAbKHwkQ}aNPmY;{@FHjQx-K$8+E(Lf6g z?BM~=ZiWU(zBV#p02R8aDX>Nul8?eti;6Sz^N>V*Qd5FbQ!rAqV?hCGlo=X?-)T}MdDalWa&&(@JEh<4snSolf(Acstgf|L7h6I-s zW#**^Ac_lc3nw0$4C0~nk&i3Xx!}S-Gug4A0Gw12+F+Rro_Qc44~vI*h_MLc-~nlA zfH1_fIM_8LGyq;$!4;W+8rDgPDe;-Gb_GLjYHo5tCBlz}Mxd+)?mGmhmVg>r{&_i- z4Dc330H|9MoLT~E{z3!O$JHe$H3gcqA>P7);CZi@p}3?d zFS(#HJ^(onx#g4=XCRzp4oV`R)0N^u#YB8+9#X+zXlMdU5}>jK5`5594h}1b3m_c; zSCFrr^7BhT=A;(EBM{m&ga;ESl%UaUXlMYL|lVqJpIrzGbD__ zHB1sHc_Zo=sB4Vj{juQG5=ciE5#WXfp!x}>657cHXDVnm2L*L#L3&YQN-8Y$A&moY z*$(Msfy)qhkQy2w1%;&rI7z^L7o3`tnp~2a;^yh*kLEM~&=6>Bh8BQg4HBJ5&hW`k z2PH*>I&13<&ab2YVzZH4n*X zP;CK=tYT5XWof=vIDuCQk z3ZVG-%)HDJq?8z%nG&2?1&S+Z(3+Znyp^0=5Fdb4e}j7M&Oy$OFrAb-d zEaABY6eG~=0;{BaKy4SeQbS{CegVg$Z(?3)T4HiZX;Eqsq>6yq1u_Vdq`^J7_##By z7$W69L!>Il)C?SY;C^O&a7k$rB8q}b5_57wiW2jR6CuM@7)`?9(&7S0sQ?WUb6BJY zrkJmmagXk-lW z5v)H9D+oLi^HOqLGLFA`mc)bG78JIBv8lmw|1CQmvQUj=D z02f9+`FZKk1O#p4=jTDISqy_*GK-VZYa%01+5wk-pvXqbl^~yjMtr~l4yue@GK)c@ zo~YF^wA=x;>Qhs|Emn-|4)V8&HzLqdQqvMkbC4=SQ&cU`CLuh^3=I)M6>n?|ZH@<* zi%92!A`w)F-0JUQooLb_8S}dS6S)o-YtX@H_LXAM7 z0(BU2UNSR-M=&&RKnFG89yA6eJ*ZA|cts3y3$*D6iWyjp$Aj9C#SHMQACeEv_HYH@ zUIDyg7J#KIWr~zA&5`O93uDLtDxy>{0@cpBr8)VK<{%_OLC%4dUXVduSbBk$uEFqJ z3HPI!0W?=b!yrEonl2&DR!AcjsvXpFfHXm%u?Q)BK;=EG>;fkrIeE$QB}{0HnAvGDB4HpyDgu0-AS`vXoO%YGO8cE&?q9Aem!gff79V z>CpK(a3+O&!_deCRGfeY5g0(j*{B|YW)!$3p2ePiAU9QlYYJ#`2ujV(FG&TpVoM8L z^FXyPsNhBno})MemeCLnFf;=>0Nkj6CIwI?fQ*8`Ee4l$;O;+kk^*Vu4wgK?(F7eG z^2&+QGQBkGH7N4oH)QC0(BLrah{qBZh#|1K;>Y5 z3Q|kT0x4%1B9;FZ;9v%sk)M(Z&ILaC>F@yu&lKc-1yWNO9!#d777(U2QO*C<4BOw9F}ijwpzklfY634WK<2B z($NAIl=zU!cckcoRi)6H9#k%ZEd`a^MJe&vJNA}H-Zw(>iV0Hufv0Dojx~cd*8*}% ziw(1(O@nxICx&>?JPl-cwK%a1Jhlp(O2SrTgPjJAZ^)n(JW33~4#_ReDTb7jKCUhy LMVaa8sYMI`O5xjc literal 303485 zcmb<-^>JflWMqH=CWc@J7|#SG7{J2tjDdl{gh7FUg+YTskbw^@zXc=*#k2ev7(ken zfq{XEfdMS<=g+{vpwIvopTxkx0K#lgIgt4e{23S~DKvmF$QW)e1_pF_28Kok5Ef=& zU;ts5eDz@lhN*`c7$zTPV3>HAfua8}14Hj&28Qm#3=Exz85r6RGcdFsW?*PO%)roi zn1P}GFatyFVFm_}zRJT44CRLz7)lQ_FccqVU?@Dyz>t5Kfg$%W0|U>L)k2wv85q(J zGccqcW?)D@%)pR%n1LbwFatyEVFrfi!wd|OhZz{c4>K@?g4L%B1s-N#@ITDJ;Cq;X z!TT@+gXdue2KU1Z46cV67@Q9?FgPA&V6Z>Tz+iirfx-GP1B2yZ1_txP3=F1+85oQY zGcXt)W?;}i%)p>~n1Mn2Fav|;VFm{E!wd|nhZz`@4>K?*9%f*WKg_@&dzgVi`Y;27 z zf#K{S28Ppz7#L0-VqiFah=JkgAqIxShZq+$b{=A2*nWtC zVe26VhRuf<7&abaU|4^Mfnn_-28Pv#7#LO_VqjQ)h=F10AqIxUhZqToUL@TuEyL`?5X#`j;K-oB;LPB{;LM=F;KGo~ zkjs$Iz`!8E3}PoT>JVPRlGQe*;C#3YKONPq>yHkhq2I@Hr8KFHC}#oreuf=Ywr zeO%o_;ywMGgIs-G{X#J1gFM|ma4CT6cX1`4AG-qQNM|3{_+ZzN5Klk%U{t$7yx z{y_>6zWy%AK0je(U|<#M=k4bo?x*1F@9XR6=YnFl)%3gk(mTYf!MKzaNqa1A_>!v%jC4r#nJ0kk^CPh&R*|)piDk zM&5AVAXi5he?Ol{gzBffmw7`2eEc1el>g)f$-DT6`yq?}1B(W^2D>5$4l^G}ZD@dd zkfRICBMc0DU{POJ-(b%ugeXX*Bwwhf3x=p6pHpZ^2(s7Q`2zWT_@HSIq!Eha_#*k7 zeOw)p!zB%Dn}@4U08|l}$^wf91qXYAxk$toundv_j47xhzwi9}v-|Hqy0>58(SipX z9=&?`?+McZ)(O0m7Flj&zxiG3(V~|d9x)z}owU|+6Z^yO%olj3c&k?)sJp;7xnUgVoHkEi|Of@_Tr8YVL^2~1*Sn)G18WG1G`4<<}zVQQGHz|`@$VX`9A z*$W3B@J(6F^I+m@l@Al&sBlhwF!7_xhl!t5IHxvD*wD*fw3>1m!HHxiGLgaBtez`=Nl$gFf{+?I?(Z;VR8jS$J>_uAb&S7{GIym zK*PiUhPH%;$pH)v69X9<|Nl7;qMQEzIWI6Nj6v~%!sG<74u#1M49#yRJZ_k*#x-HG zI#(MgdXU=&oz2&(mWeH8GZ z~$27vqtM2L<^LykXR6R8kiFC?D?~8}Bb{F!6iCgZmTDPn4g?KapeV9mYQs|0{QX zJ}>^ve53w~`;ADtVKyfQ z6mo)Wmw5!Tmt`V@a^S~A!$MYtFKP!83=3HkKipwtoc4y1XEMlCkZOpzAJ2b&;A|An zZumu_3E`%5jEvJHnn9{SE>?cvVG_hX^V=K7x98t5K0nVfm1oLzWsa#3Kc^{Met5$u zrq4I!x^m}a!GN3JA?9#Q1&P2gNCzl{?l6K(RTMR3UHLJ|ppbRK$6t(!0fw9^{HF4t z7!f~kA@`VPsZFo4>DP163AVk@czZv(Ac5O`Ni?T#KxJ*H$Q^%SfXel z>%uR_2b!if)K4@q_&PxGroz zR`re_{$QwXcrfL`qn95Z-DjM`C_70pz`)_*caEtI6aT7Ac(CBXh6i2`I{0VGuae&_ z?=|(}cZY}JZw;O}Oip79n7n{fVd6qgwf}$48%$ovsW5Q?r@$mkF^9>iZ0i4?omY6M zFgcA)`GEqGK7}U=P@QWT)6~n=9k9xE>d(?&t-o8nVe$gbhKUO~+d!qulZMF)IUAsM zVv2%%G~o%zJutZmQ1y+ITOK{K{K4M&z2RZQ0$j4<}4s!r3r6jjjDHDXyCE5M*M*U%Lan zk2{;Y9(6T0yy$Ljd)3pd@X-A2geRa7GC=Yr%+1*Rp)fg>t^NPA^B@gPam!dXQ5RObir?uoMdu1DSnbQX1O^Eau`;4@%7-w-gYm2b(#dSVnh?!t|LR zKfw~5~=adiV0S5q2-Jkqk2VD+Z@-N-(1nYld)58mfmW; z-6|IP%NaeS136Q~OW8TTtY!qID+8p^cEFOxVPXZ)G@jXB)eh1Jiu=sgs#aJU0g1!Z zg7OV6IZ*84k^`kfTyh}$L2?C?(%3GL>1I&g1et-&&G_ubCkM(WxXg4E4P>48;RoX^ zMg@LD`NW9{lNWF%OkBvB_W#d$P*^2Qgyk1%_)cNc0!~~mp;nB5Tn(y6LGDeFF69Qr zIw(bh@)f8J!ujFkIp4;(#{9;L)?46OzO!*wV;BEy`5%m+7QhPeo$NQiH$KpUm+-iA zp#KE>3HlQ_rk-rN)%3dQPgBh~K>2?GIR7_HoNjdTJ55|cPW-42LXlR`Hpx>VJ!-NO@@eR#})B5xqq?^Pi ze7=oCui*p5fQ(PZ$`3y`=}&m@gYgCbPkDz%!w3HMoF5FJeE)cdX2pPv?>o;c-I;w} z=k`n-W+^Fiep!AV;u1r!OBw|yJZKC+xMRlW={WR)+`;jsu-E{;BFGnp7;UL$8d;? z_g8t~ZWhFT^4l9m!*7>8}vHl^@gJAb5=*)88R@kss3^l)%j~{Fwd- z!Q=dx{sh5$_yN+F1GVR2?rdm=^w2n_Ha_@zzUjf|^UV)Fo^N^Z{(S3$x98g)yguLl z;N|&_2hYztKMZ(~@Sxy9@B1l_c&7YUMdfp;f&3>w36w`V3=}@_PXN`p98)`+MQ?XD zHcSS!-$5<+hJe|=4U_+=Oql#%Wy=kSDuGi96aT6hJOK6f)C-K&oAiG&zT^Kd|33bg z?}WyQf-whh$@t@xal$EMic>}dr;IdC89tmcj0ZTTmYxUsOd<9Uqe8P_6UWp)j17$w z8z%}fA7}{fFcA3A@PK1#^8LmK98>o&Ha?i}h-b=FMNl}tVN{&zsBJ^E3XI+P_pKw_y!A4ESm+%R#9N~3|{#}gl#3?e@?8(4m6n8={e7|<}8 zL7_w0^W(zHB}W@3X0WyX{dKnUJSZ&RqbO{QV0!5Hd zc&40JQhj6cz<#p+WWCoAS{+L3J%{iWALvh(pEQ4R|75-?{3^ZM=WXYi*1Lb+{?=z4 zQ#Ie3JOb&}#;KMAu9k1g7M4aqrUPAXIHq>qYk9^oHQ_@Tjiq;tTYCd8=O<8Gp=LwkB|2U=|929H^rT`^%;7p|9%3;RLmX^vdIS~{8qWB zlk&U-T7GzbJt%UKW#-3?Iv`tW7#SW2Jm8z6!}^`^0slw&hUU#vxOD{{@QBK?E`Zk+ z#~C@NwqUUv(jw-Vx`Hv`QNaUT z)Q$(U9{dNh9=!STps}&9zOfmSGW=OUdeB9~z@jhTe|el;H&v2y_MC^m&>i!*&-#{$kyC9a_U08Z(ybE#_NQVC&NJjV`Or``Z!#9PQ4Wt6K z|60R%{{4jq>@P(h^gOzuw}Y|a<%CC&(%ue?fqw>l_KsYAoA@j?G&`APpLzlY~CMA(7GX&#;jjj}FM zQJB0?MdhKwAS%GgSm8%~ENYJXK}Fa12@QcxK`b&e4tO_3vJm}FsKapeVqk#YZJX1226(%lFnJ{soil#W{ zm%9fH9(3wYc)&PaL)?;`^NYg4jEA6d1XP|1Oj@LJ5URJ;5Y$fVFy#Egb`aD;(>w?g znQ;In-!OTBO3Q%yet83K_uV_t zVHo)7;Dg)e9VX6J379xXWfmi-HdB~9Tg71V9F<>;58{9MHZ&_(7_vHkYlE6F?R+ZS zouHBuY%e&L7OFT*oURfuafV95#F;7u6KAPBm^fAC!^CMS3NH*EG(4R8h;!-*eNgLh z`+>v^AL9yCtO;BS5O!14$C#qTgR=r%e;#QW#_ z*ZVt6o~{xwd4@{D1b(FxgJw zlJn?p!R33W0}T@ws`SSEZ&kIbNts*dKj*7sf z`6|uO7~6X;1+KdjDz^C?BDEbp2XT+w`G$#$R2mHmKeQV}ercFES7rYD8T=C_&s71H zARt>nM;s__7jQ8#zo~tP(JJiONrC3WT%+Uht4x@7127F{03D-?qKFyR1u+r`R`Cg*bb&X zC_^#%*MaPZs3PwUBtAwJd2}HC3987o1G!I8MNS<^evT@#??C1YRFO>w@?WBgEIW|; z8dYT0f$TS^B7FxE-=T^G9q4#-;K9SUUmiS}*eA~U#o)lB_b|5OfyWQOLd7i(Jb4UZ zH-3Ej6vA@+`0P1^#rP34s(<2E-%=zWtIamz+JO?UCw%+P~Gv&edTc6H> zdfSeVoaP^3be=zfS5T!dXtw{O^QsRF9(*~k^1$H1$Meb$3?95Yuk^s+!Rzyi4-6i> zIIsB5?18`}0abZp$&a$eGd~C_OMd8lbMV39^9u3y{y!OACx%P}jhU?c46^GNBj?nE z52l{ii$j*P{0wS$K;+ub>!8Rfe(!v9Z&TGCfdvN%? z@^iBX2hQt0HG8o4y!sQf2fNNIJ~n%>{k--=vjgOkMD3+k>VDg422?3r-iE)-zdj`hzDw9tbQFT-5t$ z;)Axu(--%@pZ~sL`NZXo4;q?hyqMfP`N8yNscAivIi@0JD*GqTpZtFE|H%yxr#)(z zyisMs@gOH~9WtyK}2v`$4}(h3!jUBXRmFDE=` zTRnYs*TV@98rDx-|KQ0_unRyogIv)0qPe;6K|}L{N8cU@wf&#?e&YOz{S)~o@bBZF zAU{C@$sPKW?I-(BhPh_KL=Covi7Qp67AQX8{GjllgTG0;Ve(3q2@{v9%v3)3afbf% zg6RgFUpx-X(4SM#__67ChkC=$i4Qu}8zwJTnJ{sM%0$8X0~02$Qkgatl&6~yD7?_r zR+zj>rD5V)l?fBqsW47!n7meH!sK--?FBQ{JGBeHJeasq<-^2HD(4wNa*&WvXa==C zR;V;gT&e;weW^;vi-yV095BE5Pqd$?kK`kPNe&#KevA)?z$9nRhKb8nI+S02?0G%q zLBr%U&Iyy#IRz#yQvsRk!wD*#-8f+`YA+D{2ywB}0}cLmgN+}iO?7_Y!LMP^@nzan zlLr?39tH_trcG6SpuulpVDV+zR1E`#FVm)iYV&DRVXmJ5cJXGFW#>V$wD^3_bA-)@ z&MQ2qIgf~YP?&>4eEsD8kTfuHnaYF*-3Aj`8@~Qwd>Q`_++uk!alOiii5pZJ8XE=I z9B6pbFxiz&Vd82PgNbY4p$Tcf=I6!f~MWz0H|8s;tE1>Fw!L%#e)$j20kj;RkOepdM~@rw$ml;NB@<-hWQ`E?A_9Y4eJpunWnDgu+%faS53 zLZC2PrUEjvLwVyTfk|6bK<3t+UBehQ)qN@qgUaiLp9;V$JwWY-pS}r=Y2bc5}9~@FY&|Dv{u5a)_MckBK;qx|dJNBYV%L7pC zY*U#qdAkZI_P45l`uYu%FRC;l%RFqDjF17fjd0Hof_lq(;PKfWMu&+PRUotSGr((8 z^w36G(Px1;rv74l7YE6YHH;T^zB3+Zn0d8F^*Uqk+wi!u&Xfoyeu<-m3Mup~y z&7hQVQKjMGga@)L8{>io z~ZU&C1PV7uOR#x)Zp zu69A)y=%(O?;v+I7;}ESrF35^rXIKR9;l=ZmaK{exthyC*(@O+dJR7rVoj*)#D-xPgT zmj{qh#&e9^)A*)bVRd^D@L)S5s1*R>^*7FFUD>*;wPEr}l?jtisVta$T4lrJGb#yB z3LbR6neyn_6_Af6OgyEsVB%?&4HM6(G)z9LGGX#Ll?9W}t8AEjK?O9v(fek~ql;J8 zF?z^mcyRw5XzZ@d=;DVa(}N!x zOgTSJcr}B6l7Yp?8T#|fCm0)kXs}ZJ&=AvX!0{mxp2BZ1_Dr7e;NZEI2OyT@DEnnl$T^*x+SoAhl*$a@v*)HYHcULNGDG;px#^7! z6VIs35I%e^gOT@*$fJ114=>j9ZItm~yunyIp_lRY<#yF?jE$4?8Lu$TnZT(tY03l@ zPMv8}rcIfkvhvd8DHDIaQ+e>?qt3<$uhsfgzcMyXj%WPxh|yM_{o^-C9&C6t;UUYp zgo!6qK0M3^kHkAX40zD-8njC43ai4z9V!hI_oy^X)ez_W(s5whG9XKyeHP1BhuG`+J?LwMO);b}S(g{OBlY6vel zD>6-IqR8~_Mh)RvXGN#!Ocb5o)2JalO|$ z^H6&xpHKnSa2HjaF3)fnEFCE_k6>|gDNkCGtW0n+@&&M;y#rLQ#*x|&QF+lNTpLa?!3Xo-6|6% z?pK*G)lxY8{Dg^zRV;;r&pS*!qB3FPQI!c(J%xSFPndX2#Z%bh{Dg_e!6MG*Z!pf8 zC^+rUM9``!pNT@#A^Cq7W2m}|dc3x$w(zt$6DzeLtAFk=&Q$MEpQqiVy;)mf;zbn= z1I{n`2he;RG zLjS?k2b1@xywL^GdsQBQ`TJC!fa(1z4U-S39GG-ag<@ZDFT2nv$bGgET%v%|*Q7H)7!wN%NUSWmQRf!iW z7!6)L=KCm<^l+Kp4aPka^e%O){$OmJ+|S6ZvuVl(6>gnvQ?^anpz`m+<|!M0ol!aP zFHfir*VvPIwr1rn3=LGFmknHfuL3HP30B+}y0*q~59C(%kWA!UMlE z36BdNh@5SBJmJAQc$(*#a)lMt%7M%bfkuW68kNnrM&Vp<7bW&ozw#!y3RkqD5$bTe}#IN{)7h+`Y!6A z`6U?kP>)ns);CsHQ8!gzGvE(o66acm5D0CGj+1JF9Tou3;Xd_C{{EZ_mi7q8BrpS)q>Rh0u1 zuc?KCxhia6-m{$yZfA zOunY_VDfbphsl>z0w!NpNtk>^1vGjJilYS+FRQ%Le_!z7!GoCpz6T~=QaLpBe8GhW z2V(B~KIrUde4z~r$qf${#O(K-Fs*0e3+)9Huc(~ThpFjU30D!Z-xnnR;lYEr|Go{4 zptdB(RBUUyq8VQ?-eDA+=K40|QPSIzM`sxsr~hG8XzZD2@W4V_;s1sM3{MpQuRb8~ z%=`+4LG&eRKYGQ6i4>{1vF^;LQb%~&U z$18BZgY}{Kqwkj>rR(=cyoU1Z2fy=85#Y_f+@b9G!C<1Oy23;;bE`y1z86V;= zcPI;fD80Pk@+*}738>6_68F#l-f=_0x91xsimNvnczjR13}Q7*7EqsjrD39gI;aM^ zcmUKI6H(`z!oz#xyn)5WZ+@3Saz`$8Uuw8={=7kikwL;YkiH2MCDeOtA3vDK4r=c} zXCx;|s`E{`!ra5iFrD+uj`IeWcQAt1@Ep9@dTHZ%L&5du1tyBC%a^NMj=J*XQit-( z&jOPVvj_^N9RRgsMbzh?H&*8S;(fr#fb+vlusa(CRSpPDlvI~5;QTV-e53w^OAQmn z)IsZD+72w3D6hU@qJp~Mw4RBA)4S_IBWo%zgyw%>6jXT|`NLPB>A^&K^$!yj)EgT6 z>KmFH9u!`Beo6L9&Uph1&5uSFoFCH9H%ydN?=MKb1XC&4DD+!UUEpWKgXl{aFE#3W zTxxjWc8T{A)0IGodki=~_?&NiplrbTq2WQpWFhq{=LIGTsy9p&QtwbU{4A94UZvvepc zet^W3*7?QkEa#BRv(d{GcK;ZUv#-q@Y8wF zdQj|UWqkj^*f_DDvFoDZbcN}e-y0s>2DK?C_A@qK{Qv&E)P1fqqIX$2KkPdH30~5` z{E@@h&Da3)cSiNa0~4jyFHDqCKOlaQUE>324Hu|&_kvO2fx>jluY!U+2lNlL8ch6n z#*aEL zq&{*eOkeq-2=Z=5qz0`w+)UylNLaOb+ z3r2ojIo*popwPM~zzYs7&My`RbS^du+8q$M*eIxWfbn9Zpd-}xA27m;V`{4b<3|y& z${!a%q4n}Yqo5{K{m1jq&x1m`Ls{~3t3l$2=NBNM1*+WZeBeh4)s~527eH&`kVEyZ%H=7raJ{I*ccJb)4>(-Qv4ktE zjR1Q(kD!pTH=n zq8Dr7>oD;cOTfhAEbV`V4k%2PRX3O{r+%8TY3ih@6Y6KEH`LEi2laUxCd;c&n5>}A zF;y?x-XEqeX=>5bg8DM`g!(e|jQD#06#i2Agvs*i1z?q+uy4pXd>@K(23kV~(=iW8M+;FpT9I`0R)9hr7Q&4QARZzw z2sA-ln}ehSQw<`H8XH>@8k=E0Yiw+&X)xjZ0C8zUgeTk-h&ot%1+v>hLf@-7v)LT3 zMi5>fc{OG>ivLwOfT*Do;dTf$2{*ygKuhz~W`_rmwCvDqI8C6b@d5t?NIwSD?r8$e z)IjSv+$P+|C?z4ir*C>`%A8;94&*R0Jh;XvGf_}^;>T-@g45nk{4-H#y707~iNe!G zrp=i+$$;aF>wy^$JsyHqNCbS)cwq2g!h`woO8mz1dgAu%7d}tXR@B!oFnFM5V8}Y> z>-@ThCLdWVzIG@xerz;2`DH@RJ3T+$O#Mdvg8LoHk{|iww}M9!`2~-h2l)pzFQ1>l zF?B))Xf4@0y(i}iXFTwDuv)zmZf}&F zCNl{{gGR(abR?7?2&HF2>4{MKCX~JirI$zV_lKAO%DoWQ@+goPTf_Ip2fFX0{`-S+ zZo@=T_4fa)2YA3GSch`rhsJvy$|pbnJqszv6hE|r`F!VKDdEAyV=Nyg9%p$F_22(M zTjKs?(9S}Urk2LWgqCLC3&9r-yt(qAqp`odqq(E8A)}*NV3LTsz$5{6 zfk{H@0+R&QI~p5OI+{HmWISnjQFRYYKPbD`(b|yG(canEn9vFCH*ieV-~MAt(}M?Z zK0at_fA#RggC`RgyxH>L*0eX1Z%uy<=HH(7X7cUnAQeJw-H&HI>Z=!<);oF5Wbx^( z4|^szJ&>5zGg%+JLsM9N6*wI5o#u^P6wII(ka@h)@k0!sLiC!tX=uJv2pPokV&Ai zd5~E!wX09TT6T~!3u2<>ho%RxQV_I{^baGdd5xbN8#9}$?x5F|ptfpe;|y_w51Gx% zcl7RMHZ}_0KHsJvdZ*#Rb?{sr#C-gr;CBa4K@%i)JM!}2cpWJSEaPB;)1_zDsya3z%h7nX2v>3ov z(fV}8cII`~L&JaN=gvmKJDztslp8-o!h1Pb7sSOYzy4uFjjzOyZH+%~+urF=w)_Zk zufs%H^?-?T>c1G<|60M_tI#;%K@-@$C%>G3fB!v5B}j!FScO6(s9kFCKttM)^X3PL ztsGN9YXv}Y#4&Z{?GySJ9>7e7>iz!+>@S5zg9pmmn%_Ha!}P&?d-6Q;E{HdbEO$V? z*^b5u4-_U!svAs{QU}dW8-mvoL(&1Lz7L~(V9O%Oe2&o>x-{032R@!RX$EYLE0;it{FL1ni0Z4Q0U+Y$bxZg=(@-R|mFy#4nMvMsaDgKeZk~UDaq;{D-bPtLm5H*O;4F@*=p!MZ(YiN`8I6^VU5&FF zK_i%rtP@!kzoa~>eB1qW`UBmE#_vI+sfL$58KW3yGp=D={%Yfs!}qfpYZ%wO+wy)X z;}pgn_mA;imwO@iQ||jewgZh1PDowkc*xQ4;s@7>rkhQ#ntnGOW1L?O@;9tE2-`Eq zF?IX-o`(}2Z8;BG>De$@Mq$EaS%n3Yf-UFRx&St6R>HnDyG(4E_f^m9p^StJDjIMF<{+Yd1y`cWL;04hBr0~C7 z2lN{)T0vv5JYQxp{$PB>|5;w3NpISd2agY}d9dNZ!zW)JZ9i1Qn9bP5_=i!fNxZ4K zvGMK!h;tVUz`ur zG1O6bpkTD%OSe(x2ZJvSMv)(yjWWL|B5&utSgYfXaWa1M~H#CG6B=I{<25vmQ`*Xz+mPfWkwg z2R|6M|3h^n8`zDYnR$@=mN2q|UGQ7?fBAmBZU49rXzS|LFBJ*+vgIGwflYrnK>Rw^ z164ZOy37ZvbQlkm>ZttZJ@Ak56=)AwV}r5a7tK1(14{qd4irx*p2BjVNx!Xv^F#3z zWl&%7Kih#QonjG*FTp(F62&^jA_>sY)@h%4p?Hc;>$mg8A_8B`B^VDF>Ztq|Jg}V+ zG-spJ-gQBzRq4Oj0mc8!2Rfckc))a^dmn*f zs_?>65d)Cvk0(6Hz7RF#$N5!LzCc|Gl25#_P~h8nV+GDHvF9K$9&y2H%J=i%8QU7C zH!>Xn)l53m9z7H~2x>VlZ(aWP@A)OID-xEpCj=Du|2cby@iZgT0o{qL7eFNgs2ot! z2dOk~HUInfyh*Ehy-B-ytKomn17?qn+AZFi>^FR1+zyd7er(hZ8r2eNQfXFwtkkaY z*6@MKe&cq=X`uED>x9IB0tZHc8{ZqIPMF%qKVKds3KpAyDhg}QNa%Cwzh>-iZ2Zd% zcDKTTrvCy5{2JpMbsB9OL1jzLmlusc8|Q=9cWX3THVZVf9eC0Dv$av5b84ry=6AhD z`$o{(Z@p&w=0^Pq;5|2>It8@$WR<#xLEuLP!^V#@`GvBed9W_|iLwi2v-k^T8)ZQ(g$tZtGN#y1)Ow&cUr@zB(jeAw^1W~8 z89Ao9>AM#=#5zvi{DA+$$?xCJyXpHEIK+AxOMLK*HT>%k!piTj&To0JZ0hu> z?NiIArcd29_2hSk>EPYXQ$e){mmb>`&`gr~RCTai5`VFLi~Lmi1+pAdS@ov>7W=|5 zh5thMU)Bq*7uf$WU2yxtaUfu-!&HN*ic{_V{r%(pIi{lKM&fr|pOU`K4cc?fIYq0( zvcsbzz9p}vwxy?KcFU@koh>I??l-(^_}jqKDBZZKacAQ>{)@68)o&R&rY?LWrMF6Y zxAb2|-UFZ$Bi_mXmtQ2lnf(d-S9XODi=;PmKjHq$ohDx{-yuI!UTR9__k^hhQ$gtg z=|G#tZ%;w|EnGE3s!{X*kI^7C_&GZHiN;*Ir8^i1Lnjf^Zc6(DC+ zA=D$QGKe=aFf=hRF)}r@G&P5*m4O}s2yz?9<3{WZ3~e9=6hq`2g<c%(H@@f{ot3`PtL46isC7(iyTaYEFC z%mU#OuzB6uF!O{sL7~aOAOfYuptJ;(mV(kUoRH%Pm7shTD6PiHz+lF}z!1X;aYqIx z#Ql#r85lrzf$Rif(9wxZ437+9_J(mm?2X`pm>b8%z@Wguz);5piY<^12vz~RH_{lU zua657ej?lq3{xOVz$EC5D<%dWQ<%CH+zbo`3=9l6xEUDq7#JAXco-PO7#J92co-Po zfKmuA1H(Viv2}b53{^}F40Qqw43n4{7z9KZ7^=V~LI}_?TTBcE?l5z^L?Hg0A;Q3L zh>?LINQ{A@2%;1mFGs{6;r>93f#CpD97I9lks}CZ&H{0WKQ}<>1L6z}P7DkTf5aIW z?tnCa+|0nha7_YY-xCRlxlkzv5pcN3gu~2(iKl?Yr@_VlNiZ;gj@sjpWMI$$r5i~| zda#j%h`UKb>}`=`VCVsbhZIDd4@yf&fwB?*>ePJ4`(vWehn!G1{($jh7>6V z1|0?lh6z#(U^gz3g4nlCih%(fN74)oOBfg!mPs=(fa3O)G{jw>q#^45KxsA^Xna9w zBN<41Cdoj|?~{S3p8=&8$w2Je1m*96^3TXX+^cf#IAXBph!U zGB7wm%>q%NxM5;o+yygF$_V2BG9yU-2B`sIh`m+2Vd_2^LDEs3F#`iAEj}`4V3^0q zz))k#zyLZ4@0ckAgBAk=!y70qWX8a-0AvspL&}LI`(fsRglBPrNCt*u5Q;$nT4l&U zX^=2P--Bbw`e0|y!OBxRkU|CqhCV0_qCjON6T{gvFnycM7#NyBXSRYQLFENFooC#G z$$zqdgdbEIoW_|Lp2Ou~;t+FP?!)wbu>c(z3zLQ9WhRF5$1r)245(ZO(I5=TU(a76 z%bx&AFfcG2Vqjp9vt(en0p-7d(&+pLQ1Mq#8lC?RD*l6kf#I1Y1A_xJJPV-oBdGip z1_lNJYX*iqs5nd>Mi)WFLFFn)3(OrLHmFQtVkl!~WB?u3$-t0d1F4^8*)V{z7{d-5 zNV$IlO8>Bdl&4v?kaXK*3kkO^Q2LoIBpuq>F)&y$Fff$aF)++vU|`^}hm@O7>>>Fh z!~vqO!GVEc704k_49SP}0x9u z$PS45D{?S%-Z(E|G!8(_4IqL6QXhesF!Mm+1meSJm^W^L1fdvG zA2bysyGIXnjx+-#K0(T0_JYc25PuPfU|?W41*Jh0D9)G|X0{=lgAo6QLp-=0yZQ|{ z#CbcgtIxtAejJCmN+))68ZpFcg(2yTfq{k52h^ch#m2y}4sk&z`(!?YGE>mu`)1lq|62JK}VOeF>&l; z0YwFSC@%v8$3B)OkV(o6>}JSZMg|U$x~B{b44gr(!60>@6T!K_amhV{oq>UaV+Ttp zBLf4wq%i{n$1b=r&p~p#pTPD3^mh0mQuk<#Mv;fw&i;TrTz+5cd+4%gqByPE5)?>_VWB zzXBEJW1j(1brs6x=K-Y{CS?I0P_#2C3-N&Bj!9XB2NVHJ%3?gAP-Ie;U|$K!f48C9 zq}U&UV(ku;E6x4^#JvmU%CP?faqmI7vg|yd@VO7=%CSp8t^-N7&CA@fpRSvc;!Li^%NY30zr%n42&EvSfp7Q z7zB?pGcYg+zGP%z;1D$9U|@V@B%vn!w&`q zfeUOPTg6!&LAIuVdLx3{xEUB21t+mEFfa*9a4;}1GYC8b332GMCW2J$2Q{q)<=7Y) zSOnFDATvQm+-Iu-8DRpFx(_!(0htRn;y&9{kP)*$S@%A~2#}c!+_|8*=eWss z6J!hzD9PQ18v`!B??AbXJRtuvDKqha9L=Q6!UM9INtum-_aMmA55P8XS8_5iNN_Z< zM{zJP@Vj^hF>ti7!vaSZq^=dpWn{kx$_;H$E)%;xD95)$xy=0jp&<+$9Z)U{`!bMh zCzQ*|4jSy?=z?V|UJ`91v@IC`Kw4oE%I3*~aM=Ym|(2jz0H$Af~TAIjy1 z6eSa&Tpso=P)45!6)~`bQzncHP7@#5S8~8o=0|pL%1i?dL9#J%d}F@|G9m|* z6u-fZ2u9|Djrhj?24qBlYY+p+H;54+GeNHS&JG%wW7h`7%y+mE|3MysaluA>XV>Qh zxx(3zf#W;G2#}c|BYv=lb22cn-vk-)18&3>WG>inF%uDCp)MM z&Rz@35I^BYR3LM~M*L*o3NgZ&f#WB{2#}c|BYv^p1-SxrF$BjixDlW+TR0bN#4q+A z5F=a|IDSEl0GSCgf{{aki-CdN2b3TfIbhiVlz%v2T(A+09M)V641Btv=w##o#|X$w zkP%EA$si-Pf?Uo7HzEU>3pRp@12hiF2kIzrFhPs}nF%t2nPVBq2t81eW`-LfjLZca z!OU?GCiWf>_X?ED%svUky$a>BK-v`7pj=k=N>I6Q9m-_`(;PRz6q7PL z`)QDSZ$h~o?2ACIyanZQva5o!`fVtei(Ld1pLd{KXc2Q4%7qp&_n=%}NK4~Bl*)_X(6M%w7fJK812c*gHVnXHc#v z`!o>uIg~5Lz68X50p*IbZvt^&Lb(#`2SD6cP_87TUGo~sg|=(nK)KL%&08oJ+OByA zS? zG82=s4G$83nSp_)6vAU-5aQ;^dj(R&&CbBUQwg#V6n0jr3=BNg zApbBavoHur^Ca;LFfa&rXfZJGWXJO}Fn|>8FJ@risRvoXq%6R|{DX^ufu{*%m^dS^ zv$X&NgJ3Q@s2N(z0&4m0W&^c+zp#K>zRXFy3=F&pQUVMNLaMw;tb(8mqgWXjc#}ce zKxQun@lrq%Aa91VGcfR`iwlD66%>97lFNYbgoSGu85nr8Av{rGPfi8~-W&)|9CR@k z18**bCn;EY>Kq-Y8D0t-h3}GPgeL369WTp0fZ+n+zqk;8e)pVvDyp_ywIeh zEc`>0fq}P#4IBn43?gQrL?j4JNc;>EjFL>Ef(#5&jGz!U5@cYI1`{A2gCr9u7A2Wv z1sND*7(teSB^e}{>;xGYnAd`QS>`6dz#!`g$|9fn_9_jtDU@ zu!6b?%Kcmn3|tM@pyGEx;-H+a+zc8=m;lubD%<#dLD_(jQF$d70|ReGfFQ^Y6~^m4 z3=AyZjEpLb+@MaSFNh_}&cGn(24Ym48Sqr9Cc$(2DSPSqi)P8pw=BLD4DY{G2dm|54uwf z)R$zw%T^983PCM)I2Y6=V!q1;8gS)w_6uQPzRT9mz`(#Y9pq>>Cgyu=OrV}As4vNU z4{ijgFA3*@jkw1q%gDgM4eCoW--8$dGLwOgiTOU8E64~?Uy}Jg+z3!#63zu1ai1*# zWCW-$$$TGT1jtMV9&lfh`6e5v2h9%ZOETYv8w2V~GT(u68F@keWm0D11v#2YnS~c* zGpH}g2kJ{QKLFbRtpWKO1Q{4uT);V$KS7j%fsu8)5EBD~z;1p921bDvAqEB}0XHEA z24;bUA`A>H0&Dmg7+3|~3otOS2`C9NFt7`7i83&72(Sw=FmMax3otOK2$b+MFsL#J zGO>Oz2PGL$J<9qCltGx38H7OfDC=hkkCB0Sw+I6R>o<^3=FIaP@_25H-aozgmSsqFM;e;f^vD-gF$&u4XT%q{Ts+A9VnNdoly)l&3w?I9azd_Q5^26YjC|Ah+&@+Q-EH0A&3>s1Ypec0LRY ztOuZ6R`&nA3=FIXpN#s5UPiXT^;1V5-69MeI3ZH}^w6 z85jgEg4%WhH$c^mz!hFlmb?O5IVF%G1e$_n7hquc&nRHb$H2fP0IIhb1fKDON-qBW z!VCK_UX6o70#Cl)%|~GA}4wKL!P$K$sc{0t0y0%f8M4EzG1=8*t{AS?S@D>eoOAy8Ul ze-DjZAyDPS{s9z5Ov+3`E+7j&L*kN|f!Romfr0%8$dPO;?6QnCpusY*c6oSG1?yLU zCPpUqqoNE9?8;CsGXq}?sJE)l=n5L5VP*GbJO?+z7u5(qs2(Qvm%I!N?14}&Gy60UF9QSPtt!ymSeoQoP%^k(&%waJmNJF=Bks#lgU!z{tQL1uD@QAA%wf)Zmr=z|Oz`YV#?B7MF>F4Eh9; zlllj80l47T1;%C@`JlU|?Vc)v`*UrWjkp1E}~jkT@vADuJ3}oD(3L zl|O*uK#z+PRCO|gmITRz>M-R!py2jYga~&qF)+x35|6SxNcA=gh;R!?_y7w7gR&6r_a(n@0vk^D}S>f|%l@LklZN zih+TVdGjVvBP&>jfnhEq`weLZh8v6w9Ey?*46MutSwYi*;5N!(X!DCxS(br;`3Qu^ z$f+*Fz`%SI!eipRCdR4=HvjWJPzTpFfgBzU|?WA0kVv(Ndjc?4bW@{yM_eF z`qMI?@=isXfq{vAJIGA->5`z8GHfTLK}vt+fSO>>!Ac_~K#KlLF)*;O$H_1-aIqJI zmWZ)mmI5un;PR7TU|?r9Wqb^3jDekQ&IoY>12?$wWdY?fa-Rh`*AmKQ;!cxdU|_a_ za+$e5OENGpTSK`l+zH|g49qrAE-UvskRxrOTs8)tMv!JZMvyysbwHkBc4U+Q%@TTv zgZ$Sh3z}YGpDD(`(7?!^B+0;VfRTasCpa9u7+pXLbHKj)ECcf00g&D7pTrp$*xB!i zF)(m5@JC$j!68!ubw305Q;>zFP%b0)Z4kE%%4Ony0OFQIxy;=8Aiq{Xxh&kJ zAZ{g;%gS91;#NVqY}}xkY36Dumz{xUF(?_-fE~&84HVzZZHz7;7l9+E1F8_}z)mQa zk%31C!M6lYNy01A_>=mMjB<1iP>_ z1A`3v1qlWQ1@@<)Rgdg*Wk72lxk_aj7zCJaGd^WufTp#(P>UJ3Cxh(02jwzCg8x30 z%f$T$E;Bb5$bS!^To!K7v@Y`_D3_HRw1SiQF_a4p;3rTnJ2z-rm-#7_%fStr z)@6PM<#KX^rgfR0L%CesplMy^7f>!Y_Y#o3FQHr>ZqO_b^D8Kqmm4(M%lsP3<>LlT z_AE3_(QpTkTezm@G;x66|%z$6MMKZ;GFCLp@G#*?B-^DSMLdGOkRQPj_K_Wyiop>E0gf;j7i`2gc1I2d20?IyeS;VQG81IPclJz>5ukZP=I?MLK=X!hF4&0g?4b6P zptG|h1M_!?5g;=`M*Lu312O_MZ^--uZUkuF5Y7b~@q_(1$Q91cP7KUHAVz@91R3#@ z{XNJC(7Yk@Pq-1Fc|$lCY{XA?P_s(V+1Z(a`6t8(keMJOez6;IGB9w1<_(#D!HodT z8^XC@BYv^_a)Q#ovkL?BFNhH!GeJf$a+HFM0L>dRGjhOU1T=35=Yox3K!O44OA&W`-C6G81G33x^#S0|Pf`-jJCEZUkuF5Y7b~ z!NL&P7R;s(tdGGBpmnYlsphRj!?TxdqV z2IaDHgXRsHuS2ju11OiD8#Hgo{1D0&;0DbbGCzWH1-U`cVjA@d6;SDYI(Z^--- z%9Y>-%^Nbmf^sFfLF=KIUqiW4+@SSP%x|DvX>QPZDCW0Nt_(M5JrwghC|8ynv>uB2 zJ(MfQ4O$Py`~k|97Xg)IOv(z}pm{^)Pf%ecZqU3T^JgemnHw~3$ovJ$RpAEB8!~@| za#ck@MH!Q_nh2;oVp7%+0Tn7t%330zl7UHCM+B6;nUwXoLGy;pzoFU;xIy!V%zvO< zLvGN#A@g4-*N7W5Z^--)$~EQ&%^NcRhjLB0LGy;p4A9hVDgw&=Ov+{=pe)R!Y#{>5 zhfK;=BB0E~q--MsS`-SJH{=1$8#1$jQ$DXXxUuKL@d-S90B-ErfUALOaZoj21FGTJ zbwDj;_Izmu23Gc2;-G54P6pHlUn$GLz`_1NhJk^Toe|vU2$W`E;AUSZ4r(G+N-{9; zvKxVFMD}yy3=I4X&@oyj$N+>W<91Ll#+nh-%?IuC3T9$pU=#xn_%k{%f<)%Q1^~nu zXMlQTX^bEdP|$*BUBnnyNir}n<}!jrKs&;qqMe|gMkymm1hhX4Dw+ZEY6~Ms1hiWW zDhiqyVC-Q8iGcQqfknkZ)e8%B3WNbvAu%yr1Z}&6^i%i9Li(w&eF~s{DmV!t%>=OE znh9Vbb|wHCSgee!&htT=q`=dCY@lHiMmF$t9~;tiA8SG#sGY9Lnv@BeOg_xYz`&Xe z(#E9BzyX@>V@&}`Fex)~fTsIc)0-H<(|sJE=|0vB2v3*;H2T4s4dID$fTsIcb09o% z&{`h`)?5frk^?l|$C|eoY>G4oXu6Lze=C?L%K@71V=aL2NLykl=BlxuA8lU;;E&!oUL_ zGv#6GU}Rw6X9U^F2a;sqVOj}t4P@*QJo(332HGFNtS`sFz;*?+9GZs-WS0OFDX0*WID~>$eALS`FmO16j0VL*7ij#^2@)ra49waJ3=AC3 zplL>SVGdXDlC--Z^=_ciACP)EIndA>NCFgVwWPHke~}ANC32P5-cd}Cda_Q=n9T3 zkRWI$C0HVlnSnus1Ej+h6h)xjN1_`+R=I*=k}YjAWBO!92C>Z`?QV=9ZJ^DUV6C8m zcJa{66b42&kXE*g$&8sGwKGAcxif;)fi`G@)gEJJV1TG~M^-Dr$Oy8lg%P9>w2Kp@ z*aI|N4vHAY7Er{jU}9j9+``1b;K9kj5Cj_2>XqEf1Yv@-F!o7-WOUdV7^IjGzUEvLGHK z$l(lfjBy}mPGkgS3Xm{pgXvXJ!5F~Gz#sz3%8V01OgUx-2Kh_|#>t@c0t#A%3I+xS zMK4f@Ob02L!OXy*m<8g_0C7KnxP_pwoe45Jm4$&pKAC}W7AOx)WMN=Xs^er}XyODd z9${cm1P@fs0>#Tw76t}I@F?XhkWHWweFmi?pf$Uk3=DRxFtzJIYArxqu-bJXwFRL4 z98%Xf85lrblV;3dY6KOPJWQaS1j-=XvtqDXz79?Xnc_` zoq>VTt(bvdeYi3!12hw0ziL@xacgt;oQ@Xaz1TL2d?Z z_jU)3&r5@o{#J_p5>ElBndCj$dl1ZV_X$eDqG(HWElK7p3MGq5s&B88h39PT`fk|66sz)k}> z3$)W59QMmWP6JyW0@_h009vQY09Fe!9+aXuet~QY0VxE<8pJJOAh&GeVqo9|yEGi6 z_#S9&2xuD}C)h2~Ah+;wgJOY|X)UPA2L&2K0%+2n0pv;OUZ^M~NKOHjX&}WQ%nF)K zKx%-IG*JNF3&n(cFBClgfHy@kCr<-46hMw;2d`jfZekYzRrsJ4?946fpj}2x$_$*K z73|EdP%a}UXazfS8u&Xzm=m;uop}b7E5Zp{!OlDr$`$1Vtzc)K1?7ryf>y9I&xUfv8Mr_z*qP_B&jvMl zFDZhC@0W3cMgcfMo70$AaKa)0JmR(z%4OtCR$^daUIpbcae{mGtD#(GPH?Y&4V25m z3GUUeg>qRrKY{eFgL2t8cYwI-p|Lt_*7YvPBJqv z@PiuoEXg2kOv()WpjH7(3P^%UnUNpVz-LJZtwdx}7UTyt@L4h-JYjxN1D_=u!V~2O zHSk$-AUtvK3_D9MgeS=lYT&cv{Q)g-QkLciHSk&TL2EIYlx6ur4SbdY2v43L)WBzf zHSqaC4SW_@1D_w%z-K7|4NZU=_yVBujhoC241%Dr;b#zH6lMZ(MZks3H)aL~Q7{22 z8W@DZ#gH)5LuLjBF-DMOU`YmHCMM7}AEcH&OBokv-hz?UIh%!nfd|}-=K(k4dBDwh z9&j_B2i%P30XO4$z|D9ba5J6<+>GZzYR0n$sIf3G@G-GD%mxikgPQSdjv%8!VGU|6 zvN=IQ9@>m&a|R_yK4CW3n;`X|W;`3Xx&x^PHRIXbK@y<20X5^^K8q%xh68Pp<^02kfqU?#XEP6q|IB)GoF1O-2XFjE;T z1A~mT3do3PM&@O#3=9xm(Vd_js9;^u2wkyYUDB&SbwEEO^L~)>b0EF_ATm!u+y(*|NP2!L#i2TcKh!kd{vdM(J@gN)1@;pQGh zxbGms+=C!<0oR*S>EJ~J&>n<5I3&O#C%73H6kmgE_yG#ww;=8<5cemDs{}elL5Z;t zB*4tb2(krq_6yjiPId+cWw1@mj3A%X@h~u`fURN%=QOBY%3!-7LZFd2Rj_5Oj3DDr z@-Q%{f^B01^FiZj3~G!#AnODe89`Rb@Gvldty5xL01_5wWCRIu@Ir+@a4;~agCfxc zwEiEod_am(Lkl!n!=fqA#=zjk%fO%|0$Sq2JV~K}VZJsf4TIEX@h~tjZu8<`V9){W zYK99n>cW_M8mtTq`oCBh7|eJW7#4t<+7*Tz3=9U`tPBj{3_2j0ARY#WG>}P^h9FT; z8-YO^BvHb{z|aGd*qOq?zyOwHhR96fVPIGRlG#almX=Ry_)^33=GvEFSmf!7(=|Q3zIjR z#mc}i5o90(1A{RmXniZ=T}Dt)vhXo590Qr4!^Oa$4GIqjUIqrxur%Y_SWX58T^JV} zCSVV`@G>yOfV5P&a-xO_NVEtfg9sCCP;LUPbpHVof3L{Jz@Q7`nmB`&3-vI9V+OR| z<`76t$16@~%)o^jbzw}fE5I?+$IHO50~|BwIH4iN2RgwC9676a85s6~466hOC1`gJ zD1vlATRK4t!a&23jNO`%tPBk1d<+bleyj`(-h2!Ux-dzj6jla?1dw?Q3=F2AKw?|~ zT3l_$I0cmTWEmMjV&Kz`_!t-%=khWzsDtvn9UlWj9B8eX0;48q`D+$G1A`W*7s&$| zQ^=akm_3)d z^6!ayZUzSP&7c$tO3@(k7a;M865I?77N8ge2{C~B^o^DhObiT&F!SJJU;qsXF;@KN zLXEj8d<+aLKt4gl93%ro@G&q1fXtd=#0^c&!H`sWf{%gW4oJ&XUv5}xPK8K;gg=0! zre(mTQXts|B+LR@=QJIhGZ+{c^g#tWXhm8E$eNQ|co-NoAF(npECvPLbyfxj#$+wf zCRJ#7fg>NJyaA+q!AZ~oRiNzBQqKTRM;!bN3>F{@=IZc3(-B;#Q5VJphY2_}^YAk; zD1g*gfcDfP=Wvjy2}lMhOu$+~_!$^7KoSexc%Wed&8Z;K8j#GQ1T-0tC@4Z17gzJZ zLMxd8oFGBMyFi+jfDdfs&;Wu9HR{5chyXgo&%kgEq`tz07itu= z2n30~0?D8U5SIW0gB&OqtOFHdkb(}HG(f^eAgT4upu!3ibBxfW0TKpnpkUkpOBxIe z3|5RypbV$X2ySYCG92h=F-wpM3k6}-kTN5v#se*SR4#?62Gy$5K=R-^NEuu$-4JA8 zusp%Uz@Yk2iGhJp3%tz-w5U_{4~VY~=En)aDkdXv#WV@T2UlFiVE!W^Xin!5WMJ3_ zS{A4e$?2dCE1IC3?kLQ_pb5(0@xlxYx*~!M4C{m$7>q!&r zki-X&c1~hlgcyhG>G^>MF&}xFRx{(M2 zgC;1myNW<7V36twAm=UE3bP~@WEMEDiwH3=xPUB~3rbet+8i#_s0(8vlCp#l1A`7o zeFYQ9YEa@U0vQH&F-XDzBnb&5&=P4-Rs)Aajt~Pw2S{!qXpa-vN3%g1!IB_}B_PQ~ z5inEN!zDoy2SAdGOJS0SL6YE{50ZEVl7!^^Yari)a=w}<1A{J15}fVrK&z1%Alcqb zkbz+ZC`e9eg0g+FC^V=*;s-$DYahU@>IP{82h}Gb1_mWia$V&q2+j3yp+;R86A@J3 zgcumOK3naM#9Ki2E5}+6Wl>wj(Y6mF;K=~hZd?2$J0|TSF5UdQa1D645 zVhjwBGQbX;omYYQ;4;7tTn4-mV_>kn!3-+{T)~R`#bJ5g3!KMKfcW4%?+xaQfz}8@ z+VvJf3=GzwcKv^52Ae!kS>p$C0xP&Kw*?K}vQ$X3fOZzyg2rvxyg?l=Mn;AyT%hxI z#6f$FAd`Hms*o|J1(5T+!2UD`&50t7F<~2x1)sOWOzb2dcshy&JRQZ#1Ud%~I?@Cl zXJSpBg*wi}+Qcpb8)sr|VebcxC_=}XSX-f7$T$;g8R>r^NgGS0+04a$X#GqFyGav|ePtTUio z$T$=0OehyJ&cr$k%7u(GvCf8aq2o-fbJ*uIFfefIse%?nZ)A@H4b|LL294^ds4y^a z@C2wZFbMDnsWLD~@U$v3Fevb>QDI=v;OSCfU@+i0sKUTt0h{>dWn^;(EkotOJJiFL zkP6xwr^=QDT8;@G>S0R;X#))>fQEY5Qa}=*;RMi74_kT?c#sA%)Wenm;X#Ia*s>u! z$WRYk4ul68>S4=;@E}7yYfvzy%gn&QC(PlR08$Sc>ft~c>fvw)Nr2)8G}Oc4kp>;=VPyhYAOIpjgGJy_fe!U> zc!HKAyfs7y#(5bEdpyeFD*cce3NfQ5nKAu9ue^m~v=vq8zFL>i)e4oLYt zX$A(xM$joiq6`e6N|kZdHdY1(r9RNE0vk~V1{LVUD-&p2hbkzrn8X+uL_l@TEVbn< z3=A8k85op7d=!-ovLM5%L>U-Br}sc?PX*b23~D=g4>;&lRF%7 zC<6n?OLyUBc7n_-hnm?1GIK4=OpxLmATv9_W*!8&6U0X~Q~rP`1A`401B3h#Q3eJ# z5W_=^fgu1CBamv73$&pYlvCvyBpKg;(!o|nP~rhC+Px;jz`!_-oq<990%%5bD`*f` zUY3DDy*!P9fpIG+2e->YJiHy`xc#yW3^Exk3=Gm)pg7(O(s~)BAen)2AE;R1mSbR$ z=>RDJPct6?nV>1hz#t8tIz9k01Ed6W&>Yhob_NCwkS0yWlOWSBF*1Udk7~7orh6}e zk{*NhLQuyaTtP!eo^G-;FzBoYO-E)h=rUS?ymOBc7ea6ioH$7$qMG#0m=(OXrpg?-T z$-tlvcH?7^_y5R2!sjW-Zwc}Y42mE(=ZP~gRDc#Gz3ky&U{C`&*a37lw81+u28LQL z28PWX2-}%@7*wF+cC5_qprf`7{y>%8!lf)7tc*t-Vj3eS4%6Df%A}ymG;k?f4pycC zRpyUN*>SKkGpMpMT*^SZ3m6PspvvarQpOHyei;Nom4VhBz>_v|fT)9%8G<&WfWi%{ z5_gaiNWJtAw1gIv+Bv}Gusnkl1E_Yl*KoU&Kj9j3m3`_b{(CoajAQxoT3c?fSg3MY$c%od8St|%n99)F4 zez)cy@_E>%}0V+A*O_|w@3=9H{Aj`m#46IC`Q>~%rnSj@$v6O+% zK4xcR1us71xB*&x#sQwS;sDQDae!y7IKZ=39N<|i4)ClM2YA+s13YWRfii0aT71UI z#0Fk`#s#XI*g3nq~&Y4X7!@ z248%}3SNB14O@H$4i#uqhRqYa_zZkf1EU8cs5k^2{0=U189=8pfOw1>SQr?Dq18Am z^Iw$)24Q%~#=y|XAPg;J8J!sz1Q|DivZfCsNGIsLB3=A@DUfZ|S(@r5b_1N#CdM#l4?7BZ-h$`59NOFCAj ztDv=Jij4a}s&+FmGJ=8`q5!NEtV$VNpmO*!GAc8I*37X~fmonPCJrA)Musv_zn9^W z0K82611%FlhuR~rmSU{Z2PtI)Zw7##hfBVT1sz$BbU-gl4QO2ks@uSe zQdsIh%lfdE(a@m+Rwn3R!9v(z0r;d|)|8DPK4_sUI}__&wtJw$8nj!7^)A~qP^c(_ z4zp!ofO8ocI6>-ug3bv6ZLeaz%eD;E@!baU7CRH`JvPwlAP&%^3F|$$5uh_e;9Rf~ z_t@W4(oI%SC|8|dWUrelqRJp0-dwM20O1z2y|W<8|rywY$@TOr6o@6dDlSI!~Apx2KE9F6J!?XtP6IO zvo6@7i&UUzT|5J=P6myuK+n2hFIfySt%bcz6jXGABAC4bq=-qGLDbWafxQyKfu422 zUiA?%RKd>9Q4C(#%K2}PIrCUp85o2>=aq3*f-D5t0y?jZvl^5V znUq-=1f@BXG(n0$=SFa5SAqvP7=%FQm2uXCtbm_a#@PfiOpKAqHI$WsL3|D9Ja}QK5lB4qDTK`hpA$@=T&^3=9e& zrzkSc1(_Se2-0XE$-rO@8WCT?#=rnFHwI*GmJ$PlQZfT$EJ*!&B?bm%304M%GBySV z6>vW|9uy5{l^7UQ!2RHOkb6PO7*s)_AtA}Ypa9zKlAzYc%D^D3%)p=y;s;^45wvWW zah4hb17jg0$R#$QoyC(Bm>7jXeQEHrkU~(=pr*{gpaC9wF9g{fqs+h{3sTDnT8WF> z+j7v>8KeuW$tVR{x4VuJq!V<>4mdm|SV6H|&dBJ<&cL7rUfWp#Ix~$ykr8zK7UO0{ zkW$cHJd;2j=-=!N4BDWbfMJph3qH34zW$U<3Zj+%_s}faEcM67`$U1tM)U|^7DECfa6MMjWf(B(*A8$f#~ zWI;SeFK&$RW{_so1*N|0j35=D3zNWlqBt2CWI;T}BrJMN)IrvOM;lq0859~Agh9n_ zH75gu2&hnIWiSOz%CXmGgLY*wnu3lyVXp(Vco-Q?LC2l2*MoLPGBV0DtpMHN1!^Fe zf{r_3Z`cLaAsGKpdybEQV5v!fV>w9D%2QRnWv~UFqndxipVi1c#0aOH-Gv=u?FmOW7!eX2TR{>@%0-HG- zZ015P1_nz7P*%2LECm_L3SIMl0H%k*oUvP-fq~nJQ2{gs21@=GAS)Qm8GorWF!0zx z#6fuhB5uui1Z4MYMn+H`0DFVMhLKgBfq`o+Bclx?XrmpkABfeY&cMKT9mEm@v0j5% zpbdAt{vg&}H3kN5XAtYK8t4uiMn-c+OAQ7F&R&R(pcDZy-Imc8WaAV@MhKsQ33RRr zLxKprv9GHIX>x-$W`LTeAZ((9x?Z0Zd7A{d$<2z<4?wx>4E&&F)a(aYK(66n zV!zC?4rDLrwhZ>mP(=)!`Jgq}FfQ2nmsw7NoDaG!gZ(nZ`E8*6A{0a3essWx%;$BW|*Qwr&Z4Zp&c52{8g>Cdi0eEPp{pfNslRzXdnq zE+{x*T(A+hSU_jHa69`3FtFc(7y&YqffsyR2K!N#eJl(N;I-`R$Kl3+*0QsofN~i* zLAPbFpM-LmI6=2%u%Ci*nK_d|HxrzOa#=V*6%qRxD3=wIbk0J#Y@DETDcH|Jx$K;v zV^!GCL%AHBpkr0oFF?7RoS*e^o4T%4d|RoE{q#$L91EW??Jh;oS@y|?DwHuIZn{-aP|jKuDl@VwhZ=%;9SR~tRM)w zErb0Ll&c{Kx-EnKF_dc{2)ZqU{Rxz7!N3o?Erb0jI1V|O*zdA^0>u`n8_s^04ORqz z4$Xjb!I6HKjTdx845%BMEJ5VkoAIQI;ZaB!%pl&$GW_UN8{Q=kp4kq?DY}}xGFC4WP z7}(!HH8XHZ>L78!PI|+p#>T)PFbARz959bTLodANH5nLe*q^Y0S^<#U@C$g1E1sTo%qNAnt1@mz59XN+xACPSCjx>~EpM9Gsw0 zIreu@E+=O{$a(LfTrN%?5cdO=%gtE@^3_KumxnV3#Qg;2@5#*ndE|!knO!8Q6b9xgwmPlNs25LAj!w zppzNce?z%qoS^mK?0=wKaZb?54D5fQTnSFl$qelOpj=5v-un;bLh~L2J0y8S^ByCV z3(b2>P%bp@F+;h~yvG9N%5$#LU|?Wpg>n@*cYwHTP_7~;=)4AYb|_bg6Lek!I|r1j z%n3TLft?e|RpA7k*TBvN<*ITX0~y5)<*IRdfZ~V;%2nrl0+Qv0ay2+Vfw+87t|n&~ zNHIT@tHqfD;tD{y+MHaP3=HgoP_7QA1c)mH(fw;m@t{$feh${l+>T`llhhP_l zat$~^lRWHVP_7{-=yV8naVXb_6LdNRy9AVL%n3Rjf?X2IHQ|&3ZAF)Ya!omZfgC9f z<(hF$0of}9<(hLY0&!)bTno+(Ag&ygYstv~;>tt0R-CLLt^$;6&A@L2O2LZkpqvTa z)5OfG!@$4+9sp;S)M8-Z2tUoqz`)9M5wyRU5p>bTL(us#pvfTy=7S&w5pTc>KpPQ- zzzUc^=dyqZ2395xE(Qh>P;-m<3P^1v$S_ecj_61(1_m+pR0al)7!VV53h7f#1_q8; zP+Ol#SwL)&HUk4k9LO#vWg)RAAYME#Xr-632!lAtz)UU%28nf`)1Miboj_U>BtVy` zO$W72ZRz4zG0=1vSNdeoc(byg z7-%|-D+9t476VO(ab-hzqGF)wFs>X3Ph1StP~^&m@Fc}R(_vhBTfnABi-D%YxblyI zd9q@l=`gMW2v1%NG#$nT9Trj)15Jm)&hu9m15Jl!d z%LWr59(?+1CO2rmJIHWhkR$^u(=Kl4A?#dbm$(=hL|M7xBtUl+gNFRLVMBgmpdmkQ z*pQzXXvmKnHsmJ;8uH^t9rEK&xz5eNAnL@E7X~s5G~~xq0Ahjy6g1?=0~_)a108S6 z10V7e2er{byFNoHV^U@m1C90ZWkPstVxX};zAOljn?aO?uONb#fk6y3 z*2f2pR0c87SRWsJtWT7iFRvD)2sGBmR|&EZ6lkEaKE7&@e?Vh>qSAaxi$IDxv=|up zvOj^gMJqFifyVmy>Ooe($NKo1K!(Y|)+&K^tjL2GF$IC+UkDPBNDJuxX7Dh@a*(zT zkZsYR(r2wI1B2=mDF%jSF$RXYd<+a~&;cUw2%z#jDF%kwAa|%R)`HxT3N{dA*gDwA z(07o5MPNygJ1(m-FsQGRVqjP*hH97^Y-o`Sbp5*`<06oj9I$yHvzVkA7=D6g+m`dg zf+GiHUWpn5g9dn6Rvt)(sfSS$lzSQTLHTi&8UusYT3!Z*Gg1r;w?HT86z20YFlg@r z?a`VTIbR1P2J;cq#7G7P^*2%s4EvCr#?-)o>@qdz=pWO>NHw;k$&AU98JR#w&ww-3 zc7AASD$k(E_y!b)m0Jek~(-WFmWirLjkl1O@;BD zCIbWG1h7{@-UQwC4NglJKwbr>+zFtl`U`5Ws4%90RL=#g2B`$y2o6^L52P9#Fmpix z;|jWHK!wo)lup-xRfAN5R;Ynhn+h^8D1npJ8j#t!8Vn4|KcpELtUw2=sxTe^h5jb6 zHjoz3HRE7yIdE;8K-wmQv@yvrF!({Vtp{n_0oDf6A_F?k6*NK!IzAd=+YXSnof-@b z2B54AQUqEY$GA%wbogqLIA~N`hJhgmV%&338a@m*4rCPQa&xdNxIl~D!Hz!+GVVUi zIFKSW83qQ%qsm$`3=Cl7^kf(q%0R{`GNyuDcMfbE$SBYXI#64L(Gg@EIGoRcjO*8A zU{DT`ftL`$AZ=H{+CW-BSE_FX#X$vJ+f|S@do2bAzz%l& z36M6h^@vP3~axBtX}1fL;F> zWL`JOym>MV3^NIsR}S*lE3kPWvp_e(gU!nXnFmfsuR!T&qZR{$>Jk|ShE3uO44^G9 zu>1gWBZD&N#9n9#rU3Hr7qEdK!$4QdgALpXG7#**FCYhA2RU$u3e;}U_D0KY&E{0nm6J{bmv$DmjiLF74z15e06i&#U(U{DCMFoI14nFhM- z9&Dns2m^x=*o7>NASWtoGcYJ$kYQl>4KmW0Q5ED8E{H~urVLpI22YTfwkQLG5jZZn zz#4aIGccIk2FdU+g5>;k7#K{zb0oar=1!Ro1B2-W(8f*?1_l#TkU{}QkSA8_Fff=U zGcXD=f|`|&br=}TKd>?|n1E+?gu!|lbr~2;z*9TI;L%=?A_fN4UowyaiCq-ob5`aF z3W#zSwA5AILl&Y87JHaV7+9GMMHv`GKy6x!D;f+8EMZ`KnS(_c7%Y1-7#LV$!ILn? zjOCz!RDpyCC@eq=Cp>i-7#O#J!UG(TD&X+AtjoY)WhTnNkR{8&un2Tys2bxcQ3eKU z7~ckTu)U-nsM)CuIu{LGDTDV}a8;ZEU6#XW3mO~ehmMVlgIZSiM4{CLD}ya)RG+8z z9B2tEqb+DupQjEqhRVoj3mVnusb>W(>}6zS;s%|m4;pW<1&!+SG{{25l|ka5W|=K$ zR9|2MR5NJIUeFiRbYWx^2L*_)7z2YHgRKN8#@wR7nnj$%7#Qps8MPP~gf=rVf|g`3 zf@*nTPzn+TP0|U2V%CAdkr8wz6ITtm6Tk?{EMN%+C-B-NQ9njTXYe^jT(yjhpsEvM z0I2?Da0DOlBJ2l_2*#&k3=9ZKVK5i0jFsuN7z2ZgD|lI+x+Wm=AS#?0+cX&%IPDo3L4~_8XjYHGnemr40|Tc6BO|D6 zg@`#Zf`;swUo$c~flt{J^8v9yC+ms%g1iP=4lEwZ$OtNr5Uyu%1~04?4`*Zq6)Z>+ zj^I_X;t`PG0u>T4_kh+mi3T$=f-*Xa2GFV{(GZ9RP?m*gZ~|{Pm+)j{WB}dS%Ea&; zbPP3Q;SIMgWES8CXg@h9^)WCo?AAn`1t4jA4tTW;a&~$3p*3b zJvK4W8W+$oAIm+s5ujl{I2UZhJvKwoQW?-NAIm+65g;=e*qK=Fvqgf801fl8+=m+h z8s>v@!A9I?D*+h+8s=lU4>1B{CUlsOAIlvmmyr+TU(hfg z$kCu-K9J4uVLp}zU>jg#1E9_|tL-(=0!gMjjG!fc-xwJfKv)R0OH>H7HB<-`lCaLT zFe_V}9TNkC2&k_JUmhX?>MOFruCo&X^%ddELqtG*MU3Ske;FAVgq_&)YCvXz`ikrY zASRPCg9xav2wxr|0_rQW!~2S&pjhrO#Z`ih*DAPYf(2I?zvR)fyX2lW+&r8$#MfJ_4Q6*;p( zvlbvlpuQq!J;(}pUy-v3WS9gaqqhVL1B2uwT?PgQ$!t*dBPpxPz`!KwtjoZ_EV)aE zfq_NRK$n4mRdSau0|T36J7}OuausN7N%E5p=-5T6IUo&5jLe3h?F68O229}b0tPAA zf)UUWe=?v2BcL%_2HCYBYm&hAFJl`>4|qL95||0D=aWDwPi`Yf8F;Kg?mnnhl+w!r zx^0H32Xt(n0Qh7Y1#t1on9B&NJQ+X-MS>d2pxZALqd~fJPct$wKs$>J3gB{=v4Rn# zPz|Q|E$D1Lu;L12#Y*5=TE<33P@VuOexbm?Pz;)vuHj%{PzL#uu@RIgr|K~-qKT0Rw{?NDQP3WSt?@ zI*?cfNbQ^3FtyeO3=EneF_2n_iFxu23}qlyZyDL39tZ-d0*OIXf#R`6o`GQ!NY#7L zA%I$uEDQ{)DJ%>OpnW#lFiD+!76yi10|o{i&??q7pm2iN0n#}OtUHm7fk6utNSYu% z#C(wNkH|AHoCB%&(F=3MMUcNhVjxw>{sM{J0;&DE8KxGryF(Ks22u;L^8qN_K&pO$ z?!p5H_8*YHUVy|whpwrB{Pj(qfq@0I7Wt1jXuS;FUrL4y4B9YBu)oX=q5cXp1XUE^ z$Oq}<0qeE|=?41?#D};7WIpIXPbH9woy8y(AoI0A;ie6f0GnM6GrJFBHYiIqDKIef zfOPJk&(6T0YRAIBu-TA-K@B7ZG9MHoX3&_PqQJl~52Usibj%;vug5`ZL1O4?4=6A& zoC2x+{2gR2$j!GwYC&Q!wI)z=LFe~@ascCDWe#ZCcn?y0PXUr9L2mG1V9*5}eQ5#O z*8>}u;AmjbYmjGP5anWE2n0(&&KP9^NqmAzWT8pudnhn4s3RG{V894kzQ8EJ$Ov+U ziz0NB5$Fs)Lr@r5C^9gBL>VO*jX(h;s^+AKaG5LUKo?LU$QX8+8MM7*kxB!D@pMq3 z5&=q^tjr5R0(GDw1H9Iam3aY309*n^K~&5K2|NdB0iTe^$~+Gwa0w(315q&-BmnAQ zFvfz)FIMK+AOY}M3vr-IhLw3bNFWYmO9H5@VP&4G(!d}Js=U%Up;a3zg9)fP&Rz?; z^Olj(1k@a7uLCu77#U4K&2jenKG3=tMggWNpv5$xc7X|~InLg&3@W|`Bo3m*8Y-sZZY_*K@ zLGBP>PcZ_mRR*;I*L2W?xObCxn5Yz@_&w}u{83b6^3&2aK zL2W>GSQ}6f)COdSw*dvX+4E{Zwt(7z?3Ex3L171K1F~0x`~wPW0crN6g&;+sHXwWU zN07Ib83aMaAA3E>3V0iky$NI((mbIMXuAn$?;tp!}OII5QNMdg6v{a77~Qa8-h;KV^S7j06Vk*wCxC#BKTqRhVm>73<8Rb2j+v0 zl=e(vU_1zNF34!HQU(UbLm+V`Wkv?^?aT}e%x0k0+~H~#1_lX6H4s~k5wu1Ml$#mA zBU+NFAkiO;jGz@4Qke{l;5*`^JwT$rL1zj{KLVBIe?XQ6yNrNJh@eL>v zp^Dxh6oHxGEyb#A3=HC+2viUOh1&&2P-6!ocuIk%0lEiqV=; z6~_K*`mFfkEv#3j;%x2?K*VX!VQ+13Lr50!{`7H6~UDh9e+(K2`>X zSW^ZD%`3_b3}z|}439yJp`}3w%$YJUXl1c7Fx*fE-O0tkz$n6~J&~1xVY?{qe1d1&vGTw?O5VqsU2vSZ)_o?l+2D zELiRgR8E`|+3&?*xqDDKV-z{i$psAhAE0ueP2Gs_oDbH=qznm9(8_Cs+*Yuh2vn{e z#mv(nIRnu40+9a@dO&x4GB6l|j({{!W?%qaVa_PS_>_}@LE9R1%DOoNgAPbg&5ezL zK@Y@>0Hv$|HU@@c<_rvK(QFJ1a*)d*jVhEG7(j~;_3NMvP}>letXP@Pfx7EPQVrn+AsI%Tmzx2)0i7GR0UZ>u;5rmcFqnh) zws1u;GJ*mVB4z>JN5d7#$Oz#xyajFNVweuPDg)B&o(pYuUob>%YGd1!2|hH5vBm?m zCYp&o8nly&g>@Gz0|WMrkC0tsu>FsWOwOQSVFNF{!F53jQv!I&o+?ukXd@s8D9bZ} z8|9#;HfZS$Qwm4|bkzoE=?znQ8OT4%f*hcwH%u829^`@)rfdjL6nsGnQx1d&xgdop z7s7*FkiwKV9c&8Zf)u8F@RcOWkPA|n3Lrel1u0BLwjjSND}pabVJcPu^B@315rDyvUk?fu*q;6fzv_ zfuL4YJ`?Dg8_-M*E2vHecdb}cK!<>{g7PF=jVD3^&n+meBSbt06@%nlmIV4VczvaoyFFfg!AhH_ci=Yx!z z0_C!?%h@w9uug??+1bU685mfnLAf042_R=ohjKaDO)VH0SZ6@FTmZ9}L%F={1|T=jfpYoS?X4LYSm#2y{OpV%ljlLX0_@;WnGfX(GI0C@ zsb0Vg>V$A!w*#GRwUb!}bo<3?YfvZipaTN~2iFY;1_n+pB?|@yF0N>61_lAHd}9U% zL9Rk81_mK6dwm85VXjt71_lu>Nqx{b%ReIq1_iG5h71gfTn|hc7?ijsIxsLOa|K&6 zFsN|V7&0)Zaw*#|FsO0u2Q_cF?wc_%Twvh3rq94|k%24RihV@PdJBg*^kqO9rk= za|VW23|vMA3=FRsxDHt{FuY;lVm4%8c+0@G*p`9e9Rrt;83V(62CmPR3=AI_xN?mc z7(Oy^y|ZCp_{6|fZpy&$nSsmDfq~%*0~dz{1H)Gau4M)c4Br^II;ySMI z!&OGE$>t0U*BH5c3>X-$GjhopgYIGGdTGJHaFda1jwJ)b9Y(G~69$I6j9ih zpyCk9s&Y9Ksc02W@&_oe4ErlpVUU z93m^m4&7J|;fgbGKsT0yN-@r-p!OQ;eD=d^3=CXhp!p51DTWLTj9f4585o$jiY!4p zk2&vv4$NoW$NnCqst8>0owWw3QZxst3UXv%VCIrBVqjor;9+9@$POBwX9w-xVEqVn z6azb``v&JSGVp@b8L=}k@HzX1FtC1P2i9efg;6{LMn1ge{ zMtoy01sMUl@|5)(#0Zd?AS1rB&jlHw4XXRT!;Ju4dCCgof{pmjz5`?g=*m;p?+_zE zW`d0P!Ttbb1nA0B)*o;qKv$l^xnLuHu!DBA@`0{AW&Hs$0%Ru0h@b4B!FYDiL3FG? z;YNUtjfHc;M*L*A;{b()voizhPlyp9GeJiDVo&2>U|j#4q+n zh!HLftiK>efXoCL!N{=^WP}f>Sx9yBS2T4!nt50m^r*aMu0Xtvob@B0GSCgf`y|9WCZBSQ&twZ5uhti;asp0EF8Tc zBS4p(u(Cjm0GSCgf|UcbuAUuqr*JOV2v&{@AR|Cmp0ct+i~yO*zy`kZ zl=VFO8Xg7)cF^T0tQX<20@^~udI`#9WCvZ2!g?9XWnu?idCGbP%4KE;U3toS70P8{ z2W=>0y$0p7vV+>;tkgY^NF%g+wlSi|}d$`xP-ZLDE^ z1my~{gErQ%K8A9I*g+d>Sf4<-!t9`pHLOpeToHEA#v0aVP_8IDXk!iQb0}Ag9kj8A z^#znG&JNmG!}=1+m0$;LtYLixDnRucr3M@-5Zf}lc$Nm)w}R5CCr>j;9fHu;zw19s4+7S=ydt|2>UQw!@~DA$M`w5f&lACzm%4%*bh`X9%C?7H@TM2?P6O*!yASg$Gt~})cU3tpN22S}rOsqN_pnDe}1-TB? zFla#zR|GeH^Fh$9VT1h^nKf*S!Y$YETt5k?%1AS1v9xe>$&keMJOj5$_3ol+M7g~7nLAlVviyz8` z7G45SF0}9xgmR&Umk^W-Exd%GTxj7X0_8#rFHtBLT6l>;xzNH(9Lj|jUJ_6)wD6LI za-oHn6qE}syriLAXyGLTL6IsX@8W!b=^>g%(~KP%gCa(u8uMg_jnT3oX2~p-{s5&zRQ^le3vs9_%3HI@LkSa;Jci;z;`)w zode(H%=yItG-wdX;VHzxz!ho+vTX`z9D&Q!5Y%d}GXRmR^%xjfxvral$YfIn1~#rE zb|BK;jDdlj%i96evgSN#1~RFDqYY%zM{|%#ofe>hg!x7c3~FI$hjKS=4YME@d0GUQLq_%Z9&}tdrMF^fXxQnSy*lZvS~Yq zm@oqaSA!kMnQb7;xwybxicFBV8KAS)(6LD&MmA?xkaF(krn}M3uMa=0rO-<{(x>m zE`adlML^pE;Rk+;fHoGv5BwGZZ3|>8i300WVGxxSW?+yPVPFsgg%3Z2IHLp;h${&` zCDTTPfk6sPfClCmB)}`^B$(7iKqt(AECWk2NHBSTj6)imWGf2*g$)y<$3#%r+_Gn2 zVDtnrL1FU;#Pfpi7#UbWP7z{c^nED8z`)fB?(<1nf}(Mg1t=PiT7XjIA3FvH7OvBv zK{>8vW}vj_X9!A*=L|uK=7Aw7(QGwkVBlh4zG1<@z!*7Agn>au$%KJ{seqB0Rg{52 z*2)gV0oleN#}4WudV&4OtP7F^-J{0r1@fvaXgwjb7udt{uWT6@nEe=;6#_u1sD%+U z({K(p+mI&8z@Yd>gn+WDg#3?$Wbbcn@t!P z7W=J zG($ksraEA|I;|NPG_yg@(*@hL9MmnBe*m&Pjge8CQ3q67tY%~c8Sq7ef#DuVW{nsF zgAT}~E)52Tcc7z$)-mdWWEnx57Z~&yqd*pHVq^q~z0zc0;00OG0ouSKz`?*!E6%{6 zX$=zE0k+e|hJis-0%Y(`Fh9kHfk7V>K`fdK41A!?6WbX1#2FY2K(RE%hJk@W2Nd}- znhXq}8iMf*qdq95*l98__<&UJWpo6oRupAmIAFuTU??Waz`$TMO_PBEGe3=Cio>4Nk^{AS8t%)r3t4O*Sg z%Dh>nfq^wggn_|yA7}t1dc8Pk$=ODg1_lYHUeHZh@t_hb1|qy3baIgc$k(yp(P8Gb zAc0_zx8ooJt3d)=L9rAM(#^`e3M4Qcl%^6O0xLlRrl2H{2+D`7%qu_wTR_<^38G>- zNI=B_bWN141jseZKyC!(QPWSL5t$T-zNIP+3}&Dy2)2quP|{}vFB&V5fEFnK8O%Ua z5KL(apyTWr893{;Wj{;)B`{Bx8&vkQ6hL_L+@P|b1-cqYksDO@!|(Ov29^CRC7|26 zL0iJvKqD`pStY2~c^G-YlT45kl6Qe7puhyUDC7l~{k%*|K^p)VL6-4@BpG;_j)9zk zRQ9u!odd0lV`R+L2OX8O&Jh%v&z%_<7&%Lw7#Ns1Q$U3;XM!^W0}JOOX9fmV&TeN0 z1~$%AC(yXk7H0+q4$d!*pmpMc0nQ8zOj8*_E@sYUVqg#gt@~!03f^!4$^uMN!J^V& zWgvG7gVudBO@}%SBqI15WN8}2jN@=K(hz2(fz9v&nUMz4D74g(fq@CUA`4<%21r!I zFU*O7DHBvOG6sK{Z_g05l}WAp=Q-NXnI zkwb`@fNa~z2oh04i2etO?qdXrfR@~WS1O4!HiAqz3@#`^qM({o9MpXB;ep-Lc^KrF zx3&xn5}>eVJPZoX-F6HNk_{XT3`L-eC0alxUjgX=T`W<|#J~`x#lWxtbQSh>&=O{u zrA!PA1`Z4ivY-JjnSLe)2GC56ObZhOL#qP=gB(byJm^L>5KkVou63;g1A~H%J_Ex| zUIqq5*ou<|21Pc=GGIo~GG~QXdJGJp+XmqZCZ@m@7$`z_J2RSquAtCjU|6EXz%U(j z6-6ck<9Tp#eb#}2L1l^-1A_qQGD4*rS_}-Yv=|unKoz|LD|!u5bPuLT6_lL0v>6z{ zlkq41flhZ0V`5-%b!1?W@do(}!~hMWmpX#x%AhLc6PXwoKq3qb(jXH+x=(-t=)4W+ zx>k@0y&#Ps6SjgFAQRp?GBC)2RDpGacnl0m5!wt41=632LAwB|Y(0vyvna|G7!;ax7#IThkkTO{nK4bwgW1b8F$)^G z3v@t*9Rma7V@Y-f1{qM~{&#{V4{c`#1{qM~COb1Q$T4s-Fn}W$#A9HPRN!P_$N=4) z3XYPWpkijWGXsM#I7Yy$2z9^_@*9*1cRDjL=z`US-!O`&-8XHpJ*!TzGv1>c% zLLy@_JF-t;krAK^i40I96A`{RA_KG(9hC3hp%?|vduWl-pbNPORFnf@F_y?!1yyE) zq6{N4uILgS8A_mqKVEta3>!dOZ!#Get-xveqB8@7qy;Af!(5OsxS?hPZm0>lFfcHv z2qRm;bPh5SOa-KpEO=^cWa+^D!_SM0YYm(*~H@V|oy0yhT?Ft)`3^RL;QE2Ixc7 zN`fwfhLwg$L1Dz8lA#ZAjCKiBtt)P|T`;v93?Swf;#8}B2C8HVP9-Xj44_uOgQ`7% zQ?0g`AtZ#JAt}KKS#2#th`Ts>ut&WSgLZ%+q|^c3CJT!qaO!{uwL*j;?nZzE0|U6_ z4l4e@%~xg!A2i1U=Cd*wGJ@(=MrkHSP}AlXXq;z~0u$q59tH*@aA_&c1Zv-Wb!A{M z2FWslQVh%~%%2%EuvSM5CXAOs8C-#h5u{1Vh=D=c4Riq)FU(j4u(8Q*3=Eo1&dv;s zO5m0=QxBsylMy8Fw2@jiI4x2Tf~tl&iK&MX?jjRd)dOk`Nr4vXGgiD}1a;Fcsx&Z2 z6@seqDp2vy$_y$-rRqQe)er$tT_|+~J26M(8AZ^f%`4)^zK~78nx7ry&MHIvaurtjW?>I6ruzSNC zaskA1Wn=`E1`xx{z?ZhOdN4BH09m2z`&_x#K4eX#K6D--ppzb ziW^?g>Q4qPa2n?ZhcKfLV<9601IX4-Fq=UF>|mRHKsIZ8z-;ybS(WGkv)K>C{R!fN zZT1J*Z0pIuz}aTRz_15yGiZ}3Lla0X0~4g@$)E;0(4OG~BH)9e0sjFh;By^N*ENz9 z@C5gdfoglkc1Dn=>x>x~7I-o+FdhTl=HZ#gz}OB7EXEA>T`mj^j2$4(Ax{Pd_8B1V zJWx+>jTgAr3`((#+rY^XWXL0928Kso3=E84Kn=^_(p(0{eIU((-k^bOaO!6~$p}(a zW6Ho#@6Eu#cm^~g0d5?g1Tn>Y7#O(0`@oRy%fKL@Wy-(+3LHTrQw9dmK!gxu21^Ztp%mz# zK5%LhVFYDDMh-?skk>#93aflUcK|RkFo@0tS;+zR>IGj01~G6ja)H}iY<>(3;+YJL zkkeXX{1_PcmzXjz>@WrG_XoK_0vxynAZ6h3Q%Nwt*^hxiU>Vd=0_&iT0&VmGl~9a| zj9^tDSG+N0V3_O2z`zK)^IFUk>tS0|WmBQw9dmib`>??;+bt z#Qhl<1TH~s61)MmNr*86tW5%35HVUp>;u^aT9l~e&%nTF!OXw_vCkT;G|eC4QyVaE z0?58^pvf9Dm`|O-5=%h#ffgKsgZm$veInqZl`)W!5oFIMGX{q3AiL&)c4mR=l|XPP z`vovCi0Xm-8VK$YmIW{{@Y|U&FibFGU=RZ*>IkrH^8#Sekphm6p8=qzsU#?&Y++_# zkOC1bV3Hp;>mt1gWNzpg(3UV}2ZaU(8IbK@Ee~N@cL%aED}Yp8WM*Ih zs{-9N2R4$4LAnW~s`)$EtgE2gGBZH}Ef9fApxb~fK!fQFGu7Zl^bJ=?5iI~7a|1b- zfnlQy4ND4WAUo*^+4`sE}v}HM-eufrQu&xH2#>F|a3sI4qOjfTWE;`HL+b z)YM>GZ5u$>DQ{Rn& zfn^gY4nf-mnHPZU+$;mycgn)D6I8ZyMuLpk4RRyM{9us!JrEuf19L7&{azo?U28qo|Odw#kwFt9uZ z838(RSY3>Pf#oU4sZ7cooS<<%mgkUARpJZ=dFK^`r^dj|w3Cs6f%z=R=+|1 zbrML2IY`Nz2nGgGQIN|lKxsrMl7T@yf{TIS3g}`ZW{~fWgRK1)$-uxMUctq{@EWu) zHIspHCP=qh6i9dl7Xw2aD+7aQB*M8>)Qv)LdHxo#Jn+cRiz-fCY zXhSO~C9yLoFoGJPj8=@`#0Iv6fq}t3hJk@m2Q-Waj#Mjf1n-GqU{IP03QB9R9CYkh z@-V0}Z~!M>rdS3BNk)(oM=(Dc#9s^wRwr=9H93}nfk7U$v5%Vx6h_L7te`NAM(p^# z8q2`IxEOA8G??8M$H1TnwmAlD^SU?&28gwZU~8U%_+V?3zok2^w zxxoz}6-EY743#s26~g=r9=!(zz9Kl8mNSCVX=OYEgCZz9Fjg>vf_W{7{}SZhN-+Os zJOhK+4=x4<=}ZR3YH&>cf(faDN)*OguqAAevq2dc7}OXmK^Z$764;FDpb%zYcnQh` z44^}}Ss>fR@;o7RX8=;&+2oB{cak)JhqZgd3~DPgPX?8B;2S$wlEIUdptJNek_)tR2(;iE&Shla0I7QlYE*+3e6!qT19g45K(l%bY@lDg^7Vd7_>oxtpcQoNtr>|(~p6z62gHVzQ9%m8YySC^I~9NDyjk< z*TB>OYWRbb?gY@OULb-&oJrz1sCUHFv5|>^L2^B)4<%Uu5|Ok9r9uV?DNvV)X~G4N z^k1-aJ6L+QC#Z=fl?zhE&B(~i%*?FI@3uGL$pi}^v%IFP}T$#YYAP)+5MxV)` ztBO+;L2iWQa>f9qS4<2H7ZVs5ltEifKpXqOa;o2$7#LnAfZ4Jj$H{_1TaJ+n7#Kl^8$jF;j^Ty~kQ+)8VQz?oxIsP?RN_Q|IZ3DviUT|7L?TuP{YwNpNRIIg zNPiC88EQ!k42+;ny9(f-$N@Q{CW(Oo5)Qc_H#`7w!QqexveqS;fkELd$dr5#cS695lWL zQwX~I45BiHfkBh;F(}B&!6^#tdIkoDt;q}wjG)>H;@)zQdwo)1?yUg1cM^!J1JYUv zQg|bUfk7(_l*qtWvdX10FlbwFGcaf^1}UlUVP#;jNo8QrN&qQo0HvCgR0akel(=pJ z71`k6U6YD6c%P(#90)paje)6#fq_95w1rXxTuBImveP2a#eSg7#>$`vS~SL1I|+0h z8>1fREFiWzP+`f)s0TWRfvx@|SVn~DJSzhOE2wPI1DyrL)&Sb`&&Vjk^c*A(%8Lxs z1wmPaPaED*I_C{3>?1&{sX;CRT{P;4TG*r9;e@ z{A>YGE@4EexTd!Hu^I#NO7O{XJAm^4)OtAb7v6Dz@W^1BA9_e zh5L9Q1A{6z=v;C&?u~v73|idtf*2UIxt|9zFz9fDMjdpyo%|UX^tg>f7#Q@q9|bco z7;r!FXJ9bm?g(IDFy=lH06L0bs}BQ%Dfh}?(4BdvfeZ{5+&6p}7%aILg)lH!af2Gq z2N<~J{TLVyGjO{HF)*BA;9lVi+P}$N6bjl_$-u+Jc9(5C=sZSH&CYh04HoC1njOvs ztv6@8%XSIW0Rq+RYs@d5dfNkJmVtd1O0b~~F zA|AFkP|XbNpo@6mT(Fbgu)PL333L$;+Z%|JR)FRX+0KJ5;$eHjmJZrs2HHi$_6%+e zIJrKDav32B@&%O3#16WMhwUYl%gheCh==VJl*_^nx`>DEHI&OL2y!KpG8=d|5!+j+ zFb8;_2-`a-my;cI5f9sYD3^;JbP*5R2Pl`D9dr>7+eavuhaGeg58Edw7n*xML%EPm zj%;6`T*#7pwy#hwWXV0-Hz*gfC;@cHHv9G~>U@*1zPSQqz4*O=k%-MWMJSH0S$OMEW;Sgz`#<)$jB_q7|6iD;?Ky)e43MiL2fF92Vyfwfs{(K_%kptuViGr$H~CJ z3>|lqUEssOz|6?R$jkt`k{BF3j7%UlgA^#%q?-a67?=&9nqJ z&q0ap5hF9`CMQXdKBh+?rqYKX1_q`lph!^a2Qi<6+^MMa8`R%?31JI>#9u?$pflB& z-htey1iE>E3A8W++}@S~ZQ54`cRp2jfs)V#Mn+Z85GG?EBcmGQV~|%389}o+pDY*{ zc+wac7;o`2FsL(u)LMao=9AnPFumWUj5)&T-gC2;fe++anSP!EC=*%VabOr|9 zCtM5+b)d6FKyLZ7hnIoD5XRL9#V%71qb?}U+AJ6tPJz@sYXPm@u;*rA@K0x8FocO4 zgDy!n2<2vANJ(d4&;hMb2T65+R;NGF0UezRV)lW!PqjcxW-@sh7z`4*85o+=85s0# za5FF%!|8O;Ro2`L49uWSl?)6f8#oylPC%W*^w$V< z!m1cVO7n~bBq&Wmdqr*uFfeT7WneIac5ay_I-0>c!5mf$nxL&Oe?g(lU|M6&z`!BM zz;G3;9I~i}X`&;8W*aoHP5aCl7(mz2doPhyiiZ&?MO*3a;_y7v@ z=vYvogO~5LY#To5)3DBdy{H-PNZ=3-!I2H9s0Dv3ZcLLk{pM$;SS3=Bzv3=CKJKxbuTFf}qT zXnwF@U?>B*z*NivBKr{{%V@x$DFF>^O(_d#va`(KVqj3SU|?_nInzfEL>ZKEF)&O6 zIqw4K05uB+20M_2ri>P#L(yC;7#Ms&d`HG2eg+1k&zuYlXEGQVOg$_hi93lO?iwqQ zLQsM?V+7CsYU)AVWaaQpqV28=1K+z%{yic42^;e44U`M7#O-i zjBhZ;A2Uc2()?!z^}8~7=s*-yg?->>U=Rb9UaSn(prHfi+6SOU2BS4-=zzHn)C*^1 zv<3|wFxQI^W;BB#+f&|DfLBO|C3aRApjc8niD zf=!H!jE;=y0SpX0sZjHN2rw`>fC*5M%OC}+E9@9QfvoIg1l_7JLzIDmvlTo-&Zs5G zz~BI?AHk+NfVd1&`hpA$%1j`Aj*P#885nr-Av>@bL5Us7Xj?``kQu^Z5fk6J}!dlV*nqg#V}hBJ~Y!F3K^Qo zKpL7U0o5pwWkyVl9F3qG5}8;t^GZPT?nEBe#=^J~)QD1M1XU+rKs)h3OXwIPL8o~! z+(%fy18V(Y%B^J32e0H|)rb3yCk)~@&@FqQq638QA}nGSXJufZ!W;u=*og&g*og&c z*a1ohV?cgm9oO zY^Ew!(Ch%Xh0W%d3YsGTx3ERQEo@P63tJT2!WIR$utgy)Y<>>b#alqr8lbifE3985 z0P5GU!umA=pneT2tY0Gl>esNs`ZWTeehn*XzlL=c$a=94p$rU65|E;WS==#FfgWo*1Le__P<#$FjRo591Cd> zC3B03fkAdZ=wN0`1_n0JK0PNnE=vXm1{MYeYtU2!xB^k&v1DM71YJ)d22ui&RFDAe z3c7X3<~qMxaLHfV~1QJD#J zJ|!zC;V6NMex`=aQ1P9h1vj9GQPBr^SQ#|X!^p}ktlq%DdKGjqBxISM3aDaWQ~`xN zBP+A0dIN(BsCHn~2G4fEF1Wkcz`eptd=rI0P3NBrX2KJyOk#R%9?E7a7cV*+5wc zd}awVtc-vZ8E`Hrvoa$U8O(RV19PwaW5lBS_GiH&&e3K0n^WXtMX4E2snaCo8`2o04Vq;={!v@;a#||2?WJVpagmb}8 zdc*b^REmK{ESVuAmRz91f`R8eXvC8F30poZ^ym;~)DcT&)DcT&)DcT&)DcT&)DcT& z_=qJh$d#}WOJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v& zOJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v& zOJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ>v&OJ+gn zfF5MTk{NZxk{NZxk{NZxk{NZxk{NZxk{NZxk{NZxk{NZxk{NZxl35z+D#(Z>GwO&X zGwO&XGwO&XGwO&XGh)P&4>V%QtjG?^nef`5B@c9~5V-bdDF88HwLc3=?GM|G3|%I0 z6f|=QI@cUJzQ$4lTF%1X!cz7Hv`!1OOn{{VqzGF3vs6Mj(AuA+3UnU52xA?n($R!Z zJA>EA2!c!iof_AIjs$?V#F1x4 z*+`lhWk;)T*pcfScBJ}-9ksrJb3w%_J5qhaj#}TaBh@$TsPzq;3pN6&zF|kLZ`hIQ z8+O$C2F?W=fmGkHW7aq9Nc9anYJI~_WPQU9sc+zkbikXaoTM~SIS@@$_|QAJiOPY} zM1>E%gPW)vC{0uj)FvtixQQxa5CJ-0#q|TIwVWQoz`!8d2oe$f7Qw*4B)UG5fq_|c zaufpti)dsdXgpeEVmL@c9BBGdbXFKh!`dhY21ZfoNRWo-VW5+C#MGi07?^w+8I?gx zL7~IT;{T!;7?`dwGBS%T1{ux?SP!8knfso;7kg*I53{6=K z42-itm*9cj83?laX%@_#K_GY9Wy9PV0&?df5EtxD&;lEV1KA7=(lB>|&I4qOM|IdO zn8V-Q&WA=2#D~uLC_d~2aS=XrEPzHI#D~2FP#=QqQh@jn!~{DU!~pvT!~pvc#K07R zD+c=zqz1%bkYIEKf$f*$Kp8kX2*{jfF`tJ_98mRBz2MVqjqWjOs0! zVia!`fVc>6ttdwE);kav;jPXR6mMNELGo4rb-g9Qcqf8^ff?05pGz1R7+-V1qY0F; z3QAG@vkb&V_~(Bqiho?opyd}NW6cL~5gF@s8Ipf8!2VHb;ALP~#KFKI1)3vbb_Zog z&T<9@DbPF-vpcA)DF6*j;V4ev(Mdw`jKGY?zH-nJ2cWr0M1jIxf#UCY5EtR^9Th14 z{s-bB;&DMGN<6-)MDq6xh`%@RGBC{IMDaIQ6^g$Lt6)ph;VBc-mzW}O#h}~>4mJ>j zL4r{j)8GA73=E7{L35c1fAdtM_}dA@MfiJmHHyCPG3=E)2GX>aWQ3Euag8TiE9?8cKsNv()+zbrF`?wCX=#8sqU|>AT1NSkg z=>1xc;$!Uwl&Ykq0ma9sKwLx|D>b6Tab6>mkAGnCF=j!FDFTXPaKwR1TySKYOENGl zVl1rU+ay$Zv4pFX1K8_n;{t7D#yxY9t9*GcYK&fEu8D zP~WqF8%pz9puT4TH=-{# z1!3Fq zM+uvVb_NEO20jLcL;NUV(*hD-z{kMQ4H8F$&5m|x*nn)`0SOxr6I57%6Ah^BgX~2D zhYd&$95x^ZIBY-+>{1M>AUP1e53&>yHWxrsEnw5ZVFOYDHxq211mm6v1_oBtuzB1L zx+_os8aAwopfba)0~$80;B-^d0Sy~gaJsqD!N8z$fscV*ZJ3OPe%uB11|%1|cB7=!+HM906%T#} zh8aRoUqN#5N|1O4KLbM|NF0$;?{-6d`_7typ@AQii&fQZ7#Or{7#RFONY7$Ip22_ecb(u8- z!zOD6hOHo55vke=VvRL4$8UjY1f6OMP1S+X3=Gh41O+n)`}Qy}FiMJ`hGP$EIQF1~ zqj@h%ID$@}RGGog!0lk$&8vO}2F7MFlt7D`fD&j86Ho%}3W$rSivLVtU{J9T zU|{ePgECgnU{Hw=U|;|(&yzv~TFgYGKr28EGzKx62UY<293=AqA0t^hs;?Pin)I$pPz41R0c(_CEW)g*E=~fC_eh|4 zRBAGcM;#`kc(h_N1B1!|0R{#c2~>|xM)K$bqCF}kLC~X?aEl-wos1EqAdf<(;$tM> zQ}Jq`X$q!VAMk;>YM^Nf*i^h4Xqtklz8Ned$J8mozyO|#R|8E`Fg47EiZ29-gQnuu zK$Gp<(csB;Mm5kpJ2!L{mO3MQI0FOIa_Ax@4e(kgCeT_Z4e%lkH19-QgHhAp<_gY3qb@0M0CfLF(9Y+0d1_qvPsJVuc3=CQzfWrZEO`xfLP%D~IoiPA3SeykJOJ-CDubN^?f^v1? z3j`o;VqoP3O~*_yfltR2M?9+|xzmu@pPhk$r5bc%4f4zkOATl@ zHZgnFKxd<}^f@swFn~8GvnI~~U0MwC8+d~pi#;plwWWF4%~B zY{sDJbI>{>)_V{mKxQ(qF|pofiv}41>V2@@hZ_Of#suerjkwQN1~LM)j)?U>#0Zd? z&~-$tH`zc3Zh;pCu-=9n1KP&KdI!p7=sI2Y`sH*B0t3=G_$MFFgDAWk|4n*4(-3SfQ0)(Tq`!1@es3}_n@ z>vJdDy(%7tuWVtobWLbfrnzJ_vHc|op(Eec?L3l)ZJV`6;=t`qzvWOGgiS;j(3)#lR z`VY#5Y-3{m59LC(F|jhRLy|XS8xt!dlndF$#L5KaLbfrnGDEqLZA`2zP%dN}6Duo} z3)#lR$_C{^wlT4?L%EP`OspJGE@T@MD<_l-*~Y}m1?57vF|l$(xsYv4tUORIWE&GJ zFO&<}#>C186TI!19(vYt0FrnXYzjp9gV@7%D#)0fk9v~ z=l~FbTd|;9K?DqALDzu@FvT%29AE^kM7_?*z#z!V7RSWKz#s(LM#7c=DmIyv8H7Mb z6tE?N3QZLOk#Hl1KH=R!N9=o1!98i^GF9B0SK`#fkA|qje#MJje$WF&7;N}ox0wZW#VHW5@8PNJ?S#W!aF`W@4vI8b6 z2W|^7R)D<-5(Qle0bYqB4{k{@)-r-be!$d&j`vmo#TsKR$gPYS4D#TH4Pz4{NKF># z>JgA_N}LP~iXcxjHi6V#oXo(W)D8;e7LdRGfw(20?A8HNXf=g_K{+cPG>)Ue3Ca@S z({345m_V_r!URgrs^HcXqcPZrAX}PXHidCAFsOm9v<5kiK^5ExW3&RR1F6{pQ&$I4 z*JaDV096NSyD_?h)q&JJgQ)}Ukx||TD8v@!U&SLvxA;Vc^PEZJE$5p(1o~Q zL*>D%;2ConK?=)Yiob&tr`bU*R%e_B3WgP6i$Q95>=_v9r!X)u27@+>frD%XD9El% zVPH_~&|+X_oRUod;R0al(E~ufJjNok|4C;($L1s?}n+-Dei9G{@ z?^Ff`M$kz&it^eF42;u3%*PbK%UcNOkt{HV9>Y*mCdJ6vjK?>;y7E&5?mYa0UYdV*?KZgOVP|KJfiD zzB3pYl+J<*q9>sIynY4)gRvn814Ekw1H&|saZj`!2r@7zfrfDy!FybdXEHEIPS;^z zVEhBpVFJ3BbcO>1gMbhN1LF&09}WhFEe;F}`#_q1g3UVQz`$?`#QmeT1nN|^4^VF~ zFqncmT3pef0-ll46x7k;ngDA5Gct;RvfU~kXi>|`UJ8=F+dh9$qc$95>z@v z_ho?gZ$Xb|l8u9Ogr*n5J3r6`Xw0N;1%VpA%^cp#@`M_`k!ptDK^R^QHT*Oc47URJ z51B0BEKjc8_A1X>RFtBnQ z1YIM=4(dj69ELQZ8Q7I&85lT@KzNMo>M{%r97iEMCiZJ$3=AB{AUtMv4v@;@5FQHy z^C<}i296V;z9WYTsBYj8U{nR2z$gzoM~Krf0n~lw0w1fwVb5X&>RP!vv^6%KbO zmyH{AtO|z*l*`TyI#z|l6Uyb_1|6%y;RWS#@_>$2;qZoXxwt{+RB-q}x!l~K4jzXu zl*_{nY8`R-LAku#po?TV{GnVvZqU9LjsPf^pBr?n3P&K6E5N`DI#z`vhy@f%9N=SB zI6_%uL1!s~k5%CWAFIL%K30Vje5?v5_*fNA@UbeK;A2%d!N;m_f{#_<1Rtxy2|iYZ z6MU=+C-_(uPVliRoZw?sIKjuNaDtCj;RGM6!U;ZBh0_>xtO_UiSQSq2u_~P4V^ui8 z$Et9Gk5%CWAFIL%K30Vje5?v5_*fNA$gwJ%kYiOiA;+q4LXK78gdVHH$HZ}$&6Syf zfg5zJ3I}{Vf*Uj*0p~I@@PpJPFf%X+IQxY#a6rZ*1VLfKz{kXKkF5h_1ZX^h13n(X z4H}PtbHPU3V_OW`bpjfX;DC%r2!hN68F8QOG{^`OX3)9Q&|V}1H)uS912#MXHsU_p zGmsIW@dyscc!VIxOa?CSu__!l*|b;~7$ETrACKS$XC(M|gfPgzOv+5cAV)JPvj~H1 z28~DXf{s<;cmTG6kBQ?ATO7zN(0Bv~d_001bgT-T3wF{Qwn`QT1|iUR1P5e1LePu_ zbRy4r&?W_rCv0Cqr#FC;D||cxl3d~A5fBH%$0N8w$Et9^$0N8w$Et9^$0N8w$Et9^ z$0LM6u4GbX;|5*Q%mE*d;0A4~;ed}vaD$Fj;ed}vaD$Fj;ed}vaD$Fj;rIv*cOGug zu__$!@d!xn`3#li;|6U*=YWq#aD%R4=75h!aD%R4=75h!aD%R4=75h!aD$HM=YWq# zaD%R4=75h!aD%R4=75h!aD%R4=75h!a4+FuVBmm{M{t9#Vdj93M{t8yd~(3YBe+4= zFmwEex><@FbPY2Hd_001wCs`tJ|4jhx`vqpJ|4jhx`vqpJ|4jhx`vqpJ|4jhI#z`P zJ|4jhI#z`PJ|4jhx}2EEQ||BeGb9>EQ|A(aC@9>EQ|3Yr5x9>EQ|3Yr5x9>EQ|3Yr5x9>EQ|3Yr5x z9>EQ|3Yr5x9>EQ|3Yr5x9>M)fi-CayJ|4jhI#z`PJ|4jhI#z`PJ|4jhI#z`PJ|4jh zI#z{49_k}2ZqTtR9EkASQsW z12Gw7Kz@;9PhenRKEcQ=3F^1AJYd`lI%@<(NP(2HJOC+`0`=Qj9)g*mei+LmkflK#(@{E&#LCcYW!314^_HZ*WsQlz)Uu(bH>1XE zP6h@JjR~O34>Vdqq$W(6)<#YS1`q8fM+OFYUeNh$3=BGq8BClFI*e&d93DE1DU22j zx*!8V(mIS8j0VUu3=HZ=I2jl~@)JOo?#={RdJ(jJpFsr_IUrH6gZDD12EjrB$s z2GF&FKe!nf^g(L^7(GG#I4J|rf&fNOP&(|M$-uy%x5JTvVV@%dgCY-1p%+M@G(@2n zNZ~4wLUn1-ITMZy3{OB7MA-2#Fc@lbF)*A2Ng9D%$q4FqF&KkRFW`y;>0@Lx1|3|$ zl?O`OjEu&hGYhyXpd8R1Snj}DP$!L%6(nX1>J)NAJB8p(Kc5Gh>5~{t(m=^UzaONW zmDx(Gfk6zE@ejgOure5fx{WNg8$l`taSmGe${JCR)VEXbv7nVVMHXtBe+)T!kPQ z7|OXo-GiT2@ZQsu1W2dy1XAzGrWD@61oxika112qI6(O3TKM^Ykj=GlE@--l4QaCz z^f*A+=2|wS%}((1{}|Xo?N&G!Yy{F~C+Km2T+q$6Y)G4(;OGA_u!GvIa4y&gq|Hvy z;{cKO>@PY@p)+LEBcrn``0c|3T)_;9RhikT%z{VQ#KvL)u(R zlj8tUHrI|G2MAiX&!h~QM;kp35E2@Yd9;yq93XfejSaH77BY{~u_^#=tO|e|s{-K0ssN<1D&)kH$H~UPAPi}&f|#J09+bwaFlu8JJZ~fknh*my z2i{l(StiuNQs%+Nz#s-`tb!CVDKm(H8>E%` z+u5MAM=Y%%CV2J;(pUx093 zDZn#A;#WZmYat4mK+{uTg|%RX(*Hn`>5R_QI!$Y zBKZYtJIR78az<@NkO-R-baY;h@dW4?azjRt2?g3BuJ+^ zSW<(XfuX>OfuRH>nJ@z+Y0A#PU=5Z8g>#t`14A1~GFb*RO$Iv1%6~QkgJK3d14A;1 z5zEfNP!3`QK^aOgEy{K53=G|~85mURK)2(9&hz7BU{D1&g;l{#VO4NbSPf*p3Kv+4 z(EwS7fk7RVB36O!FbBCIKpy0oT}})P2S8jqP_IT29CEhAm)8kj_g^3=B6wl4eaHNs!JHAW02S;JI-zFld0>9spu=I599pffy&87#LDP zj9X3&4EZ2WXo4E49MDFpCaB@b30?Lj0?MMdI2jm3K^d5pK@-xfJOygIGipMbm7p;r zMn+9Yvyzbu)O^%pV&{S`HPeJND*yAwhYJ5#&@IP~t@p47!Zh)fpJL z&N4FUf@hOhrZY0?F+NXVVBj)m1PRK5r0;_SlR$!?Gang1$ILM?#M{D~o??lRrYD0i zXr2m!XH=jzJx9-V0qwtrZMz4x^O%vEo-{qz1-8$gl_l;6=#B|cA;nYX}W+u?FQmkdAuw$iID?o}swVtOR18XIO1Fff6s{%pFIoKAT2U!kUw!sEl zwgKLP&jwqz0X`*)4ds+5Hk2*+Y^YoC*;aurvJe5Ee#^F56LilS`1D&*@aear&7iYW zMZu@vih@tS6$PJuD+)gSRup{tttj~PTT$@ox1x~KZ^f9HAU8n5w%vPxE;3*j0pFA( z>IJ$CLeww`v{(OK5@>V(w?xq9{%eU046LI2lNcBp8Aaog85o)vMOP&;Ff=oYPDo^6 zXkiqMPh?aNuZmJfq?^j2_q;jijx@_I6^_4VolQIJXKQD(L4+{f>0BDY$BN}u$ z6v$lA^>ZA_APbq4c^H_B6B!sd(m>iJ7%P()7#Pbw<_+I=TzukxGyp+#^*7IT#qC=b^jI9CREf8&X8pK~;b%L(srG1IW*C zcULh;Go~<=GDt%&He#y48UUa>NlDXOhX_58W;Mnu91INk$R4`@3X;nr3=E8xp!jQ< z$AA=G=h+z;l;lC_30zN42L%vVZ9GWrDiAjm6!qY;b1$;7)7fDWpNbM*X`msa3s}P| zj2&Niff^5J;Z@Ec&6vbghCir?(T5RAZ#Wnjo*;WCh65H5Js_X|1o<2s5WOHS&wK_3 zC2&CWfw=PXVSevN@%x0291ILb^BEYxaft3P>RdAuL`OjMH%GEBT%l;1XVepoXj8#Vu4RM1SJiyI4GAOiGum9%{a!hWV(3YDP zsO84m5CIjB1BrubJT1`L70zf-Eyu{Hh1^=y1}}kPoy-I-W*I>P$~s^IbX`1y>;ljk z<4mBzW?4}24&E4`%eVqmNUw$Hc*x1XpaUxZbU->F1Xv6-a<20cG$<_#ibvVkV52}x z$PpiU;FV&mpz~d|!6&tH!A@#b;9_9V0TUqA46>@Av&Wf0Cjjf~ffwbmf;KT|gZF51 zO@=J#V+;jp0uvBTpgLC%ys(cIw9i48kr`BhO@KHWln&4x4R$`l(FWkn3amwp5FL8p zl}@anBWM|B^Ml4p@7u#0tP@iq4b~Y*4c3`8s0~(>vrEA%O_(uOnlNKoX#&2Gn7OV3 z)Rkpn4+EXD$icc5bVC~ldmyL{2szOdG*FDVNQVV!r3vUnQ_#wM@bQE!@R@(uiKdXn zAD{*#3(`&m7Rby$Y$pN>(oO^x_{=|e1QpH&8-cVFfdw-2&jsCyz=E_Bfdw|z4;ev) zbHPR+?L=UK%=~j9?L=Tf+KIpdpZNzbp<#i~{PTkRi*qLe3uGq(ycx?H#|LWtftslMd8GW=Clvv!gVT*RxlqwF_T2K=?orqJaK#gD~J{ATB@x!SM41AoQI9M1M zgp*3s7&t$Jn4kbZlgz-t`2~Csn=+HY<5UI)&aa@Vg-My2y*7n`fs>UHv(%psAUTEf7|!RQ9&ad2HNP}D_4Pr4!GPQvYx?&P#VPJqL02u|71FaqrSpsSwa4o9^-S^24x&choD+P4u z)>qIKX`=e63=E2*J5m@JltkS@*M>2Od;>{yZJYqoun2Tb83P+TS25!?76t}((9MQi zrHr|t!a|vWU4xf_fvXI>wvtJih5Z*d0|Qqjl*`Jl1Uj+12Fhh)-~+8U<*H=_8O$%h zouUjHUIg_4xYHnE#~=V|^>b%{ato*r0BZGfXF_;v0@i{I4BS}|9ybF&3wMDB$N*3+ z$z24Rj{`-_ZP41EQV5TUfuEZ@544;|fE%=MrV?Z!NRd@40|R$8$UmTai20?tlR)>J zfx8Xd*^j_c!5{$YHgMO2tYA_WU|uJ9u#H@JCYd~m^7Hc0mv)^y7aRLB%;Lxl2x1pVrxU#GeB$| z2zwrgtqW!|C^1@UFfcF{gRjyBjmT*^GcZKYXJBAl!p6X${4y0J31W7EnmKIF3=A{* z7#Pyo7#LLHy%t7QaIZy03M$)*BFhGmRRbB!2+|DG2=3ExLu47`LCp|JCQ!&JF^a1( zFfdL5$23S+i8BMkYmk$~K!-SioiqjHB&h`q49YUO3=E7@K{9y@7#P&UoEaF7^D!`} zfiyAR=0ms>bkCkD8|2ObkkRs>Q8Gy;(7{mhpd6sYmyA%)qc^0Rsc$ z3b?iNK-P*cWMEJR9ks(aA0(3v;)04y#syp085lM$WMEL=1ak$*3@omI+-t!6nK1>$ zMQcHaP%&+0XJF8f2PFU{#*d(oSP6C#$S5Nh28Qno85kJdIAD>p66B=FMGOqepya{0 z3M8|35d(uJ=>A$37X}6i(CxAtwd7nF7_?j%7>qd>7_`Gcx0!4OWs~QN7#P%*To@QQ zKsR!zxG*pX^D{6osDpHZ!ciS`y}A-e2z*JdP7)|V=rMu|4^T4{gu#8znH&rZy2%WT zdW@jJ{Iv*l69(uoJ$*({$)dKHfk7Xnb|*V%$TE%jGh+q=gA$`9sBqX1_8-V^>s%NZ zViq$nFsgIH{I?(EzwX5_M;`$>`aXyo33AD4P_Fs3n1R7yH7f%{j0*#Uf-nOE;|Z|u z+gunJCV_l^S{)<<_RbWTS7$-Js=fd!!eGdF1e5^U89}ai;=;fnxP*a$5p+EcBpbAY zT;i~VfkFM63nY=L-*91IFz07rPy;Dv1O)*sal<@#3gpUL;5{86?}P9Xkg=d9C&buW zAY;;gR8z{Cwj8IV2C^43T(#dB=&{j{7Q|7ob zFgPq_U|>w-f`#K}kTv;B85p#$fWrI-Na@n0P+NIi85lA^*8DR9g`=4(149Fd%gCtC z<_h&I=r(e&wP~&l3<)6nyIdIVI30*AV_+}_JHQO=Sg&Q! z{t+lV7)(k*p=F0^PSP^aee~QgbL_z8OoW@`05<0-%p6d{0S8q+$c3N~0-J2g$P02J z2P1r-gm*au1LG=?vETxQ168qcmcBF1|hg&BP7LOD?s^=!JP3IC(Hmgc++47SHv85lf3CbYOQFn|g!l@2IF2(<8tF@vd|fkCAQDy9Y%YhYl|2N?p= z0Ge!R1eJknTp1WDLCNTyD+5CZi1ERdfnhQ~1A`qC$U@N7Iw<*FUBC^hP{xgc0i0QU zppI1!fH6W~j0iVK_EC>=gPNKFGIc-5NzfPumm=yVFjLFiAjOUP6sYsnXTTV9V2pWg zkh0u<7057j&e`{>gfO= zuM%@QfW9091M3x#YVhd*Y-rb)vmsw!&W3b-IUDNroBLHp=ItMS=j_m#s}HGyXMK$m=TFtH(BU(SYleK{M__2q2$p%;xq`s8pf*cC|E zm$PABU(R+DaeX=4ZMZR@)%a{gUSG}zxxO5{s_8MvSD@ASY;O=|=`b+BxnL)~VfzO< zumH3gpY09gMs?8L$j~bT*q*Re!A=KYdj>ZKw0VT>Ig|@I9f0ixlnXf>fbAue3ppKt z?G=;@IURuQHI&QB3vwmwbO5%uP+`dF0BrA|T*&DFZ1165$msxVAD~>w=>TjWpL@%0NXDpSCk#J8lUYqlnXf>fb9>IE6xsDjnDQM%7vT`!1fQyg|BLYq&~>$ z0Bj84n_rofrP)EN@!1%mT*&DFY)nutfQ=Q(Re)V`3b6=s zIsh9xR2FhN02?GSn3N%>1F&&IWg({nuyH}TkkbL!xS?Fg=>TjzP%h+j05)DI7jilP z8y}PlIURtFAIgQC4!|Y=<-%7rK^zG=9e_;;DhoLsfK3?6g`5t+CIaO`P6uEUg>oUM z1F(rfxscNV*uPJWbO1IL@%0Gkw)3ppKtO&ZFDoDRSy1LZTjBP%iXz05(N-P|k!6uL-cbZ3GPjfYuDLdw{MY2leqi z{TSFiAsh|{{v>u6(E1`l$VPn-lS!FD5VBDpG@8q#oWLN|%gVs;40K&U8|dzG*hYPj z+5D^=aYmp8N1!1*4%iT$AZQ4W12z*a2wH-}0UN>-1kFTqpbp`2qdFStDl3r7phI}fCAMs!nP}#+^`PZXAm1}r zfD}P}&s+)NK!@;{t3V?yka0OKzt^DUSHz9WaW1xEXJ8NnjmyDL91uh~aX=7q;s7KZ znFJvx4nTM;f{+sjAUybq10d_+!)(yuEpgFw&|RkLOzof}1?)iA7>O=P2hBALrGe&} z&!jUjaEdmiF)(n6K1pL>;ARj%;ttYb$+R4#qumvBp8PG4kmvzd(D*q&Cr`)=klW`8 zGBEIjfdUZ}(!0|c7K0j34u8{(KHLE}u!zKo0@dzqye13}?~m?2JE$-uz) zoQr`$S{D>n8X#uMD(Km~pf-pnCj)~lmnQ=Qqd&-Xt5z{E$j)+QU|M6rf!grYfl7yS&i3 z$rs3nsMatjFs3n;GAJ;nFqPCRAm-6P!wIb13=IE}T@9LGQ3ku(6y$2A9!6!bqs>6B zWa?p-1-scC#1mf4z#t2DvjrD71B1hAs8bdB7#Q{wlkmY7z2w4pc%jbMh1}Fx==6r*Ru<}EtK;aFRl7flA6=RB!tervS z4QMix36y}rB@igC)IcQ=C}lCIfLLI0kh{U+ptysGt1})0T^id3PP?FV1j68+aUM4; z#dd*GY{6;<1`UuTqbfflae)UK85O{TlnhdgY9O;_zy|`Bt!7|gROW@5GXrGK^fe3& znvtLl{~*H{7#JAmYNjD`SAvg%14;7pGB7Al2W6(!AVZj{7$7NZ4Jb`9^)M^%1X;Hh zmihufxoaaR4>E?!P6A172667LVPKG50OD=|afR2S+kXn29zbakv?~Sa$YfZyK~9UH z?TT)ifZifMs4#$^|Pf`O4B&(T5(Xy>P>@3sh7hQ-@&=V9pyb2K z0G@$nuC)elFagg%GuMG83>g{0GtkWSMPM0KrV7y36Ht8)o`Gg==z@w*0EvTYI`9lM zZ#1Z~g3dtmPJo!C4erG;gL-i~;3-``*p%)KUIqqTFae5f1{F{>pbhSGGJ~dc^%#pl zMe|lhM$j44x}bEX3ub`{(2gNp8Bo?$0i_&OCTTtf27MKfNd}BtKCNijiG;4!<$;_bn zZzFJLn7Ig212Gzbd)LfKP_8k!2hI#S*AG#f?NY3Kx_CJOuz#Ne9(adUAVJ# z!GXju3%tGPtQ)*f{v`v_CtrZnC;#4w+9yYuGDq%{Gh?|+2|7;>nyA5jjUNkIpPU7` zPtJnWCuc$Jlf${7t|tpppPU7?PtJnWCuc$Jlf$`SBar&!EU0~Q7NkBo3u>Pn&IKER z)F)@b?31$~^~qUK`{XP{_Q_cweR5bso|QEYw760L)W}AkCkG`^(3BvkkxgKp{19}W z+z~NP4q}3u#h^wu-g$D+YE2vLjcleW z(C`_gken=oR21m?Y*9|owML>EpmQ=A*yK667&$=`$Nw`K7&v(tlOPkv z;vtFY44k}BE(`n83II2jleKzR zicBDXDlv9}Eb(FlxgVqggfDD%+q13OkU#0+7MUx7b1R zwQLLwed`$*bU|WziEIoEOg)U?$N^2sfkXByCj-L-(ArU0$ks8aK>I+9_A1cHdZr#m zNIZa4gQnPFfz1R`4QWb()PRlF;DV+WV;BQu8CVJ=!oZ;4A;Q3LjDvx}pb-?H8K6|K zZ9M~nAt-`CJ^*3HBG5Sr+Er`}3|H1OFc^WvKv)m7w1KIIQAZj%Y__0s4}fihTWg2m z5ReGi`yN~j4E-EP2@B*QNMoDP7TNn?6G2HD>N$|%U=zx?7#Q{-o6rDN0ro6d8%Qmf z(TCv>kQ9R;s4n`=!N346;h@{PnQB27NHIdTbu&TR(BN&|O!c4>{TLY)nLtPRv4Yyr z;BDPZ4OZY)oQh1KRi3P%ip&@^@xvVrs*4yIp_|PiZDxPJgQ`Ah zCD2KJ;G6hN!R=e{ERZSqa6qPMjEsy{;29v$QPkGpW+o4`nVAJL5lkSN2-+T{$W+S3 zz+hv|7!N9Ddm$wTD89@=*_y$G5q9!4*lP@+BlVaVSiRt_)9Kle*69tT*6Er)3RZ~mzja@Ac&vH2s%oP zpPMsa5vV~8+Ec`d(kkN&0WC9!waPd{Av`t)en!qH(CzaAec22QoH3x55O_}!52xQf zkV&An7H3#KxCsVX9LO09vI5kGV>SfoNdRdV2MyYSZZG8rt(+EzEe-@_Hf9ON%xne* zMh!-g9H?>v;Wz6U7#Q7fh+{!nhgvLj3TTI43c0=T|t(v-oU^h35ozlH;~N# z4GawO;8kbdps)zt$iSfR5_$(J$Oy(D@Kz)#cBoVJ*clkOSdpE|APs96m`Fn#28;%f z4NU3m3=9milAtA$O!BM@46>luS7KxbxikXBrQk8c4!BDrKrYSL$iScsc3LdRX)52L z&N={U$t1#^1!jP3f;9SyKz6DzUIDf6EZ~i@JsTMq7;nSPw*Z;{dLwig8{|2#DUIw5 z&@EmnNL~c5^f{te5~gIU2N`gq1-ZRP8X;g2v4l8Py?c zML@L#BcnQGtq5rQI3uGR(_S{{#t(JKT9NbMORVLXu7bot1&umrc?cJDXRrpmMh7Kv zMpkwP22C&_3U&_{J7^c206PPNEGXN7_j+i-t94Kc(gZ8i2G_yd&^kB(WD1x7=HNgbP6sQ%T@=O=e zT3~nyKK`@I2VRH2&xO?C8$>}F0)o>f;iehPLc z1bj#dUY&zt7_wwzbcBfky*dX4AgEdx5+h8|>UK251zA39%Ey8a$c;--!WoD`+@H zl8G540off5*=Qlp0_vH72oQ@wlBpWJ6N3xB69Z(FG*nKTg@J*!1T>Z=0J=q+D=`(c zyTTVVm@KLcS`aU4l?$G;=H(7r1{w|mjVEz~FZ~Aj5;UH~9R_Onfs!a_Jc&CT!ebK< z$z@>Rj)a5Ntcl>FP0s0`}L{J3@G9V_0fq^^K5#$GDMh1RY=^-RjV49sUhda^-=!M8kse1N{?0Y08&1gg(LgSSk|j371xcmcWsd^|}3 zF`o1yhk=2KpNWw<4WtLO5`u}J3B+aqFQZpv%m#&0G9$=7NWsd$ps|^Ofe|z+q_heY zV96k6_-5#c&q*EzhHb1!9dpzXACNR`5CYOtf{yse-vZVBOrXF}WSk5#cLGZLV+Y7m zchDYOu%#0~mOkIiz@P-)#V`>hW4(oeK@H@{?>x{=os6Ip`(W0Ab}_(420%v3gYOq- z3SwhmkO!qHMaC|WUuS{jK&F6k;}!-6@IfySzs>?#duj^s6z`(dx6Ut(UXJ=s00=L&Tf|6syHmFNMH->`)&KY#B zA(#aULNFr;B&0nbO?6dCt`;&(TS*S>B8U8)D#Jq(WD-5{^2Y=^n`0LZ-+ATD_C!f{Y??B346 zpw9^%P2vz`U|>9g>ha@X55Rqb;!Cg;NQA+FQ5AIAd7cOF%BUxt)Q* zP#kKP0?4kWDWE;ds;mqQwmTS*BrQOa%^P8o#UM!y&?q7(7(ke@O~Vmt5SZJJD%*)F z+XZ$g+z;uz&?tk8fEeH)2E_y{sWXA@hg4*I0cyryL)k&Gat8wgV;?621H^OJK%V=! z11TT_K<>W}57!J3_Zg}q%3zLY1*Hu|#tR^8-h(F$K|TUu*PRRujJ%)|IKi>`9%N0) zP6h@o@CJr2p!wHTJCST{09o@3ZtDyX_b(1xK@-hjDX{h0^`NvQi6v=*7C}G~qa-*n zO74PfppXW;)qfW>EJ4A+V3GtfM;X06T0x zEP%i!n=)<&!#TawOzaWR0pqXI6Xay2R%qa-%W?*0p<$;ZQS!BGNN2r?Ng z0=5 z8R$rBMn*{{&@B<*v0Q7=ST0XAs42(DXbtM6@j%x@*uZ;fpz@6IIq1+-Faava8RXx9 zE-h#J!~?3Im>3vr;T<$kttJgtV+Zb_!4~oBf|lZdswBuFeh`;I-UxL0H+T`hJ)%?Q zfZ8c@L<|sv!Utlu1H7jOcAW!!Bo)lHM|8*>P#5t#froHGi}>vkgVQ$P1rNNi1rMMI zl!m*M!2v#~4K>>%kbwa_lFcA23~G%92EaRe@A4s?y$NEV$b(?exvor%Y|UH@49uWX znxrG6z{?4k>Od_(?43Q(YJX+qCWd}YR_|O_AWe4yMd^YfzHB8EmkQr&v!T|6_9q7seHs}s~ zHpC8mHsl@nY^Xc%*^qYNv#lU{2R=I~JMcLWJMcMBcHncM?7-(hIi!jM<&Y{4)I+K` zkapm6lCuM!sRuOR3h8x$4?zK4(EtucRtAxcMGOp#T-*16x|4qkK&yXG6f!U{GKeG; zgCzEW_JWJ@7K0?NgG5Aaib0uLqzu&X;yU&Yq;FR~ScfIps57A1cTxEwkd6r;5m9f@ zZ7!nW`Je^JnMI%r$oSc~ZhfY?R)_{mjk*;f`J|EKTar@ zg}n{rKQ1VjgZ%@@F4*!99`*o`ENuCQ0Q)Tv7q^HWII12Xn>f_giD+ebh92i z*gi?9iBS8bpj@bZ(oimB$p)7Ul*L70gK)E~& ze9fRB3uOEbGEs&rl5r2*#Av7@sEIL9F4T>&P%ejre`X2;S3H!98Aj*X*f?A&k4j zFz|7K5@;dg36P00T$PNyp!*rX39=fh2x?*tlnXVn7RrTss2<9NdZ+=)g?gwF%7uEU z3CfjV;L8PhsF_iUgMooff~%YHFWmZGs3NHKeNZmc`hF-E>Y)ixF4X!-P%hN^$xyBc z179&HMN9#2kLQ=*4gekH4nC}p8)YhuI|Q^i4peu72c$wFJm^6kVGtg-z^7sc2JQ&Z zDJ4wG0s==tyhu<1%A_pBz~9ClyNZ*6LEv~10|R$FhzS~p;?HMb;7$VVz+_f#U=-K} z(gWT~!>ruMC}0PYO#u~6%*suSklJ+@=u9inHrRRw{(0Pf_d#ZY$F`zCXIp{H1dnZ{ zf_%cHEWyA$F^_?PI|HOm(zSqrfpGyN<903v2C0o;4u~oJ3RIaaJ;cSpAS0a&sxsD` z0PVIg1gThe4#eDD!oa|I<_d_Z1QI=a3&e~BsXYgBpY&2t?Q#Khnv3*APz`hm%uEFt zd>Pd4kWK`d@b&>n+kBAdyJsM#KSN`J_!SZ+#W6l25}~k|HYX=m5?|SsH_%e0+pcROrT^d&IC$5;!L1CDb57S8sbc# z952oUDvZRLK;?=2I*=bEpc`i+xfvJ~zyTux4kSf?&lCnmNk*_Z*o#t(aUeCbK)#V? zOa`&R{*?irWTOD~uqobLO?E;8{}XRQ+_Ha4Evy#ZUY$twzLn) z(te1g;82;s2v&0jRNsP_36MSx`X1^ZVz;{ z4%C*{<6&S>14no~D8diyfgW-&R}i{AVTB+Ag9;A=gC?}U%+wIL)l&i23^o8xL^k8 zaNwCB5q&NO1~9{li-F+;NW_(kfnn1=1_oWwsl8nL85nezfq}t8jDdmidJD+q zKHLlpdk-)$XghE-Fnk3uOt={sQVudOXlrmYFw6llWVjg^zJM44+zbr&4nafdnjiy1 zC@*p-8E8VMenGux&}bUNcR@6HNH3ceJc$ce&5^^vUeLDgb|}9C><4n zw~9l|VPLp)n1O+@f{%eg1)OY(K*@&j2-L4ZLJSPnpxr+36v3zoUSkN}&H|E+M3H5K z$QpwTX9P*Zk`j14nj0d^pv?FSCY(oH(Tz`)1`S|$&6LmS8qhmRm7-Oqds3?|?c zF#16o_L+JZ!47B@VqkcQ?0|{In$UqAMhjRlGa5h=F*pdohgvL$h1+gWsF*U=g9@Fc zkUR-;IS7MCU_JR67|g&S+t$OsF@FQB}*5wb)JBo4yaM;RCx zWd&eHYy=ze>?i|+8F+wu6S&;4I>x|YRs?duW^mcjaEyV$@&|~2h!NCahMn~RvJvcf zkcD8+-xOkCc+QWM&L;Z8JkP|TgYNr3LeMA$X%iMe(pJZSt`?l#Ef{ZrimEH9emZsx zbnJ;B%uiRqeu_R0^V3zZpVou;U_V_07g=AAGcZ_%fe!b%0UnpOJ^}ONQ|x|Z7lt|( z6v3yF9Xrt*yC1&oWDn*c#facGkgGOvckUYU? z3*J%03)@iy3OPGaWoQR>fDL%;iw(4y$QC^6#s)h&qd0Y=;>cLHX4VY!qYwjV%f4K*#_Z8|)MeTky&U zUf9Y9P})bh7h^z>aM>6F6})LN9N99tEVJE4Z3q?+N82*bBS4S!5E!|M@-KZP3pmuiMDMHnt!28mG6nQ73m zO$sCQG{SH%sNseSsg+tjA`GvA8tzRs!$C9G&>N7~Kn+i&g5ivUjH-OX+{}E^e4%WD zj6sY7pq2J24BXsy+{}Co49sE-%zRed*4&=L3=Aw#aSjFsR#OI$2%9h?H@6kHH7lbq z0|PrRL@leQumu+b1BW=0949XWGY3c^NEa6`STnaUBQqaDI}b<{q>&eDCo4!TAHq=3 zsp@c3Knev|Pz(^%U|{Bx;bmYDg1U+u`~Jr5)-K}HBN3NboxO>^P_=~a+rFcb!fL~w&TGKwH>5MwACgsapE>RK`y3NtV$ zn?Nn`6t?HF0ZsGhF(6C@2`~(3j6%a29CJLV(aQ^qUOwdL<%dThIJ^a5Q7DKUg+fqc zp)n*3i$W1l6f!X2j7e-EJ{=O`60Gom1YHL&iNpnUy%E6-l9lFW1Vs)greqK@3=Fam zaRvrCgea(EC9eif8VayfqX?R9Q$nbLL>)?8g0xW_b*N#<4hu^Tctn817?c&ESsIjy zxZtwjOw0`pYiK6sL5?h5xCLOPpsWea(;$QRp-~2w6F|=Vg3ufWP8LF-bilv>%a&j< z5s(mkP3xAcw*YR7KJXx?BOlwdVo(SRGjaRA_3zjba6r%{Jgd zSre3N$xly^2xh~PaM_W?Ar%CN9wVd@Z~#R+$fKN)AOwXU7u<#1>O3f(rojBd3rQ&yMQAxj8TT_WAzjUDO5q?f{ufM8UvM8Lr$u2*Dx@sBV_?r1_ljQ218*P zR?uz$21Bs1S|AZnxuA`t66{qSWB~>ST}TfAd^5XP(v_- zn}NXyq!Q$IW4I^LGq4F*2^Rx{DN4>WgKL0=3aBas*(m7OGuuuLe_?s zsjR_?hn0cB1{!kE8o(C8g)~hl%P^qi$To5rGNmX4v=S|Wf7>` zz$nNFO?h%i=~x~Vn4r2v0g^}%NdT4?VCfpv)kZQ>8C1@K@`wr|VnIn4XXyyZN}ys_ z11agUF)(N%r!KfJ7#Oq=1~V{#TM@{u0v(Y33=F#9dY+AeK@Yi92DwWgW+8|JDh3(g z0RSoo86e#*BSgy#)K@eHmA#;;PZNaYpzLLe;6n0_8L|LKg*iO$a3gv<7Lbz05|oM1 z+7OWJWsR&0B4mRc9H7i*i>ij2eFaE+f&*Hfg2x!pTinQ52sDfVN&?{Q0v=gpU?4iz zK=UO71Jb|+C<_UJieX5>EDQ-Q5lB)Lg*pq|XcU9yRA|-_hZXY@uwq^kIWtMYGLtl< z@JEa%qUJz3^t=XYVuO4L9+y-=O&cg#16stwGY4vt2DKZY2@It}4b=rJm{pOJs2WnP zREJ40FlZnW8Yr1*B5~Om7_`t+y*4NTgB0pOjDWYVLAgK=QRRTLsy;|91A_tTn1mrb zxq&Nrc!mTSUowTG3IL4uwjF4DwLPkDAX&^of`Ng-5iWz2VV%%3pEI&5h;A29 zZgxdhNR3tx1H%ASXs`-E5RngsAo)-jIRlEIWM(Vr+^PZ6fLu3eLK=D?b>MC=1A{g!x$3}@t1iSW zP)dik<{@o#Xtl+_U;y_Ttg8wuHVi@bfqW3b4cZE01acmz&N4>i7?77?IglIH#78vW z!C?SN&1R6o7NzvSW1Q#uE;5wm4QJOmI&2giBKKHU|`Sy6~Z9L zX+l(hnBbZPny6VB7$Efu8v_HZ-33X$3=Dcm83CGhAqg4Oa765sk{9FlX z>an5ranL81k$XCvsKcvVup%6(5eUjtJkb0Gu9bO_TZ>3DS>Q=#P?-SgK7leMIQ0v{ zdRRip!AxSU18Lw%z-lo`L@g!-$-&Yf5m17VL1ZjQ-6M;rBEZA0u$&C5Zsbwhe@Gb< zRQQ7X;UIHS29FpRz(Yr%;uxjZ4Audva2Oa+T7+ENl!6YOrhxnpy#s5YP$= zoLw0hU`;`2X4it`UGRt!v{wi#t3dXG%-2C`>9H~}fT|!wr$`T;U*OuHr3!dN7UWP+ zeFHKFJR%FK5Wyp|3=BpPt3gtr>ZW0;Ob7I}nr-!1)@K*2z!WptxsX zV1pIz?6AU}136i7!qP7nG{J(ac2Hu5x&oY-A*qQMWFjcJ;vY0ZPcK5q=}8!obr~2$ z5Djkz22u2Mh;tqm9wXrT8WaQY**K)R22eyu!jcN8{(*W36w1<|rUJC&1$$Tq)K~!N zkOeUq800`285rb26#+7*;{VFiO`Slo-??>4Jd)lz>65 zg6e_wX~3lbC>g_23>Tu;4^qm-z@QCt56Cpr~fDWISz@r78QJ}N4NJ$(zN&r_1u7f~+FvsjT zpwv{Lz63}ec+7y}Jb`RKiVxWlX%!Td9H=4735z%`SWe(ZHVLg8OTH@+IRWfASUJUp z7~}#aVs=!=abR%@Oebhc6BKcvB*DhOfPaD)Ng)qvaPUI>4~hpqgyjqj{19;l2Izb) zD4PgE5(kJWgp^|tbBJ)~q9+&FNHHj>gGP#>HbJ?dRTv-_Lb-?q1xU?4Xu6Yx6@5~$ zq7SL%2?{|ONGq27h(c`(AX-9jad6=R8%P3kU;|0erZr+k3|N*MmauqWZs&!$9W-Uj z3R)cp3Vzs>Ep$Xz0J((%8+-+4b|H8$V-}XesIdzwjX|XmD3Ne6Fo;6K9mEAi1EfS0 z2T>pwAdS<5atdr-7aA>6kQ4z@2nutg2$Mmi3t6OeAqUaGzyMp%1a~)Pyu#Z3P`i|% z-T-kymxv|tO~hqRl>Pb~1JCSqV7y`hQRP6Qaq!<_^ zP*Xa_fCek90|**k z5QBk11(vQWk9_f1_s#NA2?+yf`%bL z^E=RpV_;AQrFu{cSOql7rV6zRx(XLjW}wdz!P=< z6K)0uUE~xG(x3;@$-tlwPT^b(3g(7c3xNbshN&R~a}JPV7%@x@)eUlv6TH+0S9TB$*oLa%_JG@;sAC}5CtVS%(OHl+ zg8~EGJVrGGeH;a$n+n-}=u{u@f(Bd|h{6gQF=)O4#~dh=A}tz&3_*Yz7w}AnXUPj{ z@{@+-0~tsfmqkjupf&Qav-ga=7> zYLIlQ4k@NI;E4w8X;9imncoEojHsjm4-Z&b32KO;G&&(+E(R-cM^xw#pK%~N3&6D- zXwewb8cDP^3(|54P(^?|AObpE8I)NN1v#jZ4$Tv=<{2y=K_J_2PPuml4G zWOWQk2e<(i$_C1F&|!8EQw=%)fResCJUPI#2TG0ssX;Wz;Hz-7AbCt1t{YmM>%g-k z)Hsl(x^O|Ls-c#m;E4j3TlfA%YG!dq2MAKsUQZmhd{xGG@^#G9*coN3R1Me zT43NR7gU-fwZK4zfTk>w_6;G`m~zPR22HMzVgP0T5?lw!ImoSl(CS`jYYy77LMpOB zi5zLy3#i4R0!opf)*DK3jbt&%0#Nq=n)KC?Qw&rYtP7w4t4fQ@Wt83CMlmrM(~q@{k-jA`Dk4Wwy-3ACQD8qqg zXh00KEQL@7X?~zA764@$Q&<^dhFo}o>L--BR>+VMbe$V=Mk6!X)3wbHPqE;1kEm$i z;^34_*~V9BB7;^Mpa>(PqJeKsgY*($6%Eu7d=(8+y9kur;PXZD=m}5(R5pVWj3S5u zN+HlW9`Jrx$Q};R+zvRwft;<1loCO82Ur5M5d^v}8I-aa7(mqpG&g`IcA$9{lE$=P zNlF_zZ-G(}$b2108%GyCx#__Lz|A4l{^w9gWzez}oR&bvDKtz#WhUW)Nz|l>=vjh- zl7T@SE)7n>h&cjqNV{S7&?bf?D3OAip;$Kf zqmPWhDsy;cj5>S?X@SF5V1T0nQZy<;D>86f1hF&OvDyLw1ndJr#1KfIXxzfJTP{T#kXk5gPOG1tf?; zQE;F`ay-^SQ7pM1v7Q%N%eWzX1yn{bFt{TJ1H^a_xT+!A*G8|LKy7_!o1F0CNqFr8 zj#Gk_6J!VnoHar1Z%OnrKnfnd=qVgFsRqrwGKe|_www|wBL_(?pt^&o@f$?_g5HIO zlsKxeB1{cd(O~N0vZF=+s4Jrv?2^!W5#W@X3 zAVEX>tkCLB0zLi0I&h&{1JOq;py8HImv^P zGRn$fNP;(qfb%3I8R~!%7^0&Ltv*mXFrc(J+Ep3It_q~J11;uB+&c&!TLG0pc#3L7 z8de7-2MyFB7CNj5G6Q`P544O2mvo>q89uP7gW59zbyPsLC#Vwu>Zm|!3Q*HZA7mFI zFCca*p{IW2jUV6|0eO7}xW5iHoRm%qEPI-v_B{{_YmqxCsB1aEZm@)S1lqv>E#*Kg zg2!CV0nd`)@Pgz&v>myiK(>RcL&~T2@ah7ZMIDd@AXyY;eFwyNj7^B6bqS&_fwgwf z#~Pri8a^2SYkPrbSWu@AK&zc#{RVK;40b>Q)C_P;Ls~zuSvasV&~i*r{|L;1O#LFq zIyf)ET5qsZb)c;`>~q4PstI|70g^BwjWm?WHuQE7qG1K;2_f%;2eqXb7{C*4uq+Bn zpg6W;flkvw_5|AOAKJ=yq*@hpv<_S&IK;sI$Cf$S7#PeUr4_WgL~Cw=HNpZ8w(S>G zFmN$2SV64>aoHFcu;fqJlq)ogA@U~JQIH&E2dQ77tE`YaOL%i6QdUL`E`VEppb$mQ zmDHRt9N}hJfG*r&C}08|Ap4t-i-D05e6Jj%bAC!{GJ|75K~83JVo7Fx9)o^Her~FM zakhS9S&@ZqdS0n+Nq&A#az{B@)E=8GTsYS*5p}|i2&iO^D`Vqda?vDC;dc>%KD8{8SC$YF#-zBvyGdUGxopXL} zZhjsSiW$J+g5L=YA*n^VnR$sh3=Ga0iMgpcsrh-jzL|NMddZ-(+I?JI^fEvU$Gno% zyu3u8)UwnZh)8f{aYY|$GV@CGG8mW{7&7xKjExda zO7$`rSQr>w^HK`(A#$t;UOYJ9^fDOO7#N&goSi|whj>{pgMl3(1_=sEWiW6uFoXs>g(Mbd>t!%-F~B{km%+fzz!02TQj(dMUJP-&Z)$FSQ6+>O zl$e*25A~B%X-P?b9z>jhftAUKoq>VbijkR-6Li!&BPSCBBMTEVCnpO7BMT#QB_|sL zNRA1KWP!0+n3*|2>X{j#svt5D9S{;?N-0R5g@suhq?(11IR{L$GOK`XVPlTsB-5UyrplVXQ5{Z&!4b-2BY!hH)xI|s1laz@Tmu-J}h|;pO*ZhR0al6nc$LIoLrPy zP?BF%49QLKtiXtp6(E@;B{dC_NrFpKkaePD6?o=gMPvkc=3v9L7MynxS%Dptm06iq zfRgfUMo@YMrDZlynqjWv6k=dxt_QOf!6XwXH8Q7wQxZg68c94G%x2*f0PEslU}RQ%5cT3P#X{0|CYW>8LLhJ*t+heFvbpzvW}Vgbbj7Xu@h#ROIh(SfWM z!e$2PUH{z3S0(OrZphRx8V2!xeX%80hQbVlKhG! z$p&>6Be=+cI1B6%uwx;jU?)Q&kAaox708GdMo@Zyn9l`v2p0pWykcNvWME}t<78l9 z?m<$*!2ogw10$mexQh1yB>_g{DjvCV2iG>FSJ*`Az+D6pSA->&6~PKEP%(yHIe}9Z zl5ZfjCfG}u^(A_}#sIEPAteP10|Rmug<7cQg=ZZ%*<*aVR*8Q0qOYR^z;5W^r&LQt6(2DRAR`WTp4m_d=t2bN}LgOu?gQAk>YvREL}%;0(wmLND77}=n$LvSq$6Bht0W&+89 z+KlC(l*23pb_XQbz->DQRwfZ{1_tIU44`ZPQdq~y2QI@QmVrb$z$Sqz8kiWk)CN1B z1(Z3!ESN_anMI0G5Lp%m9i~P^yNznE~WZh)+O;1E_jqVusnu z#0;~Q2@R4Ou--&_%ANsSx!f=M6}C4(%{tBp9U5 z4HJ5)4{nFyF0Mh@X$2?-zrh=2EZ{I;0!KI_I5xpeDtJD*0aD(~1S*+8wJfA908`Eb zZj-Sf*SI_k49pXl7&$@Lse!6s8IZtqxc<9!oDvL-%+a85hQtiBBA6Wwjs-~42ge;V zgk6P0TnQ|0112FVXVpW!0xG^>Mu6ClzzKwT22385aFOL7L*%E|gHjgMT4Z@_P5_z9 z1y)}Nc0M>kLu&;Hy9Vr<`{3jX4^0kU1_tK4;06gO?7$5iczy(#2@?Ui5n>KFNi+9C z91ja6h*D7557B_jiI7nG49-u?Gr=*-TnLV9YQ+E_QVgVk(+?~_KyCyz#h_&Ya}8Lf zA~;xHKwMN0s&L?CHw)-qnz`VlBFDhUysVy6hJlfJBeKsSxfIfEfP}>-a4iQ9c~B*{ zu^#LWh&&{1z@ifrtk}W|Bn}BHSXTlhvL6y)#2bOjXk6k4ASo{%95Up&R~f7q;>69g zcCRqlGDtB2Ntc)rYz20wrbx21aH!a1yKMQ~+0hpq|I{dQLTPy91Of2`5@m3Wo(A)eBwCOg$nz2`(Sl5XCt47PdR~H< z1}d1)5-msql4##UN<-La2}mtFI6oF}>M?*i(U2yzfCvKv^FDB52DRT!O5Xsf7fNK`7^!bdqz-EL zrjgtX8rX()fx(S2BssJm3)%=9QcH~mv!%w0uVW2u{DIqZNS$mJc((~G18UE8f#UKs zQbz_f#sO=t&j3kY1eZ}FU?reR8Pa5cL@T&;4~=dnP;JZ%8Kr}?{e{3$j7&oGLP&6u z05|7X*MkQ2K%ElE=n}Xi0co%^F@r047AEFOu<+cSrx1r>}0To5NAV*YY5543GyIVAF~Na7sOL6Ow5bH+E^HwEy0G= zf)hKcm7s(V*2==f><-e*!pMA*0jwOX8O2Ue5W?&P4P}BgGV_77!3V~I#26Tuw^F5p z4r#hTYFp$^Ie0_>(&J+;00kGM$I8IU1R8v0z65S$f<`bvYj8j<@gpEN-2*rLnHU&3 zr9fGhftBe2Ncb_>sUV-RbJl?q3MikKgZ#vt2g>2lsQ@-G8!XNVt{E4Chx?5%@;u3X z9*XlhQmzE$Sdtw8>2$$|x4=0ac_^Z|Bn2`chNaWRj4vyvrWO=|Cwo{J7?86yDDy55 zXJBAH4i0coR0%-iWCKVTl&6_MlR%s>;R7Jy`(V|e76+v1T>@^cK&p61z657DW)`qG zB$d>GA`;%t{sS@wR4A~5OlO94=IX$`0!R@+EjA-42f?icC(94uvIyi?ShBn(!N9=$ z1?(wM2NP6DfpQn5qIv?7{0Wu>B}mwq1tT-qN8oG;7K3)*A?#{!A_WZ?K@Expb>bPq zK_p7WL~1L6v=OZem`FPi7uyY@Cq+ zHrWGqS!l46bADb)QGQNNY7u;@jSG}PSegETlKgdWk_TlI*lY@iBm)EUZEyzzG=~cs z-~tU}gK`3>_F@Lt0I+J`0HpXM*bGon4>Q9CB)kq>10Wmi1`^&376vsKA-xhOXeSIb z5zNe-0Oo-!Ar?kvNb}tqT)=>{*?efx!`Vp$iLA)xrv9LmC@wC^Pt=WhwdKf(5jwgb}^SL0z1}fmrJT zS*ikC2ZLPVV61%MMojp_SHAEtFhELG7UcCVyh!D61_K}1(V6*>nLy}d2Y5{ZQul=& zWl;513ORt#jd8 zA+-TSE2L`(Zdfr_K?`6|p$i$=1=kL6V?Ke5Spzo)+%knr{sBpD!Xe2f!@$7216&*@ zfXZnWMrO!NDx{5z>RK6);=^FYp-{!TpsEnk`(s8`Yy?t#4#`?2aD;+Z48Wo?38dsI zk`hqLK}}qJASHL;O29z__t^}PB&at9Nmi(mi$IdE;5xzmXXt7cj5aF+E7K;B@-J}Z zs6n^~B>4+2Nyw}-AmuIK5g$;d0S6`A(N{o{UEqOt$SNC9r1FAO2zcrj+|FhJrDaeT zAJ(sD0Hr}tA_Wa0K@tUotOX|x$lNw)0v(jJL9O>Zv@3jyqXW@b<~g@uv%7$b4<4jqMygPl?}GKPFfm^R>tbPK zehYD<9oYV8FbOUNSeTf9)NyKoS9o@V=50aCO(EW8VPx)sl>c8L6aA1;Gq7zeOw2W) zz+hoy?gy)3VPgIWGiL_OoEP9=V_{^T30A}W0-rgnA!=4a=3zJ1gNqTcWz3hslQGaj zoeAVxNR1B}-qQd({yx})EKJOczy`1|GV6e2kT zW=T*$!Noa6paV276d=>w%-{hUW&u!92pvc%0EG%OEbV~GQ*b53!o+;I4kQH`Bg_PK z6d0b3mQ!Rm#~DCvOjs8iTv*{Qo~TzOK`n(gzY*Pk4wS|)BLf3ctCty4c!5afWw0uk z6E^WYG9XTa5QGB|B>feQ#oyNnf_s=;}h zxf(1BseCKJi4&sV9h3r@S;1>CAn6~H%OJ%GBzxy`Dlmc;=z?s8bkSKjofsII4}O|Uq`G>Cf0^n?URC1(^ge@;+gU|>GY1S)137#SNuBYzClAQGi-PIAqT*y#XX zND1lkfHxh0hkQ``U*K`#l+fi)zTVXh!0IMoFj?VbdRm1agz1(OSEtV5P2f+vGO z)ixwSqLQGND5Qu6m!j~|oO2+fCWB`!KyxsVlnx^injl&sMncjXBy~YVAnO7lY#0gB z3$_Z9tT~0CDJo2rfq{7^cv3|IoGC#HAsrt`3jtDNgHjx5EDDr)AXyR8des7FNQl9Z zUM2@v1fmAgKLa}rw0aL(06>^v6G2Q!X9mmy53ECbb&v^LNG4!|W_3_#E~tm*a*#tI zjd6%&5TC;4d_l5ci=mxCNS*>)3LR93G{qs_AcYMw8Kxe@hLkRlHMo#mybls)`k>|% zyfbo2je&uAB@<{dB&c6|o&i+kF*AeIKzj|a;tSL_0L^1DGRuK#Y3BZVXm0?tvcTu{hCY=p@6L7W0f>Sq|h=0WEElfibDfP+E; z%m(X#kH@xYfGQehM&`Yc6^{_NLt>g0svZ<_FmX`b12zGY6QCtKq%?=Q4irKV6JY*8 zn6Ms_+`tVuxFf!R9I=rZltn;31KY*I1alHN(pVUo4?(nom$`b!uuFONeVInr~wi< z%m`ij&&&u~W5vS6>u=^sRW4{=5BDrgT~L8A4i3pO_!J?1_1}5Or z7vi$*wV>1wmRtr-RA45!ZwFoBFAK7cc^`P`01FdyAV@vLNJv^_VPrN1r7;#JW?xV` zVqs)90kub%!Q~$d6SEgc2McHk0w}FXgVaEDG9LtY)R@6V2-seb-yutwk=@@9DXXqR zRIdYPD(3&-kruG74zO3iOk{@(gT2WOwvQ8oChva%@s89L8!vF|h zkncxuJqGq88>pTIvzS2n9^?y1w-M4sg^=KwVFlGsU>3N02xfu1%*>GT7aT^+Yr)=S zo?Z(wm$?x<;>8>aPJxi7d=^*&Qc*((3QWP$$>6YrwB=udd)|;fDP*VuR1yk;T*wTm zG$B<8((VuzM&>Kvel`me^Ez0N-i5dZQk6mMgor?z6p&;IF2*78!aN0HF-%Ad9OB3% zBo093FBeh_K@5fT8^Bor+R*^JgBiS42Py)Qy$@+cf%6SCD=h}+V<-pWJD7tZX$fQ} z%w5QAP{=^i352`}E(IX_Dww~(`~z_}sL{a=4rffSLzdbhi@#w2uVMZKS?2_4AwYck z5R#L@10~>uzyj*ZfmvWjKv|Ha%EVmDsR3Sf3fT=j73L;TI|Zy9?rV@=z-=`aM&>1u z1a%**8qst%WME*P4c-d~n$(1CCA?V8%#h=4oGl9nj(;N07(>(wU&@5h9wzL)I*9($dm;v(Sgh< z1w|x0V9G#toB=oPL6Q_(!obAB0trEInE+|Hm4TuevgZV1u>*L-I-S}f3ahuly*TvH z`~>o88zZQV4e}{+3W6kkWD&@2F-Q=?#6h|si3^gNAtX!$k+--(0gRG+A??H>P<_Y@ zUONg+xsXm2%zQ{H29d}jU^cv?P-hHXV+XSYl0hLPBx8U^-ynS@r0NZlkQrE+9)S!v z$;ime1Kx`Qu*>D3r7S2`AmuA0 zCBkA06qn!{8#=rSiA#vz!6D9E0j@pyK`k6;ArDc5L~_bO`^hz?3=GU2OrRC=pqvK@ zHb_ebW-Z7J!LRw}epr<0jA!0ZSx39$yE20}vIh)hDnA+DpG4KbM$Y&(R_jKqeB zAd?VT2pI@gIRoMpXh1<^AVOe$U~jiV!skE4y%6#eL=3{I1{;N+eFzfPJ0XTc)LMb{ zK`e!cph%~Kr9qp!LBj!{82$z^1X;&-h(nNt3c>myBFJ%aAEKKBEDiP^bb1D&6yghr zEJOt2CS;WmHbflRCzP-uX0Asz0%AQ_0vrPnUx4|{5dYGL%>@ps$q@fOhS)3!7K7Li zk+=y7SBMaDcHIEc0a1nQKL{J50U`?_A^wK2kx3ll;IO%btS}$!IBqbx5n>DIfC117 z15o<83~^}>L?#8S45Gal%=QM8tq>s(FlPls?E$b(_@oTDh}sP<%0cELyAQ&y0c+*~ zlMv$|zJ=Jsk0B0GQw0`>@i*B;^-@ ztU|TqClhG9JjkCA!yvIrA2uZAL!1c?Q;5@AK})F_yg{7}lo=bW6&h%99?26Qq>s9R zr%G@+0J0nrG#E!v1w<)mA#ea9bTRHis+>t~inFS)|DpW(Edg&+&m*y`U}* zIK)|)m=Ay%%t*PKg^_t5I0b-nA2?2!*)bE%EpWe{0leI86E;K6fDK^=M=;nZNFwJ0 z8O01S7AyyeaM-q$_b_9jMK>fBLh>lY7BCxC6KFLZBwK=&voL{{B!JR0s<%FXT?BSZ zCD;|hU=m_1q@e-U4{3%#tVjj-&dw2^5Q&X`oa*$z3uN{5^dYS%($gvFI*3f!43M=s z!6k`#DTzfXL8*n1CLlx@zQBhGvF;RE4B{Qg(Nplm%!0Czh!sm>1}&X00ohfWT3ixR zSpZ#553v(+dK+REo{@pUwJbHS1UfwroAwVbDN0SuMRp7*FKhxe*9{>JsTp%4j#J$yOfz7+{b|&K(H4wDhja{VlYHIm}FsMz6c&_ zVqs*4Znbp>bsRw105sUj2AbJuf%pjKPEcP8(r*C|v9K^R+kyL#o%P_si!Sg87Yie^ z6ErkH{Z6oD%oo8^OE9xpKxV%JyPk!a`3Gcdk&(FvGC~dR2eB|SAAtlUxT^^%d=Tb= zkG+HTW<$WXK|1@8p4454&u>7&4`Kid^K}RpTxKy_fddM{26wPnn3x|!w1LOwnIW@n zJm5HkEZuEG*17z$=fKA+0H}6bmDB7r3B;sDb!^g^3xw z1d@f3ITvi-49LJ5c>SX{sPo2P3L=TC@n9((Txo#P^Ct@i24-bYU@|Z=ih&Gb5CD-V z#xXE#1eIkBz914s23LW^fJ*{WkAc=KfKO5+z1SgL2eAbetV95Z4XhME&j0WN2;;EG zVD!Ru7rK~}ay3LfM#5PtO47f=M~F+v6xn5#hr01FfI18|CAVPswfNp_HA1euU1 z1gB2OzzQTeLb4H(IArEj7ZhC#f*_KpNQ1-;=>bf-4&tH&;vRTffiqxX3ym9ae8J-e zW0fgJOhR`AfLrUD&`unvtXg7?Eim;eG-dLQ-=JauQ3(IQEt1F+n(A zBkFOK3KSek7*W9lS^x*}Y&={tC>*l*2^I_p8R-7Ec!COoASS>Q1-2GLP--Dk>wpcG zs35Ham}4M*fQZ4$2k=3!@cp^a6YRjLNgFyY#0+UyLfVMn)*%ZM^GpbXk@+QfG>L_Y zc^+69Xx#y%Wt#(TSwhB_AbPXGB9J~<35bo~oX-$*Al*ZVIS@0!ZDvRdm018}4kW$9 z+RvB3(-)w&FW5y;g%I~LF@FNPg@uuM0=Ov*ZDV5?$&Agh=z1Z2T(HT^$j$^?!3=5a zL)-v%IK-JO%nYnda+ctVikTJE=z^~4fiyrM({4gjs zgWU{H6w06p6HwSfA_vl{fP?_V*I@rbYy|a;z&3)^L)3s}k-J)u2xNwggF$2=V*>@C zh{a+Ka)$+CVX0fw&5!3flk2Vk1NiL_Jb( zicFV7Oe4?DqhSut?gNloMniry*-m}K)tb)aQYps@(pR4;gC7-$I?WXcml zf@*zG=a!Kfa_|&*_yDrJf;k0Lb3^)CpnbXEHQOwpKmk|VO3YM z2fPo3g%#FDP=dAvAZvXLYKOM)q_Kb z^lT2vnsMN9P$h6Nk^p8afY^|<46+W~x<;gBDM(sIWPC1=0Hp8&j~hbQaX?H*&G?|E z|7gaCCT?)*L&+gTW_(bZf|ZhxjvzRnK#d(OACa;iESMl+4JiXh0}IsA1&?wPSDAp5 zCAf@%jD=9KTA@iP91X6Rz*FvorFgdAw$5#s)LWP z!WpCwh?1^@xWR0a{Xnt?64nubl)`VgLLNqkjeA1Hzz2^(CNJP3%t#wpF~(J4`r#v{ z&>>soBg@#4hFUqmleeftu^h-}IDj$^11nR84Fd!71NbyQBY1&4xUPqvb2tm6OkB;3RZYuZ94V!(5okew`$+X9$j z>-s?*jw-0TK%16eYg@By85o$2VZ8}hD+P3X4D8^wCXfpF=+QLE4m%AzH|yY8V@|&=AOX1kXT&&c6Wp9Cld?NCMotWrnPe2JZ!CVPswaneK-yapwlji$fxZg^BqR z131PYdx;=BEV)5#S>_B-_n3u|c@KDN3Vb>G6Ohw)!P6LI{|Ur+NbC?|gVqH=j_w49 z3_MIi92gjwL0jM;QOyUMiU(Jq;Nv8iA^UKOKu$v!g}bc*WW*iNP%yJAsKd^}$ZQL0 zorCscft%JWjG%r9Xx<-^2Ox9cu)YCk^c>t91u+ z2au+B44`=;P;m#zn-CI`&zP83ff>*hA&kuTzy?6Oxsd7sTrsgQGh2X1wOE*qL0J}3 zFR-vOp9N=o7AEG~uw^}QAbGeG=75}F&&a~Y{2NkWKt>iY7s4D^r#9-S)h?T zaK3@pOTR#J+6XyN>jS(R3Uqg$69WUYA!s!42?J<%Hwz>4JV<@R1gdW!RnZ!l$Tjey zFBV4T?JyDWAx|uf%;4MsP2-UB1(-mat|9te!C8!nSrSY$Le86qtomYMX8r{;va!|n{wvDYYzSYUM~WR(lNhD2V{vL4*524zCXpcSNcfUqHT1b9##vSJ&u zLL1a&17D;G9{SqP2+{)Sg@FY$KpXEs2DX4C7@7Y;n4$YjAd{^SLm=iNlMweVfS3UukYR@G072FOQG_XiX%KWn5?BMM z`3!dq#Q9)x=&&j>8!~nUF%IHI2pgh?7>gCb<4O=+$RxxBjD;SMm{8&Xt!fJ-y#T;E zc!QQJ&@(19j}7R~3Ia|fIt!zj1Ib)O>joD9Xa`h+>s(l_gXcHM1u&2s0x*`A!c-$K zB!#dsiUOp2${{%#q7GEtfKFHjoy&rLWjWF{=Fk#~=u!fFV+bqL15l0o8QkIp^#maU z1F*h2s0R({$8mwX$&i~hA*V-x`+bo6-5`xX23965X9fo5so)|9WEd-GH7qEDLDt1G zGlM$OkV=r55qzEnxcY-@F9B&^0M-tgHbT}8;-hK@_4L8p{o&eAfV3lqE+8FnaCZ~z zhJ3IWz=p6eF)skOY*`qYAJu`o{NUCs^zbXlMgVXiz*{ZgvTr?nXBIg3Lh>i*`gRuv z2Il=>hl6?m5SzirK7nn{1lQ@TAm6hvF&_mtFrdKz>HCAb04$8myC93?!3)z_n3#Wq zRkAQL|EmML9kNas5+UH$ItvrC1;}j3nl;d&)F6kngB=2j08V%WfNyVMhFlQ^F#zm; zNGpaJ+;V}3BiO6Az=nXzd9YU@Au~F@rmQ@JIoN=N5R<0f!m1!iDt3z+naVHCQ?5o-VL3bWRS!1_vKF5|CFE zK$ZZ4YjadXKs)lmTA0CA3s@s$)h5I^h)W>TeGqkEaa2P9Gtl5<=c z7?{t)j$&kBWts;PfHxh$Lq*U4SZg4%Dm9ODV{Qv}-_@IG}Hmfsd={ zftS?7oC)!wUIqgP1L)icmX>S6S!E^U}U}z=};^} zu0(D_#Gu={Wx-Vmq;LZlOVBbDSp-=e!iFqf2bZGEkfR^YLQDl~17~oELQHZ4#4TWj zDE$VA2&9mQETo2rKuF}37s!S}dI=CU5OD|_yg(e{7rf3vUZjttAGPG}0#~bu`W;Cj z#0pg9py?T7aJc$`Nh1)+!o(Z~ra{Z|Kt_T4Pb|#LE5N3)Ff!kQbPgfz2Mb~eA8@4u zJ~s)X4njgy!{op8F@tARM0g^3wFchABIIm81TPFWx~LMvSGN(9J4c8CWz zg7^A*4~udW<1#QZ23d$I`XE`HD5cO2CIf?SVsUYBNq$jcI^@hsNC^fRQ6W@zAr0)a zAj%9#_Xt}z3TifZlOD`$14+_I#RNFZER4)wAu7Qdp@pI^IE;}+AZ#S( zLSlRycuZJnw9xW(b$6s?)63V>#S^&!18#f4N)+TQkKEG2S6abK6C8s*a0^k2Bs5o` zHKRx@i;z+iG;b4CI2?nQE|5gY3r?&^%f4Bdm>a-mvoJC@LlQSQ3qiX05UU``7gk{1 zKr<5DAi`COKuZOP<&Z8f#5N}8@@0~sn3$)dir)f@L(>BIR5cbR=9OSGQC)fsEn*;(ZQy`{ z=w@MJ)&qGE8jz6SfjJj^2q6m-vkrC@kU|kQGz>8T)%y2v>mex+>1)! z4~nudF^gljn1zuU>}lw3Y)E$+lIFnm2@4aXV+e5)GsIKi&|zU@hMYeL=0Q>)3lpRz zi0bs2@bm|EG(;)%_)2j2pekRCb_yF<3B-PI>mTeRh&{|;H$t*7sv&J~JHgIFmF&eQ zxrGU&1KZ>-NSqOp{+Ug{!RZesRly|0ZxA&QHiU#k7o@I*Y{7(xBavWlfzvH?a~XJN z8YERAlj!O|+X#_DhlP=OEx7DrhU}pOM=ZqWC)hyqrISgoVrez$IpD*Y#I}&3eRcSV zCWJv$Hy=`;5v3Gr3j;%tpNnTOMgM}|AQPbhPp-_ zN9!BmB8Yz=1Dgm@?6ot}ox6~lAK4j5SAroQT!UEp4N26Hou={N+yz-Ufm9A3`WdBOf9IQ9Bhoj6@gzi-HaK`7E`o?aOn`{Yhj5-k3Ks|oDUcxY5NTu* zQl>9P7J3NL2bryO0NV$VMz#-Jw}V!jgQ_D)ow^JXme2!nA%;M-L!1B+`2vZGPKaV_ zu<;Q6kU=2`I~go~5~3C&1nI;;3;_>tLMl;aJFrr)8c5*>Ys7tmcdd{ej_eiiSS_?t zfkZDPn82kfs$rl*;~`ohEhfkuBG_P1G0g^B%L5i+hPV~N29v0UEd}2L1PVFua1O`- zh%3M>NXS5jxWHDTYTgXj3~@4eEf82ExEcYokc|M_53N?f#z8X?vN(hdF%QCqs06c7 zt-r<$s}mv0!NCEx6dZqG7N+%(6aY33nv)?GKuAn+un5Fra@M#HO+5?@;DhV_|NsA= zk%6gRg-3yD2_pjo52)eJz`$U{&cINHM~w;t1H%e-28J3OY9tsK7(5sl7*seQW;*gQ zH!?Z$u{1D4_#in04hDui1_XZ|2LtGabFdpg@@t@aL2d%^cW^K;7$K>D#lgTJgTx1= zVvt(UfqdBfb%TL{L5LI7Sb^9H;)7b+pp`iweIPz4g(34nJqKhyC<7q#L4`RR)D0m0 zpwl_wGKDN26 zFg1@j85l}%sKMp;D~t>bVO$8mgZL3#3=AN*gTfHRkKN$8B82+Hx@5IO9#48iQz`y{KXW?UD zsA2+#Z!5@sZ6H6kgTl9i)sc_Alg*Kjql?{Oy*9kB%OkxI`-2^hb8Dw?~$m~{-*=-=R+d*b` zfXwa$ncW34yBlP756J9ZklB48v-?42PY`hA6PhUK$R|8U$dONEuCNoYj3b|%4%9vY z5e5cmTIm7V*9)?*4`g3I$i4|6`zEqO;tX4Uc)`rT&?N%Nb09N8{23w)47(V?e&`38 zIRRwmM39+tKxWQm13N(-oK8UMgTxpZiXh>QkzPS@1X2SnQo!j5#6Kbii7!x^0r4M* zF)$o}m;p~S*wPrtyg4ik3=6~|euD8gK>46_43a+}&cI-UVxA)(s}nCMsW5=#|A;d% z+=8Yl5FgonApSK8NSMIPeTV`!28JaNJ>4KZJs>^3AU%B`J^dg(6F~WI zA}IgO0p-8BTwo)#!Qlh4cbPN;1E_9;x$~4XBpzY>Ptu6+2C4sp#%Gg3lusae87Lo= z7C?L>8A$o&!pH0c3tRLsf~ifCAwE3&WKi8T1C75(29ak#?%0GTzXwhJj0_~*z~bYI z45aLK4@wZ2LiBI{_576G34+2Nbq*IpFCbLzaOdgMon|4k;a>`xRR{1ch}A z2Ll7>B6^VhFh1yxc{K(G1`!4Z29P}HD)~c@vV0D#js=N>?hTK@lV2ZzFS>{1dQh1G z;)5=T_JNe$7ohnJs|(|g8b75@=rg=KNCRp=|oU{ItNsr&gBE=aanL42bp`$5K`8F z;vU2YUCIUuLxjH|^#v}!DR46|fUZgdr7@7(L444)X1LnIp!6ET&AD1p z6s{m~&>dSTFmXpd7EqfB}drQW_$P;7(i#VgUS(Xc7XEY13m@@&@tj#urR|@SMcy7!WWx)pl~)o zQscXZG(O0{zyMMYItFJNq?Jl`gjbG zHZn*Z=Z9ht_6h$hz~lS0@OA{v?n3o&{=O%m%fK=YhtV=JR8( zOF@3&01dQ3GY`67kmV8>7#NWGj(p728e4PX69Gpb*6;_pag7)Q187Snw0#S2|G?xx zJ0#KNK=BRI2ipD!3R6OLHmF?!QV-him<352808Zzp@QNGq!t=%;PD_3-^c|rR*oEw zFgLDqfs6?w%Yo7(NFU4`gq$NEXbcXf7qn$>2gFTqzvFTPrdiN-A8I^f_zm3V;)A4N zWH+JP1LK1>qk-CAuy6zIMKghv**M#j*vc+YpQs1qQK-Wm`IuWkeTr64pP~)ar)UTD zDLO!XicU~^?*gUwZcuvf0j2j|PHO zdqC+KnNQF3Tq6nfELxm`f&rHtsGdWU!_x)@4dC(0U<+@M9e?oHk4p{|e#mmlfy{Ypge}A2AYQ;{eO_ZkmW)CLgo|e7JT-=@-i-SNpSW=gC>U&H^^lUvRY7DN9N-%yTPWIfX3v| z^bpnd1?x6rU~nub$jMAjEXmBz3rQ@_b}P+GW(W;-Lfo_C=IQ2N%utkCoLW?tni6kN zVPu5DGe+T=pzur?JpDopeI0|n8JwLRokHChoE?2UK!guS#yKR&#}USGVsLbEj(7Hm zFJTCB^>qwja14!baSU-}a7rvq2}&$UbqWYZ94h0Sk(isBlbWCBo0*rX@0MAVTb@{y zst*^|1&K2_`v!O*JIL4oB;_LGLJ#r6 z z!OmbP&CDw?HUgO!66E9N>=VS`?Cj(LB77KJJcB?2Ah)3epcy2l5aA!3S`wO>0*(PB ziws<0sn7#zBPgC=Vz9t~ADRW0%*oG7R{#^GdBvIOd8sK1nRy`3g3`YS11L!cgn-=W z405Bh4{GR#Bqrsg#+RTaq5w}nV^C;1dl&_|27~m04D(@t@O>~<8-P?p!Zak`Bfq!= z)fQMBdnD$i@2ckUvLfm{D-GdndT!TPS0SZo( zs0Js;U}r}^24@e$AlG0_2N@cIT;%B&VgN1;0{nwQKr!a;=jQ1i@9P%t?Bf_5?CBhD z=nd2B=@$?h;_L6?8t>xi<_6M@R8+Ymq6=JD1;m$tQlcry_nlmWRd4Q#ZT!a06LPI?L z{o*a0JVQXC0}2(C`~=QU&R|VGpi~0W2`|SSLD~XbgM45azyqWVoc*CW!UyE;lA`<^ zaCS;dOiuMH%}q)zg4GWUsAaoeGAtUAQjZCi)B`SnL1mbyA1tQ8-a<*h<{;-mk0|2$;?YH_Q_97ftiDv3&Y(V zJ^esI1@b>i0D`L+cfU{tX9W{I3q3;x-Q3*dQrpCmirm!nL}Q~wlTroU+@jQ+#0mx7 z^px_%qBLD21>JNb1zmq*1>NG36x;N?QcFt(-L&G2{Gt+FP_z{*=%(f6>t^QVWag#n z7Uw4B;-K-oRS*#MM(J^jqVp$76bO2rBa3LjS&aPTAL=AhK# zR77o#5>A#NEzW)+J`CU@5aM`5TF6Y!29;wbVCx|DBRD;{fnp!kdc!b~Q4leB1~oK- z=FsBIs??Iof>Z{_ypq(syhNYWveX=~J3)SeTI=j#04fMTW}rCI5L|u05-3;~NDWd! z;N$8R0=Em)@&P*-QawPbBWO5*q7gGKdHRL82KhPqfP4V2B|$L+DIuXJMa09ZDNx&i z!7;fcvn&-Q2Y?MmDTlzB5ad=A|A0#;n0KIc9;n&?FBkXBOUsXUc5#k}l(wK+37pkE z7(jxc!oW2zIX@*cFC8w0(ttEDMXp^8%u#q2C_GCPo+Ap+35Dl^!gGUWb8wc;P0Y*# zd)(P09+5kPJ^kE$TwVQKTwOqc3Mt|}7$7t(M&QW=94i5dMVTd);8FzAj$jB5aSREC zRNg3|YGewo;4#7#(%eL9FBuvjyW0?@-ZeyNXd9w*8w^pp4TdNoYG{UHCQA4kqJ*!Z zB`EJ0gOehpnF>z2$nHZ4WkY8alTpIl&=p0_4OIISx#bt-CYCTjvW*9F*D0VVKRLCy z7+Tnaa+ME5kgFTmDJV(S71VKnG?IM4Eo=YK5O}pz?wOa8S^-XXF2SKrA&~*D@y@~U z`Y=8uH7B(oBR?-SC^IiTwFp#Ure&r>D}I;M;^d;tf|C3qumR4&&H?d`&c4B=Ny(tI z>p({)l%y8H4TDy$D2@v*DT25lK0YxerO40>Y!b**pb|GRCq6VUGd~Y32sYl?#Titw zg0m5WZ(?3)T4HiZX;ErXF!;C?aApQ&B81c85r#QB`^H0>rAX57JctkjCs0@r8Gu_y zU^B4=kfXCNit8XQ11nD~N%YKv8N(1zl%GC z3T$>eI|g`yEyo&lzNI-Ona&xBd3mWh3@*@^MX?Iu<9M*MVG$QllwXpcoSze40@VlC z1u+H^WDMnDi8-aI3?ca?i8-i|3TjV+`~r?LzkE=P!OUcck1t9sF3l+cI~=SaEHy7B zzbLpMH90daGa0VXF{dQ8C@--j71~H(@CkKuL^!z^)EvVVGN5Bdp^Y7=7myM)*k+_) zhDV{ZXFNQyf>RR0ws;f|#+N{R4GWiIu#sTTIEH|>-X!Lw!2N+7W`U)NIhkph_#)LY z#24yh|B{Tej`FWvv znXsevso(&{ z8h$Wc5NE@^4hxd~FvK~2CK1J3!Sc_l@a zkk%QrLV(37B*{P`!#@orN{i8h6dc%~jvgfW$0Iojmd@dY9$YP~==O9$HxBM_m}ZnP z!j=W#sQ?tr&@>FU2pq`_K8bnhrHSdOkm$!9Q4q@^@_0%vP-O;-9jsyN3MyvuQcJ*N zq)v{`-tnNwa!)Nm1P%k-iHPbeu^=%iGbghoGqso@C^aWFu^85S23H7h9mNcg>H^8M z;MAhb#2mlUT)1hWd6~)iDR3`?M;9DRN{TX*N=s59u?Wh|2s4n19Y{FDmoS98gv1B9 z2F071IQw{mnxy{0&hbIc#zwx*L9TA`5&pr>#ztU?pb)I1n;`XWL4iSze(tXEmLdL- z#wMy_f5^a)kH53GlV?aU1IScxn=2^98BBu=0SSVJQzJqgec}zxyrJ$vHOa*@3^FDN zbGM<91ulh#21bw`g>$^Kk2lC@aC;hL7u>-HCL#XdK5>AL57;G;25E3fegWu&yqx^x zY=#iHeizR$uwszqC7=P1fFMsaX-E?sp~W@K*#qnfkRDJ#gWZ5C4<6Nk$s3wM{R46* zYM9^*67Zm%ql-(B5d%nbFx0z2&PKkVC`H)j;u!{33o;wlx%Bal4+?P(4swnU0STuk zGk_?V&8`t4AS2V0QA`GV0;DX!#|NYn%y)6~@j*&aMy4>IfTFO3A>7js9Ks;u5b4ec z<|)50P&*SO33W}VPXNgAAX{LL0b3K`>*8RUlho!5!cO?kGc2kSpjQ5~uw9lAL^S zdlY0k%p2eojtCxSM;}K}IfByZF)(BR~N7P;{N`K4%r9Wn11|GCCLh_o6XBfDv z4YC~?RUlKrslwSg05U%UN_kN4fL!S2=;_1Y?C%?3045E=q!Bn#AfnCK2;}qhWavCY z5NIR?xhH1e43*J?Bqy+~;1VS?*eTc_JWdQU0UFncR0eV>LNSO1E_{&G204S&q$k6R zE<;!n0x5z;23#j7vat1%QR5XnnhHvS(11Y5!b=L6Qj<&a zi{evK(-OfActmysr)E$rc=`vqx`T9rVggh~n817lO36@@5H12GXK*nD3I}+sLb5uj zhy_O#JSBr|L1+e*0MK#~WOZ-=BrPCZ1u6s}(_Wz9gvJjz%pszXBw;1MJCw zV6c@i$Cw(z(kQ}g7tb(oVGK&%pkZF$05pSOB|J!h4+FTUfrdXQu;GDf6ygsaAp{A6 zy#P+yU{@e419=2ILWk14(o1G=3JnSI_ltLQ1`pN;hxiA%#{0VZqKOB&Iy?IKV37#* zbcqKI?8UpdItRJ>x`HN0z=LkkK3_md5d&yk5i~u8m^lNFu^@7sX_J}d;lKQN<IMxoWL!*&|t@)ka%bCtfg;ofG4P6amz_8&VXr!Oz|;*Rl~X`5V6n# zP=yYbfEo)r-!zpWATd1^;y|!L5XEpOAzSDf!nIowLn++S&N5OkpeLvU(gX=+|_ zDkv1dRzu(99G_s$mGp$Sj7a4gmN0A?)DP5{QXTm0&Y5L_Jdw=7#u(xPq%g=ft9-N+c5@ z_QP_bb7gW)Dv~T{kSZO?c}}6h-mb2omPC3obWXw@%^BcnEs$3NLVbK({KLW1g~cUB z$+-onr4*!4V<;{u%7c_(aGlUV02u%Z2#7C1c@tHIqaS#x149t54^c-!stI%#L&|mV z1S-T1Z~=}8G>}1|;JyMRZ1s{6a*z}coiK%lL0Kv^Dqz70jUo(jy<`S(=1zergq8dt zPeR4~ieQ4pNXB@kAVd?(QW@goQ&Y=};*&rbDZT=i74FhdKNPp-=jJBn zrGN$^!82q&t}el;CH`q?3=yEgJ;*8{*i1LN&p^ckcq9olN)4I?2aUJ5WEO+g;V@wM z*Cn$!IX^EiHMs=tJbl>2B5Vj85^B(95OhreEP#+a4hmM#SUlKrP$dg>EmR}eT`;3T zY9Ub&0Jj$*hU_JnFECv040U#JYF=?_m{Vyn1E?Z|1{;c<7|8)S4nYoeNzF;DM79)O z48lg>P5GS6s)GS6sa zhBD{vo(fuYhFH9aGGl0D3F;pkfCyAGP-X^=P-X^=P-X^=++g8|Xca*N*0mxv8B&)* z1%gvcKvkN5UJj^X3{JD|sU<3J^{JEx!O84O0Xy!=X02 zrY* z%5!ksfrgi0W`kS;Zo?xBz?x8CF9ZcJfKw!>#RClpm|AGf3n?5y#Ry!YB(bEl*fRwj zh~U8YfJwO{+yg2gOJL$4hd`RH$Rd#X5+0dONa-mU9&xZ$g-)QT1}!}R^~U^M;z30_ zgL7$7QEFa^TTx;zY$O{=Nw}kD2za%EYkZKav#V#AYrI>Kqpz!9sIL)2P-;n0Wk_aj zYJO=6c#0hq1Yki(2LQ<&SN{+ONF&QLr2<}N=|e&WR7;0Ah9IoKVk>Cv8V-jTGK6HL z!U`~O1VSu^IT-9sXpT?8^ryd@8{9#lI0DxP&WSn6&Kar6*~O)~Xx0V<`8&G?2Qw5v z6Oc=4PG)Xq324p|8mkN-$3SJl?t!ww$%Fw^IhPhgk~=7}!J44?6rLMERV=6mfWE4$^F=A|$czzPaT;4-+Rf+iH8_AwMdQaVfxtS|u?4yr>zYZamTz@1%vFbQg? zILC*(gZox4!6E+Oh8b82q8Jp*u3^EE!ST)>zM&EEA}XR=zoVKvsu4dl>nKMlc|o15)Me0Unt_ zu@E{AjI0zfaA;^|YyloR^6__c@%49!cXJ5=4Yaz3IXZ{L2ZV!Kz$iNX!6Q_jeqei$ zWkQ^t4PYKd76-Y-5xhJdWLAiCylWU};^L18Ds*oILK@l zkPh%TC$db4vkOQExQUJ|4$|QS(gF5#2s}!I!Clf2XT$gs2EWvDNIbwhVdy5ff=mDp zy`#v$7TU%`=5mnbpgsUcGQw7HGagwP$a!E7fd}M~WkQ_Y4C7scz0g!c9!9M;0 zuAs1iMPh(skY`9FXfnVMw%Qjoe&_7y=@$Y@gC5|a0c7JHU7Vfbojt$2W)N^MbR^oiB>9@bES8QN>P&FHbM}Dj1wpaZKPUtoFyMGZN)On>9a`3d z0w>-x*g4+K(Z|Qr4?Ld+*Nd%c_YVpI2PQb~(d`FkGH_s`%YcI!BWj>23~Po3r!cVF zL!3bclP9EZ!Qv)xTL@Z8fZYx%2cYVLLxTLBTrpA*I6-2hAW+*MG-dAr-TH#m-U5Xa zICL?52d;XdwxjzR><6%~;qG#F3;<_XWTjvupcw&H%ms&lhFZ}oIjE2!185V2Z+;4> zg_;WK&mg%KT$DrO7u6aU16Uo8Vhu|0fJ4*S8CE~}hq*yR-WRg?8rei>nFLO8&K|~~ zL<KC+H>>6iNS}5O7q3U5G3L zEqkz*ZQxXlk-nh~P;j^)n*?$iIAwt28CeEY147%?;OK`G&lsr=WB}N2;Kc5iS`HdF z!`U_jXC!bafb@a0F1ScQwiqM>PI_Rwzzr0ASm~x~xyZN}xSO zW+tFjuE@C@>?Nc?1DB#8jbIN4d4d|Ipo#`mN@phKfEEEGTLI1d5TO!K;fYAbkTePM z1-LVWlJ=qL861-?sk!+na9=xnn1WI_cmf|R12Pm=Z-Y}8s99)ehGHBdZGugNI0w>y z1Nj9UMG(Etpso!xpMm|3tQK56V9C!2ZP(tN>gxLgT^N!vK^XoIMOd({w17L7Ri%f&!)G3r&@X z<^#0tifjiWPK}Ms&0tM#_`pDX2-sL;9pK~w4tr3w7vu`5IMS2h%_vZV*#MMWo#7oc zXi@I$VGi;HvS|qWEetKOBpqjX4T4=4I3=J+!5R$UgpMo&PS(&eA6Xofs=$c=OA!q2 zb%TQdoC)1B^D>JwQlV3Uus$W!cc3~lH$Mfg2H6g9BMe%|fz-k3Qj~}UIRu=Az@9=x zn@ey!*a^r6g4BXD57smd&LrS8jjRXSV8xQ%Tns=h9#8>?tR6Hp0(CRGu(L0CzzA6w zoD8ALkunE#G6dD5@CGYnu@bT|hy(#y*az|`xDfVn4ReL8+yf6If|likxiUB>7NrEG z78m5_6{j+QM&VP7;9TF#w8SFFji#B&knv-%`d~+I$o3A%5Tb{pPY45wTE~I{P(g3# z&EQ;ASx}O1=vZ2k0b~1RCMD&hGI*y}`lqE8rXCpTKX-&x z;K5I@O;BmKOwh&@|I(6z(h>%+EI6P*3!c+K+uIm|!OP@ell)-GkbKA#KCHrbgsfzT z1s8OrwJ60gB+wD8fdNdq73JqbG@^u!V?jX>c$H#kW{R^9!l~hj*{PugP_H|NhIoLc z(ZKq_rh%dZ<|?pGL#Wd5AkPq22JjFmL?I-wKqk1l#Cy81I+8ya%KsU@Wa7@-dyra?{zut3r^2DOTuK@-i87Lk8S3OJ;^Q!B&si&8-Tfm~RF zym&|-Y8hxO9dx#Xe@Y4ic#PSZ!L=+k4{QLqi4NkyBEZKjIEVq%SYU9?O9mz9)D%cQ zfuvHfen%$;x75@W(BvR^j2|>o5tNz>x+6S3z%eM;HQqC?xHK&-GdVLguf#b&2Xv@K zW`15kVo63ZSQV-mSSTp9Ait=@vm`Y)9GlYU>uY5D}d=o1eK*~WK zjF7~128bF+_<)v#fK7#{18t}%Eh>Vj@N@y~I)y3+HDb{cHT#!9TR)e_lB@C_=1^IcP#;sE(XoekBn!o~p!6!dGGdVE_5;`#Fm!#(U zl_JNBho?($Nn&!ge_3i#T26jBL^)_J2FQ0{8zB)04rGuxTqVe_5ILA3p?N7#Q+yJO z(o>5|Anpg51WFO0Y*d_D1P)<{3@E0+lS|-K2Tn>LMHp!W><)w)=nfTV*#r+KuqxDq z1lliNlvwzFiJcVo+3r z_veE;-|hrr33N6~WkD*)29U+bDFd{)1iTvrvUUSvM=>}sQu9ijGD{c&GAfI~F$mI% z(^Vy@xe#5b9tURxx17XuX!Zcb978B*8$QG)PZvnO14k<;H#qwEfH%0n6Jk81Fo%aO z$oJp?0&Vq*F99hY{4Hl4_aoUPvBuFJzb1~iGmtO*z0EK6D29V=H)m$;CcEaish9K9#c+m0%Xvqy* zL=z8gR)7*l@U`2|{? z11h1ROOzlRxIivuaB&Uubasu0G#y~}q^5uq3dB6n`Y*%|bjYqh2GDK?XJ40i*C5AW z*LcT(fcOAMckrwc$oo)@L8-a$^$J!25o=?B{1mrc~oUc5(s8M zekN!i4#IWdg+9TqA)x`_hyin9RWaNPp2c7lut|TgO87z+SQMg!IgS z!6tx~2SRs)f?N(=aTX7aPiV~r4R&Y+22}%9f)b&i#lJ|25f+S~wt75>lb(#4E?l7d zPe5{@Soiaf_YZIlas+QdNKZy{cWAI{P<*hbdwh^TWM&(7)CZ`67jFSq4eqjod;@hi zk{@9fL6R3ZAYkbW7SNC#$1ooB7!ep3EzbNyLl7dK#la3KWPI(B7JO(EdeGcNS(E#Cs40D4v8VfJmVSC`=Zj z9hCWytb+(boq--`@t(z=exPWmM2+Ckyu=dFA~MvB51tPME#QQvP~?MNU)&!5j2DvUz7?u z!3Ay-IE#AvftFW6wj+ScgQC)c5^!S+7LeeW!xhS)@P(EwsOCb-=-?92A~&Qo18NMU z=9T1t_D-jPr&5uVnrAU2PU~u{Go>~HTNNN#0WKaqym?u!pcMA;$7x?8qsd?!o z8OVtPzWxhV-X-Ni9RO~Z1ZSp$(jY9^z>I}>3pH;cg)2rO3awJXQ3_5TNl;6`4WHCJ zgvStJ4e=su=`WJ$p2bk-1gDn30~(x8Ar8WlOu@wncsE2M_(UlNH&@4y&>+wXHy=;~ zt^ibjcqHb4woy2NYEk4>)G$wjlO8B2!4m{9QAkig6F9*3 z0}y!|{T!HE-^I-rNVfcm+x ziV0jyfTI(fJ5N=0OrI8my{;qZs~!J4n%F|ftsMO;t3J!pgaRx%h@O5=})Q5x;^iE^QzynkWw8#-9^j!U10{lJwLgItM zor6PyTpfMm{qn&LYlJ5tNf(h~VP1h&Gf)Z8^fsnpPNl_&G>y=hm{}5w)k6|W5-2x5Vw0A%)oA z0kRk2GFSq{rV18cU`HTXj?fMDmuFsbK4^7mNh&-!q51$@FoRr_Sd;>7DKTI=93>fp zRt5wlCTD|IzUSm1A`21#SfUe@o=Xc-;**dPG~7`TUD#X&_AAUdsGpr&!6UH{9=g@A zuqT+rKngHI4z`*b$@j1r0Tp+SN%=)3pa_FS1**eAM#5yk4u?1~9$6d~%oYfT`<3S8 zz=Iv8-?JEG0@!@VoSgjf)D%b&0qs~}Isz6*NC7}(fq_y;x(3994-G?Fg9)DP0A~r% z*>2fki8#;MEC}SMl)OkK;s6W z<>R1ZXAp4%n$`iWm5+z2MoP4BDVXu-c^uu*5W7o@Qehh61A@X3aRjcNVN%6N;^5&l zByEt9UMz0Jm!sWN;itht&bk5}b_6O`VX@&93OU;bECx*?V4FZK2zV-ndm6p^0&O(` z9T<#oH#j;&@?8T!BXZyn2N?}6i`GY4Tk%i&iY?wOF zV1MKt!UR$(DDS~jDFL+snFXK|g;Eo9NznmU3v#t1xE~5`uYsBcPNBizU2dL`fim1J zB5;)pYEeP+Voquiin*wULE8jyYrsj&F$Z!iF{l$%3_h_2blgagGh{OX$Z;r!Ks4uN zmOu{`1@mFa6r4c7B1rB*?skBTg7gF#z#SNnrC{~ou?VmbxK9JJ7Rd;(ELa`LfM9<& zPdEo9s7iBFArhbwERfk~?PJjBPian0a6xKn3bI$B$IyUI*?@W;d_o0i&;sNVkfl&x zpoSJWl8`rzf|m&Sr-9Ql#3gjOp25AZrF$oR?klW!A3113oXk-dE6w#x` za0F^-fg>3-5tNvl3K}TKnwUYyXhIvX`i`Y3nfc(O03n$Zv|=pO#nV3?+9iSZ^cfuC zg6^p$ke%*e*MYTy=hVO^LDLE7WDR5uL8-<0Ii=ub`k*sAz|$ot>cM>($VetANdy$- z7o--IR3cd$47V0M9R=->Bb)`^lnA#4#c*hy22EnnE)ts2nR%JHrMZxF3UUGJ&>K`M zk{*zQ!CQ+MP^`iz=8F+VLb5^%sv*9K6<~`I9zpbHKpWpOL4g2@BXCNAxGXIn$qZ1q zK+V7xw6IKz2w9M!u;@bSk3qZxj#g+$fwC2f^FUWpfC3BB{D7S{2yz>=)&rIP2H^ID zA(%7*lg8k!w&*6q90qCo8XJMe&`R^tK_e7M$5Mi|LQ-fvl4C*Jkf8|`wCf6Xz%jCF zPy2V4rroc`Ci-K%}j3GB0NF0<3kz&rX*f+7b7<}Req}C^x#bD|a(;UN7Pk>IaTE6zPDB#Nt%QXdJ>ppuVwZ z9f>Mh!Q%Y08qYcIkzMd|gkh%>r@Buoa7bFCY z7FaR^D}#zbgB@HULNq~4fl5QFGmwpjU~yDuqLu^5#+HCp!=pJhF9nwkI6P>?5ab%{ z8WiU0g1re0O4qOkD9B=PaRhNRXhg9Lv@RnfixC^xS7b#J}GE|VCizmEH!xEi=rKv@g@&1`944{(^Am<9jLk|>SfM^C=g5Cl{ zjYNn-h(ka(!y#J=Epb6YV9P*Lx!~4-zrPbG@jz<|P(=m0w;?k>57O#@ilZ0}_Z4(y zHmD@4WB?s@<>&)CUIM;E8)`OmB{is<2Pr|^z-!AGf?Y$veg-)z-XpOn1#~SPB*DZx z=j4Ny!$Ca{b~30AE67PL0bTh8agTRuYJp=;W?3q-6j&|DOAL-~pmlX%UqaMFTE;Nv zIhG}6=73hyFhE@8n3I{F2Rb_3EfI8DDB)rSY$!NhAYrbT%n%sr8Waf{V}UGLM~Y3D ztxz99bim32h)Iw+4Af{xco8ZNDzYIb!eEOUq-X|Bz=F+1%Ll1N5buJb8k-TITm(_U z;G3A0Uj#d;1#A|$Vg#wc*4_uLa{%>r93d-gGV{`*IUU(bXkx$?=MdGffC9%G#39(6 z3EEZ-8oP&<+bQ7cAOsQg5a%K$-;k3CL=IFO;p%@u0~OP>EDE&_lFJ!<6DvZX=MjR#9jpXa0wHF4A*mL!a228?G%qtRvm_I|X)Xntw&6}l zg_}?Ul>+6<|P1;j{@N5G46A-07jLvJDSE6s%#D6To+BmP0hw?q2NAY&OE zQxXeGQj3C13qZ~J)D(YD7f}8OuVMh33^o|1%-7KwnoglkLv|G?C4z47geivHSpb_l z2aRll4Fo3uXh6opy@>BjGvCydOz;p;8u)q~crgnN08ohtH4o}4aA}4Sj3D=wASXSr zGNhP;BvvGSkb((jHt1dk@XS|nKxz>z;u(A$o#UZl5?{jLpInk!QVewlBr3q;ClI5N zihG!$xT{Oh*tfo8UP@7ZW{M+t8E}44CAi=O$>`x&>I-hcffOJOAcDAr)x&!I#Hoh$ zy@^we)GHvt2k;gsah4!AEQr$qPLCuwD7YjuC&x1v)@g%UvVxs~VIMmK0~(PAR6Rqm>h`x0V>DB!N9-+4he`pWPgCnL^T@{57^Cy$broM0W}*$ zgMtVae;_u5L<);;u#Pv0d^Eb4#ZY~%7JK5RKW~|Irtkp0|Uqc zP-sELgg6)&Kw6Q6Kswbp7#NrtCMht17#dIxGl*dT<*+~vV36TtU{K&hq!SQZi4#4Y zsBtndxNtHsFfwF-D0fbfFZvikbPR^#3{D1yEKaBkK#UwHhZ)4kgK}6vi~=Z!6~uT1 z<*>or1~O;-yrUzSKO#!1-Mi>_)vBMKC$RIv0 zM5Y39%eZ~>_TX=h|e15qGF%nWVy^FfRvu#t`R^FfRf2&Zm7 zh*1XN)X#@m2Ga|RYJ~P4MzD5}4mJizx`1iw<6>Z#05)lo0uzWa3CdvxF+{i_$rE1Y zgOqPV@(_s4!3|2TkmLzs^MLsf4};hsL)aJ~^2pZC0Gk6zULZC^9fXgpZVOl)B#(pG zAUi+-m@*&40@=XE0Fec;L8d@tk6NP#FHu#T?!3T_65CNSGzK8Wss zC;?GjNV-AnDG(_T1#%M;Lsvb_4IqD<04s;2eGvN$m=EzAhw;m z;Rjd&=XJP?RzU@kGs+oW28L_AAkD^bbs#Z_<{m~AL6Aabh91WGAjS=_@qLW*K@5;` zSYm{^0pun&KB!+n3=SxV8N}d%a#%nN9w>(u#NdN+*gy;cD2E-y5Q1_zKnxKmhZDpQ zgL1e)3<)TQ8^n-;a(F-t87PMr#E^q>_&^K=D2E@!P=aygR(P z3-}orcp3T_6nYqxm?4Q1B(#Melqh=``WR%Oq9Bo7n2KR;fSJY2(8o9*WCBPndNhIj z*8ue+6Nu3S^%h|vb+u!0yJP!1c2(FNtOgBU$f4hM+Q2jy^r7!#lzE)Zi9 zl*0{TOo4KEK#XZn4ljr?1Ipn8F=jzI{2<00C`SOqm+93c>65tJhgVl0Dl zL_mxc0-%K7BLboYM8Ir0SlEGrWd}I2ASD`z{X!TK&tSF)C>4OlSJ*@t7(gblF`%Xb zkSQL5plE}Xc#v8XBm&X_YGkC$2eCkUd7!Nph#F*f@CbtJh17N+HdsG&>|&lU1H&?5 z1_lm>iP=+_S{P*D=CLuvOlFKlq{ux23=ANh>YDu|In1SJ(FarY@!)L}6Xo3atF9l;)tO6+q% zRU(I$7gP)>qSN3)@Q7}L3L)zR6(T|+pun1>zyxB5Ksn4Hh8UE?0%Ax&IjkUt6qLgT zV#q)_>>x%Llml;9fUJlT0hLCOOafw;z)L|8s|HCH#0D7wD(5obAptVOM+B77kjq4n z2uMFjZOVKQ3#1c!nFumL18fhZOa!q#!2B3+i3ehX%!9=yhz)WnGebi?*ys)<#UM7w zDv-rVa7Sv1FfiDOFfhPNLJ$XJE)TSXhu91f0htb02I7Dm&jBiA!DT9lR{{1eq-ua@ z1c_83n-5E&AQM4ug|*T_>=+RS20>7(ybIKnO_6~%%R#~^=u)6EQwHu0kaIvLAeX@) zK1eGwLl@(G5CdcetlU-lMB!XJQ3eKo z1h-0*fuS40-6zVxuphxaB+9^W7{NUz%D`|P!DSL-U=S9Ao9rgWz~GMHdWkVGfLsZ6 z2F#&5L>L%Au481#gt?57Ars~*Mutq7ix?R)VXk3h$b`9sks%Z23Py%Zmh%DfDDE?0c0=4GK2Xb+5l`oJVL1fJa>tR zF)&Dhld|D_5N!muAlXcefdOO*QavUC7fOQJ19A~a6*I%cD7c9Mq6`c%qM*!SI3GkO zfGy7iQCU!75DoGckKg7l_>i=0h5-Aoe^kA5yV_*bBgXNM8-a z-U8-B^{VmKX!WK5&31z?2}3lY>kJ`5rb--b1D>Ae--lT?Yvf5c`1` ztV0BI3rN)kuquduL2QspSYs5#hUrR!X9JMPBWM&dff!Gq9A*$>fjA^Vz(=7$%HM)5 zfj9-k&JqVjHYD;u>>P2J(?F~`Bv}x<0WJ$-fh<5D7=I?l!0-tgL10=Ol1rJy85jh> zY@_)gS`N%Mo)4mRz-*KGAleGdHk}WmJ-}?U`5-zB%r>77qCqZWVz8JGqVvGw2J=Dg zX#ukh=Y!}DFxzN8i0%Qijpu{t31GI#d=Nba%r>15qGy2FX7fSx95CB_K8ObS5o8xE zqCoaliGvGB5CyUpxl}wL&cJX88tzOW#t|ro8N@gS<*|o*`MhHY4 zL`A^FL5w_zIEX5OiGvs&5OEOI0}}@^7D2>8)H0Yjh_MGE4x$dg#6gTJ5OG+DK9OKx zcp(8wg^*MUV*dp5A!C;y_CE<&s)XqRsrmpmwIg6Yi17t%Y6gh=_c2Uiw# z58{E$K$@`!8z+gdl0}k%fgQ|;_TSQ8`}7}CI&K>Q41SAqGE zV6Bm4U}!?(!@QIt$-q!12`Y>n=7ZFL3}#|*fS08jQVa}wQqb51F$|y_W)Q;+%3%R9 zET9}#5W^12VFNK7pd5A(!wt&e05LqE98M6!2g>0BG5nw$ZV)2?%HaVqf}k8;5F-J~ z;R7*Jpd2Qc??A2(l|rOw5F4Zjk`iF5Kq6T%tsq7Yl*0^S6hS#GAVvw4!wOfH?!i*aYP;gBV+&92O8`8mh#FN3hPVg3cVP#5Gd=qMaQ{0m~Y!2JtiflPpnLcmN>lV)IO0PBK` zRv^?t_%L-w(hLkB6G1~fAUZ}GR9r^SlV)H584D7IDFyL&fsKTe9U%4|FdtIYfY>L% ze26@VeG1Hn$ivJ5iCqDUL)3xTpTK-nbs({CU~z~#5c?0@<1o`eA`CL1h=!;Fvt`he z1Dgy30}qla5L*UA6-Y!0Nfn4~grN!~VkHAjLLi16l*0^SxIj59Ach;1!wO<}K{;$7 zh7Xj(4r2I0IUFEH0F=WCV#Gl?Tp&gglmjmZKrRVJaxaJtQiNI#fJ8E2T0x8~D2Exu zD1dTUK#U?NhZV#qgL2qFj0z}+9mJ@DayUSY8YqVo#OQ)@xIm0PC3+zVoZ z6rs8oBr+LE6^K0pBNjj+bCFbm*o!b!fkYM~sRFS#VWc zDpZqYU?9d8P;e{(hu0(pCJ>$QAD2D^Y z*a78mf*8l394-*!0+a*KlOUJWfx`t-euCJ$!F)(Kf!L>HVdW`^1u_EWUs$+w$ucnX z$uckqF?1cO6LL^75EF4w(biyO5EGsc5}zas8eHyTK$8L)cMiK0%w#n=1_li|NOEQZ zF!XQdO z0j3_ra#H}C52B{PB|xlM5D5^q3N8U+?SM#tr~_~b5bKHp$bDw>LG%N-42bmvq6I{O z0u{9sPLpF`D3Akb^?$dG4X$dd<6tucdyr!Xqa2XRZm0R!)O7 zaw$v@S#a+pC3 zFDQov#F(H0Q3fBE0qKoV1gC5e)c|33DKaqZfiOYT8AVt|0I{AyBtR6%IMg)Cqr|`< zrvyr)2J=C*0hnz#A4EHW*+%n0bO@MjJRd}-f!QYWL39O}Z8{%BcY)bv^Fj0+Fxz}S zh+YR~Tg(U12f%F0`5^idm~Ay5L_Yzut>=U2Z(z2~d=Sl{404<8d=M=KX4}mN(K=wZ z{rn5c3=CJGY%>)G1{)QSdb{}`+6m0Ioe!ctz-*iOAleViww@27L%?jS`5-z9%(k2l zq7%Sui}@fr4a_#552ACxY_s_wx(LiRoe!cbz-*KGAi56BHl7cnTfl6i`5?Lr%r=}4 zqCqhMO3Sb`_DGR|!2s+JgZUsDG%0|UrNMurR!^-LL*x;RhFe+9AvoYXi^%x6-KosjfuU z3vw}%Q$WT&Q3iz|q%jDJfOklI5c?N6P?`$B;lQPWPz++rg2SaLZ$2no)Q}`WY>;Kl z3{5%kQs|2^0|Ur7*gzP}Wgu%naioZjpu{t3^3bdK8OZc!o*-Y zACw0cfW-~wgEGMmFxzxKh~5Wgo6HB%N5E|3`5^ifm~Av4M1xWjDBr={<)F;K-~^5@ zNFw)9W?=9`;zuYmFhn8olav`4QjqvL$_xy7NPL*NX37i}L4*D^BX!3;g8!oY9=oL(j=Fo77Cpd4lp z;}(>|0%F{Oa#%r(dr%G=i17f*VFxk7R6&`25@_2R#1fD|1XPd-#E61&m_dvrD2D~a zNP%)#L5wsghYiHYfO6PDj4UXJ1H{OIayUVZJSc|?#5kn}aS1oX9SjUbstgPjs-Q+v zCxfZfd=Rrs6;uww>-;iR28IT(iVg-tmHADo3=B)aDl$OS8n6uWN|go%4K)S^JvETt z44CONR2dlNfK_xb*htL>F_(e$W`Zb?UM>c(-YJYWQt<2t(zQYrR52OM2hkV6S~51N zF)-|an14)-fdS+dq&b3JstgQAzzQ=#)ITsY384_~pIfR74EIz)#RH`K0b>6EyODV< zQZq3{je#KxVjGAm00&$L<9raK3M`%kqFTVr6cE)1W+sEEDPU$2h?)h_$TlCuSODR$ z!@UYJdKFkP+XOQY#_!RD2E-yxCiBM zfEW*;98M795tPFPVmyIzxIv6I4M;-afkov3bq0nr>fqQd&|qLF(*QGJvNzNj82+gv z0<}(qfuTVI!3VKhG(gFWc{NfXgKX)5+QbB6bU``HAjTIc2R@eo68HucWCAgMKsn4H z#w$&Tli|w6G#MCFH9?Mm%!1fyGB9`}@nMb!sZ-O0q&JWnA1FIWlYt=%tR9k5VCq>k z85j(pYC!6HpzLXy3=AMgAU9M%^4RPIsoen82ckjx7#Y%GRvgo0U^t@*3gR>nbph

mX-lX7NQ!& zUSR-}1+gRy5wak*k|9hM#7aSu1+f>wWkD>EPhjIdn7)A|KahL-z`lX-LF`LV-=xh4 zv2GyAg4j&j5ErD)2eIU|LGFX-1+lfXL80d`A4Iz#$${8@aGfBQKawnnT?d!#(q>?o zfFuiIFVKP63SvFeLD&jnf6{^23Zl8dp$~Bph`5=}WIHV!^KAL~Gc>)yU$Fx8$itW;4U|6RIX2NvCVw{bk4z!4TJ}AY4l)?CY`V0)9 zR14#S*r0UF&QJ$hL@6^LmT2JuFq65o85ktMv77`xL;+JA;(ttWRR0-iGcbTs7r1?z zIhhd@%P+yPjA|}I9mHIaI!O3I_@J=C7S0HL5PK2&Abf;A2p{I&0Br__C~$5tm=B^s z>6?)u`j#%F0AOT@hN%Rl?@!>6fP^t93P85N!W866P&mW*pzs9+D~xYt$iNT#IYmgYo z8%zu);Jg8{AH)V}2PJ+G8)hd=EiCnd@)Afrj1SWT<74WBgepQGgpbe%;luRF=`t|b z>w^541XIGu0AE&Trpv$payhz>K&3LD9%%Tjfr0s~3TPi5i0cFvs(=ZBxS;e8TK^7J z1+!L5kAXoCoO2>U6i5{_LnWeW{Grdl@CTd;4d#Pr2?Nl+3~<>0m$FdlWZ?KOr8plX znqh#xS{oGAAn#*epDky=z@TTqz`)1Q2QtJ$r3pkS&IgIj1Dge@wjgs52(yqyVZH#l z5|n{ql?I3nN^GFgECZgCAv|O~AT?|ZpFVG9U|@jR0OP~df!qmI$Ginq9heVO=Vrjb zfaz|SY=j{L1E`_{wPrwcks$*EJ3|Acr~z?i7=jY@XT}WBriJ++9w>jpmB7r&Fl1n8 z02jmXTnOT}K!iXPNECJ^Hul*0^S zJb-doK#V6)4l9TuWdy2u5No$U<}ez8YB`8)AT~%1YT$!Jw2)MR*ab$A8ZBc!h*g9n z3u2dn`H;2gp>l@X}KNdZwYU}hG~evpnfu&W{Q2x7m0#}J712}u@NR|Qxc z5+fjX6D&qR43IIf7y+?6FoGE*vIiW@pBXb?F#-}egrO89aty2#DMnyULx~ZPJ3!V! z!WhKb1a>7PMnI;6%z?!S%m|2TnBQP#z`_+|3dphGKnF1(MnGZ&W&}(z%n*>eY2c7f z0Z}`^On9J!g7gbGxF#tuff#khpwv7`0X|s<68r(qat8B3^dGP{x*0ehO3eqc8H_<` zxrf0)3M{5LA0)tH44S<|2(~bAC`hT#2MKc+GcbrVph^iJ37dA!ULnJ1{dDL^*+(Ngyi57*r;7GBh!$&j+#Nz*3nY3gk%+h9(9> zRgfesq(GX2j6wB752#|WQ0WFyit|BYNyeajjJz`lrVC_N12oW>K#V3RhZ)3p1m(ax zwIIPI#-Mpm=1VFK3{x0QR5|`jF*|??VUYMSuq*RG)Cpq-24RLihAsw(ng)=XDU6Eq zK@wMt85krO`WTq6AejPJ0dpM4`X^8)Fo77)pd4lp;{}w%0%E*^a#%r(H&6~6i17}} zVFxijKsg*B#wRF;6U6ue<#2%*-=G|B5TnKvlBVE;5g=!=nSi1PlGQ4&+n80>HVh_Yl0-FLE%?GhTdO>!l zAejP@g_-gTl$cCF6_3IEcP0!BYNntjPzwX|Rd5ps#MLl`NW-<5FfhoOGBC(6R54Cr z>|vb3sLlau!BjC!VeDam@D%5RROFe05*K8d73zYATP6$)Ajg3!ahSOXF$?%Ol#VF_ zLz*clL%+mo`Cw03B))B(}+?ii3R z5vVOpAch!}!wh0bKshWRh7^>;3S!7WIcy+?9F)TjVkkg493X}gl*0*Ps6aVfAch*0 z!wq6=f^y*H2FO`jW}p%PlKMbwkRtSk21uO_SRJI~0I?zJAo^fFw=!d3umk%%8ALgm zL2@vN_5uqhfv6xbGZ{pMftg7lstjy?Gq`#IvFCuL;Cq%~Mx%B`KpJz*7#PGDDnNA$ zw2E<1QS1V773YKGKn9`ef;ksPgHOIg=D;g!kPN)40de3-1jK=FI|6awSsKKF@1zBB z;A_A@94=&g;L{Eu8F;LKIK0Tp_>ejL$Q%J=4*ci}kO4x-GQ!9l5g3Pwp$E=pX6V@h zAD4kCKyUiMI%hC>W`+jD$sy>HObip@k%ulvh>xrnuO;M5B3ps(9GL%L#~~s3s5`)! z87dH+H1zG^ObioKacM+Xi_S;Zi`NqJC6TQ_w;thaNEHv`Gcio`gt0jpCi+id;_7Ec z>_VoVG|UnfhKXnE;MEIyO9YdTS{h->qqbzwX6yK0_MyWMqiNDheMKB|||t!feB-0B4n|rN^GJqJ+$x;JPv~f&fW~}UsFDaxkf9S?e3&?L44@wO zgG~iY4Bd+?41F6b;E515>B96NZFvSMK8wO@SK?Q!r3vI?R4hdLbf_ z!jz*&Eqc@=)Ip{RVSE^ksUJ0VVd{u<7DySXeR!A^m`*`WfS~w7#4UQu7*!TwCaM|4 z>O!4*#uca_-x3j5AZ0`Z3c}6k{Vde6U64-^W0mNOtT8hX=wwBh*)SS2tWkXovI9A+ zQDxC}qpF74fwZfPks%%?3Q~*6bx0CO%2Cz8bRxB7K?)G3jKLIu!kK!}0WyuEaVD6v z&|?IBI0WPwFbB2BLeJyqe1tyqe1=*?f<|DsK!mJ~MxX1p~t#Fuxhxum!O}Rk+ z7+_>b%(7r$$b$-lXplpY405qxU;wFPV`v0>7-rfR3kHU7;7FOIzyxB*S%T6f(i}QW zC8!9bQGp7x0<&;L&E%lPg`fkR;nBm!(8Ey2fZXjs)qpS{GiaR7GOcpuIp_e+ya>#6SbuhCALD-`gzy#w0=63Y<0eZ23KkV_#!t6i_ek3ML z7GDS>%OSJTV*->d6rfpy3B*u>a+pC36)1-V#888BSV0U8D2ENi(1LQ(0gf2+p2kD9c>w;vGX_gEO zr;zy9EEyQ?Sb`SX)qsylpAX`Ij0NSg8l+r?Fc{K)02w?1Y!IZK0b+v;2RSEYK8OV| z1tJTJ6%$Ja29QozrU$Wmz@|Vv1=4p2i4S5Q0f$UO{d^GP3X&v<4RSwtU;@N|*a$HR z*+x(RfZ`cMw}1_Rw0Ra-GB7N$1l2{4hAKpaV8Fi8ipPe5jKVz2GFGx2tDX3I2md{iyV=SK`)cQ$p~fw z`I0abKnV%PMh|CXIb=4vI+%W>REETa$%0Y^jVfu7(WE9g)cgmEWJH34IT^Elz@Mbp z8KA`z!hjwINO-LNCt#K_0S-y;^<%8(YXSoTcZm-b%Fhf+?0c) zAVhB;lo~)7U&2O~LuOMg1EA+mg!9mc4bYtr$pA7)IUM8}5JpP%NKB9n2oJIhFe1uk zNWU8t`XCI6NkmDEo^mnUjHpE;$P5t1mmrblklExV+(DLRMhi^_&}a@7daBry8ge0o znm-At2PI1o#+T%f<&fD!C~1Q71NMa&AkTv^W=2Dnvo}mn8!O z#0-eLK>ALA?SSw>>|0hK&o|W12Qi)@Ng^zT7zVNsgkhF~3LJ!^ z4dKB65(lXRVUWDG6?iD$0qQ?ShKvX+28LLOXpt2ILj{BhQV+r)Pk`)3pC+oYVqj=N zRSHrL!k{XL9{pC3T_B8JfuY7UNCgOEj=rJ}y(0${ET%#FKp5TgATba|PXXwBkQxw1 zHXC_?AhI|}9S9@!g9tJ~>OmNn`;ZI(DFa~|Mh?h$5Jry=bk`9ZKagAjG7*H)!!V-xIk^x~XLKKHI$XpOc4^Lvl5C7}}$Yc;EHXMO5+h#>{#uz?sdP!2nYAqVAffEXDzpb~PD0(^!B zWS@pLs5*dD4h7|t-HVh1Y zHX!pM0SaP=f%y=fAn${)iZufR$OJZq_{ofMlNk~EAnFkMAo3tRAPmz7Dhv?z8qSBQ z2Z@8!fiOru+8SJf7eJlJ$dJ)y&A`wN5nW)-z_1L$1gQsMgga0RJUJT%1~qVCHq_4t zF$|DA1!CL4BtfQtu$B!2gSHLWb`TeYS6MSKY(ljUBn-k7r+<(EMC^YB*#*MnW)sv< zK@RQVQVkHlpA{62AdHlqL0k~VA_R({p-|C7@*l_(APg!O5KEx&$2Y1@kZur$vbpoS0EcfnB4e)RDmE9Kp3-t zM3o1r0b#-!1~sFhs|T3@!bo9-#01HJFcu+DTBN9i0+|cKvQl z0#OlQW*UeB>0@PpC<19@U|;yu!0z3P!1c2ApzyEgBVg!4hM)K1Lbgn7;;b!7l@$*<#2--PaweoANmEkO3xk? zQIJ+Lhz(K$@*HBR5=<2%LmEiI7JE?m#e=9l_K-kJn-5}vbRunHQL$%W0I3I6a3Fda zSYHA{CH%Z2H+u$#KCshjSU}QOpzK@r3=DU`x-vo31E?@Gl`+7y!DbpkTCakA1DSdU zX$R?n$)oFIWXJ$%xd65y14KbBW`^lR$~+*;W`R{Ef;2(=3SZ=&2lW9XLncTTFo(dD!1yqSfz%~{J!vo>M1xF4GX^9Kx?~qbgQU@SjDp~ z3=C2bri>#41IP}feNZ4nZ-DeMK&l%M`vsT}N!uXyFEAe>53+;B5tQ~Je2_(aNPLiO z5=eZIm2zM{#5@oiMQ1K6<{Ad|TuOjt}iI5IFeLBog%#BhOf zm_dv=P!9YciFJ+)412&Pa5zEYhzZ2tf^wKa3?V3o1;h}6a#%qOF(`)(#E^h;*g*^_D2D^Ykb!bIK@2%4 zhYQ3|fO5D&3?(Rs2gFc;a(F=uH7JJ<#L$3p_(6;ZP>ul1cLq)j45yqx0b(@&juQg| zNCEPp0~SsU47 z8C=W|zDNimhB({+A%>}!nSldwITOfJFpt9m1H=af0`iFpmz)?F(8XZtiEIkNl%qFz z(3^Uw^#-~uGebuu-0P@HVHObS9*{D4(E{QO=Hs#82VWr{f(7$1W{9HB_Miq6t_et_ zVi0C9(*7)j5PZKkObEUDfQd6Pl);#Anwg;k(K>^PVznj|CJUo+o%+PYPzO^2r*T*V zFS=j~vDzFClZDZY3}G-Pj3&WS_!c*qUZjn=2q6ro5ez+08TANSkTHQ6PoNxT5JSru zQZU1de~|JwPN1p^QuTn?0?r^lr0N2(g`6Qxv5fg3mIjh6h^+}WvZHi9hygMmHC=&3 zbihg`DKLQ;dQc8Ch*1LNz}*8k@S z{v#cqfod^KEi6zGe28;le2^}Lr66aRxInTw6Nq63!2KXh65>g0EYo2Oh9Zm z7g&Y|v7(S_c!*fLM=^WI^o5U_L}Q zhz+s=)f2GL1+@W)9MXX|6_^-$;B1&V=+!Z*ZRoP-{WnzAAlE*F1_~31@dCfr^~!m>7EaUeT;CPD+9vI#Ab4XsRpqUz_JjtK|OnAm*#`wvMsPPGlcTkEUvIN7Pus{aDV+_QBw^%?N_}mMK17Ac1 z;=l(3K^z($3@i%sDHB5voDCCWV}QgEf{(hO2{p!Wt)0Z(J;LabFf){3c4n9uDqs$P z)65K2meF7A5m=R12RWK%;=3=P9I5Z9>i5V7<3IHaL8Wu27Q0xu2^h09L z8Pdvy1qf;|;hJaz4Nk*!FfzcC2@YX|N_ejlO9zvSp$=!{5*bY}i!jpyq}+qaqk9sc zEKCnwoxse{Q3Wp{QC&--dqB=6r{sedc1#RCa5l_t%QMSF7(E+YxQyF882E zA9^K2Ou>rTvBUHuqGLx$HO!?*(E}4g4@_z}p04qU-vcmjQs^XVgbJZZ0@*=&lv3z1 z^xOe*1fsW&E;~H(4z?772zU}x3@H4uR}e6Ruvv#3#Iz_Lu-S>}Mc9xX!lkJ75PFIQ zB@V=p9ZVM}1c)fTLCW9(#l(QPjt^!IHaAlmPG|#Yh#Kk|qmt5=v_ZG2Vtl7`rZb z8wgbwTo|T{NbiG`!P{ua!!a;(Xc3tpODRZC*b*%wYG4jW8LC5%FLYm#uNY<>x{1U& z5?vR}G>StAvss1+A@smNP1-OgpgRqn4^u~^Q$fn$h7Of2Vqxg{k8n9N z1Ckp+SDI!hBiw`{33DKdAgWT%Fa49JNF(rm`90$DZ8Tn>gFh870o2qH!VrW?iGcm>%QJ}EUIwG;^PVTMsJHt{AB zm~~7HJsPC2VQMK!)!6jH%pEyp1$sq5hz|=PVqy%YmR6aFkXzB^VeSFd+C)_DFy-j& z40K~rTNdcD%nTi+@X`rYDa-;Q-2+mFy|IDZil_dhDhory3q(~8b2NIWpn45mmbkVt z$cIEk3`iOFfB?y0p9ExL=z&iNGBNa+z`OyY(H%?;?_hSlF{fw{U2j}dG=#=RKrTg$ zg-|%M4GKU~gBGL*`}`{Mlmin(j~OhmVKjXLJ!Udv>|}Ty2nsIbKu48DxQrU7$0Ci> zCbYKx_jJ1_ltG$HBk=!fQAf7(jRj z2Ll5Lzv5tE0AV&x1_lrog2x5}Lk%YbLmwvt!xBygh8sxYpEwy9bhsE8EVvjL+_)GR z{J0nx!jR^NzHu@z{NiL_kl|urP(Ts~nJvP}zyQKxoD2*gEWydZ0K!t73=AMF1JcLI zz@P-hDx3@qAgsp8zyQKAoD2*goWaS!0K$(r85lqq*?tf^f{TFxgyXmv7(lp=i-7@z z`;gqTg^PjV3Ks*zBQ6F84)|O?1A`Ga1A`kk149Kj1H&XFagbgSZUzPrUV$WT#>2p1 z#lyg0$HTx71YZWgz|hCbz%YrIfngdi1H&r#Rly7lE_@6OF?L$Z;1kpg3{rv& z3`T+s3<-h^3?lFwks;!GQ1Jkbyxj zk~xP&7#MztFfee5GB5;*A;QlSffxe=2rm#vxC6xA zAkM%5!Ux0|7(n=sI0FL+Uy}eWD}`VX`-ubt0|@_YnQHF69L3~~$%YEb+_fq?;pT@(@Oekn3A=qNKVTu^3U zm;fJfVPLqS%)szWnStSzG6MsX3IhY13Il_j3Il_Z3Il@~k~#xr28J?a28KCMGhilz z#Lbi$7;Kao7@U+D7(A3282pqO7($d87^0LJ7~+%}7*doO7&4R@81kU{7br6@Y(g^! zl*U0AlU3>%R2 zz;$RcFc@euFxY7_FtlhgFig{AV0fhomu1+X$-r<-lY!xsCIiDQByo_N&Z#gkfN+>9 z0|N+y+yTOE8Vn2|{6&L-0fdpwi_&6Xh|^+VxTVLy;GxgJu*i^s;gBK1KA8MFJq89F zeFg?6eeCKav>6!Wv>6ywv>6yQv>6zTv>6!ev=Qdq(`H~;paU`c1d{n6u{Amj40m)G z7@p}cFuc)WVECYe&?lnHz;H{KfdQoF9Fjf>Jq89XJq89HJq89VJ%su^JqCt4JqCt8 zeFlaf`Ur6ldxZf5gM=XigA$TCMTQIv4TcO1O@<5%6OhC~VZ@@vzyQK>S_}*ztfs}l z0Kytt3=AL)at{dKGGt%?VJRboeIRz35d#AVe?k%mvFnT(7(n=uF#`h#*O)RefbcO> z1_ls*W6Hn)!a`;Y3?K};WejFAC@tc{gwzp|M>m^T^^~fkxBf@a>&`%Toq?`MgV`@- z&cFb=^bB+*8R+IMn0Smi0|V&#GSDqvAUT+Lp9KTM1Pca+NfrzYpgX`|;voJ!3kC+z z^K8dXV|B^Z}EH@nJN% z;-H&%a-dh{?68EH0%;?_%m&dg84w#84|j3UafEJG3=E(H2tlU~_Ce2C1f8u2I<5=m z|7m!{LB|uKt49t)V%RWy(ADA+CsrLH{kY^|;-JI6%B&d}K*xK5&h$EE&A@QRnt|bt zH3P#vYX*jQ){ukAK!=fm4m^YD1BrtU{X!Q*uw`2v?7kQ^u-;F3odhxr$DdI#vl4$xT@ zphG2K;-GUdrr9$vfW$$EYrw=o$1i+yU|@iqdjLE10CbFkh$907?Dzy^_46DU7@jyV zFuZbri83&N+&asKfdPbf*f21F@C_RV1`r0FNdv;5!(u?V$(Dfugtyo-Fo5tgTLuOY zwzFek0AbLnEFcUzzyyRr{s3Xn!4@D4I?w`yLB}}2TmWK&PGL2Qt_Kp3=D4JHm^ zgSLsm_=ISXTF`zX5C-kVfw=^iK3wv&7KgcqRC{3h&}mZ58Eop&{X;80ss2WH2QK|E zb%f+$>d5W^isgw%)GRG7&|d3sVKD!#>>gfONFu1iV}0-oZ^xq zn0QWpGK>i|7VcDn3~6X31Y4N2g@J)#mLEbJY%U5kjsXe~W{{LZ1B0JG1H&W`8;U`4 zAf`G40|RL69;9xPLIcACe+C9_q`_*KI#9nC#0IHjU}yxZLmE?L0Lg*O1Iun9JN|@2>S;xFa#hCZiCc-#C_1z&5veaxYr4jg;dBObrERl zYM(MP*upmlA=IUzsoQ16#8AHwWC8@kOfEuGXLE-MWl#*Z3Ai4r4(8vKpG*u7kxt?O znFqpMP<0Sn7#Lg&m>K*|z<3DvO+`~T*@A`P1k#`<$Sja9(0DN5lhQ$yj zn1rbV(XccDl2{SM!eC&;zyKN_zrYCE(g|UM=2?)_jv zXaFl>W`NiXN>?BOW(JrIjUX-qGXpFX!CVGr2KYQ4Sb&)Umde3g24)7NStkb2j#p61 zg~)+OW(JTiKr9GmWyh{$7#J8< zA-VT20|UcKBt8!#1H)1zzBD5P!&)T$DvS&aE0E+37#SFrBk?U585ou!@m(1i7&as6 z_hw{ZSdGLFMnon9J;Do=UM?cJFPV{nVH=Wr3KR1>UAmunC10yp7Lp2MiE`q4%VrF0{K~gWw z%)n5HBrn6vz>tT;S7l~kNJmny2dg6K6d$1aU@=npVZ+S8aFK<90aPwCGB7fDFf%Zm zLvn8*GXukEBz_c{d()X27*ycZG$TVbGXsMX62A{kJ+154`E<5#1)c5NNN4+Y(b>Mk z%nS_R_9F`@e=#$hqO<*1>1^KvkbMfU@{x(*6Npd8@)_Kaq@#UYEDQ{wiN_vj`%jF8 zf#Ir31GuLEYJVuOFfd#~;%l-nFgPeQFa&_>FD3><76t|dg$4%D{5~TC6N3d(mx3Pc zF-JPv=S^q(lIUz-F`ez}q_chV=xpD5I@`C6g@HlFoq=H*G(UsdQZfp#{wWi~VLH3# z0-f!U}RurWnj36#1}&vVgZ$pDy$3)74Y#xMg|jB28K8! zz8ji)KUM~Y8A$T6X!5jf&n45@zHB<%S59a9y6J4+TsqsghR*iwq_cfz=xpCjI@|Y# z&i4JKvwdQqfg5OX4JwamU4ClN**;r3+ZRA*`*P@PUoD;OLmU7?pYg%jboSpSI@@=M z&h}lUvwhF#Y#+4f1XG~$^AD2!AVE#|*dvI?zz~4OFGb@oM&qACMg}GS3~2AB@J2=U`ya z08J8tF70AqWGLidVEE?--pjxsz{JQAJV1G0hV4FdxM$o{DukPRt|WS%J}WWxq%e-Mc8 z&I#EF0-AXR@uN8z7=+a!<6VLb%nZ4l3=G%YAZrpp{;B3f4exg7Mm*5|F_8Y5pbdL| z3=E+8caZw^oD2-0g@})7*e?z7(g3}K=ZvI^UKlHH-q?+pre-|=1&Fjk@CkvZU%-wJ`4B44{RFccA7Q^FS7z z-+=Occu@Tt!2?;y2+QwUjj;6mj)#HaojasF0LlO0VPF6)1O%-M0P#6_QQa@f z%fO)H4=Ec37(V`2MUyw;g>3YKneW02*&qno*8(yxloztG7bc(0%fKL@+5j4?2dA$p zH1k@~_@Irdpbc!Gb}z`h)oAkD(fEha_~+61x6$~|(fD6@85lqdNn!ED#|K%!3fcz) zvR|GLHUAj$F))buFfhQ%FIPU)@C)RFY*2&AC!xvbqw%Zw7#Khs7h&aBD<5Pd94!CN z;Dc;*gN5fRKF9`Q(0Uz^`?jK)cLbYml^2ms~p7krR~xuE@SApO5U<_Rz` zOk#$lKOTNm|48s7mj@sJYwh`l*NtfQ_oDG<@_02OzyR7n12PX(e>@dH#22VMc_RSXSP5Fc2eR)Untm=p28KKCptJzO zj10npkd0xm@CI#Q25m45fuAdk9+o z)(bK)WHEu({($NuMuthCjm*-B@_&gS1H&43$oxFW{j1T;+m6ORjK)6?G7q$w2pazP z1R)E}K{xS%%=>{P4+=j)Ayog#2thW&&4apEQwXwQ5f+~|LJSO`4ZE=N%U_6r0kpvU z3DmwAH1jfqARDRwLFJ2u7#O73A#3nJ`JoB4xf?0{^q}dVDa61auMSz?1>>iy83B9MbHKOmXw1(EXmED;6<(1vAD z`xYd>LWF?f2*z=3f$FU;r)J2Tc=z($_-~$N?O%`tGX;WMerj zyqH8${lkyOmlkDU0ByX3)t~C33=ET@>&HOp(L@wc{($1oNtA&Bv|(cv)V)!nkj?!t z{}!N`UxUW)5M^Kh9ZUf8{|q$wC87)rEbNf-7UaLpqL7X1u=4JRC-!t))PdB4&4>|)62g_%KEjDZ2Pffm-DRu^Mn_^Z+YZQn98n2A9SNP)$VHRw=Rhf#KtSDUdt|14AA( z{#C_M`#ZkkkONjg2kn5uCkdn;slA_z#;*`(U^s@p!$lL;k`KIV3sLR`xqq{7(g4i@}TvF zvIJ`Q=%ewiB_Nyf_dwOVOE56Z@ImzNe9_cLN-!`ya)Xq|p!A+90XgUa*4}BAfE>^O zYmZJt)4xapawrF^eBUO4nqQBg@h?a)Fib(p-}fXK7H{rFGvS$01q1m@cI)_`n!at{~j9u zwIl<>G*IJ?fq_ARiIL%hBm)Czqdu%Y0riDI8|7f-mADiGgAh`EU?#=D5ah=Ix?&GJ z-s3EVn!W<0ARFpnfIgVHM_L#Y(xP!iC38<2aOq#zsmVfh7gxCdy17_2^B zj%NNAH2y&;NPh_we}W8*4Ckc~{sX0tt5T2yK49hdb2R;*(fI$-_}tQn@CLb8Q5x01 zx@de$G`_1e5lO$W29Qj7AToZyngl2iug(xRf&yb?Fiwkp5U+@#bZ zhM?4vqDtrd(!3G~GbA%NHNUik!6_#{IomNMr6{$yn87(QCnqT}Ioqu?FPR}IH90l2 zEHwq$6sOX(wA3QclnMstjMU`p;?i6O&tQK;6B83-T_Z=mWQO39#G(?H)ZF|O2Iu^g z)MSW;fRZAHfW)HAl1c>MC9xziC^bE^xFofRAviI&ASV@#8<1a|S(2Hb$KaG%0&%%# zG1QdI5(b~d;u0qiou8QEo1X&lxLZzQdND|SFlbAfZ)RFzQL1xJVsUY1vR*QSb7E17 zV@RN5SYl3TDwr4S=ndfnr6#7N76qji7v$#^L*x(~NNB@0B{TShx;eU}7AF^F7L?={6@%=}&r8cpFD*(0`3B5SNlo_5%Pesz&CRWZ z1XM_3aW;hOSWu9YnG9BoP=h2Glv&&A*rsUv>0M5*akyOsCkB# z<_z)4IjM<7@kzzSdZ4|C`3Qb|F(|n*=%pZw<>coVFgRx<=BDPP=I819X69vrtf(w5 z0q4%3#JrSzP&NfQ0UR8@sk!+@m3qkx5C%hVYDr0EUOLF%A*n^VnR$shddUnhCOA%0 za}p~NImZ~3bDWDR3rg}0LCFKc@^K3e0_CTYRM)c9JP6A_C4~X(O-CmP?aTm@ECJaS z8tep01bWE~u6Zd1`I&ho!6ikhiMjC+zOL>d8(_k4fzV(l=lr~qqWqkk)FNb2&%Bb< zqN37*61bqVi!(SMK@z-PGDA^fUW#5mLrQ);h{ccx+8$b*S5TChSCSTApqI~3mImb% zmw*(e6_l1F>*X`Vr(~Ap=BE^Ant(V6UVL6^x)DP>l0a%jW(h-lDXMw|H$Jt1As$IO z9vpA+AYEXSi%aqg;tPuM(~A;w8GKw_KmiLXk@S)oJUm?j5{rsci@;)_yos7$J@Si7 zQ1djz+wjl;DS&eVG7D1CLK-9lmv<~p$;?L$JP%J7Q~}?_;^N?v{G!BkNO1+R50s=l zT|7~h27rP%wFp%($j`+y7*)tIFQq6yGsQ6(R08A|Rf1(f4%bU&KsX610E=EI7v?@F z7u|I*VVK*Xd}NnFg%Iw73IvyA=Hz(h!u$ypb$0aeadLF_jt4s|9^(6W_tcW$)Dl># z4JgVlNG&RI0ei%JlRuviSv z1Zj!MshBpy6HvTcW==_J5!^t}lGI#;p-4767o{eaq{7uP#K)JVCYR(F#T#27*oFos z@Vp!ES?nJgg76KbEOo6&O$L|$2u((yTmv=C%os@=$zU^3F`JrNUKC$sXc1pwY?NqH z3d%gWr8yay#hFOD455WsP-=2wP7b^%3r;NomF#7yPL-Z146b3Wej)Lp!A`JnMX4;D zGZORCQ&Si~@}R;F;Uq&tOGMy+q}@|X5IK(l#T56{5}(ZC5(Z}%XLMUqVM(GGRt*G$ zQwpfig^7Ry$|b)%FDE|{>XKrRTQU=KGOJQk7~I|y1qBU1VgM9~%33xJLfYc1`sU=R8C8-R-;0gmQ3o1#WMnNqy z2USlnHmH7svMmkawSptK{RAq}k;4F*f}zEBP-NR!fYMTREGPh{EQB^#&VZ+U zNch1*Gah0r!Z^66EDaEbcoqk{hJ*&dixjvb6HvPysd=D$3k_&PLlanJg0ea!fS`^5hX%w2kWAy&d^GEZUe`p9a)*-VxUoi{stJ(OeE37&A6Ntr0+>S?LEltpx5y zbC4UMfoTHonSg>29IJ?6H!_74p^l{`8At&E?P|eucYHul7*cHl?sFrIu|%@Z%n)W| zK#-q1I9KJQ<{=pkDwtvMP>fN`pw}+YE(CI(1eJx5VhkLoh@61v(LzTU-~nQ2h?#Z5 z6SGr8K@IlIyv!1$G!>ee5}a8DiU?>3nwo%ok(^r)AAnR9f(9F$gPa{{M9N2oNY#L;891=OU9%5~ z#c^m$xEGv5?=B4ByMVkqzB!nCZ1kPx1>n)HARRaSgqYVs^LIqqxz!EAroT1}kATJ>_ znIRRR7D(CD(7+O!VW1v^2Av5auN1?JeQ>JBXv2a>uKd%$qg~L10d4i>=Q%;LJcb^Z z%;IG9I>88(Ccs4&C=$`yHlRT-aDalUMVHKCP$LwzVnlBVfc#_PjR=91)U?FX9HctP z6g5{vTTJlqH#9^9LAb_ zF;8XyAK1dw_GmVDyF6EjOf^GY&vKn;~jXk@xWx-js_goltRa>Z>9 z%^x70Xmt^INC}i-@(U{CK@kiqjNDU8AoUGuOgI)4fV^esjie4_EV$(ax82YHDSj+L zftFMZYdm{GhgKaO3qU0TxBzs|$xlkmft6?sxrv#148`Cf7`TxZNF|Y>0a7kO$~-0} z@V=dMWpYj`oEMx}mI@AVcxb}1JWK!)PZmfaXJ}xCS(HJVv7ky9+T=xaSn^WSi!+h+ z8zMQ>6jYjIq$U=C%MwT<4iuJ98;~*;#9UBy0Itvx{TR@w4z&IU*V&#(jYp*LF@iRA z!G#{AJyltf3TsY5dpxLBj1kCj(DDU2p@N4eq2k7%h=j7uEm6Z0)CwwQfM=hOd`ON$ z6o%mTE4-5sfTdY)iWFAnNM)*pF#~v<4G~2~Aiw68=Hx@#I2a`uB>Zw<@dB;#g5fC| zo~X=VBfRi@1n!>0+G3C#7#|NB(z{(pfrsb5k>NlA(G3%tx#~+4?10eG~@z{ByhMwQ@dYg z5@@s^DU(5qe$;GWXo!+~4H*K8@>5EaL4(fV*aUkLnx5QKOMFvvQ5$*|Na@xPsbsP+ zL2iB`HKE|~Z3?Pkp_$7Rsq{32ClyeW%_B9Z01|qTY8DYXrpPvfVjh&7Kxwk51X@W! z$}NP2mhiR%wA}+4)_|rgv~aON?J*#QHmuZ!wktrRY0$1jYHCqRJocU(XaWN^SZIXg zaucNBw?GOJGf-|QD9VS7SQRIhfrqPLqw(-^9-58eZh*!VWMBdAb3?F=xurS9kn#fn D^ZmpU diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.h b/Firmware/Chameleon-Mini/Chameleon-Mini.h index a9b39fa..3bb0f63 100644 --- a/Firmware/Chameleon-Mini/Chameleon-Mini.h +++ b/Firmware/Chameleon-Mini/Chameleon-Mini.h @@ -1,58 +1,3 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. - * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ - #ifndef CHAMELEON_MINI_H #define CHAMELEON_MINI_H @@ -70,6 +15,7 @@ #include "Configuration.h" #include "Random.h" #include "Button.h" +#include "Log.h" #include "AntennaLevel.h" #include "Settings.h" diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.hex b/Firmware/Chameleon-Mini/Chameleon-Mini.hex index 0aa0a07..03767e9 100644 --- a/Firmware/Chameleon-Mini/Chameleon-Mini.hex +++ b/Firmware/Chameleon-Mini/Chameleon-Mini.hex @@ -1,1269 +1,1588 @@ -:100000007BC3000095C3000093C3000091C30000B0 -:100010008FC300008DC300008BC3000089C30000A4 -:1000200087C3000085C3000083C3000081C30000B4 -:100030007FC300007DC300007BC3000079C30000C4 -:1000400077C3000075C3000073C3000071C30000D4 -:100050006FC300006DC300000C94AB1269C30000B5 -:1000600067C3000065C3000063C3000061C30000F4 -:100070005FC300005DC300005BC3000059C3000004 -:1000800057C3000055C300000C94671251C3000011 -:100090004FC300004DC300004BC3000049C3000024 -:1000A00047C3000045C3000043C3000041C3000034 -:1000B0003FC300003DC300003BC3000039C3000044 -:1000C00037C3000035C3000033C3000031C3000054 -:1000D0002FC300002DC300002BC3000029C3000064 -:1000E00027C3000025C3000023C3000021C3000074 -:1000F0001FC300001DC300001BC3000019C3000084 -:1001000017C3000015C3000013C3000011C3000093 -:100110000FC300000DC300000BC3000009C30000A3 -:1001200007C3000005C3000003C3000001C30000B3 -:10013000FFC20000FDC20000FBC20000F9C20000C7 -:10014000F7C20000F5C20000F3C200000C94651372 -:10015000EFC20000EDC20000EBC20000E9C20000E7 -:10016000E7C20000E5C20000E3C20000E1C20000F7 -:10017000DFC20000DDC20000DBC20000D9C2000007 -:10018000D7C20000D5C20000D3C20000D1C2000017 -:10019000CFC20000CDC20000CBC20000C9C2000027 -:1001A000C7C20000C5C20000C3C20000C1C2000037 -:1001B000BFC20000BDC20000BBC20000B9C2000047 -:1001C000B7C20000B5C20000B3C20000B1C2000057 -:1001D000AFC20000ADC20000ABC20000A9C2000067 -:1001E000A7C20000A5C20000A3C20000A1C2000077 -:1001F0009FC200000C9403219BC20000660F660F93 -:100200004E0F570F700F240F3E0F410F380F291458 -:10021000B513BE13C513D313DE1303147D131114CA -:1002200018141F148115811595155016A715C5159D -:1002300045156915691569150E1CDB1B7A1BDB1B3F -:100240007A1BC91BAB1B7A1BA21B8B1B1C034C000C -:1002500055004600410020004300440043002000B8 -:10026000440065006D006F00000018034400650045 -:1002700061006E002000430061006D0065007200A7 -:10028000610000000403090409023E00020100C0ED -:1002900032090400000102020100052400100104DB -:1002A0002402060524060001070582030800FF0951 -:1002B000040100020A0000000705040210000507FF -:1002C0000583021000051201100102000008EB0373 -:1002D000442001000102DC01004E4F4E45000000A9 -:1002E00000000000000000000089048A048B048CD8 -:1002F000048D048E049104920400000001014D4617 -:100300005F434C41535349435F314B00000043145A -:100310007A14F5140F1513151415E718ED180004C9 -:100320000400024D465F434C41535349435F344BF5 -:1003300000000043147A1402150F1513151415E765 -:1003400018ED18001004004E4F4E4500000000004C -:10035000000000000000000000000000000000009D -:10036000000000000000005549445F52414E444FD8 -:100370004D00000000000000000000000000000030 -:10038000000000000000005549445F4C4546545FA2 -:10039000494E4352454D454E5400000000000000B8 -:1003A000000000000000005549445F52494748548E -:1003B0005F494E4352454D454E5400000000000039 -:1003C000000000000000005549445F4C4546545F62 -:1003D00044454352454D454E540000000000000086 -:1003E000000000000000005549445F52494748544E -:1003F0005F44454352454D454E5400000000000007 -:10040000000000000000004359434C455F53455431 -:1004100054494E4753000000000000000000000057 -:100420000000000000000053544F52455F4D454D01 -:1004300000000000000000000000000000000000BC -:1004400000000000000000524543414C4C5F4D4508 -:100450004D0000000000000000000000000000004F -:1004600000000000000000253575206D5600257540 -:100470000025750052414E444F4D002573004368DE -:10048000616D656C656F6E2D4D696E692025532019 -:100490007573696E67204C55464120255320636F64 -:1004A0006D70696C65642077697468204156522DBF -:1004B000474343202553003134303932340031333F -:1004C0003039303100342E382E31000D0A000D0A3B -:1004D00000643130303A4F4B000000000000000053 -:1004E000000000000000000000000000000000000C -:1004F0000000653130313A4F4B2057495448205461 -:1005000045585400000000000000000000000000FA -:100510000000006E3131303A57414954494E47206E -:10052000464F5220584D4F44454D000000000000FA -:1005300000000000C83230303A554E4B4E4F574EF7 -:1005400020434F4D4D414E4400000000000000008C -:100550000000000000C93230313A494E56414C4942 -:100560004420434F4D4D414E442055534147450093 -:10057000000000000000CA3230323A494E56414C69 -:10058000494420504152414D45544552000000001D -:100590000000000000000056455253494F4E000035 -:1005A0000000000000000000000000140D434F4E4A -:1005B00046494700000000000000000000510D48BF -:1005C0000D320D55494400000000000000000000FD -:1005D0000000000000810D570D524541444F4E4C24 -:1005E0005900000000000000000000E50DD30D558B -:1005F000504C4F414400000000000000000000F992 -:100600000D00000000444F574E4C4F414400000085 -:100610000000000000FE0D0000000052455345544C -:100620000000000000000000000000030E000000B9 -:1006300000555047524144450000000000000000B2 -:10064000000E0E000000004D454D53495A45000074 -:100650000000000000000000000000190E55494491 -:1006600053495A450000000000000000000000004F -:1006700000310E425554544F4E000000000000005F -:10068000000000470E510E4C0E53455454494E473E -:1006900000000000000000000000005E0E590E4344 -:1006A0004C454152000000000000000000000066C0 -:1006B0000E0000000048454C500000000000000003 -:1006C00000000000006A0E00000000525353490071 -:1006D000000000000000000000000000000000B466 -:1006E0000E000000000000000000000000000000FC -:1006F000000000000000000011241FBECFEFCDBF9E -:10070000DFE2DEBF10E2A0E0B0E2EAE9FEE402C010 -:1007100005900D92A239B107D9F72AE2A2E9B0E219 -:1007200001C01D92AD39B207E1F703D00C944B27FD -:1007300079C07ED00E94D00B80E380930106E4D282 -:100740000DD10E949E0C87D1A0D681E0809300023B -:100750001092010292E09093020293E090930402BF -:100760008093200288E380932102CDD0C1E00E94D3 -:10077000A30CE091EB24F091EC240995E091F12495 -:10078000F091F224099580910C0A80FFF0CFC0937C -:100790000C0A75D10E94C20C7FD68091932480935D -:1007A000060610929324E3CF292F332722303105F8 -:1007B00029F12330310599F02130310541F080E0F5 -:1007C00090E020E030E0FA0120833183089582E157 -:1007D00090E026EC32E0FA012083318308959927D6 -:1007E0008130910599F082309105B1F0892B39F76C -:1007F000E4E8F2E0849190E09F01E5CF8EE390E0A1 -:1008000028E832E0FA01208331830895EAE6F2E035 -:10081000849190E09F01D7CFECE4F2E0849190E0E6 -:100820009F01D1CF1F920F920FB60F921124FFCFCD -:100830008091780083FF0AC088E08093780088ED7B -:1008400084BF81E080938000FD95FEC080915000C0 -:100850008660809350008091510081FFFCCF809191 -:10086000510082FFFCCF1092560021E020936000DF -:1008700088ED84BF2093400083ED90E38093260AA7 -:100880009093270A86E08093000A209343002093E8 -:1008900000048091CC0188608093CC01089588ED9C -:1008A00084BF81E0E8E7F0E08183089588ED84BFAC -:1008B0008BE18093800008958BEC809352008091AF -:1008C00050008860809350008091510083FFFCCFDE -:1008D00084EC80935500809150008061809350009B -:1008E0008091510084FFFCCF0895E0E4F0E0848122 -:1008F0008E7F8483E0E5F0E080818F7E808380813D -:10090000877F8083089587E0E0EAF0E0828378942F -:1009100008950895089508950895089580E090E059 -:10092000089508950895E091FE24F091FF248183B5 -:1009300095E2899FB001112468527D4F45E250E055 -:1009400088ED94E20E94E523E091ED24F091EE24FD -:100950000995E091E924F091EA240994E091FE24BC -:10096000F091FF248181DFCF0F931F93CF93DF930B -:1009700049ED52E010E0BC016F5F7F4F9A01FA0130 -:10098000C491C1110FC0EC012881222311F11F5F16 -:100990004B5D5F4F133091F780E0DF91CF911F9156 -:1009A0000F910895DC01FC91FF2389F3CF13EFCF62 -:1009B000DB0105C0FD91FF2351F3F013E8CF2F5F5A -:1009C0003F4FED01F90104910111F4CF288121116C -:1009D000DECF812FA8DF81E0DF91CF911F910F91B2 -:1009E00008950F931F93CF93DF936150710949EDE1 -:1009F00052E01CE29A01FA010491002351F16131A5 -:100A0000710520F426C06031710561F0DC010196AA -:100A1000EC010C932F5F3F4F61507109F901049174 -:100A20000111F1CFF3E043325F0731F41882DF9117 -:100A3000CF911F910F910895CE01019618836150B7 -:100A400071094B5D5F4F23E04834520799F6EC0182 -:100A5000EDCFEC01E7CF08950C94D72308951F93B1 -:100A6000CF93DF93662339F0EC01162F0E94D72332 -:100A700089931150D9F7DF91CF911F9108950E946A -:100A8000D7230E94D7230E94D7230C94D723CF9338 -:100A9000DF93DC016150710921153105A9F1623044 -:100AA000710590F1FA0121503109240F351F80E0C2 -:100AB00090E017C0D05DDC93CF704C2F50E04A30EF -:100AC000510504F5C05D1196CC93119712966250B2 -:100AD00071090296E217F307C9F031966230710589 -:100AE000A8F0C081DC2FD295DF704D2F50E04A3046 -:100AF000510504F3D95CDC93CF704C2F50E04A30A1 -:100B0000510504F3C95CDFCF80E090E01C92DF91D7 -:100B1000CF910895DC01FA018081882309F441C056 -:100B200091819923D9F120E030E061157105A1F49C -:100B300033C08295807F913430F5942F892B8D932B -:100B40002F5F3F4F32968081882331F19181992325 -:100B500029F16217730701F140ED480F4A3020F088 -:100B60004FEB480F4630D0F440ED490F4A3020F0AB -:100B70005FEB590F563090F48134D8F28295807F24 -:100B800080579134D0F29753892B8D932F5F3F4F2D -:100B9000329680818111DACFC901089580E090E01A -:100BA000089520E030E0F8CFFB01EE56FF4D20E045 -:100BB00034E0261B370B4217530708F49A0121151E -:100BC000310549F0DC01CF01820F931F21912D9354 -:100BD000E817F907D9F70895DB01AE56BF4D20E0BD -:100BE00034E0261B370B4217530708F49A012115EE -:100BF000310541F0FC01820F931F21912D93E817DD -:100C0000F907D9F7089580E094E0E2E9F0E2DF0126 -:100C10009C011D9221503040E1F708958091FD2400 -:100C200090E0A0E0B0E04AE0880F991FAA1FBB1F28 -:100C30004A95D1F740E157ED30E440936606509372 -:100C4000A0092091A10926FFFCCF3093A109209192 -:100C5000A0091092A0092091A10926FFFCCF309392 -:100C6000A1092091A0094093650627FFE6CF20E166 -:100C70002093660623E02093A0092091A10926FF76 -:100C8000FCCF20E42093A1092091A009AD016627A3 -:100C900077274093A0092091A10926FFFCCF20E4EB -:100CA0002093A1092091A009892F9A2FAB2FBB2750 -:100CB0008093A0098091A10986FFFCCF80E48093F6 -:100CC000A1098091A0091092A0098091A10986FF35 -:100CD000FCCF80E48093A1098091A009E2E9F0E2D1 -:100CE00090E41092A0098091A10986FFFCCF909317 -:100CF000A1098091A009819384E2E239F80789F77C -:100D000080E1809365060895CF93DF9300D000D0F3 -:100D1000CDB7DEB780E18093650692E090936606DA -:100D200098E0909365069AE1909361061092A60967 -:100D30001092A70990EC9093A50998E19093A409CB -:100D40008093660687ED8093A0098091A10986FFB4 -:100D5000FCCF80E48093A1098091A0091092A009A2 -:100D60008091A10986FFFCCF80E48093A109809146 -:100D7000A00990E19093650680FD3EC08DE38983D4 -:100D80008AE28A8380E88B8386EA8C8320E137EDD0 -:100D900090E4209366063093A0098091A10986FF14 -:100DA000FCCF9093A1098091A0091092A009809195 -:100DB000A10986FFFCCF9093A1098091A0092093FF -:100DC000650687FFE6CF80E180936606FE013196D7 -:100DD000CE01059630E421912093A0092091A1092C -:100DE00026FFFCCF3093A1092091A009E817F9074D -:100DF00091F780E1809365062496CDBFDEBFDF9139 -:100E0000CF910CCF5F926F927F928F929F92AF9211 -:100E1000BF92CF92DF92EF92FF920F931F93CF93E7 -:100E2000DF938091FD2490E0A0E0B0E06AE0880FBD -:100E3000991FAA1FBB1F6A95D1F700E014E0E12CAF -:100E4000FF24F394E0E1CE2EF7EDBF2EC0E4DC2EBC -:100E5000D0E1AD2E27ED922E33E5632E44E8742EBB -:100E600053E8852E492F5A2F6B2F7727382FE7010C -:100E7000C81BD1090C171D0708F4E801A0926606EB -:100E80009092A0092091A10926FFFCCFD092A10940 -:100E90002091A0091092A0092091A10926FFFCCF62 -:100EA000D092A1092091A009C092650627FFE6CF44 -:100EB000A09266066092A0092091A10926FFFCCFAE -:100EC000D092A1092091A0095093A0092091A109D5 -:100ED00026FFFCCFD092A1092091A0094093A00940 -:100EE0002091A10926FFFCCFD092A1092091A00951 -:100EF0001092A0092091A10926FFFCCFD092A10950 -:100F00002091A009C0926506C0926606B092A00921 -:100F10002091A10926FFFCCFD092A1092091A00920 -:100F20001092A0092091A10926FFFCCFD092A1091F -:100F30002091A009C092650627FFE6CFA092660621 -:100F40007092A0092091A10926FFFCCFD092A1099F -:100F50002091A0091092A0092091A10926FFFCCFA1 -:100F6000D092A1092091A0091092A0092091A10975 -:100F700026FFFCCFD092A1092091A0093093A009AF -:100F80002091A10926FFFCCFD092A1092091A009B0 -:100F9000209799F0E2E9F0E29E012E563F4D5190E4 -:100FA0005092A0095090A10956FEFCCFD092A10901 -:100FB0005090A009E217F30791F7C0926506C0921E -:100FC0006606B092A0092091A10926FFFCCFD0921D -:100FD000A1092091A0091092A0092091A10926FF42 -:100FE000FCCFD092A1092091A009C092650627FFED -:100FF000E6CFA09266068092A0092091A10926FF63 -:10100000FCCFD092A1092091A0095093A009209172 -:10101000A10926FFFCCFD092A1092091A0094093FD -:10102000A0092091A10926FFFCCFD092A10920910F -:10103000A0091092A0092091A10926FFFCCFD0920F -:10104000A1092091A009C09265060C1B1D0B8C0FF5 -:101050009D1FA11DB11D0115110509F003CFDF91E1 -:10106000CF911F910F91FF90EF90DF90CF90BF90A5 -:10107000AF909F908F907F906F905F9008952F9288 -:101080003F924F925F926F927F928F929F92AF9218 -:10109000BF92CF92DF92EF92FF920F931F93CF9365 -:1010A000DF93CDB7DEB72A97CDBFDEBF8C014115E8 -:1010B00084E058076105710508F08EC18091FD2418 -:1010C00090E0A0E0B0E0EAE0880F991FAA1FBB1FE4 -:1010D000EA95D1F7840F951FA61FB71F812CF4E066 -:1010E0009F2EA12CB12C6901E12CF12C841A950AB8 -:1010F000A60AB70A89829A82AB82BC82C814D90434 -:10110000EA04FB0408F47FC129813A8121153105E5 -:1011100009F462C1E12CFF24F394E0E17E2EF7EDA7 -:10112000DF2EE0E44E2EF0E1CF2EE7ED3E2EF3E58C -:101130005F2EE4E86E2EF3E82F2E29873A874D8341 -:101140005E836F837887B901892E9A2EAB2EBB24DC -:10115000382FA701481B51096417750708F4AB0124 -:10116000C09266063092A0092091A10926FFFCCF0B -:101170004092A1092091A0091092A0092091A109F3 -:1011800026FFFCCF4092A1092091A009709265062C -:1011900027FFE6CF69877A87C09266065092A0093A -:1011A00069857A852091A10926FFFCCF69877A8716 -:1011B0004092A1092091A0099092A00969857A85A1 -:1011C0002091A10926FFFCCF69877A874092A10967 -:1011D0002091A0098092A00969857A852091A109B2 -:1011E00026FFFCCF69877A874092A1092091A00948 -:1011F0001092A00969857A852091A10926FFFCCF6C -:1012000069877A874092A1092091A00970926506AA -:1012100069857A8570926606D092A0092091A1090D -:1012200026FFFCCF4092A1092091A0091092A009AD -:101230002091A10926FFFCCF4092A1092091A0098D -:101240007092650627FFE6CF69877A87C0926606A7 -:101250006092A00969857A852091A10926FFFCCFBB -:1012600069877A874092A1092091A0091092A0096C -:1012700069857A852091A10926FFFCCF69877A8745 -:101280004092A1092091A0091092A00969857A8550 -:101290002091A10926FFFCCF69877A874092A10996 -:1012A0002091A0093093A00969857A852091A10930 -:1012B00026FFFCCF69877A874092A1092091A00977 -:1012C0004115510591F0F8019A01200F311F6191EC -:1012D0006093A0096091A10966FFFCCF4092A1092B -:1012E0006091A009E217F30791F77092650669858E -:1012F0007A8570926606D092A0092091A10926FFF6 -:10130000FCCF4092A1092091A0091092A009209140 -:10131000A10926FFFCCF4092A1092091A00970925B -:10132000650627FFE6CF69877A87C0926606209216 -:10133000A00969857A852091A10926FFFCCF6987DC -:101340007A874092A1092091A0099092A00969850D -:101350007A852091A10926FFFCCF69877A87409280 -:10136000A1092091A0098092A00969857A85209120 -:10137000A10926FFFCCF69877A874092A1092091B5 -:10138000A0091092A00969857A852091A10926FFFC -:10139000FCCF4092A1092091A00970926506641BC0 -:1013A000750B69877A87840F951FA11DB11D611583 -:1013B000710509F0C9CE4D815E816F817885DA01B2 -:1013C000AE56BF4D89819A818A0F9B1FF8012191EA -:1013D0002D93A817B907D9F781E02A96CDBFDEBFB4 -:1013E000DF91CF911F910F91FF90EF90DF90CF9001 -:1013F000BF90AF909F908F907F906F905F904F9035 -:101400003F902F900895C982DA82EB82FC827CCED5 -:10141000CF92DF92EF92FF920F931F9369014115D4 -:1014200024E052076105710540F500E014E020E07A -:1014300030E0E12CF12C041B150B260B370BC016EA -:10144000D106E206F306B0F04E565F4D01151105C8 -:1014500049F0DA01FC01080F191F8D918193E01703 -:10146000F107D9F781E01F910F91FF90EF90DF9086 -:10147000CF90089597018601E7CF80E01F910F91EB -:10148000FF90EF90DF90CF900895E0E0F6E080E4E9 -:10149000828388E1868B0895FF920F931F93CF93E9 -:1014A000DF93CDB7DEB7A097CDBFDEBF8091080632 -:1014B0008095909192249827809392248074892318 -:1014C000D9F0E091FE24F091FF2480818130E9F091 -:1014D0008230A9F1833009F450C0843009F473C01C -:1014E000853009F48EC0863009F4ADC0873009F428 -:1014F00066C0883009F465C0A096CDBFDEBFDF911D -:10150000CF911F910F91FF9008958091FB24882324 -:1015100009F49BC0F12C8E010F5F1F4F9DDAF8017B -:10152000EF0DF11D8083F3948091FB24F816B0F346 -:10153000E091F724F091F824C8010995DDCFE091FE -:10154000F524F091F6248E010F5F1F4FC801099515 -:101550002091FB24222361F3F80191E0992339F0D3 -:10156000808191E08F3F09F090E08F5F808331961A -:101570008E2F801B821790F3DBCFE091F524F09142 -:10158000F6248E010F5F1F4FC80109952091FB249F -:1015900031E0215068F23323E1F3822F90E0F8012B -:1015A000E80FF91F408131E04F3F09F030E0F801CA -:1015B000E80FF91F4F5F4083215068F7B9CF22DC55 -:1015C0009BCF2CDB99CFE091F524F091F6248E018E -:1015D0000F5F1F4FC80109952091FB24222309F4B6 -:1015E000A7CFF80191E0992331F0808191E081113A -:1015F00090E08150808331968E2F801B821798F364 -:1016000097CFE091F524F091F6248E010F5F1F4FE4 -:10161000C80109952091FB2431E0215008F488CFBE -:101620003323D9F3822F90E0F801E80FF91F4081AE -:1016300031E0411130E0F801E80FF91F41504083DB -:10164000215070F775CFDAD057CF8E010F5F1F4F43 -:101650006FCF0F931F93CF93DF936150710947E4CE -:1016600053E01CE29A01FA010491002349F161322E -:10167000710520F425C06032710561F0DC0101962E -:10168000EC010C932F5F3F4F61507109F9010491F8 -:101690000111F1CFF4E047345F0761F0CE0101960C -:1016A000188361507109405E5F4F24E0473652074E -:1016B000C9F6EC011882DF91CF911F910F91089527 -:1016C000EC01E8CFAB01E091FE24F091FF246081B2 -:1016D00020E2629FB0011124695B7C4F0C94F723D8 -:1016E000CF93DF93EC0167E473E00E94EE23892B34 -:1016F000E9F167E673E0CE010E94EE23892B09F43D -:101700003FC067E873E0CE010E94EE23892BD1F140 -:1017100067EA73E0CE010E94EE23892BA9F167EC02 -:1017200073E0CE010E94EE23892B81F167EE73E016 -:10173000CE010E94EE23892B59F167E074E0CE01BF -:101740000E94EE23892B31F167E274E0CE010E9402 -:10175000EE23892B09F167E474E0CE010E94EE23A9 -:10176000892BE1F080E0DF91CF91089580E0E09156 -:10177000FE24F091FF24808381E0DF91CF910895D2 -:1017800081E0F5CF82E0F3CF83E0F1CF84E0EFCFCB -:1017900085E0EDCF86E0EBCF87E0E9CF88E0E7CFCB -:1017A00043E150E060E070E08DEF94E20C94FF259F -:1017B00043E150E060E070E08DEF94E20C940A2683 -:1017C000CF93DF931F92CDB7DEB7883020F00F9014 -:1017D000DF91CF910895898315DB89818093FD2462 -:1017E00090E0880F991F80509B4D8093FE2490932A -:1017F000FF24B4D80F90DF91CF9110CA2091FD241F -:1018000030E02F5F3F4F27703327822FF901EE0F13 -:10181000FF1FEF5FFA4D908191115CC02F5F3F4F2A -:1018200027703327822FF901EE0FFF1FEF5FFA4D6C -:10183000908191114FC02F5F3F4F27703327822F28 -:10184000F901EE0FFF1FEF5FFA4D9081911142C039 -:101850002F5F3F4F27703327822FF901EE0FFF1FB5 -:10186000EF5FFA4D9081911135C02F5F3F4F277088 -:101870003327822FF901EE0FFF1FEF5FFA4D9081A2 -:10188000911128C02F5F3F4F27703327822FF90116 -:10189000EE0FFF1FEF5FFA4D908191111BC02F5F7C -:1018A0003F4F27703327822FF901EE0FFF1FEF5FA5 -:1018B000FA4D908191110EC02F5F3F4F2770332753 -:1018C000822FF901EE0FFF1FEF5FFA4D908191110A -:1018D00001C0089575CF2091FD24205DFC01208377 -:1018E00011820895FC0180819181911103C0805380 -:1018F000883010F080E0089563DF81E00895BC0136 -:1019000081E090E20C949521CF93DF93EC01219636 -:10191000FC016491662349F081E090E20E94E42199 -:10192000FE01649121966111F7CFDF91CF91089567 -:10193000AB01BC0181E090E20C94BA2180E2E0E6C8 -:10194000F6E082830895CF93DF9381E090E20E94D6 -:1019500057220E947A1C81E090E20E947222EC01E0 -:1019600097FD09C080E180939324809305068C2F16 -:101970005AD2882319F0DF91CF9108958C2FDF91EF -:10198000CF91E0C380919424813031F1C8F082304E -:1019900059F0833039F480910020815080930020E9 -:1019A000882349F1A1D374C58091680685FDFACFDB -:1019B00084E18093002083E08093942495D368C5CC -:1019C0008091680685FFEECF84E18093002081E05E -:1019D0008093942489D35CC58091002081508093AA -:1019E00000208111DFCF0E945C040E94CE2082E0A3 -:1019F00080939424D7CF0E9493200E947504109264 -:101A00009424D0CF80E2E0E0F6E08583089580E280 -:101A1000E0E0F6E08683089581E090E20C94702186 -:101A200081E090E20C94CF2225EC34E03F932F9399 -:101A30002EEB34E03F932F9327EB34E03F932F932B -:101A40002EE734E03F932F9321E02F931F929F9333 -:101A50008F930E940F248DB79EB70C968DBF9EBFAB -:101A600085E6089529ED34E23F932F932BE734E088 -:101A70003F932F9321E02F931F929F938F930E9468 -:101A80000F248DB79EB708968DBF9EBF85E608953B -:101A90000E94B404811102C08AEC089589DE84E6B4 -:101AA000089560E071E00E94F10485E60895EF92E8 -:101AB000FF920F931F93CF93DF93CDB7DEB7A0971D -:101AC000CDBFDEBF8C01E090FB24F12CE091F5242A -:101AD000F091F624CE01019609959701AE014F5F72 -:101AE0005F4F60E071E0C8010E94470585E6A0965F -:101AF000CDBFDEBFDF91CF911F910F91FF90EF908F -:101B00000895BF92CF92DF92EF92FF920F931F93AF -:101B1000CF93DF93CDB7DEB7A097CDBFDEBF8C01EB -:101B2000C090FB24D12C64E774E00E94EE23892B43 -:101B300049F5C114D10499F1B12CCE0101967C0173 -:101B400000E010E00E942C05F701E00FF11F8083F8 -:101B5000B3940B2D10E00C151D05A0F3E091F724B4 -:101B6000F091F824C701099584E6A096CDBFDEBFA9 -:101B7000DF91CF911F910F91FF90EF90DF90CF9069 -:101B8000BF900895A80160E270E0CE0101967C014B -:101B90000E948A058C159D0509F38AECE6CFCE01DB -:101BA00001967C01DBCF2091FC24211107C020E3AA -:101BB000FC012083FC01118285E6089521E3FC01EC -:101BC0002083FC01118285E60895FC012181211109 -:101BD00005C08081813341F0803311F08AEC089593 -:101BE0001092FC2484E6089581E08093FC2484E62E -:101BF00008958FE398E0ECD08EE6089588E09AE0AF -:101C0000FFD08EE60895E0ECF4E081818E7F818341 -:101C10000E9493200E944F0484E60895E0ECF4E0D3 -:101C200081818E7F81830E9493200E94560484E6E6 -:101C30000895E9EFF4E221812F9320812F9321E78A -:101C400034E03F932F9321E02F931F929F938F9324 -:101C50000E940F248DB79EB708968DBF9EBF85E664 -:101C600008952091FB241F922F932EE634E03F939A -:101C70002F9321E02F931F929F938F930E940F2405 -:101C80008DB79EB708968DBF9EBF85E6089560E02C -:101C900071E0DFDC85E6089560E071E013DD85E644 -:101CA00008951EDD811102C08AEC089581DD84E66D -:101CB000089560E071E00FDE85E6089513DE81117E -:101CC00002C08AEC089574DD84E608950E9403063C -:101CD00084E60895DF92EF92FF920F931F93CF93C4 -:101CE000DF937C01CFEFD0E007E915E08CE2D82E3E -:101CF000B80180E990E20E94EE23892B39F1F801C6 -:101D00004491442379F1C132D10560F1D701F80142 -:101D100004C0C032D10551F0DC01CD0101969C0117 -:101D20004C933196219744914111F3CF79018FEF74 -:101D3000E81AF80AF901D08221970A5E1F4FB8010C -:101D400080E990E20E94EE23892BC9F6D701119712 -:101D50001C9285E6DF91CF911F910F91FF90EF903C -:101D6000DF9008959701E2CFFC01209120022068C6 -:101D7000209320022091230220FFFCCF81E080935A -:101D80002302A0911002B0911102AE5BB109B7FD20 -:101D90001CC029E637E54BE050E00E946F23AA27DC -:101DA000BB279F938F9327E634E03F932F9381E0E7 -:101DB0008F931F92FF93EF930E940F248DB79EB7CE -:101DC00008968DBF9EBF85E60895A0E0B0E0E1CF04 -:101DD00021E02093A2242093A12424E120939E2497 -:101DE00025E020939D24109297241092982410921D -:101DF000992410929A248093952490939624089580 -:101E000027E02093A22424E620939D241092972477 -:101E1000109298241092992410929A2480939524D9 -:101E2000909396240895CF934091A22450E0FA0114 -:101E30003197E930F10520F0C0E08C2FCF91089563 -:101E4000E250FF4F0C9469232091A0249091A1248B -:101E5000291709F4DDC030E0892F90E00197281799 -:101E6000390709F420C168E181E090E20E94E42191 -:101E70001092A224C1E08C2FCF910895853109F4EE -:101E800050C0883109F406C1863009F429C1853172 -:101E900009F498C0C1E08C2FCF9108958093A024BD -:101EA00084E08093A224C1E08C2FCF91089590E02C -:101EB0004091A0242FEF30E0241B310982179307B3 -:101EC00031F585E08093A224C1E0B7CF813009F4D9 -:101ED000ECC0843009F4DEC0883151F2C1E0DBCFC0 -:101EE00040919B2450919C249A012F5F3F4F209357 -:101EF0009B2430939C24FA01E05FFA4D80832038C4 -:101F0000310541F686E08093A224C1E096CF65E1D9 -:101F100081E090E20E94E42182E08093A224C1E06B -:101F20008CCF81E08093A1244091972450919824F4 -:101F30006091992470919A24E0919524F0919624CF -:101F400020E830E080E195E20995C82F882309F464 -:101F5000B7C061E081E090E20E94E4216091A12499 -:101F600081E090E20E94E4216091A124609581E0EB -:101F700090E20E94E42160E870E080E195E2D8DC24 -:101F8000E0E1F5E260E08191680F85E2E039F80771 -:101F9000D1F781E090E20E94E42140919724509192 -:101FA00098246091992470919A2440585F4F6F4F04 -:101FB0007F4F409397245093982460939924709373 -:101FC0009A243BCF61E081E090E20E94E42160919D -:101FD000A12481E090E20E94E4216091A124609517 -:101FE00081E090E20E94E42160E870E080E195E207 -:101FF0009FDCE0E1F5E260E08191680F25E2E039E5 -:10200000F207D1F781E090E20E94E421C1E043CFE2 -:10201000E0E1F5E290E02191920F25E2E039F2074C -:10202000D1F7891374CF40919724509198246091EF -:10203000992470919A24E0919524F091962420E8B7 -:1020400030E080E195E20995C82F882309F442C069 -:102050008091A1248F5F8093A12440919724509177 -:1020600098246091992470919A2440585F4F6F4F43 -:102070007F4F4093972450939824609399247093B2 -:102080009A2466E081E090E20E94E42182E080935D -:10209000A224D3CE66E081E090E20E94E421109277 -:1020A000A224C1E0CACE66E033CF10929B241092E6 -:1020B0009C2410929F2483E08093A224C1E0BDCE93 -:1020C00064E081E090E20E94E42189E08093A22410 -:1020D000C1E0B3CE68E181E090E20E94E421C3CE8A -:1020E0008091A1248F5F1ECF8091A224813071F056 -:1020F000873059F480919D249FEF980F90939D24F1 -:10210000811102C01092A2240895089580919D2407 -:102110009FEF980F90939D248111F6CF80919E247C -:102120009FEF980F90939E24811106C01092A224D5 -:1021300085E080939D24089565E181E090E20E940E -:10214000E421F6CF1F93CF93DF939FEB980F9A3143 -:1021500028F09FE9980F9A31C0F480522091A3246F -:102160003091A4242F3F310558F4A9014F5F5F4FF0 -:102170004093A3245093A424F901E05FFA4D808397 -:1021800081E0DF91CF911F91089590ED980F9A30E3 -:1021900028F38F3519F3982F9D7F9D33F9F28D30F9 -:1021A000A9F0883039F08B3159F71092A32410929E -:1021B000A424E6CF8091A3249091A424009701F356 -:1021C00001978093A3249093A424DACFE091A324D1 -:1021D000F091A424E05FFA4D10821092A324109293 -:1021E000A42480911025882309F4A0C08D7F8D330D -:1021F00009F49CC0E1E1F5E204C01F3331F01D3366 -:1022000021F0EF0111911111F8CF188267E975E003 -:1022100080E195E20E94EE23892B09F436C16DEA34 -:1022200075E080E195E20E94EE23892B09F42AC132 -:1022300063EC75E080E195E20E94EE23892B09F4BE -:102240001EC169ED75E080E195E20E94EE23892BC5 -:1022500009F412C16FEE75E080E195E20E94EE2371 -:10226000892B09F406C165E076E080E195E20E94E1 -:10227000EE23892B09F4FAC06BE176E080E195E268 -:102280000E94EE23892B09F4EEC061E376E080E141 -:1022900095E20E94EE23892B09F4E2C067E476E020 -:1022A00080E195E20E94EE23892B09F4D6C06DE50A -:1022B00076E080E195E20E94EE23892B09F4CAC002 -:1022C00063E776E080E195E20E94EE23892B09F432 -:1022D000BEC069E876E080E195E20E94EE23892B9A -:1022E00009F4B2C06FE976E080E195E20E94EE2346 -:1022F000892B09F4A6C065EB76E080E195E20E94A7 -:10230000EE23892B09F49AC06BEC76E080E195E22C -:102310000E94EE23892B09F48EC061EE76E080E105 -:1023200095E20E94EE23892B09F452C088ECC0E0AC -:10233000E1EDF4E0E4918E1709F430C0E2EFF4E04F -:10234000E4918E1709F441C0E3E1F5E0E4918E17C2 -:1023500009F438C0E4E3F5E0E4918E1781F1E5E596 -:10236000F5E0E4918E1741F1E6E7F5E0E4918E1790 -:1023700001F180E090E0C8DA8EEC94E0C5DACC237D -:1023800009F4FECE80911025882309F4F9CE80E16E -:1023900095E2B5DA8BEC94E0B7DAF2CE20E030E0EB -:1023A00041E2429FC001439F900D11248E529B4FEA -:1023B000E2CF25E030E0F4CF24E030E0F1CF23E0BD -:1023C00030E0EECF22E030E0EBCF21E030E0E8CFAC -:1023D00021EE36E0109210251F3319F11D3399F0CC -:1023E000112319F089ECC1E0A3CF205F3F4FF90121 -:1023F0004591549141155105A9F380E195E2FA0107 -:102400000995C1E095CF2E5E3F4FF901459154915A -:102410004115510539F3CE010196FA010995C1E044 -:1024200087CF2C5E3F4FF9014591549141155105DD -:1024300021F789ECD8CF2BEC36E0CCCF25EB36E07A -:10244000C9CF2FE936E0C6CF29E836E0C3CF23E76E -:1024500036E0C0CF2DE536E0BDCF27E436E0BACF79 -:1024600021E336E0B7CF2BE136E0B4CF25E036E00C -:10247000B1CF2FEE35E0AECF29ED35E0ABCF23EC79 -:1024800035E0A8CF2DEA35E0A5CF27E935E0A2CF8A -:102490000895A0E2B6E082E011968C93119715960C -:1024A0008C931597E0E4F8E010A211A28DE291E080 -:1024B00086A397A38FEF9FEF80A791A781E08083EA -:1024C00098E8938393E097831A968C9308951F92CC -:1024D0000F920FB60F9211248F939F93EF93FF9358 -:1024E00080E196E28093B1249093B22480E996E251 -:1024F0008093AF249093B0241092AA241092A92420 -:102500001092A5241092AD241092AE241092A8240B -:10251000E0E4F8E0138286E990E086AB97AB8AE1CD -:1025200090E080AF91AFE0E4F9E010A211A28FEF4C -:102530009FEF86A397A389E883838EE08083E0E200 -:10254000F6E01286FF91EF919F918F910F900FBE51 -:102550000F901F9018951F920F920FB60F92112493 -:102560002F933F934F938F939F93EF93FF9390916C -:1025700028068091A924957021E009F020E0880FB9 -:10258000822B8093A9249091A5249923C1F1982F9F -:102590009770973009F448C0982F9C7081F182FBA6 -:1025A000882780F991E089278093A7249091A82417 -:1025B00091117FC09091AA249695882309F483C035 -:1025C00020E8292B2093AA248091AD249091AE2459 -:1025D00001968093AD249093AE2487709927892B20 -:1025E00071F4E091B124F091B224CF01019680936F -:1025F000B1249093B224208381E08093A824809119 -:10260000A52491E089278093A52488E88093430836 -:10261000FF91EF919F918F914F913F912F910F904B -:102620000FBE0F901F9018951092400880E1809384 -:102630004C08109243098091A7248823E9F18CEB80 -:1026400094E080936609909367091092A62481E034 -:1026500080934C0983E0809346098091AD2490914A -:10266000AE24877011F19091AA24969522E0280F4C -:102670008730B1F0969543E0480F283088F496955E -:1026800034E0380F483060F4969525E0280F383054 -:1026900038F49695283020F49695813009F4969573 -:1026A000E091B124F091B224908381E08093B3242F -:1026B000A6CF1092A824A3CF8CE794E0809366095C -:1026C00090936709C2CF20E07CCF1F920F920FB684 -:1026D0000F9211242F933F938F939F93AF93BF93A8 -:1026E000EF93FF938091A62490E08B30910580F5C5 -:1026F000FC01E95FFE4F0C946923E091AF24F09157 -:10270000B02480818111ACC080E480934506209183 -:10271000AB243091AC248091AD249091AE24281745 -:10272000390709F46CC03196E093AF24F093B024DC -:10273000E091B124F091B224CF0101968093B124AD -:102740009093B22481818093AA2484E08093A6246C -:10275000FF91EF91BF91AF919F918F913F912F91F9 -:102760000F900FBE0F901F9018958FE390E080930D -:102770006609909367098EE08093000880E4809357 -:10278000450683E08093A624E3CF80E48093460649 -:1027900084E08093A624E091B124F091B22480815A -:1027A0008093AA24D5CF8091AA2480FD64C080E4C0 -:1027B0008093460685E08093A624CACF8091AA2400 -:1027C00090E480FD55C09093450686958093AA2499 -:1027D0008091AB249091AC2401968093AB2490938C -:1027E000AC249C0127703327232B09F448C0209187 -:1027F000AD243091AE248217930709F0A6CF88E06C -:102800008093A624A5CFE091AF24F091B0248081DD -:1028100081112AC080E48093460687E08093A62435 -:1028200097CF80E48093460689E08093A62490CFDA -:1028300080E4809346068AE08093A62489CF109294 -:102840004009109246091092000881E08093B42458 -:102850007FCF8FE790E0809366099093670978CFE8 -:1028600080E48093460653CF80E480934506D5CF1D -:1028700090934606AACF80E4809345069BCF86E0DE -:102880008093A62465CFCF93DF93E0E4F6E084E065 -:102890008283128AC0E8D1E082E68E83A0E2B6E0AD -:1028A00085E012968C93129781E050968C93509706 -:1028B00082E052968C9352971A961C921A9783E054 -:1028C00019968C9398E598839AE5998390E491837F -:1028D000968381838683E0E0F8E08FE090E086A332 -:1028E00097A388E090E082A793A783E28183DF919A -:1028F000CF91CFCDCF93DF938091B3248823C1F0C4 -:102900001092B32482E08093210680932606609182 -:10291000AD247091AE246115710589F4E091EF2426 -:10292000F091F02409951092400910924609B1DD0A -:102930008091B42481112AC0DF91CF910895E09154 -:10294000F324F091F42480E196E2099594FF23C0EA -:102950009F7E009741F38093AD249093AE24109214 -:10296000AB241092AC2480E196E28093B124909342 -:10297000B22480E996E28093AF249093B02481E062 -:102980008093A6248091B4248823B1F21092B424B9 -:10299000DF91CF917ECDAC015695479556954795E1 -:1029A0005695479541155105A1F270E020E030E0C1 -:1029B000F901E05FF94D6081062E62956025062ED3 -:1029C000669566956025E058FF4F6F5F669561706C -:1029D000C62F20E0D22F21E0C227C0837F5F272FA0 -:1029E00030E02417350720F3B6CF81E08093D1245F -:1029F00084E090E08093B6249093B72488E080939D -:102A0000B524089581E08093D12482E090E0809302 -:102A1000B6249093B72488E18093B524089581E08B -:102A20008093D124089508957F928F929F92AF92C0 -:102A3000BF92CF92DF92EF92FF920F931F93CF93AB -:102A4000DF93CDB7DEB72E97CDBFDEBF8C014091AF -:102A5000D12450E04A30510598F080E090E02E9665 -:102A6000CDBFDEBFDF91CF911F910F91FF90EF900F -:102A7000DF90CF90BF90AF909F908F907F90089500 -:102A8000FA01EE5EFE4F0C9469237C01D12CF70114 -:102A9000C08099D58C25D7018D937D01D394B2E167 -:102AA000DB12F5CF60E170E0C801E5D3882309F4BB -:102AB000ECC18091FC24882309F4EDC197D59AE0FC -:102AC0009827D8019C9385E08093D12484E090E0FE -:102AD000C6CF7C0156E0D52ED701CC9074D58C257D -:102AE000F70181937F01DA94B9F764E070E0C801DF -:102AF000C2D38111B0C17AD591E09827D8019C93B7 -:102B0000E2CF2091B6249091B724D8018C918632DF -:102B100019F0823509F0A1CFF8012083918382E07A -:102B20008093D12480E190E09ACF2091B6249091B7 -:102B3000B724D8018C91863279F3823569F38339D1 -:102B400009F4CBC11092D12480E090E088CF16D553 -:102B50006801B4E0CB0ED11CB12CF601A08033D5B6 -:102B60008A25D6018D936D01B394B4E0BB12F5CFE5 -:102B7000F80194818091C924981709F42EC181E04D -:102B80008093D12480E090E06ACF7C0174E0B72E7E -:102B9000D701AC9018D58A25F70181937F01BA94AB -:102BA000B9F7D8018C91803309F489C1803A09F4CE -:102BB000CBC1803C09F4DAC1813C09F475C2823C86 -:102BC00009F480C2803B09F48EC280568230B8F688 -:102BD00062E070E0C8014FD3882309F468C1F801AE -:102BE00081818C739081903609F4EBC26AE370E0C6 -:102BF0007B01F0E18F9FE00CF11C112464E0CE0119 -:102C000007960E942F0544E050E060E070E0CE019E -:102C10000B960E94D40546E050E0B701CE01019624 -:102C20000E94D4058F819885A985BA858093C9248F -:102C30009093CA24A093CB24B093CC2460E470E09A -:102C400089EC94E2E6D48091C9249091CA24A091A1 -:102C5000CB24B091CC248093CD249093CE24A09308 -:102C6000CF24B093D02460E270E08DEC94E2D1D414 -:102C7000AE01495F5F4FBE01655F7F4FCE01019698 -:102C8000B0D38F819885A985BA85F8018083918317 -:102C9000A283B38384E08093D12480E290E0DFCEEE -:102CA000FC0180818632D1F08235C1F0803509F196 -:102CB00090EA980F923038F1982F9F77903331F047 -:102CC000803A21F0805C833008F059CF81E0809316 -:102CD000D12484E0D8018C9390E0C1CE84E0D80167 -:102CE0008C9311961C9282E08093D12480E190E035 -:102CF000B6CEF8018181882309F413C2F80110824D -:102D000084E090E0ACCE62E070E0C801B4D28823E9 -:102D100009F40DC2D80111962C9111972C738C9146 -:102D2000803609F451C28AE390E07C01B0E12B9F28 -:102D3000E00CF11C112464E0CE0107960E942F05DF -:102D400044E050E060E070E0CE010B960E94D405B4 -:102D500046E050E0B701CE0101960E94D4058F8174 -:102D60009885A985BA858093C9249093CA24A09395 -:102D7000CB24B093CC2460E470E089EC94E249D495 -:102D80008091C9249091CA24A091CB24B091CC24E5 -:102D90008093CD249093CE24A093CF24B093D024BD -:102DA00060E270E08DEC94E234D484E08093D1242E -:102DB0008F819885A985BA85F80180839183A28344 -:102DC000B383AE01495F5F4FBE01655F7F4FCE01A8 -:102DD000019607D380E290E042CE95818091CA248B -:102DE0009813CDCE96818091CB249813C8CE97812D -:102DF0008091CC249813C3CE68010DEC14E25F01DE -:102E0000F0E8AF0EB11C4801D8017D908D01DBD3F5 -:102E10008725F60181936F01D4019C90092C92942F -:102E20009024092C969496949024A9D2939491FA84 -:102E3000EE24E0F8F12CB1E0EB268E25F50181932C -:102E40005F01F4E2013D1F07F1F685E08093D12494 -:102E500080E290E104CE6091C824F0E16F9FB00160 -:102E6000112440E150E088EB94E20E94D4052091C7 -:102E7000B8248091BC248095281709F488C0B6D363 -:102E800096E09827F80190831ECEB0D391E0982762 -:102E9000F801908318CE6091C824E0E16E9FB001E4 -:102EA000112440E150E0C8010E94EC0507CE9ED3FA -:102EB00091E09827D8019C9384E090E0D0CD62E027 -:102EC00070E0C801D8D1811138C190D391E0982722 -:102ED000F801908384E090E0C2CD44E050E060E0EF -:102EE00070E0CE0101960E94D4059091B524D801DE -:102EF00011968C91803209F454C1803709F0ADCD20 -:102F0000D80112962C91129789812813A6CD139679 -:102F10002C9113978A812813A0CD14962C91149785 -:102F20008B8128139ACD15962C9115978C81281397 -:102F300094CD9C9361E070E0C8016FD183E08093F1 -:102F4000D12488E190E08BCD62E070E0C80193D19C -:102F5000882309F4ACCFD80111968C918093C824B2 -:102F600086E08093D12442D39AE0B1CF62E070E052 -:102F7000C80181D1882309F4A8CFF8018181809309 -:102F8000C82488E08093D12431D39AE092CF8091F5 -:102F9000C024281374CFE091B9248091BD2480957A -:102FA000E8136DCF8091C124E81369CF8091BA24D2 -:102FB0009091BE249095891362CF9091C224891379 -:102FC0005ECF3091BB249091BF249095391357CF99 -:102FD0009091C324391353CF4091C4249091C524B8 -:102FE000909549134CCF9091C624491348CF9091A6 -:102FF000C7249095491343CFD8019C911196FC9119 -:10300000119712964C91129750E060E070E0BA016F -:10301000552744275F2B492B13969C91792B90E0E1 -:10302000A0E0B0E0DC01992788279E2B822BB32BF0 -:103030002091D124283009F46FC0273021F4840F67 -:10304000951FA61FB71F8093B824C92EDA2EEB2E2A -:10305000FF24C092B9248D01222733270093BA247C -:103060004B2F5527662777274093BB24E82FE09501 -:10307000E093BC24EC2DE095E093BD24E02FE09597 -:10308000E093BE24E42FE095E093BF248093C02416 -:10309000C092C1240093C2244093C32485E080934E -:1030A000D12480E090E0DBCC62E070E0C801E3D0A6 -:1030B000882309F4FCCED80111968C918093C82402 -:1030C00087E04FCF62E070E0C801D5D0882309F4D3 -:1030D000FCCEF80181818093C82489E08093D124BB -:1030E00085D29AE0E6CE62E070E0C801C4D08823C1 -:1030F00009F4DDCE8091FC24811135CFD8011196E1 -:103100006C91B0E16B9FB001112440E150E088EB7D -:1031100094E20E94EC0527CF841B950BA60BB70BFE -:1031200092CF62E070E0C801A6D081110BCD81E0A2 -:10313000D8018C9384E090E092CCF8016181F0E1B9 -:103140006F9FB001112440E150E0C8010E94D405F6 -:1031500060E170E0C80161D0780130E8E30EF11C55 -:1031600062E1A62ED801BC902ED28B25F801819366 -:103170008F010B2CB294B0240B2CB694B694B024CF -:10318000FED0B394B1FACC24C0F8D12CF1E0CF2614 -:103190008C25D7018D937D01AA9421F780E990E1D8 -:1031A0005ECC8981F80180833A8131832B8122832F -:1031B0009C819383832782278927848388E290E0F8 -:1031C0004ECC60E370E014CD80E390E0AECD44E0FF -:1031D00050E060E070E00C94D405CF93DF931F9231 -:1031E000CDB7DEB7FC01218130812327328123272F -:1031F00033812327298344E050E060E070E00E949F -:10320000EC0541E050E064E070E0CE0101960E94E0 -:10321000EC050F90DF91CF910895FC0161157105C8 -:1032200039F1680F791F23E633E64191422750E1D7 -:10323000459FC0011124A42FA8278A2F90E0582F62 -:103240004427880F991F880F991F880F991F4827B7 -:103250005927232F332724273527A295AF702A27F4 -:10326000E617F70711F7922F832F90838183089534 -:1032700083E693E6FACFFC0161157105A9F1680FA9 -:10328000791F23E633E64191422750E1459FC00173 -:103290001124A42FA8278A2F90E0582F4427880FA5 -:1032A000991F880F991F880F991F48275927232F87 -:1032B000332724273527A295AF702A27E617F7076B -:1032C00011F7A9015527808190E08417950711F027 -:1032D00080E00895418150E0232F332781E0421799 -:1032E0005307B9F380E0F5CF43E650E023E633E639 -:1032F000EACFCF93B091D524C091D6244091D72462 -:10330000A091D224F091D324E091D4249C2F9071E9 -:103310002B2F217E9227242F207292272A2F247967 -:1033200092272F2F237792272E2F2A739227392F18 -:1033300032953F703927232F269526952327922FE4 -:10334000969550E060E070E0BA01552744275C2B69 -:103350004B2B7695679557954795922791709813C3 -:103360006068A093D524F093D624E093D7244093AB -:10337000D2245093D3246093D424CF910895CF9333 -:10338000DF93A091D324EA2FEF70F0E0E05CFF4DD3 -:10339000C091D224C295CF70D0E0C05CDF4DE089EF -:1033A0008881E82BA295AF70B0E0A05CBF4D9096ED -:1033B0008C91E82BA091D424CA2FCF70D0E0C05CB0 -:1033C000DF4D88A9E82BA295AF70B0E0A058BF4DA3 -:1033D0008C91E82BF0E0E05EFF4D8081DF91CF9192 -:1033E0000895AF92BF92CF92DF92EF92FF920F9328 -:1033F0001F93CF93DF935B01EA01DC01119645ED4A -:1034000054E262ED74E2CD010197FC0120818C91C0 -:1034100030E0382B20FFB0C000E421FFABC010E447 -:10342000C9019695879596958795302F306880FFCE -:10343000302F212F206881FF212F96958795969513 -:10344000879536952695132F106880FD312F122F02 -:10345000106881FD212F96958795969587953695CD -:103460002695132F106880FD312F122F106881FDD3 -:10347000212F969587959695879536952695132FA6 -:10348000106880FD312F122F106881FD212F969535 -:1034900087959695879536952695132F106880FD0C -:1034A000312F122F106881FD212F969587959695C3 -:1034B000879536952695132F106880FD312F122F92 -:1034C000106881FD212F969587959695879536955D -:1034D0002695032F0068122F106880FD302FFA0107 -:1034E0003193AF0181FD212FFB012193BF01129682 -:1034F000F4E2483D5F0709F086CFF50181819981AB -:103500008927C2809A81C926D12CE12CF12C760121 -:10351000DD24CC24D82A808198818927C82A8381F8 -:103520009B818927F82A10E22ADF082F8C2D8170D1 -:10353000E0DEF694E794D794C794002311F06894E2 -:10354000F7F8115089F788818C25888389818D252A -:1035500089838A818E258A838B818F258B83DF9156 -:10356000CF911F910F91FF90EF90DF90CF90BF9080 -:10357000AF90089510E054CF00E04FCFCF92DF928C -:10358000EF92FF92CF93FC018181C280D12CE12C7C -:10359000F12C7601DD24CC24D82A8081C82A8381AD -:1035A000F82AC0E2ECDE9C2D91708927A2DEF69409 -:1035B000E794D794C794C150A9F7CF91FF90EF90AB -:1035C000DF90CF9008951F93CF93DF93D8E0C0E0B2 -:1035D000D6DE182F80E08DDEC6951111C068D1505F -:1035E000B9F78C2FDF91CF911F9108951F93CF933F -:1035F000DF93D4E0C0E0C3DE182F80E07ADEC6950A -:103600001111C860D150B9F78C2FDF91CF911F9164 -:1036100008958F929F92AF92BF92CF92DF92EF92D6 -:10362000FF920F931F93FC01CB010197672BB1F120 -:10363000B281A0818180038102C0A42FBC2D2B2FD9 -:103640002D72322F32953F703227232F26952695E3 -:103650002327322F3695402F50E060E070E0742F22 -:1036600066275527442758294A2B6B2B7695679553 -:1036700057954795322730FD7068852E962EA72ED8 -:10368000BB246B01EE24FF24072F112722273327A9 -:10369000019798F640838182C28203831F910F9124 -:1036A000FF90EF90DF90CF90BF90AF909F908F9062 -:1036B00008950F931F93CF93DF93CDB7DEB7EA97AB -:1036C000CDBFDEBF05E117E2F7D2F80181938F018C -:1036D000F7E20D311F07C1F70E94100D6BD388234D -:1036E00049F03091152720911627822F90E08A30DB -:1036F000910568F05FD3882311F075D3A0D3EA96C3 -:10370000CDBFDEBFDF91CF911F910F910895FC01D6 -:10371000E45EFE4FDEC73111EDCF80911727823076 -:1037200048F761D3809117278093102793D4809115 -:103730001027882309F4D1C084E0809314270E94C5 -:103740000C0DD8CF3038B1F64ED380911027C4D2AB -:103750008BD280D4CFCF3058323060F6809117278B -:10376000909118278C3DE3E09E0709F488C0AE01D4 -:103770004F5F5F4F609119270E94D4038C0100971F -:1037800009F4B8CF30D3B80189819A81C1D185D2EB -:10379000B1CF3111AFCF109117271F7724D35AD44F -:1037A000E4D28823E9F31093C304111166C082E0C8 -:1037B000809314279FCF332309F44BC0323009F094 -:1037C00099CF80911727811124C0109119271F705C -:1037D00009F490CF812F90D280911627833009F47D -:1037E00086C0A0911F27B091202711968C91119728 -:1037F0008B7F11968C9324E8129FF0011124ED59D0 -:10380000F84D1082E0911F27F091202780818E7F54 -:10381000808380E071D2E7D21DD46CCF303829F19B -:10382000323809F067CF809119278F7065D2E09107 -:103830001F27F0912027118112FB112710F980E03A -:103840005BD2D1D2812F48D280E046D20DD202D4B1 -:1038500051CF80911727813009F04CCF81E0233080 -:1038600009F080E080931227D4CF10911127809126 -:103870001227882331F31260E4CF83E099CF83E0ED -:103880008A838AE389835FB7F894DE01139620E088 -:1038900038E042E007C090E0C7968D939D932F5F7C -:1038A0002C3191F04093CA01E32FF0E08491109203 -:1038B000CA0120FF03C082958F703F5F8F708A30EE -:1038C00050F790E0C096E9CF5FBF8DD26AE370E019 -:1038D000CE01019688D0E1D10DCF8091C304882319 -:1038E00021F084E0809314272ACF81E0FBCFA7D278 -:1038F00090CF0895CF9380911427811102C0CF916A -:103900000895C091212780E0F7D154D2811103C0DE -:103910008C2FCF91F1C1CDDE8C2FCF91EDC1CF9205 -:10392000DF92EF92FF920F931F93CF93DF938C015F -:10393000EB017A01A5D3811125C0E114F10481F1D5 -:10394000F70180819181C81BD90B080F191F20979F -:1039500009F43BC0C12CD12C20911D2730911E278A -:10396000F901EF5BFF4F908131978081981778F1D3 -:103970007BD1C0DFF701808191818C0D9D1D8083FB -:10398000918385E0DF91CF911F910F91FF90EF9090 -:10399000DF90CF90089568D1ADDF72D38111F2CF5F -:1039A000209799F020911D2730911E27F901EF5B98 -:1039B000FF4F908131978081981768F7F8018191C6 -:1039C0008F018AD12197209769F780E0DBCFF8013A -:1039D00081918F0181D1FFEFCF1ADF0ACC15DD0570 -:1039E00009F0BACFF2CFCF92DF92EF92FF920F930E -:1039F0001F93CF93DF936C018B0180912127806807 -:103A00007BD1C0911B27D0911C27C017D10728F06C -:103A10000115110509F46FC0E80110E0209739F590 -:103A200011110CC02FC0853091F1C4D1811131C06A -:103A3000A8D1811127C099D181112DC0809114275F -:103A40008111F1CF82E0DF91CF911F910F91FF9013 -:103A5000EF90DF90CF9008958530C9F0ABD1811100 -:103A600018C08FD181110EC080D1811114C08091F6 -:103A700014278111F1CFE6CF80911427882311F309 -:103A8000853029F07ED18823B9F380E0DCCF83E054 -:103A9000DACF81E0D8CF8091212787FD30C02091F7 -:103AA0001D2730911E27F901E05CFF4FE080319621 -:103AB0008081F12CE81AF1082097A9F088E0E81637 -:103AC000F10488F4860104C088E0E816F10459F096 -:103AD000F80181918F0100D168012197FFEFEF1A62 -:103AE000FF0A209789F711E0E8E0EE16F10409F0EB -:103AF00010E0BAD093CFB8D0C0E0D0E08ECFE09144 -:103B00001D27F0911E27EF5BFF4FE080F12CD4CFF3 -:103B1000DF92EF92FF920F931F93CF93DF93F82ED4 -:103B2000E92E8B01809121278068E6D0C0911B2768 -:103B3000D0911C27C017D10728F00115110509F4F1 -:103B400086C0E8010F2D1E2DD12C209739F5D110FC -:103B50000DC02FC0853009F438C02CD181113EC072 -:103B600010D1811126C001D1811141C0809114274B -:103B70008111F0CF82E0DF91CF911F910F91FF90E3 -:103B8000EF90DF900895853001F114D1811126C0A6 -:103B9000F8D081110EC0E9D0811129C0809114277D -:103BA0008111F1CFE7CF80911427882319F3853055 -:103BB00061F0E7D08823B9F380E0DF91CF911F91C6 -:103BC0000F91FF90EF90DF90089583E0DF91CF9108 -:103BD0001F910F91FF90EF90DF90089581E0DF91AA -:103BE000CF911F910F91FF90EF90DF9008958091FA -:103BF000212787FD30C080911D2790911E27FC0151 -:103C0000E05CFF4FE08031968081F12CE81AF108EA -:103C10002097A1F088E0E816F10428F00FC088E0B2 -:103C2000E816F10459F0F801849156D00F5F1F4F48 -:103C30002197FFEFEF1AFF0A209789F7DD24D3942D -:103C4000E8E0EE16F10409F0D12C0ED07ECF0CD0B6 -:103C5000C0E0D0E077CFE0911D27F0911E27EF5B09 -:103C6000FF4FE080F12CD4CFE0911F27F091202767 -:103C7000A0911D27B0911E27AF5BBF4F8C9190E0A4 -:103C80008283938380818D798083E0911D27F091D9 -:103C90001E27EF5BFF4F10820895E0911F27F091E0 -:103CA000202780818D798083E0911D27F0911E2748 -:103CB000EF5BFF4F1082089580911D2790911E2782 -:103CC000FC01EF5BFF4F208131E0320F3083FC01BC -:103CD000E20FF11D8081089520911D2730911E274C -:103CE000F901EF5BFF4F908141E0490F4083F901FB -:103CF000E90FF11D8083089580932127282F2F70CD -:103D0000622F70E094E8299F900111242E5D384DB8 -:103D10004091C6045091C70487FD12C020931D270F -:103D200030931E27CB0182959295907F9827807FB4 -:103D30009827840F951F80931F279093202708951D -:103D40002E5B3F4F20931D2730931E27629572955F -:103D5000707F7627607F7627685F7F4F640F751FBF -:103D600060931F27709320270895809121278068F2 -:103D7000C3DFE0911F27F091202780818695817015 -:103D80000895809121278F77B7DFE0911F27F09169 -:103D90002027808185FF0CC020911D2730911E2790 -:103DA00082819381F901E05CFF4F808381E0089577 -:103DB00080E00895809121278F779EDFE0911F2773 -:103DC000F0912027808184FF0CC020911D27309125 -:103DD0001E2782819381F901E05CFF4F808381E09F -:103DE000089580E00895809121278F7785DFE09105 -:103DF0001F27F091202780818D788083E0911F27F5 -:103E0000F0912027808181608083E0911D27F091CF -:103E10001E27EF5BFF4F10828091212780686CDFA7 -:103E2000E0911F27F0912027808181608083E091BD -:103E30001D27F0911E27EF5BFF4F10820895E09140 -:103E40001F27F0912027818184608183E0911F27C3 -:103E5000F09120278181807C803409F00895809141 -:103E60002127805849DFE0911F27F0912027818189 -:103E70008460818308951F93CF93DF9300D0CDB7E3 -:103E8000DEB7182F4A83698337DFE0911F27F0914F -:103E900020271182E0911F27F09120274A81698114 -:103EA00017FD20C01082E0911F27F0912027618329 -:103EB000E0911F27F09120271282138280911D2705 -:103EC00090911E278483958340E0FC01E05CFF4FC6 -:103ED00040833196108281E00F900F90DF91CF9157 -:103EE0001F91089582E08083E0911F27F0912027A1 -:103EF0006183E0911F27F091202712821382809125 -:103F00001D2790911E2784839583DFCFCF92DF9268 -:103F1000EF92FF920F931F93CF93DF931F92CDB732 -:103F2000DEB7F62E662309F43EC06C0100E0D60130 -:103F30001C91112391F1D6011196ED91FC911297EC -:103F400013968C91139714969C91923008F445C067 -:103F500098E148E1E930F10550F028E030E090E0E8 -:103F60009F5F220F331F2E173F07D0F3942B212F73 -:103F70002F7030E0263031059CF59F7EE134F1054D -:103F800078F5882301F18130C9F4906CEE2E4E2D26 -:103F9000692F812F70DF882319F10F5FB5E0CB0EF9 -:103FA000D11C0F11C4CF81E00F90DF91CF911F91F1 -:103FB0000F91FF90EF90DF90CF9008959068882345 -:103FC00019F0EE2EE4CF9064EE2E4E2F692F80E88C -:103FD000810F998350DF9981DACF98E048E0BACF1A -:103FE00080E0E2CFE0ECF4E0A681B78119961C9264 -:103FF000A681B78111961C92A681B78159961C9211 -:10400000A681B78151961C92A681B78199961C9280 -:10401000A681B78191961C92A681B781D9961C92F0 -:10402000A681B781D1961C92A681B781A75BBF4FAD -:104030001C92A681B781AF5BBF4F1C92A681B7814E -:10404000A75ABF4F1C920680F781E02DEF5AFF4F11 -:10405000108208958091152787FF05C00CC08091BC -:104060001427882361F081DE8823C9F3FDCD809178 -:104070001427882321F085DE8823C9F30ECE089506 -:104080001F93CF93DF93E091C604F091C704E05AE9 -:10409000FF4FC081D18114E680912127807880383C -:1040A00031F16FDE811126C080911427882339F108 -:1040B000853051F1E0911F27F0912027818182FD09 -:1040C00028C0E091C604F091C704E05AFF4F8081F8 -:1040D0009181C817D90701F32FEF210F1123F1F0B8 -:1040E000EC01122F8091212780788038D1F63DDEB7 -:1040F0008823D1F280E0DF91CF911F91089582E073 -:10410000DF91CF911F91089583E0DF91CF911F91AF -:10411000089581E0DF91CF911F91089584E0DF91B0 -:10412000CF911F91089562D068D0E0ECF4E08181D6 -:104130008E7F818380818F778083109213270895EB -:10414000CF93DF93E0E4F0E0148284818160848384 -:104150004DD053D0C0ECD4E088818F77888388819C -:1041600080688883109214271092102710921227CB -:104170001092112788818064888348E068E480E891 -:104180007ADE48E068E480E076DE888580648887AF -:10419000898181608983DF91CF9108952FB7F89449 -:1041A00082E0E0ECF1E08287EAE1F0E0E491A0EC6B -:1041B000B4E0DA96EC93DA97EBE1F0E0E491DB9689 -:1041C000EC93DB97E0ECF1E012868BE39AE28E7FD2 -:1041D00016968D939C93179785E18C9382E01896A1 -:1041E0008C932FBF81E080931327AACFE0ECF4E0FB -:1041F00080858370808711860895E0ECF4E08FEF6E -:104200008287848708951F920F920FB60F92112410 -:104210002F933F934F935F936F937F938F939F93CE -:10422000AF93BF93EF93FF938091CA0487FD4DC076 -:104230008091CA0486FD41C08091CA0485FF0CC0EC -:1042400080E28093CA0480911027882371F184E072 -:10425000809314270E94020D8091CA0484FF14C029 -:1042600080E18093CA0482E0809314271092102783 -:104270001092C304B7DE48E068E480E8FCDD48E063 -:1042800068E480E0F8DD35DBFF91EF91BF91AF91FD -:104290009F918F917F916F915F914F913F912F915E -:1042A0000F900FBE0F901F9018958091C30481113D -:1042B00015C081E080931427CDCF80E48093CA0499 -:1042C000109214270E94070DB7CF8091C80487FF72 -:1042D000AFCF80E88093CA040CDBAACF83E0EACF9B -:1042E000CF93DF93EC01FC0170968BE0DF011D9210 -:1042F0008A95E9F782E08C83898783E08E8761E085 -:10430000CE01019603DE811104C080E0DF91CF91E0 -:10431000089561E0CE010696F9DD8823B1F361E0EE -:10432000CE010B96DF91CF91F1CDCF93DF93EB01CF -:1043300020911427243021F082E0DF91CF9108955D -:10434000FC014489558966897789452B462B472B83 -:1043500099F38181D1DCFE0101900020E9F7BF01D2 -:10436000615071096C1B7D0B40E050E0CE01DF9184 -:10437000CF91D5CAEF92FF920F931F93CF93DF9304 -:10438000EB017A0120911427243041F082E0DF9183 -:10439000CF911F910F91FF90EF900895FC01048938 -:1043A000158926893789012B022B032B79F381810B -:1043B000A3DC40E050E0B701CE01DF91CF911F9127 -:1043C0000F91FF90EF90ABCA0F931F93CF93DF93A2 -:1043D0001F92CDB7DEB720911427243039F082E048 -:1043E0000F90DF91CF911F910F910895FC010489E7 -:1043F000158926893789012B022B032B81F38181B3 -:1044000069837ADC20911D2730911E27F901EF5B2B -:10441000FF4F9081319780816981981730F06983CF -:1044200023DC2EDE69818111DBCF862F55DC80E015 -:10443000D7CFCF93DF9320911427243021F082E04F -:10444000DF91CF910895FC01448955896689778968 -:10445000452B462B472B99F381814EDC80912127F8 -:1044600020911D2730911E27F90187FD1BC0E05CBC -:10447000FF4F80813196408190E0841B9109892B08 -:1044800011F480E0DDCFF901EF5BFF4FD081319770 -:10449000C081EADBDC17A8F3F3DD8111D1CFE4DBC7 -:1044A00080E0CECFEF5BFF4F808190E0E8CFCF93ED -:1044B000DF93EC0180911427843019F0DF91CF91C4 -:1044C00008954C895D896E897F89452B462B472B42 -:1044D000A9F3898111DC49DC882381F3CE01DF91C6 -:1044E000CF91A7CFCF93DF93209114272430A9F544 -:1044F000FC014489558966897789452B462B472BD2 -:1045000061F18681F9DB3DDC882339F18091212737 -:1045100040911D2750911E27FA0187FD3AC0E05CAB -:10452000FF4F80813196208190E0821B9109892B79 -:10453000C9F4CFEFDFEF80912127FA0187FD1EC07C -:10454000E05CFF4F20813196808130E0281B3109EB -:10455000D9F0CE01DF91CF9108958FEF9FEFDF91DA -:10456000CF910895A9DBC82FD0E040911D2750912D -:104570001E2780912127FA0187FFE2CFEF5BFF4FD3 -:10458000208130E0232B29F788DBCE01DF91CF910A -:104590000895EF5BFF4F808190E0C9CF0895FF92AF -:1045A0000F931F93CF93DF93EC0104DC882349F032 -:1045B000888190E02091192730911A272817390710 -:1045C00031F0DF91CF911F910F91FF90089580916D -:1045D0001627813209F448C0A0F0823209F465C080 -:1045E000833279F780911527813259F7FCDB32DD70 -:1045F00060911727CE01DF91CF911F910F91FF900E -:10460000CDCF8032F1F6809115278132D1F6EBDBE8 -:1046100004C0809114278823A1F2B3DB8823C9F357 -:104620004BDB082F49DB182F47DBF82E45DB4F2DDE -:1046300050E060E070E0BA0155274427782B402B0A -:10464000512B4C8B5D8B6E8B7F8B36DB888F34DBF5 -:10465000898F32DB8A8F21DBFDDCCE01DF91CF91A8 -:104660001F910F91FF909ACF80911527813A09F001 -:10467000A8CFB9DB7ADB8823E9F38C89FD880E8922 -:104680001F892ADB8F2D28DB802F26DB812F24DB5F -:10469000888D22DB898D20DB8A8D1EDBE5DADF91B8 -:1046A000CF911F910F91FF90D5CC8091152781322A -:1046B00009F087CF98DBCEDC8091172790911827DF -:1046C000888B998BCE01DF91CF911F910F91FF9035 -:1046D00065CFEE0FFF1F0590F491E02D0994B7FF11 -:1046E00004C003D0821B930B089509D0A59F900DA1 -:1046F000B49F900DA49F800D911D11240895A29F39 -:10470000B001B39FC001A39F700D811D1124911DA5 -:10471000B29F700D811D1124911D08958F929F925B -:10472000AF92BF92CF92DF92EF92FF92CF93DF933F -:10473000EC01688179818A819B8161157105810510 -:10474000910521F464E279ED8BE597E02DE133EFFB -:1047500041E050E031D349015A019B01AC01A7EA85 -:10476000B1E4C3DF6B017C01ACEEB4EFA5019401B1 -:10477000B8DFC60ED71EE81EF91EF7FE06C081E0A0 -:10478000C81AD108E10880E8F80AC882D982EA820A -:10479000FB82C6019F77DF91CF91FF90EF90DF9072 -:1047A000CF90BF90AF909F908F900895B7CF8CE13E -:1047B00090E2B4CFA0E0B0E080931C2090931D2045 -:1047C000A0931E20B0931F200895FB01DC0102C0BE -:1047D00005900D9241505040D8F70895FB01DC013F -:1047E0008D91059080190110D9F3990B0895FB0163 -:1047F000DC014150504048F005900D920020C9F76F -:1048000001C01D9241505040E0F70895FB01DC01CA -:1048100002C001900D9241505040D8F70895AEE08B -:10482000B0E0E4E1F4E2F2C20D891E898F89988D2F -:104830002EE02C8309831A8397FF02C080E090E862 -:1048400001978D839E83AE01455E5F4F698D7A8DA2 -:10485000CE01019611D04D815E8157FD0AC02F8196 -:104860003885421753070CF49A01F801E20FF31F41 -:1048700010822E96E4E0E3C2ACE0B0E0E1E4F4E2C2 -:10488000B7C27C016B018A01FC0116821782838109 -:1048900081FFB0C1CE0101964C01F7019381F60171 -:1048A00093FD859193FF81916F01882309F49EC147 -:1048B000853239F493FD859193FF81916F018532A3 -:1048C00021F4B70190E0E8D1E8CF512C312C20E061 -:1048D0002032A0F48B3269F030F4803259F0833208 -:1048E00069F420612CC08D3239F0803339F42160B5 -:1048F00026C02260246023C0286021C027FD27C075 -:1049000030ED380F3A3078F426FF06C0FAE05F9EAB -:10491000300D1124532E13C08AE0389E300D11241F -:10492000332E20620CC08E3221F426FD5FC120643C -:1049300006C08C3611F4206802C0883641F4F601B6 -:1049400093FD859193FF81916F018111C1CF982FC4 -:104950009F7D9554933028F40C5F1F4FFFE3F9833C -:104960000DC0833631F0833771F0833509F057C0BD -:1049700021C0F801808189830E5F1F4F4424439436 -:10498000512C540114C03801F2E06F0E711CF80173 -:10499000A080B18026FF03C0652D70E002C06FEFDC -:1049A0007FEFC5012C876DD12C0183012C852F77DA -:1049B000222E16C03801F2E06F0E711CF801A080A3 -:1049C000B18026FF03C0652D70E002C06FEF7FEF5E -:1049D000C5012C874BD12C012C852068222E830108 -:1049E00023FC19C0832D90E048165906A0F4B701A6 -:1049F00080E290E051D13A94F5CFF50127FC859102 -:104A000027FE81915F01B70190E046D131103A94C1 -:104A1000F1E04F1A51084114510479F7DEC0843691 -:104A200011F0893631F5F80127FF07C060817181E7 -:104A3000828193810C5F1F4F08C06081718188273C -:104A400077FD8095982F0E5F1F4F2F76B22E97FF20 -:104A500009C090958095709561957F4F8F4F9F4FBE -:104A60002068B22E2AE030E0A40148D1A82EA81870 -:104A700043C0853729F42F7EB22E2AE030E025C0CE -:104A8000F22FF97FBF2E8F36C1F018F4883579F0F8 -:104A9000ADC0803719F0883721F0A8C02F2F2061D2 -:104AA000B22EB4FE0DC08B2D8460B82E09C024FF39 -:104AB0000AC09F2F9660B92E06C028E030E005C0DE -:104AC00020E130E002C020E132E0F801B7FE07C08B -:104AD00060817181828193810C5F1F4F06C060816C -:104AE000718180E090E00E5F1F4FA40107D1A82ED6 -:104AF000A818FB2DFF77BF2EB6FE0BC02B2D2E7FE7 -:104B0000A51450F4B4FE0AC0B2FC08C02B2D2E7EB2 -:104B100005C07A2C2B2D03C07A2C01C0752C24FFE4 -:104B20000DC0FE01EA0DF11D8081803311F4297E54 -:104B300009C022FF06C07394739404C0822F867844 -:104B400009F0739423FD12C020FF06C05A2C731481 -:104B500018F4530C5718732C731460F4B70180E2E7 -:104B600090E02C8799D073942C85F6CF731410F4B1 -:104B7000371801C0312C24FF11C0B70180E390E049 -:104B80002C878AD02C8522FF16C021FF03C088E520 -:104B900090E002C088E790E0B7010CC0822F8678D1 -:104BA00051F021FD02C080E201C08BE227FD8DE2C1 -:104BB000B70190E071D0A51430F4B70180E390E024 -:104BC0006BD05A94F8CFAA94F401EA0DF11D8081BC -:104BD000B70190E061D0A110F6CF332009F45DCE8B -:104BE000B70180E290E058D03A94F7CFF701868180 -:104BF000978102C08FEF9FEF2C96E2E112C1E0ECAB -:104C0000F1E0A785A7FDFDCFA485A860A48760502B -:104C1000704FFCCDDC01CB0102C02D9105D041507D -:104C20005040D8F70895262FE0ECF1E0378537FDA6 -:104C3000FDCF3485377F3487378531FF09C036E3B0 -:104C4000328738ED34BF31E03387378537FDFDCF0C -:104C500033E33287808391831282248325E3228782 -:104C600028ED31E024BF338701960895FC010590BB -:104C7000615070400110D8F7809590958E0F9F1F5E -:104C80000895FC016150704001900110D8F78095A3 -:104C900090958E0F9F1F08950F931F93CF93DF93CF -:104CA000182F092FEB018B8181FD03C08FEF9FEF40 -:104CB00020C082FF10C04E815F812C813D81421750 -:104CC00053077CF4E881F9819F012F5F3F4F2883D0 -:104CD0003983108306C0E885F985812F0995892BD2 -:104CE00029F72E813F812F5F3F4F2E833F83812FF6 -:104CF000902FDF91CF911F910F910895FA01AA276C -:104D0000283051F1203181F1E8946F936E7F6E5F0E -:104D10007F4F8F4F9F4FAF4FB1E03ED0B4E03CD0BC -:104D2000670F781F891F9A1FA11D680F791F8A1F9F -:104D3000911DA11D6A0F711D811D911DA11D20D006 -:104D400009F468943F912AE0269F11243019305DC0 -:104D50003193DEF6CF010895462F4770405D4193B1 -:104D6000B3E00FD0C9F7F6CF462F4F70405D4A33FE -:104D700018F0495D31FD4052419302D0A9F7EACFC6 -:104D8000B4E0A6959795879577956795BA95C9F7F5 -:104D900000976105710508959B01AC010A2E0694E8 -:104DA0005795479537952795BA95C9F7620F731FA1 -:104DB000841F951FA01D0895052E97FB16F40094DF -:104DC0000FD057FD05D045D007FC02D046F408C0EF -:104DD00050954095309521953F4F4F4F5F4F089527 -:104DE00090958095709561957F4F8F4F9F4F089557 -:104DF0002F923F924F925F926F927F928F929F92EB -:104E0000AF92BF92CF92DF92EF92FF920F931F93D8 -:104E1000CF93DF93CDB7DEB7CA1BDB0BCDBFDEBFB1 -:104E200009942A88398848885F846E847D848C84BC -:104E30009B84AA84B984C884DF80EE80FD800C81C5 -:104E40001B81AA81B981CE0FD11DCDBFDEBFED017F -:104E50000895A1E21A2EAA1BBB1BFD010DC0AA1FBB -:104E6000BB1FEE1FFF1FA217B307E407F50720F0D3 -:104E7000A21BB30BE40BF50B661F771F881F991F4E -:104E80001A9469F760957095809590959B01AC0197 -:0A4E9000BD01CF010895F894FFCF93 -:104E9A0014008310000001041000000182080000C1 -:104EAA0001000000000000000000000001000000F6 -:104EBA0000010001000000000000000100010101E2 -:104ECA0001010100010001000000010100010101CE -:104EDA0000010101000000010000010001010001C0 -:104EEA0000000002020000020002020202000002A8 -:104EFA000000000404000004000404040400000488 -:104F0A000008080800000008000008000808000857 -:104F1A000000001010000010001010101000001007 -:024F2A00000085 +:100000006DC4000087C4000085C4000083C40000E4 +:1000100081C400007FC400007DC400007BC40000D8 +:1000200079C4000077C4000003C5000073C4000059 +:1000300071C400006FC400006DC400006BC40000F8 +:1000400069C4000067C4000065C4000063C4000008 +:1000500061C400005FC400000C940C175BC4000076 +:1000600059C4000057C4000055C4000053C4000028 +:1000700051C400004FC400004DC400004BC4000038 +:1000800049C4000047C400000C94DB1643C40000C0 +:1000900041C400003FC400003DC400003BC4000058 +:1000A00039C4000037C4000035C4000033C4000068 +:1000B00031C400002FC400002DC400002BC4000078 +:1000C00029C4000027C4000025C4000023C4000088 +:1000D00021C400001FC400001DC400001BC4000098 +:1000E00019C4000017C4000015C4000013C40000A8 +:1000F00011C400000FC400000DC400000BC40000B8 +:1001000009C4000007C4000005C4000003C40000C7 +:1001100001C40000FFC30000FDC30000FBC30000DA +:10012000F9C30000F7C30000F5C30000F3C30000EB +:10013000F1C30000EFC30000EDC30000EBC30000FB +:10014000E9C30000E7C30000E5C300000C94B0174A +:10015000E1C30000DFC30000DDC30000DBC300001B +:10016000D9C30000D7C30000D5C30000D3C300002B +:10017000D1C30000CFC30000CDC30000CBC300003B +:10018000C9C30000C7C30000C5C30000C3C300004B +:10019000C1C30000BFC30000BDC30000BBC300005B +:1001A000B9C30000B7C30000B5C30000B3C300006B +:1001B000B1C30000AFC30000ADC30000ABC300007B +:1001C000A9C30000A7C30000A5C30000A3C300008B +:1001D000A1C300009FC300009DC300009BC300009B +:1001E00099C3000097C3000095C3000093C30000AB +:1001F00091C300000C94DA2A8DC300001C034C004C +:100200005500460041002000430044004300200008 +:10021000440065006D006F00000018034400650095 +:1002200061006E002000430061006D0065007200F7 +:10023000610000000403090409023E00020100C03D +:10024000320904000001020201000524001001042B +:100250002402060524060001070582030800FF09A1 +:10026000040100020A00000007050402100005074F +:100270000583021000051201100102000008EB03C3 +:10028000442001000102DC01004E4F4E45000000F9 +:10029000000000000000000000A005A105A205A3C9 +:1002A00005A405A505A805A90500000001014D4606 +:1002B0005F554C5452414C49474854000000A11826 +:1002C000D81889198D1991199219E41AF71A400052 +:1002D0000700024D465F434C41535349435F314B46 +:1002E000000000A118D818361B691B6D1B6E1B324D +:1002F00021532100040400034D465F504C555331F7 +:100300004B5F374200000000A118D818451B691B3D +:100310006D1B6E1B3221532100040700044D465F04 +:10032000434C41535349435F344B000000A118D85C +:10033000185A1B691B6D1B6E1B32215321001004C0 +:10034000000549534F3134343433415F534E4946ED +:100350004600A118D818A205A305A405A505A8055F +:10036000A905000000014E4F4E45000000000000AE +:10037000000000000000000000000000000000007D +:100380000000000000005549445F52414E444F4D6B +:10039000000000000000000000000000000000005D +:1003A0000000000000005549445F4C4546545F4939 +:1003B0004E4352454D454E540000000000000000E1 +:1003C0000000000000005549445F52494748545F0F +:1003D000494E4352454D454E540000000000000078 +:1003E0000000000000005549445F4C4546545F44FE +:1003F000454352454D454E540000000000000000AA +:100400000000000000005549445F52494748545FCE +:1004100044454352454D454E540000000000000045 +:100420000000000000004359434C455F53455454BD +:10043000494E47530000000000000000000000008B +:1004400000000000000053544F52455F4D454D00E1 +:10045000000000000000000000000000000000009C +:10046000000000000000524543414C4C5F4D454D9B +:10047000000000000000000000000000000000007C +:100480000000000000004F46460000000000000091 +:100490000000000000004D454D4F52590000000083 +:1004A0000000000000005445524D494E414C0000F0 +:1004B0000000000000002C004E4F4E4500000000E0 +:1004C000000000000000000000000000000000002C +:1004D00000000000000000005445524D494E414CC0 +:1004E0005F434F4E4E00000000000000000000007F +:1004F00000000000000000005445524D494E414CA0 +:100500005F52585458000000000000000000000036 +:10051000000000000000000053455454494E475F5E +:100520004348414E47450000000000000000000025 +:1005300000000000000000004D454D4F52595F5330 +:10054000544F52454400000000000000000000002D +:1005500000000000000000004D454D4F52595F4320 +:1005600048414E47454400000000000000000000E4 +:100570000000000000000000434F4445435F525814 +:10058000000000000000000000000000000000006B +:100590000000000000000000434F4445435F5458F2 +:1005A000000000000000000000000000000000004B +:1005B00000000000000000004368616D656C656F1D +:1005C0006E2D4D696E69202553207573696E672005 +:1005D0004C55464120255320636F6D70696C6564EE +:1005E0002077697468204156522D47434320255394 +:1005F000003135303232330031333039303100346C +:100600002E372E320025730052414E444F4D0025A7 +:10061000750025750025532C2553004C4F4144424D +:10062000494E00434C454152002575004C4F414412 +:1006300042494E00434C45415200253575206D56C8 +:100640000056455253494F4E000000000000000084 +:1006500000000000004F11434F4E46494700000084 +:10066000000000000000008C1183116D11554944F9 +:10067000000000000000000000000000000000B9C1 +:10068000119211524541444F4E4C59000000000058 +:1006900000000000002412121255504C4F4144003B +:1006A00000000000000000000038120000000044BC +:1006B0004F574E4C4F414400000000000000003DE9 +:1006C0001200000000524553455400000000000095 +:1006D0000000000000421200000000555047524147 +:1006E00044450000000000000000004D1200000022 +:1006F000004D454D53495A450000000000000000E0 +:100700000000000000581255494453495A45000062 +:10071000000000000000000000000070124255546C +:10072000544F4E00000000000000000000861292AE +:10073000128B12425554544F4E5F4C4F4E4700009F +:100740000000009C12A812A1124C45444752454596 +:100750004E0000000000000000B212BE12B7124CA2 +:10076000454452454400000000000000000000C85D +:1007700012D412CD124C4F474D4F4445000000009B +:100780000000000000DE12E812E3124C4F474D4516 +:100790004D00000000000000000000F01224130AC9 +:1007A0001353455454494E47000000000000000018 +:1007B00000000049134413434C454152000000001F +:1007C0000000000000000051130000000048454CEC +:1007D0005000000000000000000000000055130061 +:1007E00000000052535349000000000000000000C8 +:1007F00000000000000000A1130000000000000045 +:100800000000000000000000000000000000000DDB +:100810000A000D0A00643130303A4F4B00000000EE +:1008200000000000000000000000000000000000C8 +:10083000000000000000653130313A4F4B2057492D +:1008400054482054455854000000000000000000A7 +:10085000000000000000006E3131303A5741495429 +:10086000494E4720464F5220584D4F44454D0000B9 +:100870000000000000000000C83230303A554E4BF6 +:100880004E4F574E20434F4D4D414E440000000007 +:10089000000000000000000000C93230313A494E2B +:1008A00056414C494420434F4D4D414E44205553F1 +:1008B00041474500000000000000CA3230323A498A +:1008C0004E56414C494420504152414D45544552A9 +:1008D00000000000000000000000000011241FBE06 +:1008E000CFEFDFE2DEBFCDBF10E2A0E0B0E2EEE886 +:1008F000F2E602C005900D92A239B107D9F72EE2B7 +:10090000A2E9B0E201C01D92A93CB207E1F703D011 +:100910000C94453187C08DD00E94340E0E94D20DB8 +:100920000E941D0FFDD231D10E94DB10A4D195D7BA +:1009300081E0809300021092010292E09093020203 +:1009400093E0909304028093200288E38093210235 +:10095000F1D080914800816080934800C2E00EC0D1 +:100960000E94E010E091FB28F091FC2809950E947C +:10097000480DE091F528F091F6280995809103043F +:1009800081FFEECF8091010480FDFCCFC093030472 +:1009900085D10E94011168D70E94470D0E94220F45 +:1009A000DFCF292F33272230310539F123303105AC +:1009B000A9F02130310549F020E030E080E090E0FE +:1009C000FA0180839183C901089522E130E086E72E +:1009D00092E0FA0180839183C901089599278130BB +:1009E0009105A1F082309105B9F0892B29F7E4E354 +:1009F000F2E0249130E0CF01E3CF2EE330E088E352 +:100A000092E0FA0180839183C9010895EAE1F2E05E +:100A1000249130E0CF01D4CFECEFF1E0249130E02D +:100A2000CF01CECF1F920F920FB60F921124FFCF9E +:100A300018958091780083FF0AC088E08093780041 +:100A400088ED84BF81E080938000FD95FEC0809199 +:100A500050008660809350008091510081FFFCCF50 +:100A60008091510082FFFCCF1092560021E020932C +:100A7000600088ED84BF2093400083ED90E3809375 +:100A8000260A9093270A86E08093000A2093430069 +:100A900083E690E080930A0490930B0480930C0407 +:100AA00090930D0420930004209302048091CC01C4 +:100AB00088608093CC01089588ED84BF81E0E8E7E9 +:100AC000F0E08183089588ED84BF8BE180938000FE +:100AD0000895809148008E7F809348008BEC80932E +:100AE00052008091500088608093500080915100A6 +:100AF00083FFFCCF84EC809355008091500080618F +:100B0000809350008091510084FFFCCF0895E8E469 +:100B1000F0E0808181608083E0E4F0E084818E7F7A +:100B20008483E0E5F0E080818F7E80838081877F11 +:100B30008083089587E0E0EAF0E082837894089566 +:100B40000895089508950895089580E090E0089527 +:100B500008950895E0910A29F0910B29838395E285 +:100B6000899FB001112468577D4F45E250E082EE25 +:100B700098E20E94CC2DE091F728F091F828099591 +:100B8000E091F328F091F4280994E0910A29F0917A +:100B90000B298381DFCF0F931F93CF93DF9320E047 +:100BA00030E015E2AC014F5F5F4F022F129FF00162 +:100BB000139FF00D1124E757FD4F649161110FC091 +:100BC000EC016881662301F12F5F3F4F263031052C +:100BD00061F780E0DF91CF911F910F910895DC01C3 +:100BE0007C91772389F36713EFCFDA0105C07D91FC +:100BF000772351F37613E8CF3196ED0164916111BB +:100C0000F6CF68816111E0CF802FA4DF81E0DF9112 +:100C1000CF911F910F910895CF93DF93EC01615015 +:100C2000710980E090E035E24CE2389FF001399F95 +:100C3000F00D1124E757FD4F2491222381F06131FB +:100C4000710568F0DE0103C06031710541F02D933C +:100C5000ED0131966150710924912111F5CF853054 +:100C6000910521F41882DF91CF9108954993615045 +:100C700071090196DACF08950C94BE2D08951F9343 +:100C8000CF93DF93162F662329F0EC01F5DF8993CC +:100C90001150E1F7DF91CF911F9108950E94BE2D71 +:100CA0000E94BE2D0E94BE2D0C94BE2DCF93DF93CB +:100CB000DC01615071092115310599F1623071052E +:100CC00080F1FA01240F351F2150310940E050E036 +:100CD00017C0D05DDC93CF708C2F90E00A97FCF4A6 +:100CE000C05D1196CC9311971296625071094E5FB8 +:100CF0005F4FE217F307B9F031966230710598F053 +:100D0000C081DC2FD295DF708D2F90E00A970CF315 +:100D1000D95CDC93CF708C2F90E00A970CF3C95C00 +:100D2000E0CF40E050E01C92CA01DF91CF910895DE +:100D3000FA0140814423F1F151815523D9F1611524 +:100D40007105C1F1DC0120E030E013C04295407F25 +:100D5000513428F5582F452B4D932F5F3F4F329636 +:100D60004081442329F15181552321F162177307F2 +:100D7000F9F0842F80538A3018F081518630D0F4F6 +:100D8000852F80538A3020F0952F9154963090F41F +:100D90004134E0F24295407F40575134D8F25753E6 +:100DA000452B4D932F5F3F4F329640814111DBCF52 +:100DB000C901089520E030E0C9010895FB01EE5615 +:100DC000FF4DA0E0B4E0A61BB70B9A01A417B5072E +:100DD00008F49D012115310541F02E0F3F1FDC0164 +:100DE00081918D93E217F307D9F70895DB01AE5691 +:100DF000BF4DE0E0F4E0E61BF70B9A01E417F507BE +:100E000008F49F012115310549F0FC01C9018E0F3D +:100E10009F1F21912D93E817F907D9F761E185E02C +:100E20000C94AF0FE2E9F0E2119284E2E239F807A4 +:100E3000D9F708958091092990E0A0E0B0E04AE058 +:100E4000880F991FAA1FBB1F4A95D1F740E157EDA4 +:100E500030E4409366065093A0092091A10926FF33 +:100E6000FCCF3093A1092091A0091092A0092091F4 +:100E7000A10926FFFCCF3093A1092091A00940933E +:100E8000650627FFE6CF20E12093660623E0209346 +:100E9000A0092091A10926FFFCCF20E42093A109FD +:100EA0002091A009AD01662777274093A0092091E2 +:100EB000A10926FFFCCF20E42093A1092091A009DD +:100EC000892F9A2FAB2FBB278093A0098091A1096E +:100ED00086FFFCCF80E48093A1098091A009109245 +:100EE000A0098091A10986FFFCCF80E48093A1092D +:100EF0008091A009E2E9F0E290E41092A0098091CB +:100F0000A10986FFFCCF9093A1098091A00981934C +:100F100084E2E239F80789F780E180936506089555 +:100F2000CF93DF9300D000D0CDB7DEB780E18093C0 +:100F3000650692E09093660698E0909365069AE1C4 +:100F4000909361069FE09093A6091092A70990ECF8 +:100F50009093A50998E19093A4098093660687ED84 +:100F60008093A0098091A10986FFFCCF80E4809343 +:100F7000A1098091A0091092A0098091A10986FF82 +:100F8000FCCF80E48093A1098091A00990E1909327 +:100F9000650680FD3EC08DE389838AE28A8380E80E +:100FA0008B8386EA8C8320E137ED90E420936606FC +:100FB0003093A0098091A10986FFFCCF9093A109ED +:100FC0008091A0091092A0098091A10986FFFCCF11 +:100FD0009093A1098091A0092093650687FFE6CF31 +:100FE00080E180936606FE013196CE01059630E4DD +:100FF00021912093A0092091A10926FFFCCF3093D5 +:10100000A1092091A009E817F90791F780E18093E1 +:1010100065062496CDBFDEBFDF91CF910BCF4F92F7 +:101020005F926F927F928F929F92AF92BF92CF9278 +:10103000DF92EF92FF920F931F93CF93DF938091F4 +:10104000092990E0A0E0B0E06AE0880F991FAA1F8C +:10105000BB1F6A95D1F7E2E9F0E200E014E0E12C71 +:10106000FF24F394C0E1CC2ED7EDBD2E20E4D22E88 +:1010700030E1A32E47ED942E53E5452E64E8562E1D +:1010800073E8672E492F5A2F6B2F7727852E382F1D +:10109000E701C81BD1090C171D0708F4E801A0924D +:1010A00066069092A0092091A10926FFFCCFD0925C +:1010B000A1092091A0091092A0092091A10926FF61 +:1010C000FCCFD092A1092091A009C092650627FF0C +:1010D000E6CFA09266064092A0092091A10926FFC2 +:1010E000FCCFD092A1092091A0098092A009209163 +:1010F000A10926FFFCCFD092A1092091A009742E4E +:101100004093A0092091A10926FFFCCFD092A1090C +:101110002091A0091092A0092091A10926FFFCCFDF +:10112000D092A1092091A009C0926506C0926606DE +:10113000B092A0092091A10926FFFCCFD092A1096D +:101140002091A0091092A0092091A10926FFFCCFAF +:10115000D092A1092091A009C092650627FFE6CF91 +:10116000A09266065092A0092091A10926FFFCCF0B +:10117000D092A1092091A0091092A0092091A10963 +:1011800026FFFCCFD092A1092091A0091092A009BE +:101190002091A10926FFFCCFD092A1092091A0099E +:1011A0003093A0092091A10926FFFCCFD092A1097C +:1011B0002091A0099F01209781F02C0F3D1F4191A4 +:1011C0004093A0094091A10946FFFCCFD092A1090C +:1011D0004091A009E217F30791F7C0926506C0920B +:1011E0006606B092A0094091A10946FFFCCFD092BB +:1011F000A1094091A0091092A0094091A10946FFC0 +:10120000FCCFD092A1094091A009C092650647FF8A +:10121000E6CFA09266066092A0094091A10946FF20 +:10122000FCCFD092A1094091A0098092A0094091E1 +:10123000A10946FFFCCFD092A1094091A00970926C +:10124000A0094091A10946FFFCCFD092A10940918D +:10125000A0091092A0094091A10946FFFCCFD092AD +:10126000A1094091A009C09265060C1B1D0B8C0FB3 +:101270009D1FA11DB11DF9010115110509F002CF36 +:1012800060E185E06CD663E184E0DF91CF911F914E +:101290000F91FF90EF90DF90CF90BF90AF909F9015 +:1012A0008F907F906F905F904F9059C62F923F9292 +:1012B0004F925F926F927F928F929F92AF92BF9266 +:1012C000CF92DF92EF92FF920F931F93CF93DF9312 +:1012D000CDB7DEB72B97CDBFDEBF8D83292E590149 +:1012E000411584E058076105710508F085C18091BA +:1012F000092990E0A0E0B0E0FAE0880F991FAA1F4A +:10130000BB1FFA95D1F7840F951FA61FB71F00E0EA +:1013100014E020E030E0041B150B260B370B6501B1 +:10132000E12CF12CC982DA82EB82FC820C151D05BE +:101330002E053F0508F47AC109811A8101151105AE +:1013400009F45AC12D81322DE12CFF24F394E0E100 +:10135000CE2EF7EDBF2EE0E4DE2EF0E1AF2EE7ED6E +:101360009E2EF3E56F2EE4E88E2E2A873B874E8370 +:101370005F8368877987362C492E5A2E6B2E772407 +:10138000452D382FB701681B71090617170708F09C +:101390004AC1B801EA85FB85A09266069092A00931 +:1013A0002091A10926FFFCCFD092A1092091A0098C +:1013B0001092A0092091A10926FFFCCFD092A1098B +:1013C0002091A009C092650627FFE6CFEA87FB8738 +:1013D000A09266063092A009EA85FB852091A109BA +:1013E00026FFFCCFEA87FB87D092A1092091A009B4 +:1013F0004093A009EA85FB852091A10926FFFCCF37 +:10140000EA87FB87D092A1092091A009542D409230 +:10141000A009EA85FB852091A10926FFFCCFEA8778 +:10142000FB87D092A1092091A0091092A009EA851A +:10143000FB852091A10926FFFCCFEA87FB87D0928C +:10144000A1092091A009C0926506EA85FB85C0929A +:101450006606B092A0092091A10926FFFCCFD09288 +:10146000A1092091A0091092A0092091A10926FFAD +:10147000FCCFD092A1092091A009C092650627FF58 +:10148000E6CFEA87FB87A09266068092A009EA85EC +:10149000FB852091A10926FFFCCFEA87FB87D0922C +:1014A000A1092091A0091092A009EA85FB8520914D +:1014B000A10926FFFCCFEA87FB87D092A1092091E2 +:1014C000A0091092A009EA85FB852091A10926FFB9 +:1014D000FCCFEA87FB87D092A1092091A009309325 +:1014E000A009EA85FB852091A10926FFFCCFEA87A8 +:1014F000FB87D092A1092091A0092A853B8561151F +:10150000710591F0260F371FEA85FB857190709267 +:10151000A0097090A10976FEFCCFD092A10970902D +:10152000A009E217F30791F7C0926506C09266061C +:10153000B092A009E091A109E6FFFCCFD092A109E9 +:10154000E091A0091092A009E091A109E6FFFCCF6B +:10155000D092A109E091A009C0926506E7FFE6CF0D +:10156000A0926606E3E8E093A009E091A109E6FFF6 +:10157000FCCFD092A109E091A0094093A00940912D +:10158000A10946FFFCCFD092A1094091A009509338 +:10159000A0094091A10946FFFCCFD092A10940913A +:1015A000A0091092A0094091A10946FFFCCFD0925A +:1015B000A1094091A009C0926506061B170B860F72 +:1015C000971FA11DB11D2A873B870115110509F041 +:1015D000D3CE4E815F8168857985DA01AE56BF4DE5 +:1015E0002D81322D89819A818A0F9B1FF9012191CA +:1015F0002D93A817B907D9F781E02B96CDBFDEBF91 +:10160000DF91CF911F910F91FF90EF90DF90CF90DE +:10161000BF90AF909F908F907F906F905F904F9012 +:101620003F902F900895EA85FB85B6CE09831A83F3 +:101630002B833C8381CECF92DF92EF92FF920F9368 +:101640001F936901411524E052076105710540F5BA +:1016500000E014E020E030E0041B150B260B370BF4 +:10166000E12CF12C0C151D052E053F05B0F04E5652 +:101670005F4DC114D10449F0DA01C80ED91EFC0136 +:101680008D918193EC15FD05D9F781E01F910F91A4 +:10169000FF90EF90DF90CF90089568017901E7CF38 +:1016A00080E01F910F91FF90EF90DF90CF90089511 +:1016B000FF920F931F93CF93DF93CDB7DEB7A09721 +:1016C000CDBFDEBF8130E9F0823009F455C08330F0 +:1016D00009F474C0843079F1853009F494C08630FF +:1016E00009F4B3C0873009F4B2C0883009F489C066 +:1016F000A096CDBFDEBFDF91CF911F910F91FF90DC +:10170000089580910529882309F4A3C0F12C8E0146 +:101710000F5F1F4FB1DAF801EF0DF11D8083F394D5 +:1017200080910529F816B0F3E0910129F091022982 +:10173000C8010995DDCFE091FF28F09100298E01C5 +:101740000F5F1F4FC801099520910529222361F3DE +:10175000F801CE0102962150820F911D21E0222333 +:1017600031F0308121E0311120E031503083319669 +:10177000E817F907A1F7D8CFE091FF28F0910029E9 +:101780008E010F5F1F4FC801099520910529222363 +:1017900059F2F801CE0102962150820F911D21E0ED +:1017A000222339F0308121E03F3F09F020E03F5F04 +:1017B00030833196E817F90799F7B6CFE091FF2803 +:1017C000F09100298E010F5F1F4FC80109952091EC +:1017D000052931E0215008F4A7CF3323D9F3822F14 +:1017E00090E0F801E80FF91F408131E04F3F09F028 +:1017F00030E0F801E80FF91F4F5F4083215068F790 +:1018000093CF18DB75CFE091FF28F09100298E016E +:101810000F5F1F4FC80109952091052931E0215024 +:1018200008F482CF3323D9F3822F90E0F801E80F38 +:10183000F91F408131E0411130E0F801E80FF91F54 +:1018400041504083215070F76FCF50D251CFE7DB2A +:101850004FCF8E010F5F1F4F67CFE0E0F6E080E4CF +:10186000828388E1868B08958091080686FF08C0F0 +:101870008091922481508A30A8F010929224089589 +:10188000809192248A3050F08A30C9F7E0910A2979 +:10189000F0910B2981810CDF809192248F5F8093DE +:1018A00092240895E0910A29F0910B29808100DFAC +:1018B000E4CFCF93DF93EC016150710980E090E0B9 +:1018C0003CE2FC01EE0FFF1FE295F295F07FFE2750 +:1018D000E07FFE27EA59FC4F2491222381F06132F8 +:1018E000710568F0DE0103C06032710541F02D938F +:1018F000ED0131966150710924912111F5CF8830A5 +:10190000910521F41882DF91CF91089539936150A8 +:1019100071090196D6CF882319F0813091F008958E +:1019200060930C29609312296093182960931E29F3 +:101930006093242960932A29609330296093362983 +:10194000089560930D29609313296093192960937A +:101950001F296093252960932B2960933129609377 +:1019600037290895FB01882321F0813081F010820E +:101970000895A0910A29B0910B296C9180E2689F8B +:10198000B00111246A597C4FCF010C94EE2DA09127 +:101990000A29B0910B2911966C91F0CF1F93CF9328 +:1019A000DF93182FEB0166E673E0CE010E94D52D80 +:1019B000892BF1F166E873E0CE010E94D52D892BC9 +:1019C00009F43EC066EA73E0CE010E94D52D892B52 +:1019D000C9F166EC73E0CE010E94D52D892BA1F1EF +:1019E00066EE73E0CE010E94D52D892B79F166E079 +:1019F00074E0CE010E94D52D892B51F166E274E08E +:101A0000CE010E94D52D892B29F166E474E0CE0128 +:101A10000E94D52D892B01F166E674E0CE010E946B +:101A2000D52D892BD9F080E0DF91CF911F910895BA +:101A300060E0812F70DF81E0DF91CF911F910895E9 +:101A400061E0F7CF62E0F5CF63E0F3CF64E0F1CF80 +:101A500065E0EFCF66E0EDCF67E0EBCF68E0E9CF80 +:101A600008951F93CF93DF93EB01142F682F80E02D +:101A700090E20E94BF2B612F80E090E20E94BF2B7A +:101A8000612F70E0CE01DF91CF911F918EC3089539 +:101A900008954115E4E05E076105710580F44D5637 +:101AA0005B4D2115310549F0DA01280F391FFC0182 +:101AB0008D918193E217F307D9F781E0089580E0D3 +:101AC0000895E3E9F4E28FEF819398E2E339F907AF +:101AD000D9F783E994E2809393289093942880E047 +:101AE00094E0809395289093962808958091952866 +:101AF000909196280895E0910A29F0910B2982830C +:101B0000813091F038F480E39DE080930729909331 +:101B100008290895823009F0089581E39DE08093BB +:101B200007299093082908958BE99DE08093072960 +:101B30009093082908952091952830919628E42FB4 +:101B4000F0E0DF0112962A173B0750F122503109CD +:101B50002E1B3F0B2093952830939628E0919328D5 +:101B6000F0919428808341839F012E5F3F4F209303 +:101B7000932830939428842F8150442381F0FB01D3 +:101B8000D901982F41914D939150E0F790E0019643 +:101B9000820F931F8093932890939428089508951B +:101BA00080E0A9CF8EDFE0910A29F0910B29828194 +:101BB000A2CFCF93DF93EC0166E874E00E94D52DAD +:101BC000892B91F066E974E0CE010E94D52D892B16 +:101BD00089F066EA74E0CE010E94D52D892B61F070 +:101BE00080E0DF91CF91089580E085DF81E0DF9193 +:101BF000CF91089581E0F9CF82E0F7CFAB01E0917A +:101C00000A29F0910B29628120E1629FB001112421 +:101C10006A577B4F0C94EE2D0F931F93CF93DF9356 +:101C2000EC018B011882AB0166E874E00E94DE2DA6 +:101C3000A80166EB74E0CE010E94DE2DA80166E9E2 +:101C400074E0CE010E94DE2DA80166EB74E0CE01A7 +:101C50000E94DE2DA80166EA74E0CE01DF91CF91EB +:101C60001F910F910C94DE2D43E350E060E070E093 +:101C700089E099E20C94003043E350E060E070E0CA +:101C800089E099E20C940B301F93CF93DF931F925E +:101C9000CDB7DEB7182F1150183030F080E00F901C +:101CA000DF91CF911F9108958983B9D910930929A4 +:101CB000412F50E09A01220F331F240F351F220FAE +:101CC000331F245F364D20930A2930930B290E943D +:101CD000C50568DFAFD88981682F615E83E03FD199 +:101CE00081E00F90DF91CF911F91089520910929F4 +:101CF00030E02F5F3F4F27703327822F2F5F3F4FFA +:101D0000F901EE0FFF1FE20FF31FEE0FFF1FE75F5A +:101D1000F64D9081911178C027703327822F2F5F65 +:101D20003F4FF901EE0FFF1FE20FF31FEE0FFF1FF2 +:101D3000E75FF64D9081911167C027703327822F9E +:101D40002F5F3F4FF901EE0FFF1FE20FF31FEE0F62 +:101D5000FF1FE75FF64D9081911156C02770332722 +:101D6000822F2F5F3F4FF901EE0FFF1FE20FF31F8E +:101D7000EE0FFF1FE75FF64D9081911145C0277070 +:101D80003327822F2F5F3F4FF901EE0FFF1FE20F26 +:101D9000F31FEE0FFF1FE75FF64D9081911134C0E6 +:101DA00027703327822F2F5F3F4FF901EE0FFF1F60 +:101DB000E20FF31FEE0FFF1FE75FF64D90819111C9 +:101DC00023C027703327822F2F5F3F4FF901EE0F7B +:101DD000FF1FE20FF31FEE0FFF1FE75FF64D90812D +:101DE000911112C027703327822F2F5F3F4FF901C7 +:101DF000EE0FFF1FE20FF31FEE0FFF1FE75FF64D21 +:101E00009081911101C008958F5F3ECF8091092983 +:101E10008F5F0895CF93DF93EC01F8DF805D8883B7 +:101E20001982DF91CF910895FC01808191819923DE +:101E300011F080E00895805327CF80E3E0E0F6E0E2 +:101E40008183089580919728823109F460C0C8F099 +:101E5000833101F1982F9052983008F04DC0909145 +:101E600099289F5F913009F46BC0909399288091D5 +:101E700098288231E1F480E2809307061092982836 +:101E80000895803161F0B0F180E1809305061092F1 +:101E9000972809C08091040684FF3FC080E18093A9 +:101EA00006061092972880919828823121F3833179 +:101EB00048F48031A9F0D0F080E2809305061092BA +:101EC000982808958331D9F0982F9052983078F45B +:101ED000909199289F5F913021F1909399280895CE +:101EE00080E280930606109298280895811110923E +:101EF000982808958823B9F210929728D4CF80911A +:101F0000040685FDEDCF80E280930506089580E10B +:101F10008093070610929728C6CF80E1809305062C +:101F2000C2CF109299289091040695FFECCF90E2D1 +:101F3000909306068032D9F28150809398280895B4 +:101F4000109299289091040694FFE7CF90E1909326 +:101F50000606803289F2815080939728A4CFE091C1 +:101F60000A29F0910B299581981731F094819813E3 +:101F7000089560939728089560939828F7CFCF939A +:101F8000DF93EC016150710980E090E03CE2FC01DC +:101F9000EE0FFF1FE295F295F07FFE27E07FFE2710 +:101FA000E854FB4F2491222381F06132710568F0DF +:101FB000DE0103C06032710541F02D93ED013196D1 +:101FC0006150710924912111F5CF8730910521F4D9 +:101FD0001882DF91CF91089539936150710901966C +:101FE000D6CF982F907185FD03C091113FC0089501 +:101FF00060931129992359F160931029609317294F +:102000006093162960931D2960931C2960932329EE +:1020100060932229609329296093282960932F29AE +:1020200060932E29609335296093342960933B296E +:1020300060933A2980E280930606109298289923AB +:10204000B1F280E18093060610929728089560937C +:10205000172960931D296093232960932929609390 +:102060002F296093352960933B29E4CF6093102991 +:102070006093162960931C29609322296093282974 +:1020800060932E296093342960933A29D8CFFB01BD +:10209000803221F0803189F010820895A0910A29C0 +:1020A000B0910B2915966C9180E2689FB0011124C4 +:1020B00068547B4FCF010C94EE2DA0910A29B0916A +:1020C0000B2914966C91F0CF1F93CF93DF93182FA9 +:1020D000EB0168EB74E0CE010E94D52D892BB1F1A4 +:1020E00068ED74E0CE010E94D52D892BB9F168EF1F +:1020F00074E0CE010E94D52D892B91F168E175E045 +:10210000CE010E94D52D892B69F168E375E0CE01DF +:102110000E94D52D892B41F168E575E0CE010E9422 +:10212000D52D892B19F168E775E0CE010E94D52DD8 +:10213000892BF1F068E975E0CE010E94D52D892B3D +:10214000C9F080E0DF91CF911F91089560E0812F69 +:1021500048DF81E0DF91CF911F91089561E0F7CFD3 +:1021600062E0F5CF63E0F3CF64E0F1CF65E0EFCF5D +:1021700066E0EDCF67E0EBCFBC0180E090E20C942D +:102180006C2BCF93DF93EC012196FC0164916623C5 +:1021900049F080E090E20E94BF2BFE0121966491FD +:1021A0006111F7CFDF91CF910895AB01BC0180E0C1 +:1021B00090E20C94952B80E2E0E6F6E082830895AD +:1021C000CF93DF9380919A28823019F0DF91CF91DD +:1021D000089580E090E20E943E2C0E943F2680E01D +:1021E00090E20E94592CEC0197FDF0CF63E182E070 +:1021F000B6DE8C2F15D38111E9CF8C2FDF91CF91D3 +:1022000095C480919A28813009F138F0823071F1BB +:10221000833071F0823041F108958091680685FF26 +:10222000FBCF84E180931B2081E080939A2808955E +:1022300080911B20815080931B208111EDCF0E9443 +:10224000692A0E94870510929A28089580911B2080 +:10225000815080931B208111DFCF0E9469050E946D +:10226000A42A82E080939A2826D467C580916806C4 +:1022700085FDFACF84E180931B2083E080939A2828 +:10228000089561E181E06BCE60E181E068CE80E09D +:1022900090E20C94472B80E090E20C94B92C2FEF45 +:1022A00035E03F932F9328EF35E03F932F9321EFB5 +:1022B00035E03F932F9328EB35E03F932F9321E0B8 +:1022C0002F931F929F938F930E94062E8DB79EB7D8 +:1022D0000C968DBF9EBF85E6089523EE38E23F93AE +:1022E0002F9325E036E03F932F9321E02F931F9209 +:1022F0009F938F930E94062E8DB79EB708968DBF31 +:102300009EBF85E608950E94CB05811102C08AEC2C +:102310000895B2DC84E6089560E071E00E940C0646 +:1023200085E608950F931F93CF93DF93CDB7DEB764 +:10233000A197CDBFDEBF8C0120910529E091FF2838 +:10234000F0910029CE01019629A3099529A130E039 +:10235000AE014F5F5F4F60E071E0C8010E9456061A +:1023600085E6A196CDBFDEBFDF91CF911F910F9182 +:102370000895BF92CF92DF92EF92FF920F931F9337 +:10238000CF93DF93CDB7DEB7A097CDBFDEBF8C0173 +:10239000C0900529D12C68E076E00E94D52D892BCC +:1023A00059F5C114D104C1F1B12CEE24E394F12C00 +:1023B000EC0EFD1E00E010E00E943C06F701E00F6D +:1023C000F11F8083B3940B2D10E00C151D05A0F3B5 +:1023D000E0910129F0910229C701099584E6A096B0 +:1023E000CDBFDEBFDF91CF911F910F91FF90EF9096 +:1023F000DF90CF90BF900895A80160E270E0EE24D6 +:10240000E394F12CEC0EFD1EC7010E9498068C157A +:102410009D05F1F28AECE3CFEE24E394F12CEC0E6F +:10242000FD1ED6CF20910629211107C020E3FC0113 +:102430002083FC01118285E6089521E3FC012083BD +:10244000FC01118285E60895FC012181211105C05E +:102450008081813341F0803311F08AEC089510922D +:10246000062984E6089581E08093062984E608958C +:1024700086E599E0A4D18EE608958BE19BE0BAD180 +:102480008EE60895E0ECF4E081818E7F81830E94E6 +:10249000692A0E945C0584E60895E0ECF4E08181FD +:1024A0008E7F81830E94692A0E94630584E60895D5 +:1024B000E3E0F9E221812F9320812F932FE036E092 +:1024C0003F932F9321E02F931F929F938F930E940E +:1024D000062E8DB79EB708968DBF9EBF85E60895E0 +:1024E000209105291F922F9322E136E03F932F93ED +:1024F00021E02F931F929F938F930E94062E8DB7FA +:102500009EB708968DBF9EBF85E6089560E071E096 +:10251000D0D985E6089540E051E0BC0180E022DAA0 +:1025200085E60895BC0180E039DA811102C08AECA9 +:102530000895A2DB84E6089560E071E0BAD985E6EB +:10254000089540E051E0BC0181E00CDA85E6089591 +:10255000BC0181E023DA811102C08AEC08958CDB92 +:1025600084E6089560E071E00ADD85E6089540E0C4 +:1025700051E0BC0180E28BDD85E60895BC0180E27C +:10258000A3DD811102C08AEC089576DB84E608950C +:1025900060E071E0F4DC85E6089540E051E0BC01C4 +:1025A00080E175DD85E60895BC0180E18DDD811156 +:1025B00002C08AEC089560DB84E6089560E071E073 +:1025C0002BDB85E6089560E071E018DB85E6089571 +:1025D000F0DA811102C08AEC08954EDB84E608959A +:1025E00023E236E03F932F932BE136E03F932F9386 +:1025F00025E136E03F932F9321E02F931F929F9385 +:102600008F930E94062E8DB79EB70A968DBF9EBFF0 +:1026100085E60895CF93DF93EC0168DA9F938F935B +:1026200029E236E03F932F9381E08F931F92DF934F +:10263000CF930E94062E8DB79EB708968DBF9EBF82 +:1026400085E6DF91CF910895CF93DF93EC016CE2A3 +:1026500076E00E94D52D892B81F064E376E0CE01EF +:102660000E94D52D892B21F08AECDF91CF9108951E +:1026700028DA84E6DF91CF91089589E49DE0BAD00D +:102680008EE6DF91CF91089560E071E0C3DB85E6CF +:102690000895CADB811102C08AEC0895EDDA84E660 +:1026A00008950E94120784E60895BF92CF92DF92A8 +:1026B000EF92FF920F931F93CF93DF937C01CFEFA5 +:1026C000D0E031E4C32E36E0D32E4CE2B42E8601A6 +:1026D000B60180E990E20E94D52D892B21F1F60107 +:1026E0008491882389F0C132D10570F0D70103C0ED +:1026F000C032D10549F08D937D010F5F1F4F2197A7 +:10270000F80184918111F4CFF701B1927F012197F3 +:10271000F6E1CF0ED11C8601B60180E990E20E945D +:10272000D52D892BE1F6F7013197108285E6DF91EF +:10273000CF911F910F91FF90EF90DF90CF90BF90BE +:102740000895FC012091200220682093200220910E +:10275000230220FFFCCF81E080932302A09110028E +:10276000B0911102AE5BB109B7FD1CC029E637E597 +:102770004BE050E00E94562DAA27BB279F938F93D2 +:102780002AE336E03F932F9381E08F931F92FF93CC +:10279000EF930E94062E8DB79EB708968DBF9EBF01 +:1027A00085E60895A0E0B0E0E1CF80E0ECE3F9E257 +:1027B0009191890F99E2EC3BF907D1F7089521E057 +:1027C00020939B2820939C282CE320939D2825E090 +:1027D00030E020939E2830939F281092A0281092DA +:1027E000A1281092A2281092A3288093A428909345 +:1027F000A528089527E020939B282CE231E0209320 +:102800009E2830939F281092A0281092A128109201 +:10281000A2281092A3288093A4289093A528089515 +:10282000CF93C82F90919B28953009F484C0E0F095 +:10283000973009F44CC060F52091A92880919C281C +:10284000281709F4ECC030E090E001972817390709 +:1028500009F414C168E180E090E20E94BF2B10925D +:102860009B2881E0CF910895933009F45CC0B8F0C3 +:1028700090E04091A9282FEF30E0241B3109821706 +:10288000930709F06FC085E080939B2881E0EACF31 +:10289000983019F19930B1F080E0CF9108959130DE +:1028A000D8F3813009F4ECC0843039F0883151F02C +:1028B0008B3141F081E0CF91089566E080E090E2B5 +:1028C0000E94BF2B10929B2881E0CF910895853103 +:1028D00009F457C08B3109F450C0C83171F3C630C8 +:1028E00009F451C0C53131F761E080E090E20E9407 +:1028F000BF2B60919C2880E090E20E94BF2B6091EA +:102900009C28609580E090E20E94BF2B60E870E018 +:102910008CE399E24ADC49DF682F80E090E20E9474 +:10292000BF2B81E09FCF8093A92884E080939B28D0 +:1029300081E0CF9108952091A6283091A728F90130 +:10294000E45CF64D8083C90101968093A62890939C +:10295000A7288038910509F0ADCF86E080939B28A9 +:1029600081E080CF65E180E090E20E94BF2B82E0B1 +:1029700080939B2881E0CF91089510929B2881E05D +:102980009ACF10929C2880919C288F5F80939C28DE +:102990004091A0285091A1286091A2287091A3286D +:1029A000E091A428F091A52820E830E08CE399E29A +:1029B0000995882309F46FC061E080E090E20E94ED +:1029C000BF2B60919C2880E090E20E94BF2B609119 +:1029D0009C28609580E090E20E94BF2B60E870E048 +:1029E0008CE399E2E2DBE1DE682F80E090E20E9476 +:1029F000BF2B8091A0289091A128A091A228B091EE +:102A0000A32880589F4FAF4FBF4F8093A02890932B +:102A1000A128A093A228B093A32881E04CCFC5DEC3 +:102A20008C13A0CF4091A0285091A1286091A2289A +:102A30007091A328E091A428F091A52820E830E027 +:102A40008CE399E20995882381F180919C288F5F1E +:102A500080939C288091A0289091A128A091A228E1 +:102A6000B091A32880589F4FAF4FBF4F8093A028AD +:102A70009093A128A093A228B093A32866E073CFD7 +:102A80001092A6281092A7281092A82883E080937D +:102A90009B2881E0E7CE64E080E090E20E94BF2BBB +:102AA00089E080939B2881E0DDCE68E180E090E2C0 +:102AB0000E94BF2BCFCE80919B28813099F0873028 +:102AC00009F0089580919E2890919F289C012150A3 +:102AD000310920939E2830939F28892B91F71092DB +:102AE0009B28089580919E2890919F289C012150B9 +:102AF000310920939E2830939F28892B11F78091CC +:102B00009D28982F915090939D28811109C0109273 +:102B10009B2885E090E080939E2890939F280895BD +:102B200065E180E090E20E94BF2BF3CFAF92BF92AD +:102B3000DF92EF92FF920F931F93CF93DF931F9239 +:102B4000CDB7DEB7982F91549A3120F090529A3138 +:102B5000F0F480522091AA283091AB282F3F310504 +:102B600050F4F901E45CF64D80832F5F3F4F2093D2 +:102B7000AA283093AB2881E00F90DF91CF911F916D +:102B80000F91FF90EF90DF90BF90AF9008959F5C02 +:102B90009A3000F38F35F1F28F33E1F28D33D1F2B9 +:102BA0008D30A9F0883039F08B3129F71092AA289E +:102BB0001092AB28E0CF8091AA289091AB28009783 +:102BC000D1F201978093AA289093AB28D4CFE091BB +:102BD000AA28F091AB28E45CF64D10821092AA2846 +:102BE0001092AB2880913C29882369F18F3359F1E9 +:102BF0008D3349F1EDE3F9E204C02F3331F02D3389 +:102C000021F07F0121912111F8CFF701108200E01E +:102C100010E086E1D82ED09E5001D19EB00C112438 +:102C200081E496E0A80EB91EB5018CE399E22983F0 +:102C30000E94D52D2981892B09F43FC00F5F1F4FBA +:102C40000531110541F788EC10E0E5E1F8E0E49189 +:102C50008E1709F463C0E6E3F8E0E4918E1709F4F7 +:102C60005AC0E7E5F8E0E4918E1709F451C0E8E7AF +:102C7000F8E0E4918E1709F448C0E9E9F8E0E4913E +:102C80008E1709F43FC0EAEBF8E0E4918E1779F172 +:102C900080E090E076DA8FE098E073DA112309F4AF +:102CA0006ACF80913C29882309F465CF8CE399E2AF +:102CB00063DA82E198E065DA5ECF10923C292F3327 +:102CC00099F02D3371F1222319F089EC11E0BDCF79 +:102CD000F501709685919491FC010097B1F38CE316 +:102CE00099E2099511E0B1CFF5017496F3CF25E093 +:102CF00030E041E2429FC001439F900D11248A5E63 +:102D0000974FC8CF24E030E0F4CF23E030E0F1CF9C +:102D100022E030E0EECF21E030E0EBCF20E030E009 +:102D2000E8CFF501729685919491FC01009769F2C4 +:102D3000C7010196099511E088CF0895A0E2B6E099 +:102D400082E011968C93119715968C9315978CE3CE +:102D50009AE28093B8289093B9288CEB9AE28093FA +:102D6000BA289093BB281092B1281092B0281092E4 +:102D7000AC281092B4281092B5281092AF28E0E445 +:102D8000F8E010A211A28DE291E086A397A38FEF45 +:102D90009FEF80A791A781E0808388E8838383E009 +:102DA000878384E01A968C93E8E4F0E08081817F49 +:102DB0008660808308951F920F920FB60F921124A0 +:102DC0008F939F93EF93FF93E8E4F0E08081817FFE +:102DD0008083E0E4F8E0138286E990E086AB97AB6D +:102DE0008AE190E080AF91AFE0E4F9E010A211A297 +:102DF0008FEF9FEF86A397A389E883838EE080837C +:102E0000E0E2F6E01286FF91EF919F918F910F9093 +:102E10000FBE0F901F9018951F920F920FB60F9232 +:102E200011242F938F939F93EF93FF9390912806F4 +:102E30008091B028957021E009F020E0880F822B66 +:102E40008093B0289091AC289923A1F1982F977086 +:102E5000973009F442C0982F9C7061F191E082FD97 +:102E60006BC09093AE288091AF2881116DC0809186 +:102E7000B1288695992309F471C020E8282B209366 +:102E8000B1288091B4289091B52801968093B428F8 +:102E90009093B52887709927892B61F4E091B82821 +:102EA000F091B9282193E093B828F093B92881E0F4 +:102EB0008093AF288091AC2891E089278093AC283B +:102EC00088E880934308FF91EF919F918F912F9114 +:102ED0000F900FBE0F901F9018951092400880E140 +:102EE00080934C08109243098091AE28882379F191 +:102EF0008CEB94E080936609909367091092AD285B +:102F000081E080934C0983E0809346098091B42846 +:102F10009091B528877061F09091B1288F5F969558 +:102F20008F5F8930E1F7E091B828F091B92890835C +:102F300081E08093B628BECF90E09093AE28809138 +:102F4000AF28882309F493CF1092AF28B3CF8CE732 +:102F500094E08093660990936709D0CF20E08ECFEC +:102F60001F920F920FB60F9211242F933F938F93BE +:102F70009F93EF93FF938091AD28853009F44DC066 +:102F8000A8F0883009F47CC020F5863009F4B8C078 +:102F9000873009F48AC0FF91EF919F918F913F9103 +:102FA0002F910F900FBE0F901F901895823071F1E6 +:102FB000F8F0833009F456C0843069F78091B12865 +:102FC00080FDB7C080E48093460685E08093AD28FD +:102FD000E2CF893009F45BC08A30E9F610924009EB +:102FE000109246091092000881E08093B728D3CF51 +:102FF000882309F453C0813071F68FE390E0809309 +:103000006609909367098EE08093000880E48093BE +:10301000450683E08093AD28BECF8091B12890E42F +:1030200080FD84C09093450686958093B128809159 +:10303000B2289091B32801968093B2289093B32838 +:103040009C0127703327232B09F477C02091B428E3 +:103050003091B5288217930709F04EC088E080931D +:10306000AD2899CF80E48093460684E08093AD2814 +:10307000E091B828F091B92880818093B1288BCF56 +:1030800080E48093460689E08093AD2884CF80E475 +:10309000809346068AE08093AD287DCF8FE790E04D +:1030A000809366099093670976CFE091BA28F091F2 +:1030B000BB288081811136C080E480934506209131 +:1030C000B2283091B3288091B4289091B528281760 +:1030D000390721F23196E093BA28F093BB28E091AA +:1030E000B828F091B928CF0101968093B828909321 +:1030F000B92881818093B12884E08093AD284BCF9B +:10310000E091BA28F091BB288081811107C080E44A +:103110008093460687E08093AD283DCF80E480937E +:103120004506F8CF80E480934606C9CF90934606C3 +:103130007BCF80E48093450648CF86E08093AD281E +:103140002ACFCF93DF93E0E4F6E084E08283128A13 +:10315000C0E8D1E082E68E83A0E2B6E085E0129678 +:103160008C93129781E052968C93529782E05096FE +:103170008C9350971A961C921A9783E019968C9309 +:103180009AE5988398E5998390E491839683818367 +:103190008683E0E0F8E08FE090E086A397A388E0E4 +:1031A00090E082A793A783E28183DF91CF91C6CD80 +:1031B0000F931F93CF93DF938091B6288823C1F09C +:1031C0001092B62882E08093210680932606009113 +:1031D000B4281091B5280115110599F4E091F9284A +:1031E000F091FA2809951092400910924609A6DD3F +:1031F0008091B72881115AC0DF91CF911F910F9113 +:103200000895A801495F5F4F569547955695479594 +:1032100056954795E0910729F09108296CE37AE2E9 +:1032200080E2099563E186E00E94AF0FE091FD28FE +:10323000F091FE28B8018CE39AE209958C0194FF85 +:103240003CC01F7E0115110571F2A801495F5F4F57 +:10325000569547955695479556954795E091072978 +:10326000F09108296CE37AE281E2099563E187E055 +:103270000E94AF0F0093B4281093B5281092B22883 +:103280001092B3288CE39AE28093B8289093B928DF +:103290008CEB9AE28093BA289093BB2881E08093CC +:1032A000AD288091B728882309F4A6CF1092B728BB +:1032B000DF91CF911F910F9141CD9695879596956E +:1032C000879596958795009709F4BCCF40E020E05C +:1032D00030E0F901E45CF54D2081022E2295202595 +:1032E000022E269526952025E058FF4F30E02F5FCF +:1032F0003F4F21FB552750F9C52F20E0D22F51E039 +:10330000C527C0834F5F242F30E02817390708F303 +:1033100099CF81E08093BC28089581E08093BC28F8 +:1033200008950895FF920F931F93CF93DF9300D0DA +:1033300000D0CDB7DEB78C01FC0190818091BC2814 +:10334000823009F45BC080F49632A9F1923599F18C +:1033500020E030E0C9012496CDBFDEBFDF91CF91E0 +:103360001F910F91FF900895843079F168F496329F +:1033700011F1923501F1953909F490C081E0809303 +:10338000BC2820E030E0E6CF853011F760E170E046 +:10339000C801E7D7882309F46BC0809106298823E8 +:1033A00009F46FC084E08093BC288AE0F801808330 +:1033B00024E030E0CFCF84E4F8018083118282E002 +:1033C0008093BC2820E130E0C5CF9632A1F392353E +:1033D00091F3903309F48EC0923A09F4BAC0903A4E +:1033E00009F4D4C0903551F6F8018181882309F49D +:1033F000DFC0F801108224E030E0ACCF9632D9F281 +:103400009235C9F2933909F0B9CF19821A821B8219 +:103410001C8288E8898343E050E060E070E0CE01E0 +:1034200002960E94DE06F8018181803209F481C093 +:10343000803709F08DCFF80192818981981388CF68 +:1034400093818A81981384CF94818B81981380CF44 +:1034500095818C8198137CCF84E0808361E070E05B +:10346000C80150D783E08093BC2828E130E072CFB8 +:1034700084E08093BC2881E0F801808324E030E080 +:1034800069CF6091BD2870E0660F771F660F771FC8 +:1034900044E050E0C8010E94F60684CF44E050E0CA +:1034A00064E070E0CE0101960E94DE06F8018181A1 +:1034B000803209F43EC0803709F04ACFF80192818A +:1034C0008981981345CF93818A81981341CF948144 +:1034D0008B8198133DCF95818C81981339CF1082C1 +:1034E00061E070E0C8010ED784E08093BC2828E139 +:1034F00030E030CFF801F18062E070E0C80131D7F0 +:10350000882309F4B8CFFFE0FF1508F472CF6F2DC0 +:1035100070E0660F771F660F771F40E150E0C8012B +:103520000E94DE0660E170E0C801ECD620E930E0E0 +:1035300011CF8981F80180833A8131832B812283E5 +:103540009C819383832782278927848328E230E024 +:1035500001CFF801F18066E070E0C80102D788234E +:1035600009F489CF8F2D82508E3008F042CF8091A0 +:10357000062981111ACFF4E0FF9EB001112444E026 +:1035800050E0C80102960E94F6060FCFF801F180C4 +:1035900062E070E0C801E5D6882309F46CCF8F2D76 +:1035A00082508E3008F025CFF092BD2885E0FBCE0A +:1035B00062E070E0C801D5D6882309F45CCF109290 +:1035C000BC2820E030E0C6CECF93DF93EC0143E08F +:1035D00050E060E070E00E94DE0644E050E064E00D +:1035E00070E0CE010396DF91CF910C94DE060F932D +:1035F0001F93CF93DF9300D0CDB7DEB78C01FC01D2 +:1036000080819181892798E88927928189278A83F7 +:103610008481938189279581892796818927898348 +:1036200043E050E060E070E0C8010E94F60641E02F +:1036300050E063E070E0CE0102960E94F60644E09E +:1036400050E064E070E0C80103960E94F60641E095 +:1036500050E068E070E0CE0101960E94F6060F90FF +:103660000F90DF91CF911F910F91089581E080938A +:10367000BE2884E090E08093BF289093C02888E023 +:103680008093C1281092C228089581E08093BE28BB +:1036900084E490E08093BF289093C02888E08093D2 +:1036A000C12881E090910529973009F080E080934E +:1036B000C228089581E08093BE2882E090E0809344 +:1036C000BF289093C02888E18093C1281092C22817 +:1036D000089581E08093BE28089508956F927F92A7 +:1036E0008F929F92AF92BF92CF92DF92EF92FF9212 +:1036F0000F931F93CF93DF93CDB7DEB72E97CDBF38 +:10370000DEBF8C018091BE28853009F4D1C0F8F06D +:10371000883009F41BC1B8F5863009F4F5C187304B +:1037200009F4C9C120E030E0C9012E96CDBFDEBF4B +:10373000DF91CF911F910F91FF90EF90DF90CF908D +:10374000BF90AF909F908F907F906F900895823040 +:1037500009F4E1C008F05AC02091BF289091C02818 +:10376000D8018C91863209F4AEC0823509F4ABC021 +:103770008034C1F682E08093BE288AE0D8018C9321 +:1037800024E030E0D1CF893009F4A6C08D3050F666 +:10379000D801FC900E9433248F25F8018083F180AA +:1037A0000E9433248F25D80111968C93119712967D +:1037B000FC900E9433248F25F8018283F3800E94BD +:1037C00033248F25D80113968C9313971496FC906D +:1037D0000E9433248F25F8018483F5800E943324CE +:1037E0008F25D80115968C9364E070E0C801B9D597 +:1037F000811199C20E94742491E09827F801908366 +:1038000088E08093BE2824E030E08ECF833009F436 +:1038100042C1843009F086CF2091BF289091C02802 +:10382000D8018C91863209F44EC0823509F44BC020 +:10383000833909F095C18091C228882309F434C3E3 +:1038400043E050E060E070E0CE0102960E94DE06A8 +:1038500088E88983D80111969C91903209F4C2C4FA +:10386000903709F05FCFD80112968C911297883863 +:1038700009F058CF13969C9113978A81981352CFD1 +:1038800014969C9114978B8198134CCF15969C910C +:1038900015978C81981346CF84E08C9361E070E09B +:1038A000C80130D585E08093BE2828E130E03CCFC8 +:1038B0002091BF289091C028D8018C91863219F0B0 +:1038C000823509F04AC1F8012083918384E0809316 +:1038D000BE2820E130E028CF7801D12CD701CC9050 +:1038E000C2D78C25F70181937F01D394F2E1DF12D7 +:1038F000F5CF60E170E0C80134D5882309F47ACFB0 +:1039000080910629882309F43EC1EED79AE09827D2 +:10391000D8019C9375CFF8018081833409F46DC17F +:10392000813409F42BC1803309F434C4803A09F49A +:1039300056C1803509F0F6CEF8018181882309F45B +:103940001DC4F801108224E030E0EECED801DC90F6 +:103950008AD78D25F8018083D18085D78D25D80120 +:1039600011968C9311971296DC907DD78D25F801D6 +:103970008283D38078D78D25D80113968C931397A3 +:103980008C91803309F4FDC1803A09F46FC2803C08 +:1039900009F4AFC2813C09F446C3823C09F409C171 +:1039A000803B09F457C38056823008F0A7C062E01C +:1039B00070E0C801D6D4882309F4CFC1F801818111 +:1039C0008C739081903609F447C46AE370E05B0120 +:1039D000F0E18F9FA00CB11C11246E0137E0C30EE3 +:1039E000D11C64E0C6010E943F068091C2287E017E +:1039F000882309F415C48BE0E80EF11C44E050E084 +:103A000063E070E0C7010E94DE0646E050E0B501C9 +:103A1000CE0101960E94DE068F818093C42888859E +:103A20008093C52889858093C6288A858093C72876 +:103A300060E470E084EC98E27BD78091C4288093A6 +:103A4000C8288091C5288093C9288091C628809372 +:103A5000CA288091C7288093CB2860E270E088EC68 +:103A600098E266D7A601B701CE01019633D58F81C2 +:103A7000D8018C93888511968C931197898512961D +:103A80008C9312978A8513968C9387E08093BE2837 +:103A900020E230E049CE60E170E0C80162D48823C2 +:103AA00009F463C080910629882309F45EC18AE085 +:103AB000D8018C935DC0C801ADD6F801F480D3D68F +:103AC0008F25D80114968C9314971596FC90CBD61D +:103AD0008F25F8018583F680C6D68F25D8011696E6 +:103AE0008C9316971796FC90BED68F25F801878386 +:103AF00024819091C428291709F484C081E080931F +:103B0000BE2820E030E010CE2091BF289091C02840 +:103B1000F8018081863209F442C0823509F43FC041 +:103B2000803509F409CF982F9056923008F4ABC233 +:103B3000803351F0803A41F0803C31F0813C21F0FB +:103B4000823C11F0803BD1F681E08093BE2884E076 +:103B5000D8018C9324E030E0E7CD853909F44FC1DA +:103B60001092BE2820E030E0DFCD81E0F8018083B4 +:103B700082E08093BE2824E030E0D6CD8AE08083C6 +:103B800024E030E0D1CD6091C32830E1639FB001E3 +:103B9000112440E150E0C8010E94F606B6CED801DB +:103BA0002C9311969C9384E08093BE2820E130E012 +:103BB000BBCD62E070E0C801D4D3882309F4CDC046 +:103BC000F80181818093C3288CE08093BE288CD635 +:103BD0009AE09827D8019C9324E030E0A5CD62E0DC +:103BE00070E0C801BED3882309F4CEC2F8018181F8 +:103BF0008093C32883E08093BE288AE0808324E0FA +:103C000030E092CD25819091C528291377CF268168 +:103C10009091C628291372CF9091C72889136ECF2F +:103C2000F090C82820D68F25D8018C93F090C82812 +:103C30000F2CF294F0240F2CF694F694F02416D462 +:103C4000F801E058FF4F2F2D30E02F5F3F4F21FB51 +:103C5000882480F8912CB1E08B2688258083F09011 +:103C6000C92801D68F25F8018183F090C9280F2C2F +:103C7000F294F0240F2CF694F694F024F7D3F80184 +:103C8000EF57FF4F2F2D30E02F5F3F4F21FBAA242E +:103C9000A0F8B12C31E0A3268A258083F090CA28B1 +:103CA000E2D58F25D80112968C93F090CA280F2C5C +:103CB000F294F0240F2CF694F694F024D7D3F80164 +:103CC000EE57FF4F2F2D30E02F5F3F4F21FBCC24CD +:103CD000C0F8D12CB1E0CB268C258083F090CB2886 +:103CE000C2D58F25F8018383F090CB280F2CF29456 +:103CF000F0240F2CF694F694F024B8D3F801ED5785 +:103D0000FF4F2F2D30E02F5F3F4F21FB662460F8DF +:103D1000712C31E063268625808388E08093BE285D +:103D200020E230E101CD6091C328B0E16B9FB0018A +:103D3000112440E150E08CEC98E20E94DE062091D4 +:103D4000CC288091D0288095281709F4DFC0CCD5E5 +:103D500096E09827D8019C9353CDC6D591E098273B +:103D6000F801908324E030E0DFCC6091C328F0E1DB +:103D70006F9FB001112440E150E0C8010E94F60697 +:103D800096CE62E070E0C801ECD2882331F3F801EE +:103D90006181F0E16F9FB001112440E150E0C80162 +:103DA0000E94DE0660E170E0C801ACD2680130E834 +:103DB000C30ED11CA12CD801BC9055D58B25F80180 +:103DC00081938F010B2CB294B0240B2CB694B69433 +:103DD000B0244CD32B2D30E02F5F3F4F21FBEE243E +:103DE000E0F8F12CF1E0EF268E25D6018D936D01E0 +:103DF000A394B2E1AB12DFCF20E930E195CC44E0EF +:103E000050E063E070E0CE0101960E94DE069091E2 +:103E1000C128D80111968C91803209F4D3C1803722 +:103E200009F080CCD80112962C9112978981281321 +:103E300079CC13962C9113978A81281373CC1496FE +:103E40002C9114978B8128136DCC15962C91159776 +:103E50008C81281367CC9C9361E070E0C80152D23A +:103E600086E08093BE2828E130E05ECC62E070E01E +:103E7000C80177D2882381F0D80111968C91809364 +:103E8000C32889E08093BE282FD59AE09827F801AF +:103E9000908324E030E048CC27D591E09827D801E2 +:103EA0009C9324E030E040CC44E050E060E070E0DF +:103EB000CE0101960E94DE069091C128F801818111 +:103EC000803209F49EC1803709F02CCCF8012281A0 +:103ED0008981281327CC23818A81281323CC24812C +:103EE0008B8128131FCC25818C8128131BCC9083B8 +:103EF000B3CF62E070E0C80134D2882309F42DCF3B +:103F0000F80181818093C3288BE05FCE8091D42813 +:103F100028131DCFE091CD288091D1288095E813FA +:103F200016CF8091D528E81312CF8091CE2890919A +:103F3000D228909589130BCF9091D628891307CF5B +:103F40003091CF289091D3289095391300CF90913C +:103F5000D7283913FCCE4091D8289091D928909534 +:103F60004913F5CE9091DA284913F1CE9091DB28D0 +:103F700090954913ECCED8019C911196FC91119724 +:103F800012964C91129750E060E070E0BA0155270C +:103F900044275F2B492B13969C91792B90E0A0E04E +:103FA000B0E0DC01992788279E2B822BB32B209130 +:103FB000BE282B3009F4DDC02A3021F4840F951F70 +:103FC000A61FB71F8093CC28C92EDA2EEB2EFF2414 +:103FD000C092CD288D01222733270093CE284B2F66 +:103FE0005527662777274093CF28E82FE095E09361 +:103FF000D028EC2DE095E093D128E02FE095E093D8 +:10400000D228E42FE095E093D3288093D428C0925F +:10401000D5280093D6284093D72888E08093BE28DF +:1040200020E030E081CB62E070E0C8019AD18823C3 +:1040300009F432CFD80111968C918093C3285AE0AD +:10404000F52EF092BE2850D48F25F801808324E00D +:1040500030E06ACB62E070E0C80183D1882309F4C4 +:104060001BCF8091062981110FCFD80111966C9139 +:10407000B0E16B9FB001112440E150E08CEC98E27C +:104080000E94F60601CF62E070E0C8016AD1882381 +:1040900009F4D1C0D80111962C9111972C738C91F1 +:1040A000803609F4DCC08AE390E05C01B0E12B9F2C +:1040B000A00CB11C11246E01E7E0CE0ED11C64E00F +:1040C000C6010E943F068091C2287E01882309F420 +:1040D000B8C0FBE0EF0EF11C44E050E063E070E09C +:1040E000C7010E94DE0646E050E0B501CE01019610 +:1040F0000E94DE068F818093C42888858093C5281E +:1041000089858093C6288A858093C72860E470E0FB +:1041100084EC98E20DD48091C4288093C8288091C3 +:10412000C5288093C9288091C6288093CA28809189 +:10413000C7288093CB2860E270E088EC98E2F8D33F +:1041400087E08093BE288F81D8018C938885119653 +:104150008C931197898512968C9312978A85139662 +:104160008C93A601B701CE010196B4D120E230E0D4 +:10417000DBCA841B950BA60BB70B24CF62E070E063 +:10418000C801EFD08111ECCC81E0D8018C9324E000 +:1041900030E0CACA62E070E0C801E3D08823A1F32E +:1041A000F8016181F0E16F9FB001112440E150E01E +:1041B000C8010E94DE0660E170E0C801A3D020E9DA +:1041C00030E0B2CA8981F80180833A8131832B8142 +:1041D00022839C819383832782278927848328E2F3 +:1041E00030E0A2CAF80180833A8131839B819283B7 +:1041F0002C812383932798279227948328E230E009 +:1042000093CA898180833A8131832B8122839C8167 +:104210009383832782278927848328E230E084CA16 +:104220009BE0E90EF11C44E050E060E070E0C70163 +:104230000E94DE06EACB81E0F801808324E030E0D2 +:1042400073CA3BE0E30EF11C44E050E060E070E034 +:10425000C7010E94DE0647CF60E370E0B8CB80E381 +:1042600090E023CFCF93DF93EC018091C22881119E +:1042700009C044E050E060E070E0CE01DF91CF91F2 +:104280000C94DE0643E050E060E070E0CE010E9456 +:10429000DE0644E050E063E070E0CE010396DF917B +:1042A000CF910C94DE06CF93DF931F92CDB7DEB78C +:1042B0002091C22821111BC0FC01218130812327BC +:1042C0003281232733812327298344E050E060E0B3 +:1042D00070E00E94F60641E050E064E070E0CE013C +:1042E00001960E94F6060F90DF91CF9108954091BC +:1042F000052950E060E070E00E94F6060F90DF9123 +:10430000CF9108956115710541F1680F791FFC0186 +:1043100023E633E64191422750E1459FC001112435 +:10432000A42FA8278A2F90E0582F4427880F991F81 +:10433000880F991F880F991F48275927232F332744 +:1043400024273527A295AF702A27E617F70711F71C +:10435000922F832F908381830895FC0183E693E657 +:10436000F9CF61157105B1F1680F791FFC0123E6E2 +:1043700033E64191422750E1459FC0011124A42F0B +:10438000A8278A2F90E0582F4427880F991F880F5D +:10439000991F880F991F48275927232F3327242730 +:1043A0003527A295AF702A27E617F70711F7A9015D +:1043B0005527808190E08417950711F080E00895DB +:1043C000418150E0232F332781E042175307B9F38F +:1043D00080E0F5CFFC0143E650E023E633E6E9CF89 +:1043E000CF93B091DF28C091E0284091E128A091BF +:1043F000DC28F091DD28E091DE289C2F90712B2F96 +:10440000217E9227242F207292272A2F2479922707 +:104410002F2F237792272E2F2A739227392F329509 +:104420003F703927232F269526952327922F96957F +:1044300050E060E070E0BA01552744275C2B4B2B1D +:104440007695679557954795922791709813606870 +:10445000A093DF28F093E028E093E1284093DC2844 +:104460005093DD286093DE28CF910895CF93DF939A +:10447000C091DD289091DE28A92FAF70B0E0A05E3A +:10448000BF4DEC2FEF70F0E0E05EFF4DD0968C91C9 +:104490002089822BE091DC28E295EF70F0E0E05E6D +:1044A000FF4D2081822BC295CF70D0E0C05EDF4DE2 +:1044B00028A1822B92959F70A92FB0E0A05ABF4DE2 +:1044C0009C91892BE82FF0E0E059FF4D8081DF912E +:1044D000CF910895CF92DF92EF92FF920F931F93A7 +:1044E000CF93DF93FC01DB01EA01918180E0208121 +:1044F000822B80FD8DC130E081FD88C120E0969542 +:10450000879596958795432F406880FD342F422FDD +:10451000406881FD242F96958795969587953695C9 +:104520002695432F406880FD342F422F406881FD3F +:10453000242F969587959695879536952695432FA2 +:10454000406880FD342F422F406881FD242F9695CE +:1045500087959695879536952695432F406880FDDB +:10456000342F422F406881FD242F9695879596958C +:10457000879536952695432F406880FD342F422F2E +:10458000406881FD242F9695879596958795369559 +:104590002695432F406880FD342F422F406881FDCF +:1045A000242F969587959695879536952695532F22 +:1045B0005068422F406880FD352F3093DF2881FD01 +:1045C000242F2093DC28938180E02281822B80FDA0 +:1045D0001BC130E081FD16C120E096958795969528 +:1045E0008795432F406880FD342F422F406881FD1E +:1045F000242F969587959695879536952695432FE2 +:10460000406880FD342F422F406881FD242F96950D +:1046100087959695879536952695432F406880FD1A +:10462000342F422F406881FD242F969587959695CB +:10463000879536952695432F406880FD342F422F6D +:10464000406881FD242F9695879596958795369598 +:104650002695432F406880FD342F422F406881FD0E +:10466000242F969587959695879536952695432F71 +:10467000406880FD342F422F406881FD242F96959D +:1046800087959695879536952695532F5068422F96 +:10469000406880FD352F3093E02881FD242F209342 +:1046A000DD28958180E02481822B80FDA9C030E047 +:1046B00081FDA4C020E09695879596958795432F18 +:1046C000406880FD342F422F406881FD242F96954D +:1046D00087959695879536952695432F406880FD5A +:1046E000342F422F406881FD242F9695879596950B +:1046F000879536952695432F406880FD342F422FAD +:10470000406881FD242F96958795969587953695D7 +:104710002695432F406880FD342F422F406881FD4D +:10472000242F969587959695879536952695432FB0 +:10473000406880FD342F422F406881FD242F9695DC +:1047400087959695879536952695432F406880FDE9 +:10475000342F422F406881FD242F9695879596959A +:10476000879536952695532F5068422F406880FDD7 +:10477000352F3093E12881FD242F2093DE28898175 +:1047800011969C9111978927CA8012969C91129735 +:10479000C926D12CE12CF12C7601DD24CC24D82A99 +:1047A00088819C918927C82A8B8113969C9189279F +:1047B000F82A10E25BDE082F8C2D817011DEF69452 +:1047C000E794D794C794002311F06894F7F8115038 +:1047D00089F788818C25888389818D2589838A81C1 +:1047E0008E258A838B818F258B83DF91CF911F91BB +:1047F0000F91FF90EF90DF90CF90089520E45BCF72 +:1048000030E456CF20E4E9CE30E4E4CE20E477CEA5 +:1048100030E472CECF92DF92EF92FF92CF93FC0101 +:104820008181C280D12CE12CF12C7601DD24CC24B5 +:10483000D82A8081C82A8381F82AC0E217DEB7010E +:10484000A60141705527662777278427C9DDF6948E +:10485000E794D794C794C15089F7CF91FF90EF9018 +:10486000DF90CF900895CF93DF9300DEC82F80E0D4 +:10487000B7DDCC2309F436C0C0E8F8DDD82F80E0DE +:10488000AFDDC695D111C068F1DDD82F80E0A8DD7D +:10489000C695D111C068EADDD82F80E0A1DDC695AC +:1048A000D111C068E3DDD82F80E09ADDC695D11123 +:1048B000C068DCDDD82F80E093DDC695D111C068DB +:1048C000D5DDD82F80E08CDDC695D111C068CEDD56 +:1048D000D82F80E085DD8C2F8695D1118068DF91FF +:1048E000CF910895C0E0C9CFCF93DF93BFDDC82F2C +:1048F00080E076DDCC23D1F0C8E0B8DDD82F80E0B1 +:104900006FDDC695D111C860B1DDD82F80E068DDBC +:10491000C695D111C860AADDD82F80E061DD8C2F4B +:104920008695D1118860DF91CF910895C0E0E5CFE1 +:104930006F927F928F929F92AF92BF92CF92DF92AF +:10494000EF92FF920F931F93CF93DF933C01CB0124 +:104950000197672BC9F1F301A281C081B181D38195 +:104960002A2F2D72322F32953F703227232F269512 +:1049700026952327322F36954D2F50E060E070E0CA +:10498000742F6627552744275B2B4C2B6A2B769573 +:10499000679557954795322730FD7068C42F852E4F +:1049A000962EA72EBB24B82D6B01EE24FF24AC2D30 +:1049B000072F112722273327D02F019788F6F301DD +:1049C00040838182C2820383DF91CF911F910F9137 +:1049D000FF90EF90DF90CF90BF90AF909F908F901F +:1049E0007F906F9008950F931F93CF93DF93CDB770 +:1049F000DEB7EC97CDBFDEBF2BD38093412B28D3FE +:104A00008093422B25D38093432B22D38093442B36 +:104A10001FD38093452B1CD38093462B19D38093AF +:104A2000472B16D38093482B0E944B11B0D3882379 +:104A300089F09091412B8091422B853009F452C02E +:104A4000B0F0883009F4B3C0893009F498C08630DA +:104A500009F45AC09CD3882311F06DD350D3EC963F +:104A6000CDBFDEBFDF91CF911F910F9108958130AF +:104A700021F008F468C0833069F7992309F4A1C0D4 +:104A8000923041F78091432B811127C00091452B33 +:104A90001091462B0F70112701151105D9F2802FA7 +:104AA000F5D28091422B833009F4E6C0E0914B2B84 +:104AB000F0914C2B81818B7F818384E8809FF00172 +:104AC000819FF00D1124E157F44D1082E0914B2BA2 +:104AD000F0914C2B80818E7F808380E0D7D22BD3C6 +:104AE0008FD4B8CF9111B6CF1091432B1F7723D31A +:104AF00087D47FD38823E9F31093C304111176C0C0 +:104B000082E08093402BA6CF9058923008F0A2CF3D +:104B10008091432B9091442B8C3D23E0920709F424 +:104B200067C0AE01455C5F4F6091452B0E94D10488 +:104B30008C01009709F48ECFFED2B8018BAD9CADED +:104B4000C0D177D287CF903809F447C0923809F0A6 +:104B500081CF8091452B8F7099D2E0914B2BF091B2 +:104B60004C2B118112FB112710F980E08FD2E3D278 +:104B7000812F7DD280E07BD243D242D46BCF911182 +:104B800069CF8091432B823008F064CFD4D28091DA +:104B9000432B80933C2B34D480913C2B882309F405 +:104BA00061C084E08093402B0E94471153CF90381E +:104BB00009F050CFC0D280913C2B59D221D220D4C1 +:104BC00049CF9091432B913009F044CF91E083304D +:104BD00009F090E090933E2B80CF10913D2B809177 +:104BE0003E2B882309F4C3CF1260C1CF83E089CF65 +:104BF00083E08A838AE389835FB7F89482E08093B5 +:104C0000CA01E8E0F0E0E4911092CA01DE011396D7 +:104C100020E038E042E0EF708E2F90E0EA30B8F00C +:104C2000C7968D939D932F5F2C3199F04093CA01C5 +:104C3000E32FF0E0E4911092CA0120FFECCFE2955F +:104C4000EF703F5FEF708E2F90E0EA3048F7C0962C +:104C5000E8CF5FBF70D26AE370E0CE01019690D0DA +:104C6000E8D1F8CE8091C304882321F084E08093BA +:104C7000402B9ACF81E0FBCF42D22FCF0895CF9324 +:104C80008091402B811102C0CF910895C0914D2B8E +:104C900080E0FCD17CD2811103C08C2FCF91F6C172 +:104CA000A2DE8C2FCF91F2C1AF92BF92DF92EF9232 +:104CB000FF920F931F93CF93DF938C01EB017A0147 +:104CC000B5D3D82E811127C0E114F104A1F1F70169 +:104CD00020813181C21BD30B020F131F2097D9F003 +:104CE000A12CB12C8091492B90914A2BFC01EF5BB8 +:104CF000FF4F2081FC01E05CFF4F8081281790F17D +:104D00007FD1BDDFF701808191818A0D9B1D80835A +:104D1000918325E0D22E8D2DDF91CF911F910F91A0 +:104D2000FF90EF90DF90BF90AF90089569D1A7DF1B +:104D30007DD3811123C0209771F32091492B3091AD +:104D40004A2BF901EF5BFF4F9081F901E05CFF4FC7 +:104D50008081981758F7F80181918F0188D12197A8 +:104D600061F7D9CFF80181918F0181D1FFEFAF1A9F +:104D7000BF0ACA15DB0509F0B5CFCDCFD82ECBCFF2 +:104D8000CF92DF92EF92FF920F931F93CF93DF9317 +:104D90006C01EB0180914D2B806878D10091472BFD +:104DA0001091482B0C171D0720F0209709F483C0A1 +:104DB0008E01C0E00115110509F04AC0CC2309F4A9 +:104DC0005CC08091402B882309F455C0853009F4DC +:104DD0005DC0DDD181116DC0F3D181114EC009D20A +:104DE000882379F380914D2B87FD5AC02091492B60 +:104DF00030914A2BF901E05CFF4FE080F901EF5B55 +:104E0000FF4F8081F12CE81AF10801151105A9F076 +:104E100088E0E816F10488F4E60104C088E0E816AA +:104E2000F10459F0899123D16E01015011098FEFDE +:104E3000E81AF80A0115110589F7C1E088E0E816BB +:104E4000F10409F0C0E0DCD00115110509F4B6CF7A +:104E50008091402B882379F08530C1F098D1811161 +:104E600028C0AED1811109C0C4D18111BBCF8091BE +:104E7000402B8111F1CF82E00AC0A2D181111FC065 +:104E80008091402B8823B9F38530B9F783E0DF9117 +:104E9000CF911F910F91FF90EF90DF90CF900895E9 +:104EA000E091492BF0914A2BEF5BFF4FE080F12C12 +:104EB000ACCF81E0ECCFA4D000E010E07ACF80E06E +:104EC000E6CFCF92DF92EF92FF920F931F93CF9393 +:104ED000DF93D82EC92E8B0180914D2B8068D6D0C0 +:104EE000C091472BD091482BC017D10728F001154E +:104EF000110509F47FC0E801ED2CFC2CD12C209782 +:104F000009F045C0DD2009F457C08091402B88236B +:104F100009F450C0853009F458C039D1811168C0F6 +:104F20004FD1811149C065D1882379F380914D2BF0 +:104F300087FD55C08091492B90914A2BFC01E05C84 +:104F4000FF4F0081FC01EF5BFF4F808110E0081BE9 +:104F50001109209791F00830110520F00EC008309B +:104F6000110559F0F701849182D0FFEFEF1AFF0A83 +:104F700021970F5F1F4F209791F7DD24D3940830BE +:104F8000110509F0D12C3CD0209709F4BBCF8091BA +:104F9000402B882379F08530C1F0F9D0811128C0E9 +:104FA0000FD1811109C025D18111C0CF8091402B33 +:104FB0008111F1CF82E00AC003D181111FC080911D +:104FC000402B8823B9F38530B9F783E0DF91CF9187 +:104FD0001F910F91FF90EF90DF90CF900895E09197 +:104FE000492BF0914A2BEF5BFF4F008110E0B1CFCE +:104FF00081E0ECCF05D0C0E0D0E07ECF80E0E6CF0E +:10500000E0914B2BF0914C2BA091492BB0914A2B66 +:10501000AF5BBF4F8C9190E08283938380818D79C9 +:105020008083E091492BF0914A2BEF5BFF4F108278 +:105030000895E0914B2BF0914C2B80818D798083EA +:10504000E091492BF0914A2BEF5BFF4F10820895BE +:105050008091492B90914A2BFC01EF5BFF4F2081FF +:10506000DC01A20FB11D8C912F5F20830895209148 +:10507000492B30914A2BF901EF5BFF4F9081D90109 +:10508000A90FB11D8C939F5F9083089580934D2B42 +:10509000282F2F70622F70E094E8299F900111242F +:1050A000225B344D4091C6045091C70487FD12C065 +:1050B0002093492B30934A2BCB0182959295907F78 +:1050C0009827807F9827840F951F80934B2B909370 +:1050D0004C2B08952E5B3F4F2093492B30934A2B46 +:1050E00062957295707F7627607F7627685F7F4F25 +:1050F000640F751F60934B2B70934C2B0895E091B8 +:105100004B2BF0914C2B818184608183E0914B2B60 +:10511000F0914C2B8181807C803409F0089580913E +:105120004D2B8058B3DFE0914B2BF0914C2B8181BC +:1051300084608183089580914D2B8F77A7DFE09164 +:105140004B2BF0914C2B80818D788083E0914B2B01 +:10515000F0914C2B808181608083E091492BF0910C +:105160004A2BEF5BFF4F108280914D2B80688EDFC2 +:10517000E0914B2BF0914C2B808181608083E091FA +:10518000492BF0914A2BEF5BFF4F108208958091DD +:105190004D2B8F777BDFE0914B2BF0914C2B808157 +:1051A00084FF0CC02091492B30914A2B828193813E +:1051B000F901E05CFF4F808381E0089580E008956D +:1051C00080914D2B8F7762DFE0914B2BF0914C2B30 +:1051D000808185FF0CC02091492B30914A2B828120 +:1051E0009381F901E05CFF4F808381E0089580E0C6 +:1051F000089580914D2B806849DFE0914B2BF09111 +:105200004C2B80818695817008951F93CF93DF93F7 +:1052100000D0CDB7DEB7182F4A83698337DFE0911E +:105220004B2BF0914C2B1182E0914B2BF0914C2B9E +:105230004A81698117FD22C01082E0914B2BF091C9 +:105240004C2B6183E0914B2BF0914C2B12821382FB +:105250008091492B90914A2B8483958340E0FC01F7 +:10526000E05CFF4F4083FC01EF5BFF4F108281E069 +:105270000F900F90DF91CF911F91089582E080836E +:10528000E0914B2BF0914C2B6183E0914B2BF091F3 +:105290004C2B128213828091492B90914A2B84834C +:1052A0009583DDCFAF92BF92DF92EF92FF920F9383 +:1052B0001F93CF93DF9300D0CDB7DEB7E62E6623E2 +:1052C00009F44AC05C018C010C5F1F4FF12CD50121 +:1052D0005C915523C9F1D5011196ED91FC9112977E +:1052E000D80111974C91D8018C91823008F443C0B9 +:1052F00098E188E1E930F10550F028E030E090E0F5 +:105300009F5F220F331F2E173F07D0F3982B252FB7 +:105310002F7030E02630310564F5E134F10548F5B1 +:105320009F7E41112BC09064DE2E4E2F692F852F5A +:10533000805859839A8369DF9A8159814D2D692F4D +:10534000852F63DF8823A9F0F394B5E0AB0EB11C81 +:105350000B5F1F4FFE10BBCF81E00F900F90DF91CE +:10536000CF911F910F91FF90EF90DF90BF90AF9082 +:10537000089580E0F2CF98E088E0BCCF413029F07A +:105380009068442389F2DE2ED9CF906CDE2ED6CFE2 +:10539000E0ECF4E0A681B78119961C92A681B78152 +:1053A00011961C92A681B78159961C92A681B7814D +:1053B00051961C92A681B78199961C92A681B781BD +:1053C00091961C92A681B781D9961C92A681B7812D +:1053D000D1961C92A681B781A75BBF4F1C92A68174 +:1053E000B781AF5BBF4F1C92A681B781A75ABF4F51 +:1053F0001C920680F781E02DEF5AFF4F108208952E +:105400008091412B87FD08C0F4DE81110DC0809191 +:10541000402B8111F9CF0895D3DE811106C0809110 +:10542000402B8111F9CF0895EBCD03CE1F93CF937D +:10543000DF93E091C604F091C704E05AFF4FC081AA +:10544000D18114E680914D2B8078803831F1B8DE1F +:10545000811126C08091402B882339F1853051F18C +:10546000E0914B2BF0914C2B818182FD28C0E09183 +:10547000C604F091C704E05AFF4F80819181C8179C +:10548000D90701F3212F21501123F1F0EC01122F44 +:1054900080914D2B80788038D1F6ABDE8823D1F215 +:1054A00080E0DF91CF911F91089582E0DF91CF914D +:1054B0001F91089583E0DF91CF911F91089581E0BE +:1054C000DF91CF911F91089584E0DF91CF911F91DB +:1054D000089563D069D0E0ECF4E081818E7F818310 +:1054E00080818F77808310923F2B0895CF93DF9335 +:1054F000E0E4F0E014828481816084834ED054D053 +:10550000C0ECD4E088818F77888388818068888325 +:105510001092402B10923C2B10923E2B10923D2B60 +:1055200088818064888348E068E480E86EDE48E033 +:1055300068E480E06ADE888580648887898181608C +:105540008983DF91CF910895CF93DF933FB7F8948C +:10555000C0ECD1E022E02A87EAE1F0E0E491A0EC9F +:10556000B4E0DA96EC93DA97EBE1F0E0E491DB96C5 +:10557000EC93DB971A8687E69EE28E7F16968D93D4 +:105580009C93179785E18C9318962C933FBF81E0ED +:1055900080933F2BDF91CF91A9CFE0ECF4E08085A1 +:1055A0008370808711860895E0ECF4E08FEF8287A6 +:1055B000848708951F920F920FB60F9211242F9394 +:1055C0003F934F935F936F937F938F939F93AF938B +:1055D000BF93EF93FF938091CA0487FD4DC08091E4 +:1055E000CA0486FD41C08091CA0485FF0CC080E2D8 +:1055F0008093CA0480913C2B882371F184E08093CE +:10560000402B0E9441118091CA0484FF14C080E1A4 +:105610008093CA0482E08093402B10923C2B10921E +:10562000C304B6DE48E068E480E8EFDD48E068E403 +:1056300080E0EBDD23DBFF91EF91BF91AF919F9174 +:105640008F917F916F915F914F913F912F910F902B +:105650000FBE0F901F9018958091C304811115C043 +:1056600081E08093402BCDCF80E48093CA041092D8 +:10567000402B0E944411B7CF8091C80487FFAFCF61 +:1056800080E88093CA04FADAAACF83E0EACFCF9306 +:10569000DF93EC014096FC018BE0DF011D928A95BF +:1056A000E9F782E08C83898783E08E8761E0CE0111 +:1056B0000196F8DD811104C080E0DF91CF9108955B +:1056C00061E0CE010696EEDD8823B1F361E0CE0104 +:1056D0000B96DF91CF91E6CDCF93DF93D62FC72FD7 +:1056E0002091402B243021F082E0DF91CF9108956A +:1056F000FC014489558966897789452B462B472BC0 +:1057000099F38181C3DCAD2FBC2FFD0101900020F6 +:10571000E9F7BF01615071096A1B7B0B40E050E063 +:105720008D2F9C2FDF91CF91BFCAEF92FF920F93E5 +:105730001F93CF93DF93EB017A012091402B24300C +:1057400041F082E0DF91CF911F910F91FF90EF9098 +:105750000895FC010489158926893789012B022BBC +:10576000032B79F3818192DC40E050E0B701CE0158 +:10577000DF91CF911F910F91FF90EF9095CA0F93FA +:105780001F93CF93DF931F92CDB7DEB72091402BAD +:10579000243039F082E00F90DF91CF911F910F916B +:1057A0000895FC010489158926893789012B022B6C +:1057B000032B81F38181698369DC2091492B30912E +:1057C0004A2BF901EF5BFF4F9081F901E05CFF4F3D +:1057D00080816981981730F0698312DC27DE698146 +:1057E0008111D9CF862F43DC80E0D5CF0F931F9353 +:1057F000CF93DF931F92CDB7DEB72091402B24309B +:1058000039F082E00F90DF91CF911F910F910895B1 +:10581000FC014489558966897789452B462B472B9E +:1058200081F3818133DC80914D2B2091492B309184 +:105830004A2BF90187FD1DC0E05CFF4F8081F90113 +:10584000EF5BFF4F408190E0841B9109892B11F49D +:1058500080E0D8CF0081F901E05CFF4F1081D0DB00 +:105860000117B0F3E3DD8111CDCF8983C9DB8981D5 +:10587000C9CFEF5BFF4F808190E0E8CFCF93DF93FC +:10588000EC018091402B843019F0DF91CF91089585 +:105890004C895D896E897F89452B462B472BA9F35F +:1058A0008981F4DBA6DC882381F3CE01DF91CF91DF +:1058B0009DCFCF93DF932091402B2430C1F5FC0185 +:1058C0004489558966897789452B462B472B79F181 +:1058D0008681DCDB75DC882351F180914D2B87FDBF +:1058E0003DC08091492B90914A2BFC01E05CFF4F19 +:1058F0002081FC01EF5BFF4F408130E0241B310928 +:10590000232BD9F4CFEFDFEF20914D2B27FD23C0C0 +:10591000DC01A05CBF4F8C91208190E0821B91093B +:10592000892B39F486DBCE01DF91CF910895CFEF3B +:10593000DFEFCE01DF91CF9108958ADBC82FD0E051 +:105940008091492B90914A2BFC01EF5BFF4F2091F6 +:105950004D2B27FFDDCF808190E0E2CF8091492B56 +:1059600090914A2BFC01EF5BFF4F208130E0C8CFC4 +:105970000895FF920F931F93CF93DF93EC0107DC01 +:10598000882349F0888190E02091452B3091462B67 +:105990002817390731F0DF91CF911F910F91FF90B8 +:1059A00008958091422B813209F44BC008F033C036 +:1059B000803289F78091412B813269F7BCDB04C0CA +:1059C0008091402B882339F3FBDB8823C9F340DB2C +:1059D000082F3EDB182F3CDBF82E3ADB4F2D50E032 +:1059E00060E070E0BA0155274427782B402B512BFB +:1059F0004C8B5D8B6E8B7F8B2BDB888F29DB898FAC +:105A000027DB8A8F16DBFCDCCE01DF91CF911F9163 +:105A10000F91FF90ADCF823209F434C0833209F088 +:105A2000BACF8091412B813209F0B5CF84DBE8DC1D +:105A30006091432BCE01DF91CF911F910F91FF9089 +:105A400097CF8091412B813A09F0A5CF74DBD1DB50 +:105A50008823E9F38C89FD880E891F8908DB8F2D47 +:105A600006DB802F04DB812F02DB888D00DB898D34 +:105A7000FEDA8A8DFCDAC4DADF91CF911F910F91A3 +:105A8000FF90BECC8091412B813209F084CF53DB53 +:105A9000B7DC8091432B9091442B888B998BCE015E +:105AA000DF91CF911F910F91FF9062CFB7FF04C09C +:105AB00003D0821B930B089509D0A59F900DB49F2E +:105AC000900DA49F800D911D11240895A29FB001F7 +:105AD000B39FC001A39F01D0B29F700D811D1124FF +:105AE000911D08958F929F92AF92BF92CF92DF92B5 +:105AF000EF92FF92CF93DF93EC01688179818A81E5 +:105B00009B81611571058105910521F464E279EDB0 +:105B10008BE597E02DE133EF41E050E048D34901B8 +:105B20005A019B01AC01A7EAB1E4C6DF6B017C011D +:105B3000ACEEB4EFA5019401BBDFC60ED71EE81E84 +:105B4000F91EF7FE06C081E0C81AD108E10880E816 +:105B5000F80AC882D982EA82FB82E894D7F8EE2458 +:105B6000FF24C601DF91CF91FF90EF90DF90CF909F +:105B7000BF90AF909F908F900895B4CF8CE190E24A +:105B8000B1CFA0E0B0E080931C2090931D20A093A3 +:105B90001E20B0931F200895FB01DC0102C0059078 +:105BA0000D9241505040D8F70895FB01DC018D91D2 +:105BB000059080190110D9F3990B0895FB01DC01C0 +:105BC0000D900020E9F711974150504028F00590C2 +:105BD00000200D92C9F708951C920895FB01DC0185 +:105BE0004150504048F005900D920020C9F701C087 +:105BF0001D9241505040E0F70895FB01DC0102C0C6 +:105C000001900D9241505040D8F70895AEE0B0E0B9 +:105C1000EBE0FEE2F5C20D891E898F89988D2EE09A +:105C20002C8309831A8397FF02C080E090E80197D4 +:105C30008D839E83CE014B96AC01698D7A8DCE010A +:105C4000019611D04D815E8157FD0AC02F813885A4 +:105C5000421753070CF49A01F801E20FF31F108268 +:105C60002E96E4E0E6C2ACE0B0E0E8E3FEE2BAC2C1 +:105C70007C016B018A01FC0116821782838181FFFE +:105C8000B9C188248394912C8C0E9D1EF7019381B9 +:105C9000F60193FD859193FF81916F01882309F4AB +:105CA000A5C1853239F493FD859193FF81916F01F0 +:105CB000853221F4B70190E0F0D1E8CF512C312C9E +:105CC00020E02032A8F48B3261F028F4803251F0C9 +:105CD000833271F40BC08D3239F0803349F4216086 +:105CE00028C02260246025C0286023C0206121C014 +:105CF00027FD27C0382F30533A3078F426FF06C0EE +:105D0000FAE05F9E300D1124532E13C08AE0389EB6 +:105D1000300D1124332E20620CC08E3221F426FD6A +:105D200065C1206406C08C3611F4206802C0883634 +:105D300041F4F60193FD859193FF81916F018111EB +:105D4000C0CF982F9554933018F09052933028F488 +:105D50000C5F1F4FFFE3F9830DC0833631F08337AB +:105D600071F0833509F05AC022C0F801808189831F +:105D70000E5F1F4F44244394512C540114C038012A +:105D8000F2E06F0E711CF801A080B18026FF03C005 +:105D9000652D70E002C06FEF7FEFC5012C8772D1D7 +:105DA0002C0183012C856FE7262E222217C0380193 +:105DB000F2E06F0E711CF801A080B18026FF03C0D5 +:105DC000652D70E002C06FEF7FEFC5012C874FD1CA +:105DD0002C012C8550E8252E222A830123FC1AC091 +:105DE00005C0B70180E290E058D13A94832D90E04D +:105DF00048165906B0F30EC0F50127FC859127FE21 +:105E000081915F01B70190E048D131103A94F1E0FF +:105E10004F1A51084114510479F7E5C0843611F046 +:105E2000893639F5F80127FF07C0608171818281C9 +:105E300093810C5F1F4F08C060817181882777FDB7 +:105E40008095982F0E5F1F4F4FE6B42EB22297FF1A +:105E500009C090958095709561957F4F8F4F9F4FAA +:105E6000F0E8BF2A2AE030E0A40143D1A82EA81808 +:105E700042C0853731F43FEEB32EB2222AE030E043 +:105E800024C099EFB92EB2228F36B9F020F48835AC +:105E900009F0ACC00DC0803721F0883709F0A6C0EA +:105EA00002C020E1B22AB4FE0BC084E0B82A08C0C8 +:105EB00024FF09C0E6E0BE2A06C028E030E005C0A5 +:105EC00020E130E002C020E132E0F801B7FE07C077 +:105ED00060817181828193810C5F1F4F06C0608158 +:105EE000718180E090E00E5F1F4FA40102D1A82EC7 +:105EF000A818FFE7BF22B6FE0BC02B2D2E7FA514DE +:105F000050F4B4FE0AC0B2FC08C02B2D2E7E05C092 +:105F10007A2C2B2D03C07A2C01C0752C24FF0DC0C8 +:105F2000FE01EA0DF11D8081803311F4297E09C044 +:105F300022FF06C07394739404C0822F867809F000 +:105F4000739423FD13C020FF0EC05A2C731458F411 +:105F5000530C5718732C07C0B70180E290E02C87D0 +:105F60009CD073942C857314B8F304C0731410F48C +:105F7000371801C0312C24FF11C0B70180E390E035 +:105F80002C878BD02C8522FF1CC021FF03C088E505 +:105F900090E002C088E790E0B7010CC0822F8678BD +:105FA00081F021FD02C080E201C08BE227FD8DE27D +:105FB000B70190E072D005C0B70180E390E06DD0EA +:105FC0005A94A514C8F3AA94F401EA0DF11DB7017F +:105FD000808190E062D0A110F6CF05C0B70180E2C9 +:105FE00090E05BD03A943110F9CF50CEF701268182 +:105FF000378102C02FEF3FEFC9012C96E2E10BC1C0 +:10600000E0ECF1E0A785A7FDFDCFA485A860A487FB +:106010006050704FF2CDDC01CB0102C02D9105D054 +:1060200041505040D8F70895262FE0ECF1E0378535 +:1060300037FDFDCF3485377F3487378531FF09C081 +:1060400036E3328738ED34BF31E03387378537FDAB +:10605000FDCF33E33287808391831282248325E34B +:10606000228728ED31E024BF338701960895FC0193 +:106070000590615070400110D8F7809590958E0F73 +:106080009F1F0895FC016150704001900110D8F7E6 +:10609000809590958E0F9F1F08950F931F93CF9318 +:1060A000DF938C01EB018B8181FD03C00FEF1FEFAC +:1060B0001AC082FF0DC02E813F818C819D812817DF +:1060C000390764F4E881F9810193E883F98306C014 +:1060D000E885F985802F0995892B41F78E819F816D +:1060E00001968E839F83C801DF91CF911F910F91FD +:1060F0000895FA01AA27283051F1203181F1E8945E +:106100006F936E7F6E5F7F4F8F4F9F4FAF4FB1E0AA +:106110003ED0B4E03CD0670F781F891F9A1FA11DA5 +:10612000680F791F8A1F911DA11D6A0F711D811DA6 +:10613000911DA11D20D009F468943F912AE0269F6B +:1061400011243019305D3193DEF6CF010895462FCA +:106150004770405D4193B3E00FD0C9F7F6CF462FAB +:106160004F70405D4A3318F0495D31FD4052419314 +:1061700002D0A9F7EACFB4E0A695979587957795D1 +:106180006795BA95C9F700976105710508959B0158 +:10619000AC010A2E06945795479537952795BA95E1 +:1061A000C9F7620F731F841F951FA01D0895052E48 +:1061B00097FB16F4009406D057FD0CD044D007FC92 +:1061C00009D07EF490958095709561957F4F8F4FA3 +:1061D0009F4F089550954095309521953F4F4F4FD3 +:1061E0005F4F08952F923F924F925F926F927F92EE +:1061F0008F929F92AF92BF92CF92DF92EF92FF92D7 +:106200000F931F93CF93DF93CDB7DEB7CA1BDB0B82 +:10621000CDBFDEBF09942A88398848885F846E84A0 +:106220007D848C849B84AA84B984C884DF80EE80BA +:10623000FD800C811B81AA81B981CE0FD11DCDBFFC +:10624000DEBFED010895A1E21A2EAA1BBB1BFD01C2 +:106250000DC0AA1FBB1FEE1FFF1FA217B307E40745 +:10626000F50720F0A21BB30BE40BF50B661F771F9D +:10627000881F991F1A9469F760957095809590957D +:0E6280009B01AC01BD01CF010895F894FFCF42 +:10628E0000831000000104100000018208000001CC +:10629E0000000000000000000000001401000000DB +:1062AE0000010101000000010000010001010001D8 +:1062BE0000000002020000020002020202000002C0 +:1062CE0000000004040000040004040404000004A0 +:1062DE000008080800000008000008000808000870 +:1062EE000000001010000010001010101000001020 +:1062FE00000100010000000000000001000101018A +:10630E000101010001000100000001010001010175 +:02631E0000007D :00000001FF diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.lss b/Firmware/Chameleon-Mini/Chameleon-Mini.lss index 40fcbce..3ea4573 100644 --- a/Firmware/Chameleon-Mini/Chameleon-Mini.lss +++ b/Firmware/Chameleon-Mini/Chameleon-Mini.lss @@ -1,15474 +1,20098 @@ - -Chameleon-Mini.elf: file format elf32-avr - -Sections: -Idx Name Size VMA LMA File off Algn - 0 .text 00004e9a 00000000 00000000 000000b4 2**1 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .data 00000092 00802000 00004e9a 00004f4e 2**0 - CONTENTS, ALLOC, LOAD, DATA - 2 .bss 00000a0b 00802092 00802092 00004fe0 2**0 - ALLOC - 3 .eeprom 00000013 00810000 00810000 00004fe0 2**0 - CONTENTS, ALLOC, LOAD, DATA - 4 .comment 0000005c 00000000 00000000 00004ff3 2**0 - CONTENTS, READONLY - 5 .debug_aranges 00000b50 00000000 00000000 0000504f 2**0 - CONTENTS, READONLY, DEBUGGING - 6 .debug_info 000189de 00000000 00000000 00005b9f 2**0 - CONTENTS, READONLY, DEBUGGING - 7 .debug_abbrev 0000553d 00000000 00000000 0001e57d 2**0 - CONTENTS, READONLY, DEBUGGING - 8 .debug_line 0000a17f 00000000 00000000 00023aba 2**0 - CONTENTS, READONLY, DEBUGGING - 9 .debug_frame 00001d28 00000000 00000000 0002dc3c 2**2 - CONTENTS, READONLY, DEBUGGING - 10 .debug_str 000076e1 00000000 00000000 0002f964 2**0 - CONTENTS, READONLY, DEBUGGING - 11 .debug_loc 0000c84e 00000000 00000000 00037045 2**0 - CONTENTS, READONLY, DEBUGGING - 12 .debug_ranges 000016c8 00000000 00000000 00043893 2**0 - CONTENTS, READONLY, DEBUGGING - -Disassembly of section .text: - -00000000 <__vectors>: - 0: 7b c3 rjmp .+1782 ; 0x6f8 <__ctors_end> - 2: 00 00 nop - 4: 95 c3 rjmp .+1834 ; 0x730 <__bad_interrupt> - 6: 00 00 nop - 8: 93 c3 rjmp .+1830 ; 0x730 <__bad_interrupt> - a: 00 00 nop - c: 91 c3 rjmp .+1826 ; 0x730 <__bad_interrupt> - e: 00 00 nop - 10: 8f c3 rjmp .+1822 ; 0x730 <__bad_interrupt> - 12: 00 00 nop - 14: 8d c3 rjmp .+1818 ; 0x730 <__bad_interrupt> - 16: 00 00 nop - 18: 8b c3 rjmp .+1814 ; 0x730 <__bad_interrupt> - 1a: 00 00 nop - 1c: 89 c3 rjmp .+1810 ; 0x730 <__bad_interrupt> - 1e: 00 00 nop - 20: 87 c3 rjmp .+1806 ; 0x730 <__bad_interrupt> - 22: 00 00 nop - 24: 85 c3 rjmp .+1802 ; 0x730 <__bad_interrupt> - 26: 00 00 nop - 28: 83 c3 rjmp .+1798 ; 0x730 <__bad_interrupt> - 2a: 00 00 nop - 2c: 81 c3 rjmp .+1794 ; 0x730 <__bad_interrupt> - 2e: 00 00 nop - 30: 7f c3 rjmp .+1790 ; 0x730 <__bad_interrupt> - 32: 00 00 nop - 34: 7d c3 rjmp .+1786 ; 0x730 <__bad_interrupt> - 36: 00 00 nop - 38: 7b c3 rjmp .+1782 ; 0x730 <__bad_interrupt> - 3a: 00 00 nop - 3c: 79 c3 rjmp .+1778 ; 0x730 <__bad_interrupt> - 3e: 00 00 nop - 40: 77 c3 rjmp .+1774 ; 0x730 <__bad_interrupt> - 42: 00 00 nop - 44: 75 c3 rjmp .+1770 ; 0x730 <__bad_interrupt> - 46: 00 00 nop - 48: 73 c3 rjmp .+1766 ; 0x730 <__bad_interrupt> - 4a: 00 00 nop - 4c: 71 c3 rjmp .+1762 ; 0x730 <__bad_interrupt> - 4e: 00 00 nop - 50: 6f c3 rjmp .+1758 ; 0x730 <__bad_interrupt> - 52: 00 00 nop - 54: 6d c3 rjmp .+1754 ; 0x730 <__bad_interrupt> - 56: 00 00 nop - 58: 0c 94 ab 12 jmp 0x2556 ; 0x2556 <__vector_22> - 5c: 69 c3 rjmp .+1746 ; 0x730 <__bad_interrupt> - 5e: 00 00 nop - 60: 67 c3 rjmp .+1742 ; 0x730 <__bad_interrupt> - 62: 00 00 nop - 64: 65 c3 rjmp .+1738 ; 0x730 <__bad_interrupt> - 66: 00 00 nop - 68: 63 c3 rjmp .+1734 ; 0x730 <__bad_interrupt> - 6a: 00 00 nop - 6c: 61 c3 rjmp .+1730 ; 0x730 <__bad_interrupt> - 6e: 00 00 nop - 70: 5f c3 rjmp .+1726 ; 0x730 <__bad_interrupt> - 72: 00 00 nop - 74: 5d c3 rjmp .+1722 ; 0x730 <__bad_interrupt> - 76: 00 00 nop - 78: 5b c3 rjmp .+1718 ; 0x730 <__bad_interrupt> - 7a: 00 00 nop - 7c: 59 c3 rjmp .+1714 ; 0x730 <__bad_interrupt> - 7e: 00 00 nop - 80: 57 c3 rjmp .+1710 ; 0x730 <__bad_interrupt> - 82: 00 00 nop - 84: 55 c3 rjmp .+1706 ; 0x730 <__bad_interrupt> - 86: 00 00 nop - 88: 0c 94 67 12 jmp 0x24ce ; 0x24ce <__vector_34> - 8c: 51 c3 rjmp .+1698 ; 0x730 <__bad_interrupt> - 8e: 00 00 nop - 90: 4f c3 rjmp .+1694 ; 0x730 <__bad_interrupt> - 92: 00 00 nop - 94: 4d c3 rjmp .+1690 ; 0x730 <__bad_interrupt> - 96: 00 00 nop - 98: 4b c3 rjmp .+1686 ; 0x730 <__bad_interrupt> - 9a: 00 00 nop - 9c: 49 c3 rjmp .+1682 ; 0x730 <__bad_interrupt> - 9e: 00 00 nop - a0: 47 c3 rjmp .+1678 ; 0x730 <__bad_interrupt> - a2: 00 00 nop - a4: 45 c3 rjmp .+1674 ; 0x730 <__bad_interrupt> - a6: 00 00 nop - a8: 43 c3 rjmp .+1670 ; 0x730 <__bad_interrupt> - aa: 00 00 nop - ac: 41 c3 rjmp .+1666 ; 0x730 <__bad_interrupt> - ae: 00 00 nop - b0: 3f c3 rjmp .+1662 ; 0x730 <__bad_interrupt> - b2: 00 00 nop - b4: 3d c3 rjmp .+1658 ; 0x730 <__bad_interrupt> - b6: 00 00 nop - b8: 3b c3 rjmp .+1654 ; 0x730 <__bad_interrupt> - ba: 00 00 nop - bc: 39 c3 rjmp .+1650 ; 0x730 <__bad_interrupt> - be: 00 00 nop - c0: 37 c3 rjmp .+1646 ; 0x730 <__bad_interrupt> - c2: 00 00 nop - c4: 35 c3 rjmp .+1642 ; 0x730 <__bad_interrupt> - c6: 00 00 nop - c8: 33 c3 rjmp .+1638 ; 0x730 <__bad_interrupt> - ca: 00 00 nop - cc: 31 c3 rjmp .+1634 ; 0x730 <__bad_interrupt> - ce: 00 00 nop - d0: 2f c3 rjmp .+1630 ; 0x730 <__bad_interrupt> - d2: 00 00 nop - d4: 2d c3 rjmp .+1626 ; 0x730 <__bad_interrupt> - d6: 00 00 nop - d8: 2b c3 rjmp .+1622 ; 0x730 <__bad_interrupt> - da: 00 00 nop - dc: 29 c3 rjmp .+1618 ; 0x730 <__bad_interrupt> - de: 00 00 nop - e0: 27 c3 rjmp .+1614 ; 0x730 <__bad_interrupt> - e2: 00 00 nop - e4: 25 c3 rjmp .+1610 ; 0x730 <__bad_interrupt> - e6: 00 00 nop - e8: 23 c3 rjmp .+1606 ; 0x730 <__bad_interrupt> - ea: 00 00 nop - ec: 21 c3 rjmp .+1602 ; 0x730 <__bad_interrupt> - ee: 00 00 nop - f0: 1f c3 rjmp .+1598 ; 0x730 <__bad_interrupt> - f2: 00 00 nop - f4: 1d c3 rjmp .+1594 ; 0x730 <__bad_interrupt> - f6: 00 00 nop - f8: 1b c3 rjmp .+1590 ; 0x730 <__bad_interrupt> - fa: 00 00 nop - fc: 19 c3 rjmp .+1586 ; 0x730 <__bad_interrupt> - fe: 00 00 nop - 100: 17 c3 rjmp .+1582 ; 0x730 <__bad_interrupt> - 102: 00 00 nop - 104: 15 c3 rjmp .+1578 ; 0x730 <__bad_interrupt> - 106: 00 00 nop - 108: 13 c3 rjmp .+1574 ; 0x730 <__bad_interrupt> - 10a: 00 00 nop - 10c: 11 c3 rjmp .+1570 ; 0x730 <__bad_interrupt> - 10e: 00 00 nop - 110: 0f c3 rjmp .+1566 ; 0x730 <__bad_interrupt> - 112: 00 00 nop - 114: 0d c3 rjmp .+1562 ; 0x730 <__bad_interrupt> - 116: 00 00 nop - 118: 0b c3 rjmp .+1558 ; 0x730 <__bad_interrupt> - 11a: 00 00 nop - 11c: 09 c3 rjmp .+1554 ; 0x730 <__bad_interrupt> - 11e: 00 00 nop - 120: 07 c3 rjmp .+1550 ; 0x730 <__bad_interrupt> - 122: 00 00 nop - 124: 05 c3 rjmp .+1546 ; 0x730 <__bad_interrupt> - 126: 00 00 nop - 128: 03 c3 rjmp .+1542 ; 0x730 <__bad_interrupt> - 12a: 00 00 nop - 12c: 01 c3 rjmp .+1538 ; 0x730 <__bad_interrupt> - 12e: 00 00 nop - 130: ff c2 rjmp .+1534 ; 0x730 <__bad_interrupt> - 132: 00 00 nop - 134: fd c2 rjmp .+1530 ; 0x730 <__bad_interrupt> - 136: 00 00 nop - 138: fb c2 rjmp .+1526 ; 0x730 <__bad_interrupt> - 13a: 00 00 nop - 13c: f9 c2 rjmp .+1522 ; 0x730 <__bad_interrupt> - 13e: 00 00 nop - 140: f7 c2 rjmp .+1518 ; 0x730 <__bad_interrupt> - 142: 00 00 nop - 144: f5 c2 rjmp .+1514 ; 0x730 <__bad_interrupt> - 146: 00 00 nop - 148: f3 c2 rjmp .+1510 ; 0x730 <__bad_interrupt> - 14a: 00 00 nop - 14c: 0c 94 65 13 jmp 0x26ca ; 0x26ca <__vector_83> - 150: ef c2 rjmp .+1502 ; 0x730 <__bad_interrupt> - 152: 00 00 nop - 154: ed c2 rjmp .+1498 ; 0x730 <__bad_interrupt> - 156: 00 00 nop - 158: eb c2 rjmp .+1494 ; 0x730 <__bad_interrupt> - 15a: 00 00 nop - 15c: e9 c2 rjmp .+1490 ; 0x730 <__bad_interrupt> - 15e: 00 00 nop - 160: e7 c2 rjmp .+1486 ; 0x730 <__bad_interrupt> - 162: 00 00 nop - 164: e5 c2 rjmp .+1482 ; 0x730 <__bad_interrupt> - 166: 00 00 nop - 168: e3 c2 rjmp .+1478 ; 0x730 <__bad_interrupt> - 16a: 00 00 nop - 16c: e1 c2 rjmp .+1474 ; 0x730 <__bad_interrupt> - 16e: 00 00 nop - 170: df c2 rjmp .+1470 ; 0x730 <__bad_interrupt> - 172: 00 00 nop - 174: dd c2 rjmp .+1466 ; 0x730 <__bad_interrupt> - 176: 00 00 nop - 178: db c2 rjmp .+1462 ; 0x730 <__bad_interrupt> - 17a: 00 00 nop - 17c: d9 c2 rjmp .+1458 ; 0x730 <__bad_interrupt> - 17e: 00 00 nop - 180: d7 c2 rjmp .+1454 ; 0x730 <__bad_interrupt> - 182: 00 00 nop - 184: d5 c2 rjmp .+1450 ; 0x730 <__bad_interrupt> - 186: 00 00 nop - 188: d3 c2 rjmp .+1446 ; 0x730 <__bad_interrupt> - 18a: 00 00 nop - 18c: d1 c2 rjmp .+1442 ; 0x730 <__bad_interrupt> - 18e: 00 00 nop - 190: cf c2 rjmp .+1438 ; 0x730 <__bad_interrupt> - 192: 00 00 nop - 194: cd c2 rjmp .+1434 ; 0x730 <__bad_interrupt> - 196: 00 00 nop - 198: cb c2 rjmp .+1430 ; 0x730 <__bad_interrupt> - 19a: 00 00 nop - 19c: c9 c2 rjmp .+1426 ; 0x730 <__bad_interrupt> - 19e: 00 00 nop - 1a0: c7 c2 rjmp .+1422 ; 0x730 <__bad_interrupt> - 1a2: 00 00 nop - 1a4: c5 c2 rjmp .+1418 ; 0x730 <__bad_interrupt> - 1a6: 00 00 nop - 1a8: c3 c2 rjmp .+1414 ; 0x730 <__bad_interrupt> - 1aa: 00 00 nop - 1ac: c1 c2 rjmp .+1410 ; 0x730 <__bad_interrupt> - 1ae: 00 00 nop - 1b0: bf c2 rjmp .+1406 ; 0x730 <__bad_interrupt> - 1b2: 00 00 nop - 1b4: bd c2 rjmp .+1402 ; 0x730 <__bad_interrupt> - 1b6: 00 00 nop - 1b8: bb c2 rjmp .+1398 ; 0x730 <__bad_interrupt> - 1ba: 00 00 nop - 1bc: b9 c2 rjmp .+1394 ; 0x730 <__bad_interrupt> - 1be: 00 00 nop - 1c0: b7 c2 rjmp .+1390 ; 0x730 <__bad_interrupt> - 1c2: 00 00 nop - 1c4: b5 c2 rjmp .+1386 ; 0x730 <__bad_interrupt> - 1c6: 00 00 nop - 1c8: b3 c2 rjmp .+1382 ; 0x730 <__bad_interrupt> - 1ca: 00 00 nop - 1cc: b1 c2 rjmp .+1378 ; 0x730 <__bad_interrupt> - 1ce: 00 00 nop - 1d0: af c2 rjmp .+1374 ; 0x730 <__bad_interrupt> - 1d2: 00 00 nop - 1d4: ad c2 rjmp .+1370 ; 0x730 <__bad_interrupt> - 1d6: 00 00 nop - 1d8: ab c2 rjmp .+1366 ; 0x730 <__bad_interrupt> - 1da: 00 00 nop - 1dc: a9 c2 rjmp .+1362 ; 0x730 <__bad_interrupt> - 1de: 00 00 nop - 1e0: a7 c2 rjmp .+1358 ; 0x730 <__bad_interrupt> - 1e2: 00 00 nop - 1e4: a5 c2 rjmp .+1354 ; 0x730 <__bad_interrupt> - 1e6: 00 00 nop - 1e8: a3 c2 rjmp .+1350 ; 0x730 <__bad_interrupt> - 1ea: 00 00 nop - 1ec: a1 c2 rjmp .+1346 ; 0x730 <__bad_interrupt> - 1ee: 00 00 nop - 1f0: 9f c2 rjmp .+1342 ; 0x730 <__bad_interrupt> - 1f2: 00 00 nop - 1f4: 0c 94 03 21 jmp 0x4206 ; 0x4206 <__vector_125> - 1f8: 9b c2 rjmp .+1334 ; 0x730 <__bad_interrupt> - 1fa: 00 00 nop - 1fc: 66 0f add r22, r22 - 1fe: 66 0f add r22, r22 - 200: 4e 0f add r20, r30 - 202: 57 0f add r21, r23 - 204: 70 0f add r23, r16 - 206: 24 0f add r18, r20 - 208: 3e 0f add r19, r30 - 20a: 41 0f add r20, r17 - 20c: 38 0f add r19, r24 - 20e: 29 14 cp r2, r9 - 210: b5 13 cpse r27, r21 - 212: be 13 cpse r27, r30 - 214: c5 13 cpse r28, r21 - 216: d3 13 cpse r29, r19 - 218: de 13 cpse r29, r30 - 21a: 03 14 cp r0, r3 - 21c: 7d 13 cpse r23, r29 - 21e: 11 14 cp r1, r1 - 220: 18 14 cp r1, r8 - 222: 1f 14 cp r1, r15 - 224: 81 15 cp r24, r1 - 226: 81 15 cp r24, r1 - 228: 95 15 cp r25, r5 - 22a: 50 16 cp r5, r16 - 22c: a7 15 cp r26, r7 - 22e: c5 15 cp r28, r5 - 230: 45 15 cp r20, r5 - 232: 69 15 cp r22, r9 - 234: 69 15 cp r22, r9 - 236: 69 15 cp r22, r9 - 238: 0e 1c adc r0, r14 - 23a: db 1b sub r29, r27 - 23c: 7a 1b sub r23, r26 - 23e: db 1b sub r29, r27 - 240: 7a 1b sub r23, r26 - 242: c9 1b sub r28, r25 - 244: ab 1b sub r26, r27 - 246: 7a 1b sub r23, r26 - 248: a2 1b sub r26, r18 - 24a: 8b 1b sub r24, r27 - -0000024c : - 24c: 1c 03 4c 00 55 00 46 00 41 00 20 00 43 00 44 00 ..L.U.F.A. .C.D. - 25c: 43 00 20 00 44 00 65 00 6d 00 6f 00 00 00 C. .D.e.m.o... - -0000026a : - 26a: 18 03 44 00 65 00 61 00 6e 00 20 00 43 00 61 00 ..D.e.a.n. .C.a. - 27a: 6d 00 65 00 72 00 61 00 00 00 m.e.r.a... - -00000284 : - 284: 04 03 09 04 .... - -00000288 : - 288: 09 02 3e 00 02 01 00 c0 32 09 04 00 00 01 02 02 ..>.....2....... - 298: 01 00 05 24 00 10 01 04 24 02 06 05 24 06 00 01 ...$....$...$... - 2a8: 07 05 82 03 08 00 ff 09 04 01 00 02 0a 00 00 00 ................ - 2b8: 07 05 04 02 10 00 05 07 05 83 02 10 00 05 .............. - -000002c6 : - 2c6: 12 01 10 01 02 00 00 08 eb 03 44 20 01 00 01 02 ..........D .... - 2d6: dc 01 .. - -000002d8 : - 2d8: 00 4e 4f 4e 45 00 00 00 00 00 00 00 00 00 00 00 .NONE........... - 2e8: 00 89 04 8a 04 8b 04 8c 04 8d 04 8e 04 91 04 92 ................ - 2f8: 04 00 00 00 01 01 4d 46 5f 43 4c 41 53 53 49 43 ......MF_CLASSIC - 308: 5f 31 4b 00 00 00 43 14 7a 14 f5 14 0f 15 13 15 _1K...C.z....... - 318: 14 15 e7 18 ed 18 00 04 04 00 02 4d 46 5f 43 4c ...........MF_CL - 328: 41 53 53 49 43 5f 34 4b 00 00 00 43 14 7a 14 02 ASSIC_4K...C.z.. - 338: 15 0f 15 13 15 14 15 e7 18 ed 18 00 10 04 00 ............... - -00000347 : - 347: 4e 4f 4e 45 00 00 00 00 00 00 00 00 00 00 00 00 NONE............ - 357: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - 367: 55 49 44 5f 52 41 4e 44 4f 4d 00 00 00 00 00 00 UID_RANDOM...... - 377: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - 387: 55 49 44 5f 4c 45 46 54 5f 49 4e 43 52 45 4d 45 UID_LEFT_INCREME - 397: 4e 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 NT.............. - 3a7: 55 49 44 5f 52 49 47 48 54 5f 49 4e 43 52 45 4d UID_RIGHT_INCREM - 3b7: 45 4e 54 00 00 00 00 00 00 00 00 00 00 00 00 00 ENT............. - 3c7: 55 49 44 5f 4c 45 46 54 5f 44 45 43 52 45 4d 45 UID_LEFT_DECREME - 3d7: 4e 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 NT.............. - 3e7: 55 49 44 5f 52 49 47 48 54 5f 44 45 43 52 45 4d UID_RIGHT_DECREM - 3f7: 45 4e 54 00 00 00 00 00 00 00 00 00 00 00 00 00 ENT............. - 407: 43 59 43 4c 45 5f 53 45 54 54 49 4e 47 53 00 00 CYCLE_SETTINGS.. - 417: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - 427: 53 54 4f 52 45 5f 4d 45 4d 00 00 00 00 00 00 00 STORE_MEM....... - 437: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - 447: 52 45 43 41 4c 4c 5f 4d 45 4d 00 00 00 00 00 00 RECALL_MEM...... - 457: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - -00000467 <__c.6505>: - 467: 25 35 75 20 6d 56 00 %5u mV. - -0000046e <__c.6466>: - 46e: 25 75 00 %u. - -00000471 <__c.6461>: - 471: 25 75 00 %u. - -00000474 <__c.6434>: - 474: 52 41 4e 44 4f 4d 00 RANDOM. - -0000047b <__c.6416>: - 47b: 25 73 00 %s. - -0000047e <__c.6405>: - 47e: 43 68 61 6d 65 6c 65 6f 6e 2d 4d 69 6e 69 20 25 Chameleon-Mini % - 48e: 53 20 75 73 69 6e 67 20 4c 55 46 41 20 25 53 20 S using LUFA %S - 49e: 63 6f 6d 70 69 6c 65 64 20 77 69 74 68 20 41 56 compiled with AV - 4ae: 52 2d 47 43 43 20 25 53 00 R-GCC %S. - -000004b7 <__c.6407>: - 4b7: 31 34 30 39 32 34 00 140924. - -000004be <__c.6409>: - 4be: 31 33 30 39 30 31 00 130901. - -000004c5 <__c.6411>: - 4c5: 34 2e 38 2e 31 00 4.8.1. - -000004cb <__c.6197>: - 4cb: 0d 0a 00 ... - -000004ce <__c.6195>: - 4ce: 0d 0a 00 ... - -000004d1 : - 4d1: 64 31 30 30 3a 4f 4b 00 00 00 00 00 00 00 00 00 d100:OK......... - 4e1: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - 4f1: 00 65 31 30 31 3a 4f 4b 20 57 49 54 48 20 54 45 .e101:OK WITH TE - 501: 58 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 XT.............. - 511: 00 00 6e 31 31 30 3a 57 41 49 54 49 4e 47 20 46 ..n110:WAITING F - 521: 4f 52 20 58 4d 4f 44 45 4d 00 00 00 00 00 00 00 OR XMODEM....... - 531: 00 00 00 c8 32 30 30 3a 55 4e 4b 4e 4f 57 4e 20 ....200:UNKNOWN - 541: 43 4f 4d 4d 41 4e 44 00 00 00 00 00 00 00 00 00 COMMAND......... - 551: 00 00 00 00 c9 32 30 31 3a 49 4e 56 41 4c 49 44 .....201:INVALID - 561: 20 43 4f 4d 4d 41 4e 44 20 55 53 41 47 45 00 00 COMMAND USAGE.. - 571: 00 00 00 00 00 ca 32 30 32 3a 49 4e 56 41 4c 49 ......202:INVALI - 581: 44 20 50 41 52 41 4d 45 54 45 52 00 00 00 00 00 D PARAMETER..... - 591: 00 00 00 00 00 00 ...... - -00000597 : - 597: 56 45 52 53 49 4f 4e 00 00 00 00 00 00 00 00 00 VERSION......... - 5a7: 00 00 00 00 14 0d 43 4f 4e 46 49 47 00 00 00 00 ......CONFIG.... - 5b7: 00 00 00 00 00 00 51 0d 48 0d 32 0d 55 49 44 00 ......Q.H.2.UID. - 5c7: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 81 0d ................ - 5d7: 57 0d 52 45 41 44 4f 4e 4c 59 00 00 00 00 00 00 W.READONLY...... - 5e7: 00 00 00 00 e5 0d d3 0d 55 50 4c 4f 41 44 00 00 ........UPLOAD.. - 5f7: 00 00 00 00 00 00 00 00 f9 0d 00 00 00 00 44 4f ..............DO - 607: 57 4e 4c 4f 41 44 00 00 00 00 00 00 00 00 fe 0d WNLOAD.......... - 617: 00 00 00 00 52 45 53 45 54 00 00 00 00 00 00 00 ....RESET....... - 627: 00 00 00 00 03 0e 00 00 00 00 55 50 47 52 41 44 ..........UPGRAD - 637: 45 00 00 00 00 00 00 00 00 00 0e 0e 00 00 00 00 E............... - 647: 4d 45 4d 53 49 5a 45 00 00 00 00 00 00 00 00 00 MEMSIZE......... - 657: 00 00 00 00 19 0e 55 49 44 53 49 5a 45 00 00 00 ......UIDSIZE... - 667: 00 00 00 00 00 00 00 00 00 00 31 0e 42 55 54 54 ..........1.BUTT - 677: 4f 4e 00 00 00 00 00 00 00 00 00 00 47 0e 51 0e ON..........G.Q. - 687: 4c 0e 53 45 54 54 49 4e 47 00 00 00 00 00 00 00 L.SETTING....... - 697: 00 00 00 00 5e 0e 59 0e 43 4c 45 41 52 00 00 00 ....^.Y.CLEAR... - 6a7: 00 00 00 00 00 00 00 00 66 0e 00 00 00 00 48 45 ........f.....HE - 6b7: 4c 50 00 00 00 00 00 00 00 00 00 00 00 00 6a 0e LP............j. - 6c7: 00 00 00 00 52 53 53 49 00 00 00 00 00 00 00 00 ....RSSI........ - 6d7: 00 00 00 00 00 00 00 00 b4 0e 00 00 00 00 00 00 ................ - 6e7: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - 6f7: 00 . - -000006f8 <__ctors_end>: - 6f8: 11 24 eor r1, r1 - 6fa: 1f be out 0x3f, r1 ; 63 - 6fc: cf ef ldi r28, 0xFF ; 255 - 6fe: cd bf out 0x3d, r28 ; 61 - 700: df e2 ldi r29, 0x2F ; 47 - 702: de bf out 0x3e, r29 ; 62 - -00000704 <__do_copy_data>: - 704: 10 e2 ldi r17, 0x20 ; 32 - 706: a0 e0 ldi r26, 0x00 ; 0 - 708: b0 e2 ldi r27, 0x20 ; 32 - 70a: ea e9 ldi r30, 0x9A ; 154 - 70c: fe e4 ldi r31, 0x4E ; 78 - 70e: 02 c0 rjmp .+4 ; 0x714 <__do_copy_data+0x10> - 710: 05 90 lpm r0, Z+ - 712: 0d 92 st X+, r0 - 714: a2 39 cpi r26, 0x92 ; 146 - 716: b1 07 cpc r27, r17 - 718: d9 f7 brne .-10 ; 0x710 <__do_copy_data+0xc> - -0000071a <__do_clear_bss>: - 71a: 2a e2 ldi r18, 0x2A ; 42 - 71c: a2 e9 ldi r26, 0x92 ; 146 - 71e: b0 e2 ldi r27, 0x20 ; 32 - 720: 01 c0 rjmp .+2 ; 0x724 <.do_clear_bss_start> - -00000722 <.do_clear_bss_loop>: - 722: 1d 92 st X+, r1 - -00000724 <.do_clear_bss_start>: - 724: ad 39 cpi r26, 0x9D ; 157 - 726: b2 07 cpc r27, r18 - 728: e1 f7 brne .-8 ; 0x722 <.do_clear_bss_loop> - 72a: 03 d0 rcall .+6 ; 0x732

- 72c: 0c 94 4b 27 jmp 0x4e96 ; 0x4e96 <_exit> - -00000730 <__bad_interrupt>: - 730: 79 c0 rjmp .+242 ; 0x824 <__vector_default> - -00000732
: - -#include "Chameleon-Mini.h" - -int main(void) -{ - SystemInit(); - 732: 7e d0 rcall .+252 ; 0x830 - SettingsLoad(); - 734: 0e 94 d0 0b call 0x17a0 ; 0x17a0 - -extern uint8_t LEDPulseMask; - -static inline -void LEDInit(void) { - LED_PORT.DIRSET = LED_MASK; - 738: 80 e3 ldi r24, 0x30 ; 48 - 73a: 80 93 01 06 sts 0x0601, r24 - LEDInit(); - MemoryInit(); - 73e: e4 d2 rcall .+1480 ; 0xd08 - ConfigurationInit(); - 740: 0d d1 rcall .+538 ; 0x95c - TerminalInit(); - 742: 0e 94 9e 0c call 0x193c ; 0x193c - RandomInit(); - 746: 87 d1 rcall .+782 ; 0xa56 - ButtonInit(); - 748: a0 d6 rcall .+3392 ; 0x148a -#define ANTENNA_LEVEL_DENOMINATOR (ANTENNA_LEVEL_SCALE) - -static inline -void AntennaLevelInit(void) -{ - ADCA.CTRLA = ADC_ENABLE_bm; - 74a: 81 e0 ldi r24, 0x01 ; 1 - 74c: 80 93 00 02 sts 0x0200, r24 - ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc; - 750: 10 92 01 02 sts 0x0201, r1 - ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm; - 754: 92 e0 ldi r25, 0x02 ; 2 - 756: 90 93 02 02 sts 0x0202, r25 - ADCA.PRESCALER = ADC_PRESCALER_DIV32_gc; - 75a: 93 e0 ldi r25, 0x03 ; 3 - 75c: 90 93 04 02 sts 0x0204, r25 - ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; - 760: 80 93 20 02 sts 0x0220, r24 - ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN7_gc; - 764: 88 e3 ldi r24, 0x38 ; 56 - 766: 80 93 21 02 sts 0x0221, r24 - AntennaLevelInit(); - - SystemInterruptInit(); - 76a: cd d0 rcall .+410 ; 0x906 -} - -INLINE bool SystemTick100ms(void) -{ - if (TCE0.INTFLAGS & TC0_OVFIF_bm) { - TCE0.INTFLAGS = TC0_OVFIF_bm; - 76c: c1 e0 ldi r28, 0x01 ; 1 - - while(1) { - TerminalTask(); - 76e: 0e 94 a3 0c call 0x1946 ; 0x1946 -INLINE void CodecInit(void) { - ActiveConfiguration.CodecInitFunc(); -} - -INLINE void CodecTask(void) { - ActiveConfiguration.CodecTaskFunc(); - 772: e0 91 eb 24 lds r30, 0x24EB - 776: f0 91 ec 24 lds r31, 0x24EC - 77a: 09 95 icall -INLINE void ApplicationInit(void) { - ActiveConfiguration.ApplicationInitFunc(); -} - -INLINE void ApplicationTask(void) { - ActiveConfiguration.ApplicationTaskFunc(); - 77c: e0 91 f1 24 lds r30, 0x24F1 - 780: f0 91 f2 24 lds r31, 0x24F2 - 784: 09 95 icall - return RTC.CNT; -} - -INLINE bool SystemTick100ms(void) -{ - if (TCE0.INTFLAGS & TC0_OVFIF_bm) { - 786: 80 91 0c 0a lds r24, 0x0A0C - 78a: 80 ff sbrs r24, 0 - 78c: f0 cf rjmp .-32 ; 0x76e - TCE0.INTFLAGS = TC0_OVFIF_bm; - 78e: c0 93 0c 0a sts 0x0A0C, r28 - CodecTask(); - ApplicationTask(); - - if (SystemTick100ms()) { - RandomTick(); - 792: 75 d1 rcall .+746 ; 0xa7e - TerminalTick(); - 794: 0e 94 c2 0c call 0x1984 ; 0x1984 - ButtonTick(); - 798: 7f d6 rcall .+3326 ; 0x1498 - LED_PORT.OUTSET = Mask; -} - -static inline -void LEDTick(void) { - LED_PORT.OUTCLR = LEDPulseMask; - 79a: 80 91 93 24 lds r24, 0x2493 - 79e: 80 93 06 06 sts 0x0606, r24 - LEDPulseMask = 0; - 7a2: 10 92 93 24 sts 0x2493, r1 - 7a6: e3 cf rjmp .-58 ; 0x76e - -000007a8 : - */ -uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, - const uint8_t wIndex, - const void** const DescriptorAddress) -{ - const uint8_t DescriptorType = (wValue >> 8); - 7a8: 29 2f mov r18, r25 - 7aa: 33 27 eor r19, r19 - const uint8_t DescriptorNumber = (wValue & 0xFF); - - const void* Address = NULL; - uint16_t Size = NO_DESCRIPTOR; - - switch (DescriptorType) - 7ac: 22 30 cpi r18, 0x02 ; 2 - 7ae: 31 05 cpc r19, r1 - 7b0: 29 f1 breq .+74 ; 0x7fc - 7b2: 23 30 cpi r18, 0x03 ; 3 - 7b4: 31 05 cpc r19, r1 - 7b6: 99 f0 breq .+38 ; 0x7de - 7b8: 21 30 cpi r18, 0x01 ; 1 - 7ba: 31 05 cpc r19, r1 - 7bc: 41 f0 breq .+16 ; 0x7ce -{ - const uint8_t DescriptorType = (wValue >> 8); - const uint8_t DescriptorNumber = (wValue & 0xFF); - - const void* Address = NULL; - uint16_t Size = NO_DESCRIPTOR; - 7be: 80 e0 ldi r24, 0x00 ; 0 - 7c0: 90 e0 ldi r25, 0x00 ; 0 - const void** const DescriptorAddress) -{ - const uint8_t DescriptorType = (wValue >> 8); - const uint8_t DescriptorNumber = (wValue & 0xFF); - - const void* Address = NULL; - 7c2: 20 e0 ldi r18, 0x00 ; 0 - 7c4: 30 e0 ldi r19, 0x00 ; 0 - } - - break; - } - - *DescriptorAddress = Address; - 7c6: fa 01 movw r30, r20 - 7c8: 20 83 st Z, r18 - 7ca: 31 83 std Z+1, r19 ; 0x01 - return Size; -} - 7cc: 08 95 ret - - switch (DescriptorType) - { - case DTYPE_Device: - Address = &DeviceDescriptor; - Size = sizeof(USB_Descriptor_Device_t); - 7ce: 82 e1 ldi r24, 0x12 ; 18 - 7d0: 90 e0 ldi r25, 0x00 ; 0 - uint16_t Size = NO_DESCRIPTOR; - - switch (DescriptorType) - { - case DTYPE_Device: - Address = &DeviceDescriptor; - 7d2: 26 ec ldi r18, 0xC6 ; 198 - 7d4: 32 e0 ldi r19, 0x02 ; 2 - } - - break; - } - - *DescriptorAddress = Address; - 7d6: fa 01 movw r30, r20 - 7d8: 20 83 st Z, r18 - 7da: 31 83 std Z+1, r19 ; 0x01 - return Size; -} - 7dc: 08 95 ret - 7de: 99 27 eor r25, r25 - case DTYPE_Configuration: - Address = &ConfigurationDescriptor; - Size = sizeof(USB_Descriptor_Configuration_t); - break; - case DTYPE_String: - switch (DescriptorNumber) - 7e0: 81 30 cpi r24, 0x01 ; 1 - 7e2: 91 05 cpc r25, r1 - 7e4: 99 f0 breq .+38 ; 0x80c - 7e6: 82 30 cpi r24, 0x02 ; 2 - 7e8: 91 05 cpc r25, r1 - 7ea: b1 f0 breq .+44 ; 0x818 - 7ec: 89 2b or r24, r25 - 7ee: 39 f7 brne .-50 ; 0x7be - { - case 0x00: - Address = &LanguageString; - Size = pgm_read_byte(&LanguageString.Header.Size); - 7f0: e4 e8 ldi r30, 0x84 ; 132 - 7f2: f2 e0 ldi r31, 0x02 ; 2 - 7f4: 84 91 lpm r24, Z - 7f6: 90 e0 ldi r25, 0x00 ; 0 - break; - case DTYPE_String: - switch (DescriptorNumber) - { - case 0x00: - Address = &LanguageString; - 7f8: 9f 01 movw r18, r30 - Size = pgm_read_byte(&LanguageString.Header.Size); - break; - 7fa: e5 cf rjmp .-54 ; 0x7c6 - Address = &DeviceDescriptor; - Size = sizeof(USB_Descriptor_Device_t); - break; - case DTYPE_Configuration: - Address = &ConfigurationDescriptor; - Size = sizeof(USB_Descriptor_Configuration_t); - 7fc: 8e e3 ldi r24, 0x3E ; 62 - 7fe: 90 e0 ldi r25, 0x00 ; 0 - case DTYPE_Device: - Address = &DeviceDescriptor; - Size = sizeof(USB_Descriptor_Device_t); - break; - case DTYPE_Configuration: - Address = &ConfigurationDescriptor; - 800: 28 e8 ldi r18, 0x88 ; 136 - 802: 32 e0 ldi r19, 0x02 ; 2 - } - - break; - } - - *DescriptorAddress = Address; - 804: fa 01 movw r30, r20 - 806: 20 83 st Z, r18 - 808: 31 83 std Z+1, r19 ; 0x01 - return Size; -} - 80a: 08 95 ret - Address = &LanguageString; - Size = pgm_read_byte(&LanguageString.Header.Size); - break; - case 0x01: - Address = &ManufacturerString; - Size = pgm_read_byte(&ManufacturerString.Header.Size); - 80c: ea e6 ldi r30, 0x6A ; 106 - 80e: f2 e0 ldi r31, 0x02 ; 2 - 810: 84 91 lpm r24, Z - 812: 90 e0 ldi r25, 0x00 ; 0 - case 0x00: - Address = &LanguageString; - Size = pgm_read_byte(&LanguageString.Header.Size); - break; - case 0x01: - Address = &ManufacturerString; - 814: 9f 01 movw r18, r30 - Size = pgm_read_byte(&ManufacturerString.Header.Size); - break; - 816: d7 cf rjmp .-82 ; 0x7c6 - case 0x02: - Address = &ProductString; - Size = pgm_read_byte(&ProductString.Header.Size); - 818: ec e4 ldi r30, 0x4C ; 76 - 81a: f2 e0 ldi r31, 0x02 ; 2 - 81c: 84 91 lpm r24, Z - 81e: 90 e0 ldi r25, 0x00 ; 0 - case 0x01: - Address = &ManufacturerString; - Size = pgm_read_byte(&ManufacturerString.Header.Size); - break; - case 0x02: - Address = &ProductString; - 820: 9f 01 movw r18, r30 - Size = pgm_read_byte(&ProductString.Header.Size); - break; - 822: d1 cf rjmp .-94 ; 0x7c6 - -00000824 <__vector_default>: - -#include "System.h" -#include "LED.h" - -ISR(BADISR_vect) -{ - 824: 1f 92 push r1 - 826: 0f 92 push r0 - 828: 0f b6 in r0, 0x3f ; 63 - 82a: 0f 92 push r0 - 82c: 11 24 eor r1, r1 - 82e: ff cf rjmp .-2 ; 0x82e <__vector_default+0xa> - -00000830 : - while(1); -} - -void SystemInit(void) -{ - if (RST.STATUS & RST_WDRF_bm) { - 830: 80 91 78 00 lds r24, 0x0078 - 834: 83 ff sbrs r24, 3 - 836: 0a c0 rjmp .+20 ; 0x84c - /* On Watchdog reset clear WDRF bit, disable watchdog - * and jump into bootloader */ - RST.STATUS = RST_WDRF_bm; - 838: 88 e0 ldi r24, 0x08 ; 8 - 83a: 80 93 78 00 sts 0x0078, r24 - - CCP = CCP_IOREG_gc; - 83e: 88 ed ldi r24, 0xD8 ; 216 - 840: 84 bf out 0x34, r24 ; 52 - WDT.CTRL = WDT_CEN_bm; - 842: 81 e0 ldi r24, 0x01 ; 1 - 844: 80 93 80 00 sts 0x0080, r24 - - asm volatile ("jmp %0"::"i" (BOOT_SECTION_START + 0x1FC)); - 848: fd 95 fe c0 jmp 0x7f81fc ; 0x7f81fc <__data_load_end+0x7f32d0> - } - - /* 32MHz system clock using internal RC and 32K DFLL*/ - OSC.CTRL |= OSC_RC32MEN_bm | OSC_RC32KEN_bm; - 84c: 80 91 50 00 lds r24, 0x0050 - 850: 86 60 ori r24, 0x06 ; 6 - 852: 80 93 50 00 sts 0x0050, r24 - while(!(OSC.STATUS & OSC_RC32MRDY_bm)) - 856: 80 91 51 00 lds r24, 0x0051 - 85a: 81 ff sbrs r24, 1 - 85c: fc cf rjmp .-8 ; 0x856 - ; - while(!(OSC.STATUS & OSC_RC32KRDY_bm)) - 85e: 80 91 51 00 lds r24, 0x0051 - 862: 82 ff sbrs r24, 2 - 864: fc cf rjmp .-8 ; 0x85e - ; - - OSC.DFLLCTRL = OSC_RC32MCREF_RC32K_gc; - 866: 10 92 56 00 sts 0x0056, r1 - DFLLRC32M.CTRL = DFLL_ENABLE_bm; - 86a: 21 e0 ldi r18, 0x01 ; 1 - 86c: 20 93 60 00 sts 0x0060, r18 - - CCP = CCP_IOREG_gc; - 870: 88 ed ldi r24, 0xD8 ; 216 - 872: 84 bf out 0x34, r24 ; 52 - CLK.CTRL = CLK_SCLKSEL_RC32M_gc; - 874: 20 93 40 00 sts 0x0040, r18 - - /* Use TCE0 as system tick */ - TCE0.PER = F_CPU / 256 / SYSTEM_TICK_FREQ - 1; - 878: 83 ed ldi r24, 0xD3 ; 211 - 87a: 90 e3 ldi r25, 0x30 ; 48 - 87c: 80 93 26 0a sts 0x0A26, r24 - 880: 90 93 27 0a sts 0x0A27, r25 - TCE0.CTRLA = TC_CLKSEL_DIV256_gc; - 884: 86 e0 ldi r24, 0x06 ; 6 - 886: 80 93 00 0a sts 0x0A00, r24 - - /* Enable RTC with roughly 1kHz clock */ - CLK.RTCCTRL = CLK_RTCSRC_ULP_gc | CLK_RTCEN_bm; - 88a: 20 93 43 00 sts 0x0043, r18 - RTC.CTRL = RTC_PRESCALER_DIV1_gc; - 88e: 20 93 00 04 sts 0x0400, r18 - - /* Enable EEPROM data memory mapping */ - NVM.CTRLB |= NVM_EEMAPEN_bm; - 892: 80 91 cc 01 lds r24, 0x01CC - 896: 88 60 ori r24, 0x08 ; 8 - 898: 80 93 cc 01 sts 0x01CC, r24 - 89c: 08 95 ret - -0000089e : -} - -void SystemReset(void) -{ - CCP = CCP_IOREG_gc; - 89e: 88 ed ldi r24, 0xD8 ; 216 - 8a0: 84 bf out 0x34, r24 ; 52 - RST.CTRL = RST_SWRST_bm; - 8a2: 81 e0 ldi r24, 0x01 ; 1 - 8a4: e8 e7 ldi r30, 0x78 ; 120 - 8a6: f0 e0 ldi r31, 0x00 ; 0 - 8a8: 81 83 std Z+1, r24 ; 0x01 - 8aa: 08 95 ret - -000008ac : -} - -void SystemEnterBootloader(void) -{ - /* Use Watchdog timer to reset into bootloader. */ - CCP = CCP_IOREG_gc; - 8ac: 88 ed ldi r24, 0xD8 ; 216 - 8ae: 84 bf out 0x34, r24 ; 52 - WDT.CTRL = WDT_PER_512CLK_gc | WDT_ENABLE_bm | WDT_CEN_bm; - 8b0: 8b e1 ldi r24, 0x1B ; 27 - 8b2: 80 93 80 00 sts 0x0080, r24 - 8b6: 08 95 ret - -000008b8 : - - -void SystemStartUSBClock(void) -{ - /* 48MHz USB Clock using 12MHz XTAL */ - OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc; - 8b8: 8b ec ldi r24, 0xCB ; 203 - 8ba: 80 93 52 00 sts 0x0052, r24 - OSC.CTRL |= OSC_XOSCEN_bm; - 8be: 80 91 50 00 lds r24, 0x0050 - 8c2: 88 60 ori r24, 0x08 ; 8 - 8c4: 80 93 50 00 sts 0x0050, r24 - while(!(OSC.STATUS & OSC_XOSCRDY_bm)) - 8c8: 80 91 51 00 lds r24, 0x0051 - 8cc: 83 ff sbrs r24, 3 - 8ce: fc cf rjmp .-8 ; 0x8c8 - ; - - OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | (4 << OSC_PLLFAC_gp); - 8d0: 84 ec ldi r24, 0xC4 ; 196 - 8d2: 80 93 55 00 sts 0x0055, r24 - - OSC.CTRL |= OSC_PLLEN_bm; - 8d6: 80 91 50 00 lds r24, 0x0050 - 8da: 80 61 ori r24, 0x10 ; 16 - 8dc: 80 93 50 00 sts 0x0050, r24 - while(!(OSC.STATUS & OSC_PLLRDY_bm)) - 8e0: 80 91 51 00 lds r24, 0x0051 - 8e4: 84 ff sbrs r24, 4 - 8e6: fc cf rjmp .-8 ; 0x8e0 - ; -} - 8e8: 08 95 ret - -000008ea : - -void SystemStopUSBClock(void) -{ - /* Disable USB Clock to minimize power consumption */ - CLK.USBCTRL &= ~CLK_USBSEN_bm; - 8ea: e0 e4 ldi r30, 0x40 ; 64 - 8ec: f0 e0 ldi r31, 0x00 ; 0 - 8ee: 84 81 ldd r24, Z+4 ; 0x04 - 8f0: 8e 7f andi r24, 0xFE ; 254 - 8f2: 84 83 std Z+4, r24 ; 0x04 - OSC.CTRL &= ~OSC_PLLEN_bm; - 8f4: e0 e5 ldi r30, 0x50 ; 80 - 8f6: f0 e0 ldi r31, 0x00 ; 0 - 8f8: 80 81 ld r24, Z - 8fa: 8f 7e andi r24, 0xEF ; 239 - 8fc: 80 83 st Z, r24 - OSC.CTRL &= ~OSC_XOSCEN_bm; - 8fe: 80 81 ld r24, Z - 900: 87 7f andi r24, 0xF7 ; 247 - 902: 80 83 st Z, r24 - 904: 08 95 ret - -00000906 : -} - -void SystemInterruptInit(void) -{ - /* Enable all interrupt levels */ - PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; - 906: 87 e0 ldi r24, 0x07 ; 7 - 908: e0 ea ldi r30, 0xA0 ; 160 - 90a: f0 e0 ldi r31, 0x00 ; 0 - 90c: 82 83 std Z+2, r24 ; 0x02 - sei(); - 90e: 78 94 sei - 910: 08 95 ret - -00000912 : - -/* Include all Codecs and Applications */ -#include "Codec/Codec.h" -#include "Application/Application.h" - -static void CodecInitDummy(void) { } - 912: 08 95 ret - -00000914 : -static void CodecTaskDummy(void) { } - 914: 08 95 ret - -00000916 : -static void ApplicationInitDummy(void) {} - 916: 08 95 ret - -00000918 : -static void ApplicationResetDummy(void) {} - 918: 08 95 ret - -0000091a : -static void ApplicationTaskDummy(void) {} - 91a: 08 95 ret - -0000091c : -static uint16_t ApplicationProcessDummy(uint8_t* ByteBuffer, uint16_t ByteCount) { return 0; } - 91c: 80 e0 ldi r24, 0x00 ; 0 - 91e: 90 e0 ldi r25, 0x00 ; 0 - 920: 08 95 ret - -00000922 : -static void ApplicationGetUidDummy(ConfigurationUidType Uid) { } - 922: 08 95 ret - -00000924 : -static void ApplicationSetUidDummy(ConfigurationUidType Uid) { } - 924: 08 95 ret - -00000926 : - ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration); -} - -void ConfigurationSetById( ConfigurationEnum Configuration ) -{ - GlobalSettings.ActiveSettingPtr->Configuration = Configuration; - 926: e0 91 fe 24 lds r30, 0x24FE - 92a: f0 91 ff 24 lds r31, 0x24FF - 92e: 81 83 std Z+1, r24 ; 0x01 - - /* Copy struct from PROGMEM to RAM */ - memcpy_P(&ActiveConfiguration, - &ConfigurationTable[Configuration], sizeof(ConfigurationType)); - 930: 95 e2 ldi r25, 0x25 ; 37 - 932: 89 9f mul r24, r25 - 934: b0 01 movw r22, r0 - 936: 11 24 eor r1, r1 - 938: 68 52 subi r22, 0x28 ; 40 - 93a: 7d 4f sbci r23, 0xFD ; 253 -void ConfigurationSetById( ConfigurationEnum Configuration ) -{ - GlobalSettings.ActiveSettingPtr->Configuration = Configuration; - - /* Copy struct from PROGMEM to RAM */ - memcpy_P(&ActiveConfiguration, - 93c: 45 e2 ldi r20, 0x25 ; 37 - 93e: 50 e0 ldi r21, 0x00 ; 0 - 940: 88 ed ldi r24, 0xD8 ; 216 - 942: 94 e2 ldi r25, 0x24 ; 36 - 944: 0e 94 e5 23 call 0x47ca ; 0x47ca -/* Applications */ -#include "MifareClassic.h" - -/* Function wrappers */ -INLINE void ApplicationInit(void) { - ActiveConfiguration.ApplicationInitFunc(); - 948: e0 91 ed 24 lds r30, 0x24ED - 94c: f0 91 ee 24 lds r31, 0x24EE - 950: 09 95 icall -#define CODEC_CARRIER_FREQ 13560000 - -extern uint8_t CodecBuffer[CODEC_BUFFER_SIZE]; - -INLINE void CodecInit(void) { - ActiveConfiguration.CodecInitFunc(); - 952: e0 91 e9 24 lds r30, 0x24E9 - 956: f0 91 ea 24 lds r31, 0x24EA - 95a: 09 94 ijmp - -0000095c : - -ConfigurationType ActiveConfiguration; - -void ConfigurationInit(void) -{ - ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration); - 95c: e0 91 fe 24 lds r30, 0x24FE - 960: f0 91 ff 24 lds r31, 0x24FF - 964: 81 81 ldd r24, Z+1 ; 0x01 - 966: df cf rjmp .-66 ; 0x926 - -00000968 : - ApplicationInit(); - CodecInit(); -} - -bool ConfigurationSetByName(const char* ConfigurationName) -{ - 968: 0f 93 push r16 - 96a: 1f 93 push r17 - 96c: cf 93 push r28 - 96e: df 93 push r29 - 970: 49 ed ldi r20, 0xD9 ; 217 - 972: 52 e0 ldi r21, 0x02 ; 2 - uint8_t i; - - /* Loop through table trying to find the configuration */ - for (i=0; i<(sizeof(ConfigurationTable) / sizeof(*ConfigurationTable)); i++) { - 974: 10 e0 ldi r17, 0x00 ; 0 - 976: bc 01 movw r22, r24 - 978: 6f 5f subi r22, 0xFF ; 255 - 97a: 7f 4f sbci r23, 0xFF ; 255 - const char* pTableConfigName = ConfigurationTable[i].ConfigurationName; - 97c: 9a 01 movw r18, r20 - const char* pRequestedConfigName = ConfigurationName; - bool StringMismatch = false; - char c = pgm_read_byte(pTableConfigName); - 97e: fa 01 movw r30, r20 - 980: c4 91 lpm r28, Z - - /* Try to keep running until both strings end at the same point */ - while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { - 982: c1 11 cpse r28, r1 - 984: 0f c0 rjmp .+30 ; 0x9a4 - uint8_t i; - - /* Loop through table trying to find the configuration */ - for (i=0; i<(sizeof(ConfigurationTable) / sizeof(*ConfigurationTable)); i++) { - const char* pTableConfigName = ConfigurationTable[i].ConfigurationName; - const char* pRequestedConfigName = ConfigurationName; - 986: ec 01 movw r28, r24 - bool StringMismatch = false; - char c = pgm_read_byte(pTableConfigName); - - /* Try to keep running until both strings end at the same point */ - while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { - 988: 28 81 ld r18, Y - 98a: 22 23 and r18, r18 - 98c: 11 f1 breq .+68 ; 0x9d2 -bool ConfigurationSetByName(const char* ConfigurationName) -{ - uint8_t i; - - /* Loop through table trying to find the configuration */ - for (i=0; i<(sizeof(ConfigurationTable) / sizeof(*ConfigurationTable)); i++) { - 98e: 1f 5f subi r17, 0xFF ; 255 - 990: 4b 5d subi r20, 0xDB ; 219 - 992: 5f 4f sbci r21, 0xFF ; 255 - 994: 13 30 cpi r17, 0x03 ; 3 - 996: 91 f7 brne .-28 ; 0x97c - ConfigurationSetById(i); - return true; - } - } - - return false; - 998: 80 e0 ldi r24, 0x00 ; 0 -} - 99a: df 91 pop r29 - 99c: cf 91 pop r28 - 99e: 1f 91 pop r17 - 9a0: 0f 91 pop r16 - 9a2: 08 95 ret - bool StringMismatch = false; - char c = pgm_read_byte(pTableConfigName); - - /* Try to keep running until both strings end at the same point */ - while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { - if ( (c == '\0') || (*pRequestedConfigName == '\0') ) { - 9a4: dc 01 movw r26, r24 - 9a6: fc 91 ld r31, X - 9a8: ff 23 and r31, r31 - 9aa: 89 f3 breq .-30 ; 0x98e - /* One String ended before the other did -> unequal length */ - StringMismatch = true; - break; - } - - if (c != *pRequestedConfigName) { - 9ac: cf 13 cpse r28, r31 - 9ae: ef cf rjmp .-34 ; 0x98e - 9b0: db 01 movw r26, r22 - 9b2: 05 c0 rjmp .+10 ; 0x9be - bool StringMismatch = false; - char c = pgm_read_byte(pTableConfigName); - - /* Try to keep running until both strings end at the same point */ - while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { - if ( (c == '\0') || (*pRequestedConfigName == '\0') ) { - 9b4: fd 91 ld r31, X+ - 9b6: ff 23 and r31, r31 - 9b8: 51 f3 breq .-44 ; 0x98e - /* One String ended before the other did -> unequal length */ - StringMismatch = true; - break; - } - - if (c != *pRequestedConfigName) { - 9ba: f0 13 cpse r31, r16 - 9bc: e8 cf rjmp .-48 ; 0x98e - StringMismatch = true; - break; - } - - /* Proceed to next character */ - pTableConfigName++; - 9be: 2f 5f subi r18, 0xFF ; 255 - 9c0: 3f 4f sbci r19, 0xFF ; 255 - pRequestedConfigName++; - 9c2: ed 01 movw r28, r26 - - c = pgm_read_byte(pTableConfigName); - 9c4: f9 01 movw r30, r18 - 9c6: 04 91 lpm r16, Z - const char* pRequestedConfigName = ConfigurationName; - bool StringMismatch = false; - char c = pgm_read_byte(pTableConfigName); - - /* Try to keep running until both strings end at the same point */ - while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { - 9c8: 01 11 cpse r16, r1 - 9ca: f4 cf rjmp .-24 ; 0x9b4 - 9cc: 28 81 ld r18, Y - 9ce: 21 11 cpse r18, r1 - 9d0: de cf rjmp .-68 ; 0x98e - c = pgm_read_byte(pTableConfigName); - } - - if (!StringMismatch) { - /* Configuration found */ - ConfigurationSetById(i); - 9d2: 81 2f mov r24, r17 - 9d4: a8 df rcall .-176 ; 0x926 - return true; - 9d6: 81 e0 ldi r24, 0x01 ; 1 - } - } - - return false; -} - 9d8: df 91 pop r29 - 9da: cf 91 pop r28 - 9dc: 1f 91 pop r17 - 9de: 0f 91 pop r16 - 9e0: 08 95 ret - -000009e2 : - -void ConfigurationGetList(char* ConfigListOut, uint16_t ByteCount) -{ - 9e2: 0f 93 push r16 - 9e4: 1f 93 push r17 - 9e6: cf 93 push r28 - 9e8: df 93 push r29 - uint8_t i; - - /* Account for '\0' */ - ByteCount--; - 9ea: 61 50 subi r22, 0x01 ; 1 - 9ec: 71 09 sbc r23, r1 - 9ee: 49 ed ldi r20, 0xD9 ; 217 - 9f0: 52 e0 ldi r21, 0x02 ; 2 - ByteCount--; - } - - if ( i < (CONFIG_COUNT - 1) ) { - /* No comma on last configuration */ - *ConfigListOut++ = ','; - 9f2: 1c e2 ldi r17, 0x2C ; 44 - - /* Account for '\0' */ - ByteCount--; - - for (i=0; i CONFIGURATION_NAME_LENGTH_MAX) { - 9f6: fa 01 movw r30, r20 - 9f8: 04 91 lpm r16, Z - 9fa: 00 23 and r16, r16 - 9fc: 51 f1 breq .+84 ; 0xa52 - 9fe: 61 31 cpi r22, 0x11 ; 17 - a00: 71 05 cpc r23, r1 - a02: 20 f4 brcc .+8 ; 0xa0c - a04: 26 c0 rjmp .+76 ; 0xa52 - a06: 60 31 cpi r22, 0x10 ; 16 - a08: 71 05 cpc r23, r1 - a0a: 61 f0 breq .+24 ; 0xa24 - a0c: dc 01 movw r26, r24 - a0e: 01 96 adiw r24, 0x01 ; 1 - a10: ec 01 movw r28, r24 - /* While not end-of-string and enough buffer to - * put a complete configuration name */ - *ConfigListOut++ = c; - a12: 0c 93 st X, r16 - ConfigName++; - a14: 2f 5f subi r18, 0xFF ; 255 - a16: 3f 4f sbci r19, 0xFF ; 255 - ByteCount--; - a18: 61 50 subi r22, 0x01 ; 1 - a1a: 71 09 sbc r23, r1 - - for (i=0; i CONFIGURATION_NAME_LENGTH_MAX) { - a1c: f9 01 movw r30, r18 - a1e: 04 91 lpm r16, Z - a20: 01 11 cpse r16, r1 - a22: f1 cf rjmp .-30 ; 0xa06 - *ConfigListOut++ = c; - ConfigName++; - ByteCount--; - } - - if ( i < (CONFIG_COUNT - 1) ) { - a24: f3 e0 ldi r31, 0x03 ; 3 - a26: 43 32 cpi r20, 0x23 ; 35 - a28: 5f 07 cpc r21, r31 - a2a: 31 f4 brne .+12 ; 0xa38 - *ConfigListOut++ = ','; - ByteCount--; - } - } - - *ConfigListOut = '\0'; - a2c: 18 82 st Y, r1 -} - a2e: df 91 pop r29 - a30: cf 91 pop r28 - a32: 1f 91 pop r17 - a34: 0f 91 pop r16 - a36: 08 95 ret - ByteCount--; - } - - if ( i < (CONFIG_COUNT - 1) ) { - /* No comma on last configuration */ - *ConfigListOut++ = ','; - a38: ce 01 movw r24, r28 - a3a: 01 96 adiw r24, 0x01 ; 1 - a3c: 18 83 st Y, r17 - ByteCount--; - a3e: 61 50 subi r22, 0x01 ; 1 - a40: 71 09 sbc r23, r1 - a42: 4b 5d subi r20, 0xDB ; 219 - a44: 5f 4f sbci r21, 0xFF ; 255 - uint8_t i; - - /* Account for '\0' */ - ByteCount--; - - for (i=0; i - ByteCount--; - } - - if ( i < (CONFIG_COUNT - 1) ) { - /* No comma on last configuration */ - *ConfigListOut++ = ','; - a4e: ec 01 movw r28, r24 - a50: ed cf rjmp .-38 ; 0xa2c - - for (i=0; i CONFIGURATION_NAME_LENGTH_MAX) { - a52: ec 01 movw r28, r24 - a54: e7 cf rjmp .-50 ; 0xa24 - -00000a56 : -#include "Random.h" - -#include - -void RandomInit(void) -{ - a56: 08 95 ret - -00000a58 : - -} - -uint8_t RandomGetByte(void) -{ - return rand() & 0xFF; - a58: 0c 94 d7 23 jmp 0x47ae ; 0x47ae -} - a5c: 08 95 ret - -00000a5e : - -void RandomGetBuffer(void* Buffer, uint8_t ByteCount) -{ - a5e: 1f 93 push r17 - a60: cf 93 push r28 - a62: df 93 push r29 - uint8_t* BufferPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - a64: 66 23 and r22, r22 - a66: 39 f0 breq .+14 ; 0xa76 - a68: ec 01 movw r28, r24 - a6a: 16 2f mov r17, r22 - -} - -uint8_t RandomGetByte(void) -{ - return rand() & 0xFF; - a6c: 0e 94 d7 23 call 0x47ae ; 0x47ae - a70: 89 93 st Y+, r24 - a72: 11 50 subi r17, 0x01 ; 1 - -void RandomGetBuffer(void* Buffer, uint8_t ByteCount) -{ - uint8_t* BufferPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - a74: d9 f7 brne .-10 ; 0xa6c - *BufferPtr++ = RandomGetByte(); - } -} - a76: df 91 pop r29 - a78: cf 91 pop r28 - a7a: 1f 91 pop r17 - a7c: 08 95 ret - -00000a7e : - -void RandomTick(void) -{ - rand(); - a7e: 0e 94 d7 23 call 0x47ae ; 0x47ae - rand(); - a82: 0e 94 d7 23 call 0x47ae ; 0x47ae - rand(); - a86: 0e 94 d7 23 call 0x47ae ; 0x47ae - rand(); - a8a: 0c 94 d7 23 jmp 0x47ae ; 0x47ae - -00000a8e : - */ - -#include "Common.h" - -uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount) -{ - a8e: cf 93 push r28 - a90: df 93 push r29 - a92: dc 01 movw r26, r24 - uint8_t* ByteBuffer = (uint8_t*) Buffer; - uint16_t CharCount = 0; - - /* Account for '\0' at the end */ - MaxChars--; - a94: 61 50 subi r22, 0x01 ; 1 - a96: 71 09 sbc r23, r1 - - while( (ByteCount > 0) && (MaxChars >= 2) ) { - a98: 21 15 cp r18, r1 - a9a: 31 05 cpc r19, r1 - a9c: a9 f1 breq .+106 ; 0xb08 - a9e: 62 30 cpi r22, 0x02 ; 2 - aa0: 71 05 cpc r23, r1 - aa2: 90 f1 brcs .+100 ; 0xb08 - aa4: fa 01 movw r30, r20 - aa6: 21 50 subi r18, 0x01 ; 1 - aa8: 31 09 sbc r19, r1 - aaa: 24 0f add r18, r20 - aac: 35 1f adc r19, r21 -#include "Common.h" - -uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - uint16_t CharCount = 0; - aae: 80 e0 ldi r24, 0x00 ; 0 - ab0: 90 e0 ldi r25, 0x00 ; 0 - ab2: 17 c0 rjmp .+46 ; 0xae2 - MaxChars--; - - while( (ByteCount > 0) && (MaxChars >= 2) ) { - uint8_t Byte = *ByteBuffer; - - HexOut[0] = NIBBLE_TO_HEXCHAR( (Byte >> 4) & 0x0F ); - ab4: d0 5d subi r29, 0xD0 ; 208 - ab6: dc 93 st X, r29 - HexOut[1] = NIBBLE_TO_HEXCHAR( (Byte >> 0) & 0x0F ); - ab8: cf 70 andi r28, 0x0F ; 15 - aba: 4c 2f mov r20, r28 - abc: 50 e0 ldi r21, 0x00 ; 0 - abe: 4a 30 cpi r20, 0x0A ; 10 - ac0: 51 05 cpc r21, r1 - ac2: 04 f5 brge .+64 ; 0xb04 - ac4: c0 5d subi r28, 0xD0 ; 208 - ac6: 11 96 adiw r26, 0x01 ; 1 - ac8: cc 93 st X, r28 - aca: 11 97 sbiw r26, 0x01 ; 1 - - HexOut += 2; - acc: 12 96 adiw r26, 0x02 ; 2 - MaxChars -= 2; - ace: 62 50 subi r22, 0x02 ; 2 - ad0: 71 09 sbc r23, r1 - CharCount += 2; - ad2: 02 96 adiw r24, 0x02 ; 2 - uint16_t CharCount = 0; - - /* Account for '\0' at the end */ - MaxChars--; - - while( (ByteCount > 0) && (MaxChars >= 2) ) { - ad4: e2 17 cp r30, r18 - ad6: f3 07 cpc r31, r19 - ad8: c9 f0 breq .+50 ; 0xb0c - ada: 31 96 adiw r30, 0x01 ; 1 - adc: 62 30 cpi r22, 0x02 ; 2 - ade: 71 05 cpc r23, r1 - ae0: a8 f0 brcs .+42 ; 0xb0c - uint8_t Byte = *ByteBuffer; - ae2: c0 81 ld r28, Z - - HexOut[0] = NIBBLE_TO_HEXCHAR( (Byte >> 4) & 0x0F ); - ae4: dc 2f mov r29, r28 - ae6: d2 95 swap r29 - ae8: df 70 andi r29, 0x0F ; 15 - aea: 4d 2f mov r20, r29 - aec: 50 e0 ldi r21, 0x00 ; 0 - aee: 4a 30 cpi r20, 0x0A ; 10 - af0: 51 05 cpc r21, r1 - af2: 04 f3 brlt .-64 ; 0xab4 - af4: d9 5c subi r29, 0xC9 ; 201 - af6: dc 93 st X, r29 - HexOut[1] = NIBBLE_TO_HEXCHAR( (Byte >> 0) & 0x0F ); - af8: cf 70 andi r28, 0x0F ; 15 - afa: 4c 2f mov r20, r28 - afc: 50 e0 ldi r21, 0x00 ; 0 - afe: 4a 30 cpi r20, 0x0A ; 10 - b00: 51 05 cpc r21, r1 - b02: 04 f3 brlt .-64 ; 0xac4 - b04: c9 5c subi r28, 0xC9 ; 201 - b06: df cf rjmp .-66 ; 0xac6 -#include "Common.h" - -uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - uint16_t CharCount = 0; - b08: 80 e0 ldi r24, 0x00 ; 0 - b0a: 90 e0 ldi r25, 0x00 ; 0 - CharCount += 2; - ByteBuffer++; - ByteCount -= 1; - } - - *HexOut = '\0'; - b0c: 1c 92 st X, r1 - - return CharCount; -} - b0e: df 91 pop r29 - b10: cf 91 pop r28 - b12: 08 95 ret - -00000b14 : - -uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) -{ - b14: dc 01 movw r26, r24 - b16: fa 01 movw r30, r20 - uint8_t* ByteBuffer = (uint8_t*) Buffer; - uint16_t ByteCount = 0; - - while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) { - b18: 80 81 ld r24, Z - b1a: 88 23 and r24, r24 - b1c: 09 f4 brne .+2 ; 0xb20 - b1e: 41 c0 rjmp .+130 ; 0xba2 - b20: 91 81 ldd r25, Z+1 ; 0x01 - b22: 99 23 and r25, r25 - b24: d9 f1 breq .+118 ; 0xb9c -} - -uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - uint16_t ByteCount = 0; - b26: 20 e0 ldi r18, 0x00 ; 0 - b28: 30 e0 ldi r19, 0x00 ; 0 - - while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) { - b2a: 61 15 cp r22, r1 - b2c: 71 05 cpc r23, r1 - b2e: a1 f4 brne .+40 ; 0xb58 - b30: 33 c0 rjmp .+102 ; 0xb98 - if (VALID_HEXCHAR(HexIn[0]) && VALID_HEXCHAR(HexIn[1])) { - uint8_t Byte = 0; - - Byte |= HEXCHAR_TO_NIBBLE(HexIn[0]) << 4; - b32: 82 95 swap r24 - b34: 80 7f andi r24, 0xF0 ; 240 - Byte |= HEXCHAR_TO_NIBBLE(HexIn[1]) << 0; - b36: 91 34 cpi r25, 0x41 ; 65 - b38: 30 f5 brcc .+76 ; 0xb86 - b3a: 94 2f mov r25, r20 - b3c: 89 2b or r24, r25 - - *ByteBuffer = Byte; - b3e: 8d 93 st X+, r24 - - ByteBuffer++; - MaxBytes--; - ByteCount++; - b40: 2f 5f subi r18, 0xFF ; 255 - b42: 3f 4f sbci r19, 0xFF ; 255 - HexIn += 2; - b44: 32 96 adiw r30, 0x02 ; 2 -uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - uint16_t ByteCount = 0; - - while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) { - b46: 80 81 ld r24, Z - b48: 88 23 and r24, r24 - b4a: 31 f1 breq .+76 ; 0xb98 - b4c: 91 81 ldd r25, Z+1 ; 0x01 - b4e: 99 23 and r25, r25 - b50: 29 f1 breq .+74 ; 0xb9c - b52: 62 17 cp r22, r18 - b54: 73 07 cpc r23, r19 - b56: 01 f1 breq .+64 ; 0xb98 - if (VALID_HEXCHAR(HexIn[0]) && VALID_HEXCHAR(HexIn[1])) { - b58: 40 ed ldi r20, 0xD0 ; 208 - b5a: 48 0f add r20, r24 - b5c: 4a 30 cpi r20, 0x0A ; 10 - b5e: 20 f0 brcs .+8 ; 0xb68 - b60: 4f eb ldi r20, 0xBF ; 191 - b62: 48 0f add r20, r24 - b64: 46 30 cpi r20, 0x06 ; 6 - b66: d0 f4 brcc .+52 ; 0xb9c - b68: 40 ed ldi r20, 0xD0 ; 208 - b6a: 49 0f add r20, r25 - b6c: 4a 30 cpi r20, 0x0A ; 10 - b6e: 20 f0 brcs .+8 ; 0xb78 - b70: 5f eb ldi r21, 0xBF ; 191 - b72: 59 0f add r21, r25 - b74: 56 30 cpi r21, 0x06 ; 6 - b76: 90 f4 brcc .+36 ; 0xb9c - uint8_t Byte = 0; - - Byte |= HEXCHAR_TO_NIBBLE(HexIn[0]) << 4; - b78: 81 34 cpi r24, 0x41 ; 65 - b7a: d8 f2 brcs .-74 ; 0xb32 - b7c: 82 95 swap r24 - b7e: 80 7f andi r24, 0xF0 ; 240 - b80: 80 57 subi r24, 0x70 ; 112 - Byte |= HEXCHAR_TO_NIBBLE(HexIn[1]) << 0; - b82: 91 34 cpi r25, 0x41 ; 65 - b84: d0 f2 brcs .-76 ; 0xb3a - b86: 97 53 subi r25, 0x37 ; 55 - b88: 89 2b or r24, r25 - - *ByteBuffer = Byte; - b8a: 8d 93 st X+, r24 - - ByteBuffer++; - MaxBytes--; - ByteCount++; - b8c: 2f 5f subi r18, 0xFF ; 255 - b8e: 3f 4f sbci r19, 0xFF ; 255 - HexIn += 2; - b90: 32 96 adiw r30, 0x02 ; 2 -uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - uint16_t ByteCount = 0; - - while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) { - b92: 80 81 ld r24, Z - b94: 81 11 cpse r24, r1 - b96: da cf rjmp .-76 ; 0xb4c - if ( (HexIn[0] != '\0') && (HexIn[1] == '\0') ) { - /* Odd number of characters */ - return 0; - } - - return ByteCount; - b98: c9 01 movw r24, r18 - b9a: 08 95 ret - } - } - - if ( (HexIn[0] != '\0') && (HexIn[1] == '\0') ) { - /* Odd number of characters */ - return 0; - b9c: 80 e0 ldi r24, 0x00 ; 0 - b9e: 90 e0 ldi r25, 0x00 ; 0 - } - - return ByteCount; -} - ba0: 08 95 ret -} - -uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - uint16_t ByteCount = 0; - ba2: 20 e0 ldi r18, 0x00 ; 0 - ba4: 30 e0 ldi r19, 0x00 ; 0 - ba6: f8 cf rjmp .-16 ; 0xb98 - -00000ba8 : - MemoryRecall(); -} - -void MemoryReadBlock(void* Buffer, uint16_t Address, uint16_t ByteCount) -{ - uint8_t* SrcPtr = &Memory[Address]; - ba8: fb 01 movw r30, r22 - baa: ee 56 subi r30, 0x6E ; 110 - bac: ff 4d sbci r31, 0xDF ; 223 - uint8_t* DstPtr = (uint8_t*) Buffer; - - /* Prevent Buf Ovfs */ - ByteCount = MIN(ByteCount, MEMORY_SIZE_PER_SETTING - Address); - bae: 20 e0 ldi r18, 0x00 ; 0 - bb0: 34 e0 ldi r19, 0x04 ; 4 - bb2: 26 1b sub r18, r22 - bb4: 37 0b sbc r19, r23 - bb6: 42 17 cp r20, r18 - bb8: 53 07 cpc r21, r19 - bba: 08 f4 brcc .+2 ; 0xbbe - bbc: 9a 01 movw r18, r20 - - while(ByteCount--) { - bbe: 21 15 cp r18, r1 - bc0: 31 05 cpc r19, r1 - bc2: 49 f0 breq .+18 ; 0xbd6 - bc4: dc 01 movw r26, r24 - bc6: cf 01 movw r24, r30 - bc8: 82 0f add r24, r18 - bca: 93 1f adc r25, r19 - *DstPtr++ = *SrcPtr++; - bcc: 21 91 ld r18, Z+ - bce: 2d 93 st X+, r18 - uint8_t* DstPtr = (uint8_t*) Buffer; - - /* Prevent Buf Ovfs */ - ByteCount = MIN(ByteCount, MEMORY_SIZE_PER_SETTING - Address); - - while(ByteCount--) { - bd0: e8 17 cp r30, r24 - bd2: f9 07 cpc r31, r25 - bd4: d9 f7 brne .-10 ; 0xbcc - bd6: 08 95 ret - -00000bd8 : -} - -void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount) -{ - uint8_t* SrcPtr = (uint8_t*) Buffer; - uint8_t* DstPtr = &Memory[Address]; - bd8: db 01 movw r26, r22 - bda: ae 56 subi r26, 0x6E ; 110 - bdc: bf 4d sbci r27, 0xDF ; 223 - - /* Prevent Buf Ovfs */ - ByteCount = MIN(ByteCount, MEMORY_SIZE_PER_SETTING - Address); - bde: 20 e0 ldi r18, 0x00 ; 0 - be0: 34 e0 ldi r19, 0x04 ; 4 - be2: 26 1b sub r18, r22 - be4: 37 0b sbc r19, r23 - be6: 42 17 cp r20, r18 - be8: 53 07 cpc r21, r19 - bea: 08 f4 brcc .+2 ; 0xbee - bec: 9a 01 movw r18, r20 - - while(ByteCount--) { - bee: 21 15 cp r18, r1 - bf0: 31 05 cpc r19, r1 - bf2: 41 f0 breq .+16 ; 0xc04 - bf4: fc 01 movw r30, r24 - bf6: 82 0f add r24, r18 - bf8: 93 1f adc r25, r19 - *DstPtr++ = *SrcPtr++; - bfa: 21 91 ld r18, Z+ - bfc: 2d 93 st X+, r18 - uint8_t* DstPtr = &Memory[Address]; - - /* Prevent Buf Ovfs */ - ByteCount = MIN(ByteCount, MEMORY_SIZE_PER_SETTING - Address); - - while(ByteCount--) { - bfe: e8 17 cp r30, r24 - c00: f9 07 cpc r31, r25 - c02: d9 f7 brne .-10 ; 0xbfa - c04: 08 95 ret - -00000c06 : - *DstPtr++ = *SrcPtr++; - } -} - -void MemoryClear(void) -{ - c06: 80 e0 ldi r24, 0x00 ; 0 - c08: 94 e0 ldi r25, 0x04 ; 4 - c0a: e2 e9 ldi r30, 0x92 ; 146 - c0c: f0 e2 ldi r31, 0x20 ; 32 - c0e: df 01 movw r26, r30 - c10: 9c 01 movw r18, r24 - c12: 1d 92 st X+, r1 - c14: 21 50 subi r18, 0x01 ; 1 - c16: 30 40 sbci r19, 0x00 ; 0 - c18: e1 f7 brne .-8 ; 0xc12 - c1a: 08 95 ret - -00000c1c : -} - -void MemoryRecall(void) -{ - /* Recall memory from permanent flash */ - FlashRead(Memory, (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); - c1c: 80 91 fd 24 lds r24, 0x24FD - c20: 90 e0 ldi r25, 0x00 ; 0 - c22: a0 e0 ldi r26, 0x00 ; 0 - c24: b0 e0 ldi r27, 0x00 ; 0 - c26: 4a e0 ldi r20, 0x0A ; 10 - c28: 88 0f add r24, r24 - c2a: 99 1f adc r25, r25 - c2c: aa 1f adc r26, r26 - c2e: bb 1f adc r27, r27 - c30: 4a 95 dec r20 - c32: d1 f7 brne .-12 ; 0xc28 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - c34: 40 e1 ldi r20, 0x10 ; 16 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - c36: 57 ed ldi r21, 0xD7 ; 215 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - c38: 30 e4 ldi r19, 0x40 ; 64 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - c3a: 40 93 66 06 sts 0x0666, r20 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - c3e: 50 93 a0 09 sts 0x09A0, r21 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - c42: 20 91 a1 09 lds r18, 0x09A1 - c46: 26 ff sbrs r18, 6 - c48: fc cf rjmp .-8 ; 0xc42 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - c4a: 30 93 a1 09 sts 0x09A1, r19 - - return MEMORY_FLASH_USART.DATA; - c4e: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - c52: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - c56: 20 91 a1 09 lds r18, 0x09A1 - c5a: 26 ff sbrs r18, 6 - c5c: fc cf rjmp .-8 ; 0xc56 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - c5e: 30 93 a1 09 sts 0x09A1, r19 - - return MEMORY_FLASH_USART.DATA; - c62: 20 91 a0 09 lds r18, 0x09A0 - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_STATUS_REG_READ); - Register = SPITransferByte(0); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - c66: 40 93 65 06 sts 0x0665, r20 - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; -} - -INLINE void FlashRead(void* Buffer, uint32_t Address, uint16_t ByteCount) -{ - while(FlashIsBusy()); - c6a: 27 ff sbrs r18, 7 - c6c: e6 cf rjmp .-52 ; 0xc3a - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - c6e: 20 e1 ldi r18, 0x10 ; 16 - c70: 20 93 66 06 sts 0x0666, r18 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - c74: 23 e0 ldi r18, 0x03 ; 3 - c76: 20 93 a0 09 sts 0x09A0, r18 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - c7a: 20 91 a1 09 lds r18, 0x09A1 - c7e: 26 ff sbrs r18, 6 - c80: fc cf rjmp .-8 ; 0xc7a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - c82: 20 e4 ldi r18, 0x40 ; 64 - c84: 20 93 a1 09 sts 0x09A1, r18 - - return MEMORY_FLASH_USART.DATA; - c88: 20 91 a0 09 lds r18, 0x09A0 -{ - while(FlashIsBusy()); - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(0x03); - SPITransferByte( (Address >> 16) & 0xFF ); - c8c: ad 01 movw r20, r26 - c8e: 66 27 eor r22, r22 - c90: 77 27 eor r23, r23 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - c92: 40 93 a0 09 sts 0x09A0, r20 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - c96: 20 91 a1 09 lds r18, 0x09A1 - c9a: 26 ff sbrs r18, 6 - c9c: fc cf rjmp .-8 ; 0xc96 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - c9e: 20 e4 ldi r18, 0x40 ; 64 - ca0: 20 93 a1 09 sts 0x09A1, r18 - - return MEMORY_FLASH_USART.DATA; - ca4: 20 91 a0 09 lds r18, 0x09A0 - while(FlashIsBusy()); - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(0x03); - SPITransferByte( (Address >> 16) & 0xFF ); - SPITransferByte( (Address >> 8) & 0xFF ); - ca8: 89 2f mov r24, r25 - caa: 9a 2f mov r25, r26 - cac: ab 2f mov r26, r27 - cae: bb 27 eor r27, r27 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - cb0: 80 93 a0 09 sts 0x09A0, r24 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - cb4: 80 91 a1 09 lds r24, 0x09A1 - cb8: 86 ff sbrs r24, 6 - cba: fc cf rjmp .-8 ; 0xcb4 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - cbc: 80 e4 ldi r24, 0x40 ; 64 - cbe: 80 93 a1 09 sts 0x09A1, r24 - - return MEMORY_FLASH_USART.DATA; - cc2: 80 91 a0 09 lds r24, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - cc6: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - cca: 80 91 a1 09 lds r24, 0x09A1 - cce: 86 ff sbrs r24, 6 - cd0: fc cf rjmp .-8 ; 0xcca - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - cd2: 80 e4 ldi r24, 0x40 ; 64 - cd4: 80 93 a1 09 sts 0x09A1, r24 - - return MEMORY_FLASH_USART.DATA; - cd8: 80 91 a0 09 lds r24, 0x09A0 - cdc: e2 e9 ldi r30, 0x92 ; 146 - cde: f0 e2 ldi r31, 0x20 ; 32 - uint8_t* ByteBuffer = (uint8_t*) Buffer; - - while(ByteCount-- > 0) { - MEMORY_FLASH_USART.DATA = 0; - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - ce0: 90 e4 ldi r25, 0x40 ; 64 -INLINE void SPIReadBlock(void* Buffer, uint16_t ByteCount) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - - while(ByteCount-- > 0) { - MEMORY_FLASH_USART.DATA = 0; - ce2: 10 92 a0 09 sts 0x09A0, r1 - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - ce6: 80 91 a1 09 lds r24, 0x09A1 - cea: 86 ff sbrs r24, 6 - cec: fc cf rjmp .-8 ; 0xce6 - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - cee: 90 93 a1 09 sts 0x09A1, r25 - *ByteBuffer++ = MEMORY_FLASH_USART.DATA; - cf2: 80 91 a0 09 lds r24, 0x09A0 - cf6: 81 93 st Z+, r24 - -INLINE void SPIReadBlock(void* Buffer, uint16_t ByteCount) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - - while(ByteCount-- > 0) { - cf8: 84 e2 ldi r24, 0x24 ; 36 - cfa: e2 39 cpi r30, 0x92 ; 146 - cfc: f8 07 cpc r31, r24 - cfe: 89 f7 brne .-30 ; 0xce2 - SPITransferByte(0x03); - SPITransferByte( (Address >> 16) & 0xFF ); - SPITransferByte( (Address >> 8) & 0xFF ); - SPITransferByte( (Address >> 0) & 0xFF ); - SPIReadBlock(Buffer, ByteCount); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - d00: 80 e1 ldi r24, 0x10 ; 16 - d02: 80 93 65 06 sts 0x0665, r24 - d06: 08 95 ret - -00000d08 : - SPITransferByte( 0 ); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; -} - -void MemoryInit(void) -{ - d08: cf 93 push r28 - d0a: df 93 push r29 - d0c: 00 d0 rcall .+0 ; 0xd0e - d0e: 00 d0 rcall .+0 ; 0xd10 - d10: cd b7 in r28, 0x3d ; 61 - d12: de b7 in r29, 0x3e ; 62 - /* Configure MEMORY_FLASH_USART for SPI master mode 0 with maximum clock frequency */ - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - d14: 80 e1 ldi r24, 0x10 ; 16 - d16: 80 93 65 06 sts 0x0665, r24 - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_SCK; - d1a: 92 e0 ldi r25, 0x02 ; 2 - d1c: 90 93 66 06 sts 0x0666, r25 - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_MOSI; - d20: 98 e0 ldi r25, 0x08 ; 8 - d22: 90 93 65 06 sts 0x0665, r25 - - MEMORY_FLASH_PORT.DIRSET = MEMORY_FLASH_SCK | MEMORY_FLASH_MOSI | MEMORY_FLASH_CS; - d26: 9a e1 ldi r25, 0x1A ; 26 - d28: 90 93 61 06 sts 0x0661, r25 - - MEMORY_FLASH_USART.BAUDCTRLA = 0; - d2c: 10 92 a6 09 sts 0x09A6, r1 - MEMORY_FLASH_USART.BAUDCTRLB = 0; - d30: 10 92 a7 09 sts 0x09A7, r1 - MEMORY_FLASH_USART.CTRLC = USART_CMODE_MSPI_gc; - d34: 90 ec ldi r25, 0xC0 ; 192 - d36: 90 93 a5 09 sts 0x09A5, r25 - MEMORY_FLASH_USART.CTRLB = USART_RXEN_bm | USART_TXEN_bm; - d3a: 98 e1 ldi r25, 0x18 ; 24 - d3c: 90 93 a4 09 sts 0x09A4, r25 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - d40: 80 93 66 06 sts 0x0666, r24 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - d44: 87 ed ldi r24, 0xD7 ; 215 - d46: 80 93 a0 09 sts 0x09A0, r24 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - d4a: 80 91 a1 09 lds r24, 0x09A1 - d4e: 86 ff sbrs r24, 6 - d50: fc cf rjmp .-8 ; 0xd4a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - d52: 80 e4 ldi r24, 0x40 ; 64 - d54: 80 93 a1 09 sts 0x09A1, r24 - - return MEMORY_FLASH_USART.DATA; - d58: 80 91 a0 09 lds r24, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - d5c: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - d60: 80 91 a1 09 lds r24, 0x09A1 - d64: 86 ff sbrs r24, 6 - d66: fc cf rjmp .-8 ; 0xd60 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - d68: 80 e4 ldi r24, 0x40 ; 64 - d6a: 80 93 a1 09 sts 0x09A1, r24 - - return MEMORY_FLASH_USART.DATA; - d6e: 80 91 a0 09 lds r24, 0x09A0 - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_STATUS_REG_READ); - Register = SPITransferByte(0); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - d72: 90 e1 ldi r25, 0x10 ; 16 - d74: 90 93 65 06 sts 0x0665, r25 - MEMORY_FLASH_USART.BAUDCTRLB = 0; - MEMORY_FLASH_USART.CTRLC = USART_CMODE_MSPI_gc; - MEMORY_FLASH_USART.CTRLB = USART_RXEN_bm | USART_TXEN_bm; - - - if ( !(FlashReadStatusRegister() & FLASH_STATUS_REG_PAGESIZE_BIT) ) { - d78: 80 fd sbrc r24, 0 - d7a: 3e c0 rjmp .+124 ; 0xdf8 - return !(FlashReadStatusRegister() & FLASH_STATUS_REG_READY_BIT); -} - -INLINE void FlashConfigurePageSize(void) -{ - uint8_t Sequence[] = {0x3D, 0x2A, 0x80, 0xA6}; - d7c: 8d e3 ldi r24, 0x3D ; 61 - d7e: 89 83 std Y+1, r24 ; 0x01 - d80: 8a e2 ldi r24, 0x2A ; 42 - d82: 8a 83 std Y+2, r24 ; 0x02 - d84: 80 e8 ldi r24, 0x80 ; 128 - d86: 8b 83 std Y+3, r24 ; 0x03 - d88: 86 ea ldi r24, 0xA6 ; 166 - d8a: 8c 83 std Y+4, r24 ; 0x04 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - d8c: 20 e1 ldi r18, 0x10 ; 16 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - d8e: 37 ed ldi r19, 0xD7 ; 215 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - d90: 90 e4 ldi r25, 0x40 ; 64 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - d92: 20 93 66 06 sts 0x0666, r18 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - d96: 30 93 a0 09 sts 0x09A0, r19 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - d9a: 80 91 a1 09 lds r24, 0x09A1 - d9e: 86 ff sbrs r24, 6 - da0: fc cf rjmp .-8 ; 0xd9a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - da2: 90 93 a1 09 sts 0x09A1, r25 - - return MEMORY_FLASH_USART.DATA; - da6: 80 91 a0 09 lds r24, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - daa: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - dae: 80 91 a1 09 lds r24, 0x09A1 - db2: 86 ff sbrs r24, 6 - db4: fc cf rjmp .-8 ; 0xdae - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - db6: 90 93 a1 09 sts 0x09A1, r25 - - return MEMORY_FLASH_USART.DATA; - dba: 80 91 a0 09 lds r24, 0x09A0 - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_STATUS_REG_READ); - Register = SPITransferByte(0); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - dbe: 20 93 65 06 sts 0x0665, r18 - -INLINE void FlashConfigurePageSize(void) -{ - uint8_t Sequence[] = {0x3D, 0x2A, 0x80, 0xA6}; - - while(FlashIsBusy()); - dc2: 87 ff sbrs r24, 7 - dc4: e6 cf rjmp .-52 ; 0xd92 - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - dc6: 80 e1 ldi r24, 0x10 ; 16 - dc8: 80 93 66 06 sts 0x0666, r24 - dcc: fe 01 movw r30, r28 - dce: 31 96 adiw r30, 0x01 ; 1 - dd0: ce 01 movw r24, r28 - dd2: 05 96 adiw r24, 0x05 ; 5 - uint8_t* ByteBuffer = (uint8_t*) Buffer; - - while(ByteCount-- > 0) { - MEMORY_FLASH_USART.DATA = *ByteBuffer++; - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - dd4: 30 e4 ldi r19, 0x40 ; 64 -INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - - while(ByteCount-- > 0) { - MEMORY_FLASH_USART.DATA = *ByteBuffer++; - dd6: 21 91 ld r18, Z+ - dd8: 20 93 a0 09 sts 0x09A0, r18 - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - ddc: 20 91 a1 09 lds r18, 0x09A1 - de0: 26 ff sbrs r18, 6 - de2: fc cf rjmp .-8 ; 0xddc - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - de4: 30 93 a1 09 sts 0x09A1, r19 - MEMORY_FLASH_USART.DATA; /* Flush Buffer */ - de8: 20 91 a0 09 lds r18, 0x09A0 - -INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - - while(ByteCount-- > 0) { - dec: e8 17 cp r30, r24 - dee: f9 07 cpc r31, r25 - df0: 91 f7 brne .-28 ; 0xdd6 - - while(FlashIsBusy()); - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPIWriteBlock(Sequence, sizeof(Sequence)); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - df2: 80 e1 ldi r24, 0x10 ; 16 - df4: 80 93 65 06 sts 0x0665, r24 - FlashConfigurePageSize(); - } - - /* Load permanent flash contents to memory at startup */ - MemoryRecall(); -} - df8: 24 96 adiw r28, 0x04 ; 4 - dfa: cd bf out 0x3d, r28 ; 61 - dfc: de bf out 0x3e, r29 ; 62 - dfe: df 91 pop r29 - e00: cf 91 pop r28 - /* Configure for 256 byte Dataflash if not already done. */ - FlashConfigurePageSize(); - } - - /* Load permanent flash contents to memory at startup */ - MemoryRecall(); - e02: 0c cf rjmp .-488 ; 0xc1c - -00000e04 : - /* Recall memory from permanent flash */ - FlashRead(Memory, (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); -} - -void MemoryStore(void) -{ - e04: 5f 92 push r5 - e06: 6f 92 push r6 - e08: 7f 92 push r7 - e0a: 8f 92 push r8 - e0c: 9f 92 push r9 - e0e: af 92 push r10 - e10: bf 92 push r11 - e12: cf 92 push r12 - e14: df 92 push r13 - e16: ef 92 push r14 - e18: ff 92 push r15 - e1a: 0f 93 push r16 - e1c: 1f 93 push r17 - e1e: cf 93 push r28 - e20: df 93 push r29 - /* Store current memory into permanent flash */ - FlashWrite(Memory, (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); - e22: 80 91 fd 24 lds r24, 0x24FD - e26: 90 e0 ldi r25, 0x00 ; 0 - e28: a0 e0 ldi r26, 0x00 ; 0 - e2a: b0 e0 ldi r27, 0x00 ; 0 - e2c: 6a e0 ldi r22, 0x0A ; 10 - e2e: 88 0f add r24, r24 - e30: 99 1f adc r25, r25 - e32: aa 1f adc r26, r26 - e34: bb 1f adc r27, r27 - e36: 6a 95 dec r22 - e38: d1 f7 brne .-12 ; 0xe2e - e3a: 00 e0 ldi r16, 0x00 ; 0 - e3c: 14 e0 ldi r17, 0x04 ; 4 -INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) -{ - while(ByteCount > 0) { - uint16_t PageAddress = Address / FLASH_PAGE_SIZE; - uint8_t ByteAddress = Address % FLASH_PAGE_SIZE; - uint16_t PageBytes = MIN(FLASH_PAGE_SIZE - ByteAddress, ByteCount); - e3e: e1 2c mov r14, r1 - e40: ff 24 eor r15, r15 - e42: f3 94 inc r15 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - e44: e0 e1 ldi r30, 0x10 ; 16 - e46: ce 2e mov r12, r30 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - e48: f7 ed ldi r31, 0xD7 ; 215 - e4a: bf 2e mov r11, r31 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - e4c: c0 e4 ldi r28, 0x40 ; 64 - e4e: dc 2e mov r13, r28 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - e50: d0 e1 ldi r29, 0x10 ; 16 - e52: ad 2e mov r10, r29 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - e54: 27 ed ldi r18, 0xD7 ; 215 - e56: 92 2e mov r9, r18 - e58: 33 e5 ldi r19, 0x53 ; 83 - e5a: 63 2e mov r6, r19 - e5c: 44 e8 ldi r20, 0x84 ; 132 - e5e: 74 2e mov r7, r20 - e60: 53 e8 ldi r21, 0x83 ; 131 - e62: 85 2e mov r8, r21 -} - -INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) -{ - while(ByteCount > 0) { - uint16_t PageAddress = Address / FLASH_PAGE_SIZE; - e64: 49 2f mov r20, r25 - e66: 5a 2f mov r21, r26 - e68: 6b 2f mov r22, r27 - e6a: 77 27 eor r23, r23 - uint8_t ByteAddress = Address % FLASH_PAGE_SIZE; - e6c: 38 2f mov r19, r24 - uint16_t PageBytes = MIN(FLASH_PAGE_SIZE - ByteAddress, ByteCount); - e6e: e7 01 movw r28, r14 - e70: c8 1b sub r28, r24 - e72: d1 09 sbc r29, r1 - e74: 0c 17 cp r16, r28 - e76: 1d 07 cpc r17, r29 - e78: 08 f4 brcc .+2 ; 0xe7c - e7a: e8 01 movw r28, r16 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - e7c: a0 92 66 06 sts 0x0666, r10 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - e80: 90 92 a0 09 sts 0x09A0, r9 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - e84: 20 91 a1 09 lds r18, 0x09A1 - e88: 26 ff sbrs r18, 6 - e8a: fc cf rjmp .-8 ; 0xe84 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - e8c: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - e90: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - e94: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - e98: 20 91 a1 09 lds r18, 0x09A1 - e9c: 26 ff sbrs r18, 6 - e9e: fc cf rjmp .-8 ; 0xe98 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - ea0: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - ea4: 20 91 a0 09 lds r18, 0x09A0 - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_STATUS_REG_READ); - Register = SPITransferByte(0); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - ea8: c0 92 65 06 sts 0x0665, r12 - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; -} - -INLINE void FlashMemoryToBuffer(uint16_t PageAddress) -{ - while(FlashIsBusy()); - eac: 27 ff sbrs r18, 7 - eae: e6 cf rjmp .-52 ; 0xe7c - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - eb0: a0 92 66 06 sts 0x0666, r10 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - eb4: 60 92 a0 09 sts 0x09A0, r6 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - eb8: 20 91 a1 09 lds r18, 0x09A1 - ebc: 26 ff sbrs r18, 6 - ebe: fc cf rjmp .-8 ; 0xeb8 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - ec0: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - ec4: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - ec8: 50 93 a0 09 sts 0x09A0, r21 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - ecc: 20 91 a1 09 lds r18, 0x09A1 - ed0: 26 ff sbrs r18, 6 - ed2: fc cf rjmp .-8 ; 0xecc - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - ed4: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - ed8: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - edc: 40 93 a0 09 sts 0x09A0, r20 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - ee0: 20 91 a1 09 lds r18, 0x09A1 - ee4: 26 ff sbrs r18, 6 - ee6: fc cf rjmp .-8 ; 0xee0 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - ee8: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - eec: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - ef0: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - ef4: 20 91 a1 09 lds r18, 0x09A1 - ef8: 26 ff sbrs r18, 6 - efa: fc cf rjmp .-8 ; 0xef4 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - efc: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - f00: 20 91 a0 09 lds r18, 0x09A0 - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_MEM_TO_BUF1); - SPITransferByte( (PageAddress >> 8) & 0xFF ); - SPITransferByte( (PageAddress >> 0) & 0xFF ); - SPITransferByte( 0 ); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - f04: c0 92 65 06 sts 0x0665, r12 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - f08: c0 92 66 06 sts 0x0666, r12 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - f0c: b0 92 a0 09 sts 0x09A0, r11 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - f10: 20 91 a1 09 lds r18, 0x09A1 - f14: 26 ff sbrs r18, 6 - f16: fc cf rjmp .-8 ; 0xf10 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - f18: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - f1c: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - f20: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - f24: 20 91 a1 09 lds r18, 0x09A1 - f28: 26 ff sbrs r18, 6 - f2a: fc cf rjmp .-8 ; 0xf24 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - f2c: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - f30: 20 91 a0 09 lds r18, 0x09A0 - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_STATUS_REG_READ); - Register = SPITransferByte(0); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - f34: c0 92 65 06 sts 0x0665, r12 - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; -} - -INLINE void FlashWriteBuffer(const void* Buffer, uint8_t Address, uint16_t ByteCount) -{ - while(FlashIsBusy()); - f38: 27 ff sbrs r18, 7 - f3a: e6 cf rjmp .-52 ; 0xf08 - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - f3c: a0 92 66 06 sts 0x0666, r10 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - f40: 70 92 a0 09 sts 0x09A0, r7 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - f44: 20 91 a1 09 lds r18, 0x09A1 - f48: 26 ff sbrs r18, 6 - f4a: fc cf rjmp .-8 ; 0xf44 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - f4c: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - f50: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - f54: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - f58: 20 91 a1 09 lds r18, 0x09A1 - f5c: 26 ff sbrs r18, 6 - f5e: fc cf rjmp .-8 ; 0xf58 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - f60: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - f64: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - f68: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - f6c: 20 91 a1 09 lds r18, 0x09A1 - f70: 26 ff sbrs r18, 6 - f72: fc cf rjmp .-8 ; 0xf6c - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - f74: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - f78: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - f7c: 30 93 a0 09 sts 0x09A0, r19 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - f80: 20 91 a1 09 lds r18, 0x09A1 - f84: 26 ff sbrs r18, 6 - f86: fc cf rjmp .-8 ; 0xf80 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - f88: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - f8c: 20 91 a0 09 lds r18, 0x09A0 - -INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - - while(ByteCount-- > 0) { - f90: 20 97 sbiw r28, 0x00 ; 0 - f92: 99 f0 breq .+38 ; 0xfba - f94: e2 e9 ldi r30, 0x92 ; 146 - f96: f0 e2 ldi r31, 0x20 ; 32 - f98: 9e 01 movw r18, r28 - f9a: 2e 56 subi r18, 0x6E ; 110 - f9c: 3f 4d sbci r19, 0xDF ; 223 - MEMORY_FLASH_USART.DATA = *ByteBuffer++; - f9e: 51 90 ld r5, Z+ - fa0: 50 92 a0 09 sts 0x09A0, r5 - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - fa4: 50 90 a1 09 lds r5, 0x09A1 - fa8: 56 fe sbrs r5, 6 - faa: fc cf rjmp .-8 ; 0xfa4 - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - fac: d0 92 a1 09 sts 0x09A1, r13 - MEMORY_FLASH_USART.DATA; /* Flush Buffer */ - fb0: 50 90 a0 09 lds r5, 0x09A0 - -INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - - while(ByteCount-- > 0) { - fb4: e2 17 cp r30, r18 - fb6: f3 07 cpc r31, r19 - fb8: 91 f7 brne .-28 ; 0xf9e - SPITransferByte(FLASH_CMD_BUF1_WRITE); - SPITransferByte( 0 ); - SPITransferByte( 0 ); - SPITransferByte( Address ); - SPIWriteBlock(Buffer, ByteCount); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - fba: c0 92 65 06 sts 0x0665, r12 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - fbe: c0 92 66 06 sts 0x0666, r12 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - fc2: b0 92 a0 09 sts 0x09A0, r11 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - fc6: 20 91 a1 09 lds r18, 0x09A1 - fca: 26 ff sbrs r18, 6 - fcc: fc cf rjmp .-8 ; 0xfc6 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - fce: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - fd2: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - fd6: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - fda: 20 91 a1 09 lds r18, 0x09A1 - fde: 26 ff sbrs r18, 6 - fe0: fc cf rjmp .-8 ; 0xfda - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - fe2: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - fe6: 20 91 a0 09 lds r18, 0x09A0 - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_STATUS_REG_READ); - Register = SPITransferByte(0); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - fea: c0 92 65 06 sts 0x0665, r12 - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; -} - -INLINE void FlashBufferToMemory(uint16_t PageAddress) -{ - while(FlashIsBusy()); - fee: 27 ff sbrs r18, 7 - ff0: e6 cf rjmp .-52 ; 0xfbe - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - ff2: a0 92 66 06 sts 0x0666, r10 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - ff6: 80 92 a0 09 sts 0x09A0, r8 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - ffa: 20 91 a1 09 lds r18, 0x09A1 - ffe: 26 ff sbrs r18, 6 - 1000: fc cf rjmp .-8 ; 0xffa - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1002: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - 1006: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 100a: 50 93 a0 09 sts 0x09A0, r21 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 100e: 20 91 a1 09 lds r18, 0x09A1 - 1012: 26 ff sbrs r18, 6 - 1014: fc cf rjmp .-8 ; 0x100e - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1016: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - 101a: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 101e: 40 93 a0 09 sts 0x09A0, r20 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 1022: 20 91 a1 09 lds r18, 0x09A1 - 1026: 26 ff sbrs r18, 6 - 1028: fc cf rjmp .-8 ; 0x1022 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 102a: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - 102e: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 1032: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 1036: 20 91 a1 09 lds r18, 0x09A1 - 103a: 26 ff sbrs r18, 6 - 103c: fc cf rjmp .-8 ; 0x1036 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 103e: d0 92 a1 09 sts 0x09A1, r13 - - return MEMORY_FLASH_USART.DATA; - 1042: 20 91 a0 09 lds r18, 0x09A0 - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_BUF1_TO_MEM_ERASE); - SPITransferByte( (PageAddress >> 8) & 0xFF ); - SPITransferByte( (PageAddress >> 0) & 0xFF ); - SPITransferByte( 0 ); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - 1046: c0 92 65 06 sts 0x0665, r12 - - FlashMemoryToBuffer(PageAddress); - FlashWriteBuffer(Buffer, ByteAddress, PageBytes); - FlashBufferToMemory(PageAddress); - - ByteCount -= PageBytes; - 104a: 0c 1b sub r16, r28 - 104c: 1d 0b sbc r17, r29 - Address += PageBytes; - 104e: 8c 0f add r24, r28 - 1050: 9d 1f adc r25, r29 - 1052: a1 1d adc r26, r1 - 1054: b1 1d adc r27, r1 - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; -} - -INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) -{ - while(ByteCount > 0) { - 1056: 01 15 cp r16, r1 - 1058: 11 05 cpc r17, r1 - 105a: 09 f0 breq .+2 ; 0x105e - 105c: 03 cf rjmp .-506 ; 0xe64 - -void MemoryStore(void) -{ - /* Store current memory into permanent flash */ - FlashWrite(Memory, (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); -} - 105e: df 91 pop r29 - 1060: cf 91 pop r28 - 1062: 1f 91 pop r17 - 1064: 0f 91 pop r16 - 1066: ff 90 pop r15 - 1068: ef 90 pop r14 - 106a: df 90 pop r13 - 106c: cf 90 pop r12 - 106e: bf 90 pop r11 - 1070: af 90 pop r10 - 1072: 9f 90 pop r9 - 1074: 8f 90 pop r8 - 1076: 7f 90 pop r7 - 1078: 6f 90 pop r6 - 107a: 5f 90 pop r5 - 107c: 08 95 ret - -0000107e : - -bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) -{ - 107e: 2f 92 push r2 - 1080: 3f 92 push r3 - 1082: 4f 92 push r4 - 1084: 5f 92 push r5 - 1086: 6f 92 push r6 - 1088: 7f 92 push r7 - 108a: 8f 92 push r8 - 108c: 9f 92 push r9 - 108e: af 92 push r10 - 1090: bf 92 push r11 - 1092: cf 92 push r12 - 1094: df 92 push r13 - 1096: ef 92 push r14 - 1098: ff 92 push r15 - 109a: 0f 93 push r16 - 109c: 1f 93 push r17 - 109e: cf 93 push r28 - 10a0: df 93 push r29 - 10a2: cd b7 in r28, 0x3d ; 61 - 10a4: de b7 in r29, 0x3e ; 62 - 10a6: 2a 97 sbiw r28, 0x0a ; 10 - 10a8: cd bf out 0x3d, r28 ; 61 - 10aa: de bf out 0x3e, r29 ; 62 - 10ac: 8c 01 movw r16, r24 - if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { - 10ae: 41 15 cp r20, r1 - 10b0: 84 e0 ldi r24, 0x04 ; 4 - 10b2: 58 07 cpc r21, r24 - 10b4: 61 05 cpc r22, r1 - 10b6: 71 05 cpc r23, r1 - 10b8: 08 f0 brcs .+2 ; 0x10bc - 10ba: 8e c1 rjmp .+796 ; 0x13d8 - /* Prevent writing out of bounds by silently ignoring it */ - return true; - } else { - /* Calculate bytes left in memory and start writing */ - uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; - uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; - 10bc: 80 91 fd 24 lds r24, 0x24FD - 10c0: 90 e0 ldi r25, 0x00 ; 0 - 10c2: a0 e0 ldi r26, 0x00 ; 0 - 10c4: b0 e0 ldi r27, 0x00 ; 0 - 10c6: ea e0 ldi r30, 0x0A ; 10 - 10c8: 88 0f add r24, r24 - 10ca: 99 1f adc r25, r25 - 10cc: aa 1f adc r26, r26 - 10ce: bb 1f adc r27, r27 - 10d0: ea 95 dec r30 - 10d2: d1 f7 brne .-12 ; 0x10c8 - 10d4: 84 0f add r24, r20 - 10d6: 95 1f adc r25, r21 - 10d8: a6 1f adc r26, r22 - 10da: b7 1f adc r27, r23 - if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { - /* Prevent writing out of bounds by silently ignoring it */ - return true; - } else { - /* Calculate bytes left in memory and start writing */ - uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; - 10dc: 81 2c mov r8, r1 - 10de: f4 e0 ldi r31, 0x04 ; 4 - 10e0: 9f 2e mov r9, r31 - 10e2: a1 2c mov r10, r1 - 10e4: b1 2c mov r11, r1 - uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; - ByteCount = MIN(ByteCount, BytesLeft); - 10e6: 69 01 movw r12, r18 - 10e8: e1 2c mov r14, r1 - 10ea: f1 2c mov r15, r1 - 10ec: 84 1a sub r8, r20 - 10ee: 95 0a sbc r9, r21 - 10f0: a6 0a sbc r10, r22 - 10f2: b7 0a sbc r11, r23 - 10f4: 89 82 std Y+1, r8 ; 0x01 - 10f6: 9a 82 std Y+2, r9 ; 0x02 - 10f8: ab 82 std Y+3, r10 ; 0x03 - 10fa: bc 82 std Y+4, r11 ; 0x04 - 10fc: c8 14 cp r12, r8 - 10fe: d9 04 cpc r13, r9 - 1100: ea 04 cpc r14, r10 - 1102: fb 04 cpc r15, r11 - 1104: 08 f4 brcc .+2 ; 0x1108 - 1106: 7f c1 rjmp .+766 ; 0x1406 - 1108: 29 81 ldd r18, Y+1 ; 0x01 - 110a: 3a 81 ldd r19, Y+2 ; 0x02 - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; -} - -INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) -{ - while(ByteCount > 0) { - 110c: 21 15 cp r18, r1 - 110e: 31 05 cpc r19, r1 - 1110: 09 f4 brne .+2 ; 0x1114 - 1112: 62 c1 rjmp .+708 ; 0x13d8 - uint16_t PageAddress = Address / FLASH_PAGE_SIZE; - uint8_t ByteAddress = Address % FLASH_PAGE_SIZE; - uint16_t PageBytes = MIN(FLASH_PAGE_SIZE - ByteAddress, ByteCount); - 1114: e1 2c mov r14, r1 - 1116: ff 24 eor r15, r15 - 1118: f3 94 inc r15 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - 111a: e0 e1 ldi r30, 0x10 ; 16 - 111c: 7e 2e mov r7, r30 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 111e: f7 ed ldi r31, 0xD7 ; 215 - 1120: df 2e mov r13, r31 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1122: e0 e4 ldi r30, 0x40 ; 64 - 1124: 4e 2e mov r4, r30 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - 1126: f0 e1 ldi r31, 0x10 ; 16 - 1128: cf 2e mov r12, r31 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 112a: e7 ed ldi r30, 0xD7 ; 215 - 112c: 3e 2e mov r3, r30 - 112e: f3 e5 ldi r31, 0x53 ; 83 - 1130: 5f 2e mov r5, r31 - 1132: e4 e8 ldi r30, 0x84 ; 132 - 1134: 6e 2e mov r6, r30 - 1136: f3 e8 ldi r31, 0x83 ; 131 - 1138: 2f 2e mov r2, r31 - 113a: 29 87 std Y+9, r18 ; 0x09 - 113c: 3a 87 std Y+10, r19 ; 0x0a - 113e: 4d 83 std Y+5, r20 ; 0x05 - 1140: 5e 83 std Y+6, r21 ; 0x06 - 1142: 6f 83 std Y+7, r22 ; 0x07 - 1144: 78 87 std Y+8, r23 ; 0x08 - 1146: b9 01 movw r22, r18 -} - -INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) -{ - while(ByteCount > 0) { - uint16_t PageAddress = Address / FLASH_PAGE_SIZE; - 1148: 89 2e mov r8, r25 - 114a: 9a 2e mov r9, r26 - 114c: ab 2e mov r10, r27 - 114e: bb 24 eor r11, r11 - uint8_t ByteAddress = Address % FLASH_PAGE_SIZE; - 1150: 38 2f mov r19, r24 - uint16_t PageBytes = MIN(FLASH_PAGE_SIZE - ByteAddress, ByteCount); - 1152: a7 01 movw r20, r14 - 1154: 48 1b sub r20, r24 - 1156: 51 09 sbc r21, r1 - 1158: 64 17 cp r22, r20 - 115a: 75 07 cpc r23, r21 - 115c: 08 f4 brcc .+2 ; 0x1160 - 115e: ab 01 movw r20, r22 - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - 1160: c0 92 66 06 sts 0x0666, r12 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 1164: 30 92 a0 09 sts 0x09A0, r3 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 1168: 20 91 a1 09 lds r18, 0x09A1 - 116c: 26 ff sbrs r18, 6 - 116e: fc cf rjmp .-8 ; 0x1168 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1170: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 1174: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 1178: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 117c: 20 91 a1 09 lds r18, 0x09A1 - 1180: 26 ff sbrs r18, 6 - 1182: fc cf rjmp .-8 ; 0x117c - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1184: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 1188: 20 91 a0 09 lds r18, 0x09A0 - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_STATUS_REG_READ); - Register = SPITransferByte(0); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - 118c: 70 92 65 06 sts 0x0665, r7 - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; -} - -INLINE void FlashMemoryToBuffer(uint16_t PageAddress) -{ - while(FlashIsBusy()); - 1190: 27 ff sbrs r18, 7 - 1192: e6 cf rjmp .-52 ; 0x1160 - 1194: 69 87 std Y+9, r22 ; 0x09 - 1196: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - 1198: c0 92 66 06 sts 0x0666, r12 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 119c: 50 92 a0 09 sts 0x09A0, r5 - 11a0: 69 85 ldd r22, Y+9 ; 0x09 - 11a2: 7a 85 ldd r23, Y+10 ; 0x0a - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 11a4: 20 91 a1 09 lds r18, 0x09A1 - 11a8: 26 ff sbrs r18, 6 - 11aa: fc cf rjmp .-8 ; 0x11a4 - 11ac: 69 87 std Y+9, r22 ; 0x09 - 11ae: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 11b0: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 11b4: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 11b8: 90 92 a0 09 sts 0x09A0, r9 - 11bc: 69 85 ldd r22, Y+9 ; 0x09 - 11be: 7a 85 ldd r23, Y+10 ; 0x0a - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 11c0: 20 91 a1 09 lds r18, 0x09A1 - 11c4: 26 ff sbrs r18, 6 - 11c6: fc cf rjmp .-8 ; 0x11c0 - 11c8: 69 87 std Y+9, r22 ; 0x09 - 11ca: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 11cc: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 11d0: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 11d4: 80 92 a0 09 sts 0x09A0, r8 - 11d8: 69 85 ldd r22, Y+9 ; 0x09 - 11da: 7a 85 ldd r23, Y+10 ; 0x0a - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 11dc: 20 91 a1 09 lds r18, 0x09A1 - 11e0: 26 ff sbrs r18, 6 - 11e2: fc cf rjmp .-8 ; 0x11dc - 11e4: 69 87 std Y+9, r22 ; 0x09 - 11e6: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 11e8: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 11ec: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 11f0: 10 92 a0 09 sts 0x09A0, r1 - 11f4: 69 85 ldd r22, Y+9 ; 0x09 - 11f6: 7a 85 ldd r23, Y+10 ; 0x0a - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 11f8: 20 91 a1 09 lds r18, 0x09A1 - 11fc: 26 ff sbrs r18, 6 - 11fe: fc cf rjmp .-8 ; 0x11f8 - 1200: 69 87 std Y+9, r22 ; 0x09 - 1202: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1204: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 1208: 20 91 a0 09 lds r18, 0x09A0 - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_MEM_TO_BUF1); - SPITransferByte( (PageAddress >> 8) & 0xFF ); - SPITransferByte( (PageAddress >> 0) & 0xFF ); - SPITransferByte( 0 ); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - 120c: 70 92 65 06 sts 0x0665, r7 - 1210: 69 85 ldd r22, Y+9 ; 0x09 - 1212: 7a 85 ldd r23, Y+10 ; 0x0a - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - 1214: 70 92 66 06 sts 0x0666, r7 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 1218: d0 92 a0 09 sts 0x09A0, r13 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 121c: 20 91 a1 09 lds r18, 0x09A1 - 1220: 26 ff sbrs r18, 6 - 1222: fc cf rjmp .-8 ; 0x121c - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1224: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 1228: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 122c: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 1230: 20 91 a1 09 lds r18, 0x09A1 - 1234: 26 ff sbrs r18, 6 - 1236: fc cf rjmp .-8 ; 0x1230 - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1238: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 123c: 20 91 a0 09 lds r18, 0x09A0 - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_STATUS_REG_READ); - Register = SPITransferByte(0); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - 1240: 70 92 65 06 sts 0x0665, r7 - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; -} - -INLINE void FlashWriteBuffer(const void* Buffer, uint8_t Address, uint16_t ByteCount) -{ - while(FlashIsBusy()); - 1244: 27 ff sbrs r18, 7 - 1246: e6 cf rjmp .-52 ; 0x1214 - 1248: 69 87 std Y+9, r22 ; 0x09 - 124a: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - 124c: c0 92 66 06 sts 0x0666, r12 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 1250: 60 92 a0 09 sts 0x09A0, r6 - 1254: 69 85 ldd r22, Y+9 ; 0x09 - 1256: 7a 85 ldd r23, Y+10 ; 0x0a - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 1258: 20 91 a1 09 lds r18, 0x09A1 - 125c: 26 ff sbrs r18, 6 - 125e: fc cf rjmp .-8 ; 0x1258 - 1260: 69 87 std Y+9, r22 ; 0x09 - 1262: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1264: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 1268: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 126c: 10 92 a0 09 sts 0x09A0, r1 - 1270: 69 85 ldd r22, Y+9 ; 0x09 - 1272: 7a 85 ldd r23, Y+10 ; 0x0a - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 1274: 20 91 a1 09 lds r18, 0x09A1 - 1278: 26 ff sbrs r18, 6 - 127a: fc cf rjmp .-8 ; 0x1274 - 127c: 69 87 std Y+9, r22 ; 0x09 - 127e: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1280: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 1284: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 1288: 10 92 a0 09 sts 0x09A0, r1 - 128c: 69 85 ldd r22, Y+9 ; 0x09 - 128e: 7a 85 ldd r23, Y+10 ; 0x0a - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 1290: 20 91 a1 09 lds r18, 0x09A1 - 1294: 26 ff sbrs r18, 6 - 1296: fc cf rjmp .-8 ; 0x1290 - 1298: 69 87 std Y+9, r22 ; 0x09 - 129a: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 129c: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 12a0: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 12a4: 30 93 a0 09 sts 0x09A0, r19 - 12a8: 69 85 ldd r22, Y+9 ; 0x09 - 12aa: 7a 85 ldd r23, Y+10 ; 0x0a - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 12ac: 20 91 a1 09 lds r18, 0x09A1 - 12b0: 26 ff sbrs r18, 6 - 12b2: fc cf rjmp .-8 ; 0x12ac - 12b4: 69 87 std Y+9, r22 ; 0x09 - 12b6: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 12b8: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 12bc: 20 91 a0 09 lds r18, 0x09A0 - -INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - - while(ByteCount-- > 0) { - 12c0: 41 15 cp r20, r1 - 12c2: 51 05 cpc r21, r1 - 12c4: 91 f0 breq .+36 ; 0x12ea - 12c6: f8 01 movw r30, r16 - 12c8: 9a 01 movw r18, r20 - 12ca: 20 0f add r18, r16 - 12cc: 31 1f adc r19, r17 - MEMORY_FLASH_USART.DATA = *ByteBuffer++; - 12ce: 61 91 ld r22, Z+ - 12d0: 60 93 a0 09 sts 0x09A0, r22 - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 12d4: 60 91 a1 09 lds r22, 0x09A1 - 12d8: 66 ff sbrs r22, 6 - 12da: fc cf rjmp .-8 ; 0x12d4 - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 12dc: 40 92 a1 09 sts 0x09A1, r4 - MEMORY_FLASH_USART.DATA; /* Flush Buffer */ - 12e0: 60 91 a0 09 lds r22, 0x09A0 - -INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) -{ - uint8_t* ByteBuffer = (uint8_t*) Buffer; - - while(ByteCount-- > 0) { - 12e4: e2 17 cp r30, r18 - 12e6: f3 07 cpc r31, r19 - 12e8: 91 f7 brne .-28 ; 0x12ce - SPITransferByte(FLASH_CMD_BUF1_WRITE); - SPITransferByte( 0 ); - SPITransferByte( 0 ); - SPITransferByte( Address ); - SPIWriteBlock(Buffer, ByteCount); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - 12ea: 70 92 65 06 sts 0x0665, r7 - 12ee: 69 85 ldd r22, Y+9 ; 0x09 - 12f0: 7a 85 ldd r23, Y+10 ; 0x0a - -INLINE uint8_t FlashReadStatusRegister(void) -{ - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - 12f2: 70 92 66 06 sts 0x0666, r7 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 12f6: d0 92 a0 09 sts 0x09A0, r13 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 12fa: 20 91 a1 09 lds r18, 0x09A1 - 12fe: 26 ff sbrs r18, 6 - 1300: fc cf rjmp .-8 ; 0x12fa - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1302: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 1306: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 130a: 10 92 a0 09 sts 0x09A0, r1 - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 130e: 20 91 a1 09 lds r18, 0x09A1 - 1312: 26 ff sbrs r18, 6 - 1314: fc cf rjmp .-8 ; 0x130e - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1316: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 131a: 20 91 a0 09 lds r18, 0x09A0 - uint8_t Register; - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_STATUS_REG_READ); - Register = SPITransferByte(0); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - 131e: 70 92 65 06 sts 0x0665, r7 - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; -} - -INLINE void FlashBufferToMemory(uint16_t PageAddress) -{ - while(FlashIsBusy()); - 1322: 27 ff sbrs r18, 7 - 1324: e6 cf rjmp .-52 ; 0x12f2 - 1326: 69 87 std Y+9, r22 ; 0x09 - 1328: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - 132a: c0 92 66 06 sts 0x0666, r12 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 132e: 20 92 a0 09 sts 0x09A0, r2 - 1332: 69 85 ldd r22, Y+9 ; 0x09 - 1334: 7a 85 ldd r23, Y+10 ; 0x0a - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 1336: 20 91 a1 09 lds r18, 0x09A1 - 133a: 26 ff sbrs r18, 6 - 133c: fc cf rjmp .-8 ; 0x1336 - 133e: 69 87 std Y+9, r22 ; 0x09 - 1340: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1342: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 1346: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 134a: 90 92 a0 09 sts 0x09A0, r9 - 134e: 69 85 ldd r22, Y+9 ; 0x09 - 1350: 7a 85 ldd r23, Y+10 ; 0x0a - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 1352: 20 91 a1 09 lds r18, 0x09A1 - 1356: 26 ff sbrs r18, 6 - 1358: fc cf rjmp .-8 ; 0x1352 - 135a: 69 87 std Y+9, r22 ; 0x09 - 135c: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 135e: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 1362: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 1366: 80 92 a0 09 sts 0x09A0, r8 - 136a: 69 85 ldd r22, Y+9 ; 0x09 - 136c: 7a 85 ldd r23, Y+10 ; 0x0a - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 136e: 20 91 a1 09 lds r18, 0x09A1 - 1372: 26 ff sbrs r18, 6 - 1374: fc cf rjmp .-8 ; 0x136e - 1376: 69 87 std Y+9, r22 ; 0x09 - 1378: 7a 87 std Y+10, r23 ; 0x0a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 137a: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 137e: 20 91 a0 09 lds r18, 0x09A0 - -static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; - -INLINE uint8_t SPITransferByte(uint8_t Data) -{ - MEMORY_FLASH_USART.DATA = Data; - 1382: 10 92 a0 09 sts 0x09A0, r1 - 1386: 69 85 ldd r22, Y+9 ; 0x09 - 1388: 7a 85 ldd r23, Y+10 ; 0x0a - - while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); - 138a: 20 91 a1 09 lds r18, 0x09A1 - 138e: 26 ff sbrs r18, 6 - 1390: fc cf rjmp .-8 ; 0x138a - - MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; - 1392: 40 92 a1 09 sts 0x09A1, r4 - - return MEMORY_FLASH_USART.DATA; - 1396: 20 91 a0 09 lds r18, 0x09A0 - MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; - SPITransferByte(FLASH_CMD_BUF1_TO_MEM_ERASE); - SPITransferByte( (PageAddress >> 8) & 0xFF ); - SPITransferByte( (PageAddress >> 0) & 0xFF ); - SPITransferByte( 0 ); - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; - 139a: 70 92 65 06 sts 0x0665, r7 - - FlashMemoryToBuffer(PageAddress); - FlashWriteBuffer(Buffer, ByteAddress, PageBytes); - FlashBufferToMemory(PageAddress); - - ByteCount -= PageBytes; - 139e: 64 1b sub r22, r20 - 13a0: 75 0b sbc r23, r21 - 13a2: 69 87 std Y+9, r22 ; 0x09 - 13a4: 7a 87 std Y+10, r23 ; 0x0a - Address += PageBytes; - 13a6: 84 0f add r24, r20 - 13a8: 95 1f adc r25, r21 - 13aa: a1 1d adc r26, r1 - 13ac: b1 1d adc r27, r1 - MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; -} - -INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) -{ - while(ByteCount > 0) { - 13ae: 61 15 cp r22, r1 - 13b0: 71 05 cpc r23, r1 - 13b2: 09 f0 breq .+2 ; 0x13b6 - 13b4: c9 ce rjmp .-622 ; 0x1148 - 13b6: 4d 81 ldd r20, Y+5 ; 0x05 - 13b8: 5e 81 ldd r21, Y+6 ; 0x06 - 13ba: 6f 81 ldd r22, Y+7 ; 0x07 - 13bc: 78 85 ldd r23, Y+8 ; 0x08 - - /* Store into flash */ - FlashWrite(Buffer, FlashAddress, ByteCount); - - /* Store to local memory */ - uint8_t* DstPtr = &Memory[BlockAddress]; - 13be: da 01 movw r26, r20 - 13c0: ae 56 subi r26, 0x6E ; 110 - 13c2: bf 4d sbci r27, 0xDF ; 223 - 13c4: 89 81 ldd r24, Y+1 ; 0x01 - 13c6: 9a 81 ldd r25, Y+2 ; 0x02 - 13c8: 8a 0f add r24, r26 - 13ca: 9b 1f adc r25, r27 - 13cc: f8 01 movw r30, r16 - uint8_t* SrcPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - *DstPtr++ = *SrcPtr++; - 13ce: 21 91 ld r18, Z+ - 13d0: 2d 93 st X+, r18 - - /* Store to local memory */ - uint8_t* DstPtr = &Memory[BlockAddress]; - uint8_t* SrcPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - 13d2: a8 17 cp r26, r24 - 13d4: b9 07 cpc r27, r25 - 13d6: d9 f7 brne .-10 ; 0x13ce - } - - return true; - } - -} - 13d8: 81 e0 ldi r24, 0x01 ; 1 - 13da: 2a 96 adiw r28, 0x0a ; 10 - 13dc: cd bf out 0x3d, r28 ; 61 - 13de: de bf out 0x3e, r29 ; 62 - 13e0: df 91 pop r29 - 13e2: cf 91 pop r28 - 13e4: 1f 91 pop r17 - 13e6: 0f 91 pop r16 - 13e8: ff 90 pop r15 - 13ea: ef 90 pop r14 - 13ec: df 90 pop r13 - 13ee: cf 90 pop r12 - 13f0: bf 90 pop r11 - 13f2: af 90 pop r10 - 13f4: 9f 90 pop r9 - 13f6: 8f 90 pop r8 - 13f8: 7f 90 pop r7 - 13fa: 6f 90 pop r6 - 13fc: 5f 90 pop r5 - 13fe: 4f 90 pop r4 - 1400: 3f 90 pop r3 - 1402: 2f 90 pop r2 - 1404: 08 95 ret - return true; - } else { - /* Calculate bytes left in memory and start writing */ - uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; - uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; - ByteCount = MIN(ByteCount, BytesLeft); - 1406: c9 82 std Y+1, r12 ; 0x01 - 1408: da 82 std Y+2, r13 ; 0x02 - 140a: eb 82 std Y+3, r14 ; 0x03 - 140c: fc 82 std Y+4, r15 ; 0x04 - 140e: 7c ce rjmp .-776 ; 0x1108 - -00001410 : - } - -} - -bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) -{ - 1410: cf 92 push r12 - 1412: df 92 push r13 - 1414: ef 92 push r14 - 1416: ff 92 push r15 - 1418: 0f 93 push r16 - 141a: 1f 93 push r17 - 141c: 69 01 movw r12, r18 - if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { - 141e: 41 15 cp r20, r1 - 1420: 24 e0 ldi r18, 0x04 ; 4 - 1422: 52 07 cpc r21, r18 - 1424: 61 05 cpc r22, r1 - 1426: 71 05 cpc r23, r1 - 1428: 40 f5 brcc .+80 ; 0x147a - /* There are bytes out of bounds to be read. Notify that we are done. */ - return false; - } else { - /* Calculate bytes left in memory and issue reading */ - uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; - 142a: 00 e0 ldi r16, 0x00 ; 0 - 142c: 14 e0 ldi r17, 0x04 ; 4 - 142e: 20 e0 ldi r18, 0x00 ; 0 - 1430: 30 e0 ldi r19, 0x00 ; 0 - //uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; - ByteCount = MIN(ByteCount, BytesLeft); - 1432: e1 2c mov r14, r1 - 1434: f1 2c mov r15, r1 - 1436: 04 1b sub r16, r20 - 1438: 15 0b sbc r17, r21 - 143a: 26 0b sbc r18, r22 - 143c: 37 0b sbc r19, r23 - 143e: c0 16 cp r12, r16 - 1440: d1 06 cpc r13, r17 - 1442: e2 06 cpc r14, r18 - 1444: f3 06 cpc r15, r19 - 1446: b0 f0 brcs .+44 ; 0x1474 - - /* Output local memory contents */ - uint8_t* DstPtr = (uint8_t*) Buffer; - uint8_t* SrcPtr = &Memory[BlockAddress]; - 1448: 4e 56 subi r20, 0x6E ; 110 - 144a: 5f 4d sbci r21, 0xDF ; 223 - - while(ByteCount--) { - 144c: 01 15 cp r16, r1 - 144e: 11 05 cpc r17, r1 - 1450: 49 f0 breq .+18 ; 0x1464 - 1452: da 01 movw r26, r20 - 1454: fc 01 movw r30, r24 - 1456: 08 0f add r16, r24 - 1458: 19 1f adc r17, r25 - *DstPtr++ = *SrcPtr++; - 145a: 8d 91 ld r24, X+ - 145c: 81 93 st Z+, r24 - - /* Output local memory contents */ - uint8_t* DstPtr = (uint8_t*) Buffer; - uint8_t* SrcPtr = &Memory[BlockAddress]; - - while(ByteCount--) { - 145e: e0 17 cp r30, r16 - 1460: f1 07 cpc r31, r17 - 1462: d9 f7 brne .-10 ; 0x145a - *DstPtr++ = *SrcPtr++; - } - - return true; - 1464: 81 e0 ldi r24, 0x01 ; 1 - } - 1466: 1f 91 pop r17 - 1468: 0f 91 pop r16 - 146a: ff 90 pop r15 - 146c: ef 90 pop r14 - 146e: df 90 pop r13 - 1470: cf 90 pop r12 - 1472: 08 95 ret - return false; - } else { - /* Calculate bytes left in memory and issue reading */ - uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; - //uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; - ByteCount = MIN(ByteCount, BytesLeft); - 1474: 97 01 movw r18, r14 - 1476: 86 01 movw r16, r12 - 1478: e7 cf rjmp .-50 ; 0x1448 - -bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) -{ - if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { - /* There are bytes out of bounds to be read. Notify that we are done. */ - return false; - 147a: 80 e0 ldi r24, 0x00 ; 0 - *DstPtr++ = *SrcPtr++; - } - - return true; - } - 147c: 1f 91 pop r17 - 147e: 0f 91 pop r16 - 1480: ff 90 pop r15 - 1482: ef 90 pop r14 - 1484: df 90 pop r13 - 1486: cf 90 pop r12 - 1488: 08 95 ret - -0000148a : -} - -void ButtonSetActionById(ButtonActionEnum Action) -{ -#ifndef BUTTON_SETTING_GLOBAL - GlobalSettings.ActiveSettingPtr->ButtonAction = Action; - 148a: e0 e0 ldi r30, 0x00 ; 0 - 148c: f6 e0 ldi r31, 0x06 ; 6 - 148e: 80 e4 ldi r24, 0x40 ; 64 - 1490: 82 83 std Z+2, r24 ; 0x02 - 1492: 88 e1 ldi r24, 0x18 ; 24 - 1494: 86 8b std Z+22, r24 ; 0x16 - 1496: 08 95 ret - -00001498 : - 1498: ff 92 push r15 - 149a: 0f 93 push r16 - 149c: 1f 93 push r17 - 149e: cf 93 push r28 - 14a0: df 93 push r29 - 14a2: cd b7 in r28, 0x3d ; 61 - 14a4: de b7 in r29, 0x3e ; 62 - 14a6: a0 97 sbiw r28, 0x20 ; 32 - 14a8: cd bf out 0x3d, r28 ; 61 - 14aa: de bf out 0x3e, r29 ; 62 - 14ac: 80 91 08 06 lds r24, 0x0608 - 14b0: 80 95 com r24 - 14b2: 90 91 92 24 lds r25, 0x2492 - 14b6: 98 27 eor r25, r24 - 14b8: 80 93 92 24 sts 0x2492, r24 - 14bc: 80 74 andi r24, 0x40 ; 64 - 14be: 89 23 and r24, r25 - 14c0: d9 f0 breq .+54 ; 0x14f8 - 14c2: e0 91 fe 24 lds r30, 0x24FE - 14c6: f0 91 ff 24 lds r31, 0x24FF - 14ca: 80 81 ld r24, Z - 14cc: 81 30 cpi r24, 0x01 ; 1 - 14ce: e9 f0 breq .+58 ; 0x150a - 14d0: 82 30 cpi r24, 0x02 ; 2 - 14d2: a9 f1 breq .+106 ; 0x153e - 14d4: 83 30 cpi r24, 0x03 ; 3 - 14d6: 09 f4 brne .+2 ; 0x14da - 14d8: 50 c0 rjmp .+160 ; 0x157a - 14da: 84 30 cpi r24, 0x04 ; 4 - 14dc: 09 f4 brne .+2 ; 0x14e0 - 14de: 73 c0 rjmp .+230 ; 0x15c6 - 14e0: 85 30 cpi r24, 0x05 ; 5 - 14e2: 09 f4 brne .+2 ; 0x14e6 - 14e4: 8e c0 rjmp .+284 ; 0x1602 - 14e6: 86 30 cpi r24, 0x06 ; 6 - 14e8: 09 f4 brne .+2 ; 0x14ec - 14ea: ad c0 rjmp .+346 ; 0x1646 - 14ec: 87 30 cpi r24, 0x07 ; 7 - 14ee: 09 f4 brne .+2 ; 0x14f2 - 14f0: 66 c0 rjmp .+204 ; 0x15be - 14f2: 88 30 cpi r24, 0x08 ; 8 - 14f4: 09 f4 brne .+2 ; 0x14f8 - 14f6: 65 c0 rjmp .+202 ; 0x15c2 - 14f8: a0 96 adiw r28, 0x20 ; 32 - 14fa: cd bf out 0x3d, r28 ; 61 - 14fc: de bf out 0x3e, r29 ; 62 - 14fe: df 91 pop r29 - 1500: cf 91 pop r28 - 1502: 1f 91 pop r17 - 1504: 0f 91 pop r16 - 1506: ff 90 pop r15 - 1508: 08 95 ret - 150a: 80 91 fb 24 lds r24, 0x24FB - 150e: 88 23 and r24, r24 - 1510: 09 f4 brne .+2 ; 0x1514 - 1512: 9b c0 rjmp .+310 ; 0x164a - 1514: f1 2c mov r15, r1 - 1516: 8e 01 movw r16, r28 - 1518: 0f 5f subi r16, 0xFF ; 255 - 151a: 1f 4f sbci r17, 0xFF ; 255 - 151c: 9d da rcall .-2758 ; 0xa58 - 151e: f8 01 movw r30, r16 - 1520: ef 0d add r30, r15 - 1522: f1 1d adc r31, r1 - 1524: 80 83 st Z, r24 - 1526: f3 94 inc r15 - 1528: 80 91 fb 24 lds r24, 0x24FB - 152c: f8 16 cp r15, r24 - 152e: b0 f3 brcs .-20 ; 0x151c - 1530: e0 91 f7 24 lds r30, 0x24F7 - 1534: f0 91 f8 24 lds r31, 0x24F8 - 1538: c8 01 movw r24, r16 - 153a: 09 95 icall - 153c: dd cf rjmp .-70 ; 0x14f8 - 153e: e0 91 f5 24 lds r30, 0x24F5 - 1542: f0 91 f6 24 lds r31, 0x24F6 - 1546: 8e 01 movw r16, r28 - 1548: 0f 5f subi r16, 0xFF ; 255 - 154a: 1f 4f sbci r17, 0xFF ; 255 - 154c: c8 01 movw r24, r16 - 154e: 09 95 icall - 1550: 20 91 fb 24 lds r18, 0x24FB - 1554: 22 23 and r18, r18 - 1556: 61 f3 breq .-40 ; 0x1530 - 1558: f8 01 movw r30, r16 - 155a: 91 e0 ldi r25, 0x01 ; 1 - 155c: 99 23 and r25, r25 - 155e: 39 f0 breq .+14 ; 0x156e - 1560: 80 81 ld r24, Z - 1562: 91 e0 ldi r25, 0x01 ; 1 - 1564: 8f 3f cpi r24, 0xFF ; 255 - 1566: 09 f0 breq .+2 ; 0x156a - 1568: 90 e0 ldi r25, 0x00 ; 0 - 156a: 8f 5f subi r24, 0xFF ; 255 - 156c: 80 83 st Z, r24 - 156e: 31 96 adiw r30, 0x01 ; 1 - 1570: 8e 2f mov r24, r30 - 1572: 80 1b sub r24, r16 - 1574: 82 17 cp r24, r18 - 1576: 90 f3 brcs .-28 ; 0x155c - 1578: db cf rjmp .-74 ; 0x1530 - 157a: e0 91 f5 24 lds r30, 0x24F5 - 157e: f0 91 f6 24 lds r31, 0x24F6 - 1582: 8e 01 movw r16, r28 - 1584: 0f 5f subi r16, 0xFF ; 255 - 1586: 1f 4f sbci r17, 0xFF ; 255 - 1588: c8 01 movw r24, r16 - 158a: 09 95 icall - 158c: 20 91 fb 24 lds r18, 0x24FB - 1590: 31 e0 ldi r19, 0x01 ; 1 - 1592: 21 50 subi r18, 0x01 ; 1 - 1594: 68 f2 brcs .-102 ; 0x1530 - 1596: 33 23 and r19, r19 - 1598: e1 f3 breq .-8 ; 0x1592 - 159a: 82 2f mov r24, r18 - 159c: 90 e0 ldi r25, 0x00 ; 0 - 159e: f8 01 movw r30, r16 - 15a0: e8 0f add r30, r24 - 15a2: f9 1f adc r31, r25 - 15a4: 40 81 ld r20, Z - 15a6: 31 e0 ldi r19, 0x01 ; 1 - 15a8: 4f 3f cpi r20, 0xFF ; 255 - 15aa: 09 f0 breq .+2 ; 0x15ae - 15ac: 30 e0 ldi r19, 0x00 ; 0 - 15ae: f8 01 movw r30, r16 - 15b0: e8 0f add r30, r24 - 15b2: f9 1f adc r31, r25 - 15b4: 4f 5f subi r20, 0xFF ; 255 - 15b6: 40 83 st Z, r20 - 15b8: 21 50 subi r18, 0x01 ; 1 - 15ba: 68 f7 brcc .-38 ; 0x1596 - 15bc: b9 cf rjmp .-142 ; 0x1530 - 15be: 22 dc rcall .-1980 ; 0xe04 - 15c0: 9b cf rjmp .-202 ; 0x14f8 - 15c2: 2c db rcall .-2472 ; 0xc1c - 15c4: 99 cf rjmp .-206 ; 0x14f8 - 15c6: e0 91 f5 24 lds r30, 0x24F5 - 15ca: f0 91 f6 24 lds r31, 0x24F6 - 15ce: 8e 01 movw r16, r28 - 15d0: 0f 5f subi r16, 0xFF ; 255 - 15d2: 1f 4f sbci r17, 0xFF ; 255 - 15d4: c8 01 movw r24, r16 - 15d6: 09 95 icall - 15d8: 20 91 fb 24 lds r18, 0x24FB - 15dc: 22 23 and r18, r18 - 15de: 09 f4 brne .+2 ; 0x15e2 - 15e0: a7 cf rjmp .-178 ; 0x1530 - 15e2: f8 01 movw r30, r16 - 15e4: 91 e0 ldi r25, 0x01 ; 1 - 15e6: 99 23 and r25, r25 - 15e8: 31 f0 breq .+12 ; 0x15f6 - 15ea: 80 81 ld r24, Z - 15ec: 91 e0 ldi r25, 0x01 ; 1 - 15ee: 81 11 cpse r24, r1 - 15f0: 90 e0 ldi r25, 0x00 ; 0 - 15f2: 81 50 subi r24, 0x01 ; 1 - 15f4: 80 83 st Z, r24 - 15f6: 31 96 adiw r30, 0x01 ; 1 - 15f8: 8e 2f mov r24, r30 - 15fa: 80 1b sub r24, r16 - 15fc: 82 17 cp r24, r18 - 15fe: 98 f3 brcs .-26 ; 0x15e6 - 1600: 97 cf rjmp .-210 ; 0x1530 - 1602: e0 91 f5 24 lds r30, 0x24F5 - 1606: f0 91 f6 24 lds r31, 0x24F6 - 160a: 8e 01 movw r16, r28 - 160c: 0f 5f subi r16, 0xFF ; 255 - 160e: 1f 4f sbci r17, 0xFF ; 255 - 1610: c8 01 movw r24, r16 - 1612: 09 95 icall - 1614: 20 91 fb 24 lds r18, 0x24FB - 1618: 31 e0 ldi r19, 0x01 ; 1 - 161a: 21 50 subi r18, 0x01 ; 1 - 161c: 08 f4 brcc .+2 ; 0x1620 - 161e: 88 cf rjmp .-240 ; 0x1530 - 1620: 33 23 and r19, r19 - 1622: d9 f3 breq .-10 ; 0x161a - 1624: 82 2f mov r24, r18 - 1626: 90 e0 ldi r25, 0x00 ; 0 - 1628: f8 01 movw r30, r16 - 162a: e8 0f add r30, r24 - 162c: f9 1f adc r31, r25 - 162e: 40 81 ld r20, Z - 1630: 31 e0 ldi r19, 0x01 ; 1 - 1632: 41 11 cpse r20, r1 - 1634: 30 e0 ldi r19, 0x00 ; 0 - 1636: f8 01 movw r30, r16 - 1638: e8 0f add r30, r24 - 163a: f9 1f adc r31, r25 - 163c: 41 50 subi r20, 0x01 ; 1 - 163e: 40 83 st Z, r20 - 1640: 21 50 subi r18, 0x01 ; 1 - 1642: 70 f7 brcc .-36 ; 0x1620 - 1644: 75 cf rjmp .-278 ; 0x1530 - 1646: da d0 rcall .+436 ; 0x17fc - 1648: 57 cf rjmp .-338 ; 0x14f8 - 164a: 8e 01 movw r16, r28 - 164c: 0f 5f subi r16, 0xFF ; 255 - 164e: 1f 4f sbci r17, 0xFF ; 255 - 1650: 6f cf rjmp .-290 ; 0x1530 - -00001652 : - 1652: 0f 93 push r16 - 1654: 1f 93 push r17 - 1656: cf 93 push r28 - 1658: df 93 push r29 - 165a: 61 50 subi r22, 0x01 ; 1 - 165c: 71 09 sbc r23, r1 - 165e: 47 e4 ldi r20, 0x47 ; 71 - 1660: 53 e0 ldi r21, 0x03 ; 3 - 1662: 1c e2 ldi r17, 0x2C ; 44 - 1664: 9a 01 movw r18, r20 - 1666: fa 01 movw r30, r20 - 1668: 04 91 lpm r16, Z - 166a: 00 23 and r16, r16 - 166c: 49 f1 breq .+82 ; 0x16c0 - 166e: 61 32 cpi r22, 0x21 ; 33 - 1670: 71 05 cpc r23, r1 - 1672: 20 f4 brcc .+8 ; 0x167c - 1674: 25 c0 rjmp .+74 ; 0x16c0 - 1676: 60 32 cpi r22, 0x20 ; 32 - 1678: 71 05 cpc r23, r1 - 167a: 61 f0 breq .+24 ; 0x1694 - 167c: dc 01 movw r26, r24 - 167e: 01 96 adiw r24, 0x01 ; 1 - 1680: ec 01 movw r28, r24 - 1682: 0c 93 st X, r16 - 1684: 2f 5f subi r18, 0xFF ; 255 - 1686: 3f 4f sbci r19, 0xFF ; 255 - 1688: 61 50 subi r22, 0x01 ; 1 - 168a: 71 09 sbc r23, r1 - 168c: f9 01 movw r30, r18 - 168e: 04 91 lpm r16, Z - 1690: 01 11 cpse r16, r1 - 1692: f1 cf rjmp .-30 ; 0x1676 - 1694: f4 e0 ldi r31, 0x04 ; 4 - 1696: 47 34 cpi r20, 0x47 ; 71 - 1698: 5f 07 cpc r21, r31 - 169a: 61 f0 breq .+24 ; 0x16b4 - 169c: ce 01 movw r24, r28 - 169e: 01 96 adiw r24, 0x01 ; 1 - 16a0: 18 83 st Y, r17 - 16a2: 61 50 subi r22, 0x01 ; 1 - 16a4: 71 09 sbc r23, r1 - 16a6: 40 5e subi r20, 0xE0 ; 224 - 16a8: 5f 4f sbci r21, 0xFF ; 255 - 16aa: 24 e0 ldi r18, 0x04 ; 4 - 16ac: 47 36 cpi r20, 0x67 ; 103 - 16ae: 52 07 cpc r21, r18 - 16b0: c9 f6 brne .-78 ; 0x1664 - 16b2: ec 01 movw r28, r24 - 16b4: 18 82 st Y, r1 - 16b6: df 91 pop r29 - 16b8: cf 91 pop r28 - 16ba: 1f 91 pop r17 - 16bc: 0f 91 pop r16 - 16be: 08 95 ret - 16c0: ec 01 movw r28, r24 - 16c2: e8 cf rjmp .-48 ; 0x1694 - -000016c4 : - } -#endif -} - -void ButtonGetActionByName(char* ActionOut, uint16_t BufferSize) -{ - 16c4: ab 01 movw r20, r22 - strncpy_P(ActionOut, ButtonActionTable[GlobalSettings.ActiveSettingPtr->ButtonAction], BufferSize); - 16c6: e0 91 fe 24 lds r30, 0x24FE - 16ca: f0 91 ff 24 lds r31, 0x24FF - 16ce: 60 81 ld r22, Z - 16d0: 20 e2 ldi r18, 0x20 ; 32 - 16d2: 62 9f mul r22, r18 - 16d4: b0 01 movw r22, r0 - 16d6: 11 24 eor r1, r1 - 16d8: 69 5b subi r22, 0xB9 ; 185 - 16da: 7c 4f sbci r23, 0xFC ; 252 - 16dc: 0c 94 f7 23 jmp 0x47ee ; 0x47ee - -000016e0 : -} - -bool ButtonSetActionByName(const char* Action) -{ - 16e0: cf 93 push r28 - 16e2: df 93 push r29 - 16e4: ec 01 movw r28, r24 - uint8_t i; - - for (i=0; i - 16ee: 89 2b or r24, r25 - 16f0: e9 f1 breq .+122 ; 0x176c - 16f2: 67 e6 ldi r22, 0x67 ; 103 - 16f4: 73 e0 ldi r23, 0x03 ; 3 - 16f6: ce 01 movw r24, r28 - 16f8: 0e 94 ee 23 call 0x47dc ; 0x47dc - 16fc: 89 2b or r24, r25 - 16fe: 09 f4 brne .+2 ; 0x1702 - 1700: 3f c0 rjmp .+126 ; 0x1780 - 1702: 67 e8 ldi r22, 0x87 ; 135 - 1704: 73 e0 ldi r23, 0x03 ; 3 - 1706: ce 01 movw r24, r28 - 1708: 0e 94 ee 23 call 0x47dc ; 0x47dc - 170c: 89 2b or r24, r25 - 170e: d1 f1 breq .+116 ; 0x1784 - 1710: 67 ea ldi r22, 0xA7 ; 167 - 1712: 73 e0 ldi r23, 0x03 ; 3 - 1714: ce 01 movw r24, r28 - 1716: 0e 94 ee 23 call 0x47dc ; 0x47dc - 171a: 89 2b or r24, r25 - 171c: a9 f1 breq .+106 ; 0x1788 - 171e: 67 ec ldi r22, 0xC7 ; 199 - 1720: 73 e0 ldi r23, 0x03 ; 3 - 1722: ce 01 movw r24, r28 - 1724: 0e 94 ee 23 call 0x47dc ; 0x47dc - 1728: 89 2b or r24, r25 - 172a: 81 f1 breq .+96 ; 0x178c - 172c: 67 ee ldi r22, 0xE7 ; 231 - 172e: 73 e0 ldi r23, 0x03 ; 3 - 1730: ce 01 movw r24, r28 - 1732: 0e 94 ee 23 call 0x47dc ; 0x47dc - 1736: 89 2b or r24, r25 - 1738: 59 f1 breq .+86 ; 0x1790 - 173a: 67 e0 ldi r22, 0x07 ; 7 - 173c: 74 e0 ldi r23, 0x04 ; 4 - 173e: ce 01 movw r24, r28 - 1740: 0e 94 ee 23 call 0x47dc ; 0x47dc - 1744: 89 2b or r24, r25 - 1746: 31 f1 breq .+76 ; 0x1794 - 1748: 67 e2 ldi r22, 0x27 ; 39 - 174a: 74 e0 ldi r23, 0x04 ; 4 - 174c: ce 01 movw r24, r28 - 174e: 0e 94 ee 23 call 0x47dc ; 0x47dc - 1752: 89 2b or r24, r25 - 1754: 09 f1 breq .+66 ; 0x1798 - 1756: 67 e4 ldi r22, 0x47 ; 71 - 1758: 74 e0 ldi r23, 0x04 ; 4 - 175a: ce 01 movw r24, r28 - 175c: 0e 94 ee 23 call 0x47dc ; 0x47dc - 1760: 89 2b or r24, r25 - 1762: e1 f0 breq .+56 ; 0x179c - return true; - } - } - - /* Button action not found */ - return false; - 1764: 80 e0 ldi r24, 0x00 ; 0 -} - 1766: df 91 pop r29 - 1768: cf 91 pop r28 - 176a: 08 95 ret - -bool ButtonSetActionByName(const char* Action) -{ - uint8_t i; - - for (i=0; iButtonAction = Action; - 176e: e0 91 fe 24 lds r30, 0x24FE - 1772: f0 91 ff 24 lds r31, 0x24FF - 1776: 80 83 st Z, r24 - uint8_t i; - - for (i=0; i - 1784: 82 e0 ldi r24, 0x02 ; 2 - 1786: f3 cf rjmp .-26 ; 0x176e - 1788: 83 e0 ldi r24, 0x03 ; 3 - 178a: f1 cf rjmp .-30 ; 0x176e - 178c: 84 e0 ldi r24, 0x04 ; 4 - 178e: ef cf rjmp .-34 ; 0x176e - 1790: 85 e0 ldi r24, 0x05 ; 5 - 1792: ed cf rjmp .-38 ; 0x176e - 1794: 86 e0 ldi r24, 0x06 ; 6 - 1796: eb cf rjmp .-42 ; 0x176e - 1798: 87 e0 ldi r24, 0x07 ; 7 - 179a: e9 cf rjmp .-46 ; 0x176e - 179c: 88 e0 ldi r24, 0x08 ; 8 - 179e: e7 cf rjmp .-50 ; 0x176e - -000017a0 : - } -} - -uint8_t SettingsGetActiveById(void) { - return GlobalSettings.ActiveSetting; -} - 17a0: 43 e1 ldi r20, 0x13 ; 19 - 17a2: 50 e0 ldi r21, 0x00 ; 0 - 17a4: 60 e0 ldi r22, 0x00 ; 0 - 17a6: 70 e0 ldi r23, 0x00 ; 0 - 17a8: 8d ef ldi r24, 0xFD ; 253 - 17aa: 94 e2 ldi r25, 0x24 ; 36 - 17ac: 0c 94 ff 25 jmp 0x4bfe ; 0x4bfe <__eerd_block_x32a4u> - -000017b0 : - 17b0: 43 e1 ldi r20, 0x13 ; 19 - 17b2: 50 e0 ldi r21, 0x00 ; 0 - 17b4: 60 e0 ldi r22, 0x00 ; 0 - 17b6: 70 e0 ldi r23, 0x00 ; 0 - 17b8: 8d ef ldi r24, 0xFD ; 253 - 17ba: 94 e2 ldi r25, 0x24 ; 36 - 17bc: 0c 94 0a 26 jmp 0x4c14 ; 0x4c14 <__eewr_block_x32a4u> - -000017c0 : - 17c0: cf 93 push r28 - 17c2: df 93 push r29 - 17c4: 1f 92 push r1 - 17c6: cd b7 in r28, 0x3d ; 61 - 17c8: de b7 in r29, 0x3e ; 62 - 17ca: 88 30 cpi r24, 0x08 ; 8 - 17cc: 20 f0 brcs .+8 ; 0x17d6 - 17ce: 0f 90 pop r0 - 17d0: df 91 pop r29 - 17d2: cf 91 pop r28 - 17d4: 08 95 ret - 17d6: 89 83 std Y+1, r24 ; 0x01 - 17d8: 15 db rcall .-2518 ; 0xe04 - 17da: 89 81 ldd r24, Y+1 ; 0x01 - 17dc: 80 93 fd 24 sts 0x24FD, r24 - 17e0: 90 e0 ldi r25, 0x00 ; 0 - 17e2: 88 0f add r24, r24 - 17e4: 99 1f adc r25, r25 - 17e6: 80 50 subi r24, 0x00 ; 0 - 17e8: 9b 4d sbci r25, 0xDB ; 219 - 17ea: 80 93 fe 24 sts 0x24FE, r24 - 17ee: 90 93 ff 24 sts 0x24FF, r25 - 17f2: b4 d8 rcall .-3736 ; 0x95c - 17f4: 0f 90 pop r0 - 17f6: df 91 pop r29 - 17f8: cf 91 pop r28 - 17fa: 10 ca rjmp .-3040 ; 0xc1c - -000017fc : - 17fc: 20 91 fd 24 lds r18, 0x24FD - 1800: 30 e0 ldi r19, 0x00 ; 0 - 1802: 2f 5f subi r18, 0xFF ; 255 - 1804: 3f 4f sbci r19, 0xFF ; 255 - 1806: 27 70 andi r18, 0x07 ; 7 - 1808: 33 27 eor r19, r19 - 180a: 82 2f mov r24, r18 - 180c: f9 01 movw r30, r18 - 180e: ee 0f add r30, r30 - 1810: ff 1f adc r31, r31 - 1812: ef 5f subi r30, 0xFF ; 255 - 1814: fa 4d sbci r31, 0xDA ; 218 - 1816: 90 81 ld r25, Z - 1818: 91 11 cpse r25, r1 - 181a: 5c c0 rjmp .+184 ; 0x18d4 - 181c: 2f 5f subi r18, 0xFF ; 255 - 181e: 3f 4f sbci r19, 0xFF ; 255 - 1820: 27 70 andi r18, 0x07 ; 7 - 1822: 33 27 eor r19, r19 - 1824: 82 2f mov r24, r18 - 1826: f9 01 movw r30, r18 - 1828: ee 0f add r30, r30 - 182a: ff 1f adc r31, r31 - 182c: ef 5f subi r30, 0xFF ; 255 - 182e: fa 4d sbci r31, 0xDA ; 218 - 1830: 90 81 ld r25, Z - 1832: 91 11 cpse r25, r1 - 1834: 4f c0 rjmp .+158 ; 0x18d4 - 1836: 2f 5f subi r18, 0xFF ; 255 - 1838: 3f 4f sbci r19, 0xFF ; 255 - 183a: 27 70 andi r18, 0x07 ; 7 - 183c: 33 27 eor r19, r19 - 183e: 82 2f mov r24, r18 - 1840: f9 01 movw r30, r18 - 1842: ee 0f add r30, r30 - 1844: ff 1f adc r31, r31 - 1846: ef 5f subi r30, 0xFF ; 255 - 1848: fa 4d sbci r31, 0xDA ; 218 - 184a: 90 81 ld r25, Z - 184c: 91 11 cpse r25, r1 - 184e: 42 c0 rjmp .+132 ; 0x18d4 - 1850: 2f 5f subi r18, 0xFF ; 255 - 1852: 3f 4f sbci r19, 0xFF ; 255 - 1854: 27 70 andi r18, 0x07 ; 7 - 1856: 33 27 eor r19, r19 - 1858: 82 2f mov r24, r18 - 185a: f9 01 movw r30, r18 - 185c: ee 0f add r30, r30 - 185e: ff 1f adc r31, r31 - 1860: ef 5f subi r30, 0xFF ; 255 - 1862: fa 4d sbci r31, 0xDA ; 218 - 1864: 90 81 ld r25, Z - 1866: 91 11 cpse r25, r1 - 1868: 35 c0 rjmp .+106 ; 0x18d4 - 186a: 2f 5f subi r18, 0xFF ; 255 - 186c: 3f 4f sbci r19, 0xFF ; 255 - 186e: 27 70 andi r18, 0x07 ; 7 - 1870: 33 27 eor r19, r19 - 1872: 82 2f mov r24, r18 - 1874: f9 01 movw r30, r18 - 1876: ee 0f add r30, r30 - 1878: ff 1f adc r31, r31 - 187a: ef 5f subi r30, 0xFF ; 255 - 187c: fa 4d sbci r31, 0xDA ; 218 - 187e: 90 81 ld r25, Z - 1880: 91 11 cpse r25, r1 - 1882: 28 c0 rjmp .+80 ; 0x18d4 - 1884: 2f 5f subi r18, 0xFF ; 255 - 1886: 3f 4f sbci r19, 0xFF ; 255 - 1888: 27 70 andi r18, 0x07 ; 7 - 188a: 33 27 eor r19, r19 - 188c: 82 2f mov r24, r18 - 188e: f9 01 movw r30, r18 - 1890: ee 0f add r30, r30 - 1892: ff 1f adc r31, r31 - 1894: ef 5f subi r30, 0xFF ; 255 - 1896: fa 4d sbci r31, 0xDA ; 218 - 1898: 90 81 ld r25, Z - 189a: 91 11 cpse r25, r1 - 189c: 1b c0 rjmp .+54 ; 0x18d4 - 189e: 2f 5f subi r18, 0xFF ; 255 - 18a0: 3f 4f sbci r19, 0xFF ; 255 - 18a2: 27 70 andi r18, 0x07 ; 7 - 18a4: 33 27 eor r19, r19 - 18a6: 82 2f mov r24, r18 - 18a8: f9 01 movw r30, r18 - 18aa: ee 0f add r30, r30 - 18ac: ff 1f adc r31, r31 - 18ae: ef 5f subi r30, 0xFF ; 255 - 18b0: fa 4d sbci r31, 0xDA ; 218 - 18b2: 90 81 ld r25, Z - 18b4: 91 11 cpse r25, r1 - 18b6: 0e c0 rjmp .+28 ; 0x18d4 - 18b8: 2f 5f subi r18, 0xFF ; 255 - 18ba: 3f 4f sbci r19, 0xFF ; 255 - 18bc: 27 70 andi r18, 0x07 ; 7 - 18be: 33 27 eor r19, r19 - 18c0: 82 2f mov r24, r18 - 18c2: f9 01 movw r30, r18 - 18c4: ee 0f add r30, r30 - 18c6: ff 1f adc r31, r31 - 18c8: ef 5f subi r30, 0xFF ; 255 - 18ca: fa 4d sbci r31, 0xDA ; 218 - 18cc: 90 81 ld r25, Z - 18ce: 91 11 cpse r25, r1 - 18d0: 01 c0 rjmp .+2 ; 0x18d4 - 18d2: 08 95 ret - 18d4: 75 cf rjmp .-278 ; 0x17c0 - -000018d6 : - -void SettingsGetActiveByName(char* SettingOut, uint16_t BufferSize) { - SettingOut[0] = SettingsGetActiveById() + '0'; - 18d6: 20 91 fd 24 lds r18, 0x24FD - 18da: 20 5d subi r18, 0xD0 ; 208 - 18dc: fc 01 movw r30, r24 - 18de: 20 83 st Z, r18 - SettingOut[1] = '\0'; - 18e0: 11 82 std Z+1, r1 ; 0x01 - 18e2: 08 95 ret - -000018e4 : -} - -bool SettingsSetActiveByName(const char* Setting) { - 18e4: fc 01 movw r30, r24 - uint8_t SettingNr = Setting[0] - '0'; - 18e6: 80 81 ld r24, Z - - if ((Setting[1] == '\0') && (SettingNr < SETTINGS_COUNT)) { - 18e8: 91 81 ldd r25, Z+1 ; 0x01 - 18ea: 91 11 cpse r25, r1 - 18ec: 03 c0 rjmp .+6 ; 0x18f4 - SettingOut[0] = SettingsGetActiveById() + '0'; - SettingOut[1] = '\0'; -} - -bool SettingsSetActiveByName(const char* Setting) { - uint8_t SettingNr = Setting[0] - '0'; - 18ee: 80 53 subi r24, 0x30 ; 48 - - if ((Setting[1] == '\0') && (SettingNr < SETTINGS_COUNT)) { - 18f0: 88 30 cpi r24, 0x08 ; 8 - 18f2: 10 f0 brcs .+4 ; 0x18f8 - SettingsSetActiveById(SettingNr); - return true; - } else { - return false; - 18f4: 80 e0 ldi r24, 0x00 ; 0 - } -} - 18f6: 08 95 ret - -bool SettingsSetActiveByName(const char* Setting) { - uint8_t SettingNr = Setting[0] - '0'; - - if ((Setting[1] == '\0') && (SettingNr < SETTINGS_COUNT)) { - SettingsSetActiveById(SettingNr); - 18f8: 63 df rcall .-314 ; 0x17c0 - return true; - 18fa: 81 e0 ldi r24, 0x01 ; 1 - 18fc: 08 95 ret - -000018fe : -uint8_t TerminalBuffer[TERMINAL_BUFFER_SIZE]; -TerminalStateEnum TerminalState = TERMINAL_UNINITIALIZED; -static uint8_t TerminalInitDelay = INIT_DELAY; - -void TerminalSendString(const char* s) { - CDC_Device_SendString(&TerminalHandle, s); - 18fe: bc 01 movw r22, r24 - 1900: 81 e0 ldi r24, 0x01 ; 1 - 1902: 90 e2 ldi r25, 0x20 ; 32 - 1904: 0c 94 95 21 jmp 0x432a ; 0x432a - -00001908 : -} - -void TerminalSendStringP(const char* s) { - 1908: cf 93 push r28 - 190a: df 93 push r29 - char c; - - while( (c = pgm_read_byte(s++)) != '\0' ) { - 190c: ec 01 movw r28, r24 - 190e: 21 96 adiw r28, 0x01 ; 1 - 1910: fc 01 movw r30, r24 - 1912: 64 91 lpm r22, Z - 1914: 66 23 and r22, r22 - 1916: 49 f0 breq .+18 ; 0x192a -void EVENT_USB_Device_Connect(void); -void EVENT_USB_Device_Disconnect(void); -void EVENT_USB_Device_ConfigurationChanged(void); -void EVENT_USB_Device_ControlRequest(void); - -INLINE void TerminalSendChar(char c) { CDC_Device_SendByte(&TerminalHandle, c); } - 1918: 81 e0 ldi r24, 0x01 ; 1 - 191a: 90 e2 ldi r25, 0x20 ; 32 - 191c: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - 1920: fe 01 movw r30, r28 - 1922: 64 91 lpm r22, Z - 1924: 21 96 adiw r28, 0x01 ; 1 - 1926: 61 11 cpse r22, r1 - 1928: f7 cf rjmp .-18 ; 0x1918 - TerminalSendChar(c); - } -} - 192a: df 91 pop r29 - 192c: cf 91 pop r28 - 192e: 08 95 ret - -00001930 : -#endif - - - -void TerminalSendBlock(void* Buffer, uint16_t ByteCount) -{ - 1930: ab 01 movw r20, r22 - CDC_Device_SendData(&TerminalHandle, Buffer, ByteCount); - 1932: bc 01 movw r22, r24 - 1934: 81 e0 ldi r24, 0x01 ; 1 - 1936: 90 e2 ldi r25, 0x20 ; 32 - 1938: 0c 94 ba 21 jmp 0x4374 ; 0x4374 - -0000193c : - } -} - -void TerminalInit(void) -{ - TERMINAL_VBUS_PORT.DIRCLR = TERMINAL_VBUS_MASK; - 193c: 80 e2 ldi r24, 0x20 ; 32 - 193e: e0 e6 ldi r30, 0x60 ; 96 - 1940: f6 e0 ldi r31, 0x06 ; 6 - 1942: 82 83 std Z+2, r24 ; 0x02 - 1944: 08 95 ret - -00001946 : -} - -void TerminalTask(void) -{ - 1946: cf 93 push r28 - 1948: df 93 push r29 - CDC_Device_USBTask(&TerminalHandle); - 194a: 81 e0 ldi r24, 0x01 ; 1 - 194c: 90 e2 ldi r25, 0x20 ; 32 - 194e: 0e 94 57 22 call 0x44ae ; 0x44ae - USB_USBTask(); - 1952: 0e 94 7a 1c call 0x38f4 ; 0x38f4 - CDC_Device_SendData(&TerminalHandle, Buffer, ByteCount); -} - - -static void ProcessByte(void) { - int16_t Byte = CDC_Device_ReceiveByte(&TerminalHandle); - 1956: 81 e0 ldi r24, 0x01 ; 1 - 1958: 90 e2 ldi r25, 0x20 ; 32 - 195a: 0e 94 72 22 call 0x44e4 ; 0x44e4 - 195e: ec 01 movw r28, r24 - - if (Byte >= 0) { - 1960: 97 fd sbrc r25, 7 - 1962: 09 c0 rjmp .+18 ; 0x1976 - LED_PORT.OUTTGL = Mask; -} - -static inline -void LEDPulse(uint8_t Mask) { - LEDPulseMask = Mask; - 1964: 80 e1 ldi r24, 0x10 ; 16 - 1966: 80 93 93 24 sts 0x2493, r24 - LED_PORT.OUTSET = Mask; - 196a: 80 93 05 06 sts 0x0605, r24 - /* Byte received */ - LEDPulse(LED_RED); - - if (XModemProcessByte(Byte)) { - 196e: 8c 2f mov r24, r28 - 1970: 5a d2 rcall .+1204 ; 0x1e26 - 1972: 88 23 and r24, r24 - 1974: 19 f0 breq .+6 ; 0x197c -{ - CDC_Device_USBTask(&TerminalHandle); - USB_USBTask(); - - ProcessByte(); -} - 1976: df 91 pop r29 - 1978: cf 91 pop r28 - 197a: 08 95 ret - /* Byte received */ - LEDPulse(LED_RED); - - if (XModemProcessByte(Byte)) { - /* XModem handled the byte */ - } else if (CommandLineProcessByte(Byte)) { - 197c: 8c 2f mov r24, r28 -{ - CDC_Device_USBTask(&TerminalHandle); - USB_USBTask(); - - ProcessByte(); -} - 197e: df 91 pop r29 - 1980: cf 91 pop r28 - /* Byte received */ - LEDPulse(LED_RED); - - if (XModemProcessByte(Byte)) { - /* XModem handled the byte */ - } else if (CommandLineProcessByte(Byte)) { - 1982: e0 c3 rjmp .+1984 ; 0x2144 - -00001984 : - } -} - -static void SenseVBus(void) -{ - switch(TerminalState) { - 1984: 80 91 94 24 lds r24, 0x2494 - 1988: 81 30 cpi r24, 0x01 ; 1 - 198a: 31 f1 breq .+76 ; 0x19d8 - 198c: c8 f0 brcs .+50 ; 0x19c0 - 198e: 82 30 cpi r24, 0x02 ; 2 - 1990: 59 f0 breq .+22 ; 0x19a8 - 1992: 83 30 cpi r24, 0x03 ; 3 - 1994: 39 f4 brne .+14 ; 0x19a4 - TerminalState = TERMINAL_UNITIALIZING; - } - break; - - case TERMINAL_UNITIALIZING: - if (--TerminalInitDelay == 0) { - 1996: 80 91 00 20 lds r24, 0x2000 - 199a: 81 50 subi r24, 0x01 ; 1 - 199c: 80 93 00 20 sts 0x2000, r24 - 19a0: 88 23 and r24, r24 - 19a2: 49 f1 breq .+82 ; 0x19f6 - -void TerminalTick(void) -{ - SenseVBus(); - - XModemTick(); - 19a4: a1 d3 rcall .+1858 ; 0x20e8 - CommandLineTick(); - 19a6: 74 c5 rjmp .+2792 ; 0x2490 - TerminalState = TERMINAL_INITIALIZED; - } - break; - - case TERMINAL_INITIALIZED: - if (!(TERMINAL_VBUS_PORT.IN & TERMINAL_VBUS_MASK)) { - 19a8: 80 91 68 06 lds r24, 0x0668 - 19ac: 85 fd sbrc r24, 5 - 19ae: fa cf rjmp .-12 ; 0x19a4 - /* Initialized and VBUS sense low */ - TerminalInitDelay = INIT_DELAY; - 19b0: 84 e1 ldi r24, 0x14 ; 20 - 19b2: 80 93 00 20 sts 0x2000, r24 - TerminalState = TERMINAL_UNITIALIZING; - 19b6: 83 e0 ldi r24, 0x03 ; 3 - 19b8: 80 93 94 24 sts 0x2494, r24 - -void TerminalTick(void) -{ - SenseVBus(); - - XModemTick(); - 19bc: 95 d3 rcall .+1834 ; 0x20e8 - CommandLineTick(); - 19be: 68 c5 rjmp .+2768 ; 0x2490 - -static void SenseVBus(void) -{ - switch(TerminalState) { - case TERMINAL_UNINITIALIZED: - if (TERMINAL_VBUS_PORT.IN & TERMINAL_VBUS_MASK) { - 19c0: 80 91 68 06 lds r24, 0x0668 - 19c4: 85 ff sbrs r24, 5 - 19c6: ee cf rjmp .-36 ; 0x19a4 - /* Not initialized and VBUS sense high */ - TerminalInitDelay = INIT_DELAY; - 19c8: 84 e1 ldi r24, 0x14 ; 20 - 19ca: 80 93 00 20 sts 0x2000, r24 - TerminalState = TERMINAL_INITIALIZING; - 19ce: 81 e0 ldi r24, 0x01 ; 1 - 19d0: 80 93 94 24 sts 0x2494, r24 - -void TerminalTick(void) -{ - SenseVBus(); - - XModemTick(); - 19d4: 89 d3 rcall .+1810 ; 0x20e8 - CommandLineTick(); - 19d6: 5c c5 rjmp .+2744 ; 0x2490 - TerminalState = TERMINAL_INITIALIZING; - } - break; - - case TERMINAL_INITIALIZING: - if (--TerminalInitDelay == 0) { - 19d8: 80 91 00 20 lds r24, 0x2000 - 19dc: 81 50 subi r24, 0x01 ; 1 - 19de: 80 93 00 20 sts 0x2000, r24 - 19e2: 81 11 cpse r24, r1 - 19e4: df cf rjmp .-66 ; 0x19a4 - SystemStartUSBClock(); - 19e6: 0e 94 5c 04 call 0x8b8 ; 0x8b8 - USB_Init(); - 19ea: 0e 94 ce 20 call 0x419c ; 0x419c - TerminalState = TERMINAL_INITIALIZED; - 19ee: 82 e0 ldi r24, 0x02 ; 2 - 19f0: 80 93 94 24 sts 0x2494, r24 - 19f4: d7 cf rjmp .-82 ; 0x19a4 - } - break; - - case TERMINAL_UNITIALIZING: - if (--TerminalInitDelay == 0) { - USB_Disable(); - 19f6: 0e 94 93 20 call 0x4126 ; 0x4126 - SystemStopUSBClock(); - 19fa: 0e 94 75 04 call 0x8ea ; 0x8ea - TerminalState = TERMINAL_UNINITIALIZED; - 19fe: 10 92 94 24 sts 0x2494, r1 - 1a02: d0 cf rjmp .-96 ; 0x19a4 - -00001a04 : - LED_PORT.DIRSET = LED_MASK; -} - -static inline -void LEDSetOn(uint8_t Mask) { - LED_PORT.OUTSET = Mask; - 1a04: 80 e2 ldi r24, 0x20 ; 32 - 1a06: e0 e0 ldi r30, 0x00 ; 0 - 1a08: f6 e0 ldi r31, 0x06 ; 6 - 1a0a: 85 83 std Z+5, r24 ; 0x05 - 1a0c: 08 95 ret - -00001a0e : -} - -static inline -void LEDSetOff(uint8_t Mask) { - LED_PORT.OUTCLR = Mask; - 1a0e: 80 e2 ldi r24, 0x20 ; 32 - 1a10: e0 e0 ldi r30, 0x00 ; 0 - 1a12: f6 e0 ldi r31, 0x06 ; 6 - 1a14: 86 83 std Z+6, r24 ; 0x06 - 1a16: 08 95 ret - -00001a18 : - - -/** Event handler for the library USB Configuration Changed event. */ -void EVENT_USB_Device_ConfigurationChanged(void) -{ - CDC_Device_ConfigureEndpoints(&TerminalHandle); - 1a18: 81 e0 ldi r24, 0x01 ; 1 - 1a1a: 90 e2 ldi r25, 0x20 ; 32 - 1a1c: 0c 94 70 21 jmp 0x42e0 ; 0x42e0 - -00001a20 : -} - -/** Event handler for the library USB Control Request reception event. */ -void EVENT_USB_Device_ControlRequest(void) -{ - CDC_Device_ProcessControlRequest(&TerminalHandle); - 1a20: 81 e0 ldi r24, 0x01 ; 1 - 1a22: 90 e2 ldi r25, 0x20 ; 32 - 1a24: 0c 94 cf 22 jmp 0x459e ; 0x459e - -00001a28 : - -extern const PROGMEM CommandEntryType CommandTable[]; - -CommandStatusIdType CommandGetVersion(char* OutParam) -{ - snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR( - 1a28: 25 ec ldi r18, 0xC5 ; 197 - 1a2a: 34 e0 ldi r19, 0x04 ; 4 - 1a2c: 3f 93 push r19 - 1a2e: 2f 93 push r18 - 1a30: 2e eb ldi r18, 0xBE ; 190 - 1a32: 34 e0 ldi r19, 0x04 ; 4 - 1a34: 3f 93 push r19 - 1a36: 2f 93 push r18 - 1a38: 27 eb ldi r18, 0xB7 ; 183 - 1a3a: 34 e0 ldi r19, 0x04 ; 4 - 1a3c: 3f 93 push r19 - 1a3e: 2f 93 push r18 - 1a40: 2e e7 ldi r18, 0x7E ; 126 - 1a42: 34 e0 ldi r19, 0x04 ; 4 - 1a44: 3f 93 push r19 - 1a46: 2f 93 push r18 - 1a48: 21 e0 ldi r18, 0x01 ; 1 - 1a4a: 2f 93 push r18 - 1a4c: 1f 92 push r1 - 1a4e: 9f 93 push r25 - 1a50: 8f 93 push r24 - 1a52: 0e 94 0f 24 call 0x481e ; 0x481e - "Chameleon-Mini %S using LUFA %S compiled with AVR-GCC %S" - ), PSTR(CHAMELEON_MINI_VERSION_STRING), PSTR(LUFA_VERSION_STRING), PSTR(__VERSION__) - ); - - return COMMAND_INFO_OK_WITH_TEXT_ID; - 1a56: 8d b7 in r24, 0x3d ; 61 - 1a58: 9e b7 in r25, 0x3e ; 62 - 1a5a: 0c 96 adiw r24, 0x0c ; 12 - 1a5c: 8d bf out 0x3d, r24 ; 61 - 1a5e: 9e bf out 0x3e, r25 ; 62 -} - 1a60: 85 e6 ldi r24, 0x65 ; 101 - 1a62: 08 95 ret - -00001a64 : - -CommandStatusIdType CommandGetConfig(char* OutParam) -{ - snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, - 1a64: 29 ed ldi r18, 0xD9 ; 217 - 1a66: 34 e2 ldi r19, 0x24 ; 36 - 1a68: 3f 93 push r19 - 1a6a: 2f 93 push r18 - 1a6c: 2b e7 ldi r18, 0x7B ; 123 - 1a6e: 34 e0 ldi r19, 0x04 ; 4 - 1a70: 3f 93 push r19 - 1a72: 2f 93 push r18 - 1a74: 21 e0 ldi r18, 0x01 ; 1 - 1a76: 2f 93 push r18 - 1a78: 1f 92 push r1 - 1a7a: 9f 93 push r25 - 1a7c: 8f 93 push r24 - 1a7e: 0e 94 0f 24 call 0x481e ; 0x481e - PSTR("%s"), ActiveConfiguration.ConfigurationName); - - return COMMAND_INFO_OK_WITH_TEXT_ID; - 1a82: 8d b7 in r24, 0x3d ; 61 - 1a84: 9e b7 in r25, 0x3e ; 62 - 1a86: 08 96 adiw r24, 0x08 ; 8 - 1a88: 8d bf out 0x3d, r24 ; 61 - 1a8a: 9e bf out 0x3e, r25 ; 62 - -} - 1a8c: 85 e6 ldi r24, 0x65 ; 101 - 1a8e: 08 95 ret - -00001a90 : - -CommandStatusIdType CommandSetConfig(const char* InParam) -{ - if (ConfigurationSetByName(InParam)) { - 1a90: 0e 94 b4 04 call 0x968 ; 0x968 - 1a94: 81 11 cpse r24, r1 - 1a96: 02 c0 rjmp .+4 ; 0x1a9c - SettingsSave(); - return COMMAND_INFO_OK_ID; - } else { - return COMMAND_ERR_INVALID_PARAM_ID; - 1a98: 8a ec ldi r24, 0xCA ; 202 - } -} - 1a9a: 08 95 ret -} - -CommandStatusIdType CommandSetConfig(const char* InParam) -{ - if (ConfigurationSetByName(InParam)) { - SettingsSave(); - 1a9c: 89 de rcall .-750 ; 0x17b0 - return COMMAND_INFO_OK_ID; - 1a9e: 84 e6 ldi r24, 0x64 ; 100 - 1aa0: 08 95 ret - -00001aa2 : - } -} - -CommandStatusIdType CommandExecConfig(char* OutMessage) -{ - ConfigurationGetList(OutMessage, TERMINAL_BUFFER_SIZE); - 1aa2: 60 e0 ldi r22, 0x00 ; 0 - 1aa4: 71 e0 ldi r23, 0x01 ; 1 - 1aa6: 0e 94 f1 04 call 0x9e2 ; 0x9e2 - - return COMMAND_INFO_OK_WITH_TEXT_ID; -} - 1aaa: 85 e6 ldi r24, 0x65 ; 101 - 1aac: 08 95 ret - -00001aae : - -CommandStatusIdType CommandGetUid(char* OutParam) -{ - 1aae: ef 92 push r14 - 1ab0: ff 92 push r15 - 1ab2: 0f 93 push r16 - 1ab4: 1f 93 push r17 - 1ab6: cf 93 push r28 - 1ab8: df 93 push r29 - 1aba: cd b7 in r28, 0x3d ; 61 - 1abc: de b7 in r29, 0x3e ; 62 - 1abe: a0 97 sbiw r28, 0x20 ; 32 - 1ac0: cd bf out 0x3d, r28 ; 61 - 1ac2: de bf out 0x3e, r29 ; 62 - 1ac4: 8c 01 movw r16, r24 - uint8_t UidBuffer[COMMAND_UID_BUFSIZE]; - uint16_t UidSize = ActiveConfiguration.UidSize; - 1ac6: e0 90 fb 24 lds r14, 0x24FB - 1aca: f1 2c mov r15, r1 -INLINE void ApplicationReset(void) { - ActiveConfiguration.ApplicationResetFunc(); -} - -INLINE void ApplicationGetUid(ConfigurationUidType Uid) { - ActiveConfiguration.ApplicationGetUidFunc(Uid); - 1acc: e0 91 f5 24 lds r30, 0x24F5 - 1ad0: f0 91 f6 24 lds r31, 0x24F6 - 1ad4: ce 01 movw r24, r28 - 1ad6: 01 96 adiw r24, 0x01 ; 1 - 1ad8: 09 95 icall - - ApplicationGetUid(UidBuffer); - - BufferToHexString(OutParam, TERMINAL_BUFFER_SIZE, - 1ada: 97 01 movw r18, r14 - 1adc: ae 01 movw r20, r28 - 1ade: 4f 5f subi r20, 0xFF ; 255 - 1ae0: 5f 4f sbci r21, 0xFF ; 255 - 1ae2: 60 e0 ldi r22, 0x00 ; 0 - 1ae4: 71 e0 ldi r23, 0x01 ; 1 - 1ae6: c8 01 movw r24, r16 - 1ae8: 0e 94 47 05 call 0xa8e ; 0xa8e - UidBuffer, UidSize); - - return COMMAND_INFO_OK_WITH_TEXT_ID; -} - 1aec: 85 e6 ldi r24, 0x65 ; 101 - 1aee: a0 96 adiw r28, 0x20 ; 32 - 1af0: cd bf out 0x3d, r28 ; 61 - 1af2: de bf out 0x3e, r29 ; 62 - 1af4: df 91 pop r29 - 1af6: cf 91 pop r28 - 1af8: 1f 91 pop r17 - 1afa: 0f 91 pop r16 - 1afc: ff 90 pop r15 - 1afe: ef 90 pop r14 - 1b00: 08 95 ret - -00001b02 : - -CommandStatusIdType CommandSetUid(const char* InParam) -{ - 1b02: bf 92 push r11 - 1b04: cf 92 push r12 - 1b06: df 92 push r13 - 1b08: ef 92 push r14 - 1b0a: ff 92 push r15 - 1b0c: 0f 93 push r16 - 1b0e: 1f 93 push r17 - 1b10: cf 93 push r28 - 1b12: df 93 push r29 - 1b14: cd b7 in r28, 0x3d ; 61 - 1b16: de b7 in r29, 0x3e ; 62 - 1b18: a0 97 sbiw r28, 0x20 ; 32 - 1b1a: cd bf out 0x3d, r28 ; 61 - 1b1c: de bf out 0x3e, r29 ; 62 - 1b1e: 8c 01 movw r16, r24 - uint8_t UidBuffer[COMMAND_UID_BUFSIZE]; - uint16_t UidSize = ActiveConfiguration.UidSize; - 1b20: c0 90 fb 24 lds r12, 0x24FB - 1b24: d1 2c mov r13, r1 - - if (strcmp_P(InParam, PSTR(COMMAND_UID_RANDOM)) == 0) { - 1b26: 64 e7 ldi r22, 0x74 ; 116 - 1b28: 74 e0 ldi r23, 0x04 ; 4 - 1b2a: 0e 94 ee 23 call 0x47dc ; 0x47dc - 1b2e: 89 2b or r24, r25 - 1b30: 49 f5 brne .+82 ; 0x1b84 - /* Load with random bytes */ - for (uint8_t i=0; i - 1b38: b1 2c mov r11, r1 - 1b3a: ce 01 movw r24, r28 - 1b3c: 01 96 adiw r24, 0x01 ; 1 - 1b3e: 7c 01 movw r14, r24 - 1b40: 00 e0 ldi r16, 0x00 ; 0 - 1b42: 10 e0 ldi r17, 0x00 ; 0 - UidBuffer[i] = RandomGetByte(); - 1b44: 0e 94 2c 05 call 0xa58 ; 0xa58 - 1b48: f7 01 movw r30, r14 - 1b4a: e0 0f add r30, r16 - 1b4c: f1 1f adc r31, r17 - 1b4e: 80 83 st Z, r24 - uint8_t UidBuffer[COMMAND_UID_BUFSIZE]; - uint16_t UidSize = ActiveConfiguration.UidSize; - - if (strcmp_P(InParam, PSTR(COMMAND_UID_RANDOM)) == 0) { - /* Load with random bytes */ - for (uint8_t i=0; i -} - -INLINE void ApplicationSetUid(ConfigurationUidType Uid) { - ActiveConfiguration.ApplicationSetUidFunc(Uid); - 1b5c: e0 91 f7 24 lds r30, 0x24F7 - 1b60: f0 91 f8 24 lds r31, 0x24F8 - 1b64: c7 01 movw r24, r14 - 1b66: 09 95 icall - } - } - - ApplicationSetUid(UidBuffer); - - return COMMAND_INFO_OK_ID; - 1b68: 84 e6 ldi r24, 0x64 ; 100 -} - 1b6a: a0 96 adiw r28, 0x20 ; 32 - 1b6c: cd bf out 0x3d, r28 ; 61 - 1b6e: de bf out 0x3e, r29 ; 62 - 1b70: df 91 pop r29 - 1b72: cf 91 pop r28 - 1b74: 1f 91 pop r17 - 1b76: 0f 91 pop r16 - 1b78: ff 90 pop r15 - 1b7a: ef 90 pop r14 - 1b7c: df 90 pop r13 - 1b7e: cf 90 pop r12 - 1b80: bf 90 pop r11 - 1b82: 08 95 ret - for (uint8_t i=0; i - 1b94: 8c 15 cp r24, r12 - 1b96: 9d 05 cpc r25, r13 - 1b98: 09 f3 breq .-62 ; 0x1b5c - /* Malformed input. Abort */ - return COMMAND_ERR_INVALID_PARAM_ID; - 1b9a: 8a ec ldi r24, 0xCA ; 202 - 1b9c: e6 cf rjmp .-52 ; 0x1b6a - 1b9e: ce 01 movw r24, r28 - 1ba0: 01 96 adiw r24, 0x01 ; 1 - 1ba2: 7c 01 movw r14, r24 - 1ba4: db cf rjmp .-74 ; 0x1b5c - -00001ba6 : - return COMMAND_INFO_OK_ID; -} - -CommandStatusIdType CommandGetReadOnly(char* OutParam) -{ - if (ActiveConfiguration.ReadOnly) { - 1ba6: 20 91 fc 24 lds r18, 0x24FC - 1baa: 21 11 cpse r18, r1 - 1bac: 07 c0 rjmp .+14 ; 0x1bbc - OutParam[0] = COMMAND_CHAR_TRUE; - } else { - OutParam[0] = COMMAND_CHAR_FALSE; - 1bae: 20 e3 ldi r18, 0x30 ; 48 - 1bb0: fc 01 movw r30, r24 - 1bb2: 20 83 st Z, r18 - } - - OutParam[1] = '\0'; - 1bb4: fc 01 movw r30, r24 - 1bb6: 11 82 std Z+1, r1 ; 0x01 - - return COMMAND_INFO_OK_WITH_TEXT_ID; -} - 1bb8: 85 e6 ldi r24, 0x65 ; 101 - 1bba: 08 95 ret -} - -CommandStatusIdType CommandGetReadOnly(char* OutParam) -{ - if (ActiveConfiguration.ReadOnly) { - OutParam[0] = COMMAND_CHAR_TRUE; - 1bbc: 21 e3 ldi r18, 0x31 ; 49 - 1bbe: fc 01 movw r30, r24 - 1bc0: 20 83 st Z, r18 - } else { - OutParam[0] = COMMAND_CHAR_FALSE; - } - - OutParam[1] = '\0'; - 1bc2: fc 01 movw r30, r24 - 1bc4: 11 82 std Z+1, r1 ; 0x01 - - return COMMAND_INFO_OK_WITH_TEXT_ID; -} - 1bc6: 85 e6 ldi r24, 0x65 ; 101 - 1bc8: 08 95 ret - -00001bca : - -CommandStatusIdType CommandSetReadOnly(const char* InParam) -{ - if (InParam[1] == '\0') { - 1bca: fc 01 movw r30, r24 - 1bcc: 21 81 ldd r18, Z+1 ; 0x01 - 1bce: 21 11 cpse r18, r1 - 1bd0: 05 c0 rjmp .+10 ; 0x1bdc - if (InParam[0] == COMMAND_CHAR_TRUE) { - 1bd2: 80 81 ld r24, Z - 1bd4: 81 33 cpi r24, 0x31 ; 49 - 1bd6: 41 f0 breq .+16 ; 0x1be8 - ActiveConfiguration.ReadOnly = true; - return COMMAND_INFO_OK_ID; - } else if (InParam[0] == COMMAND_CHAR_FALSE) { - 1bd8: 80 33 cpi r24, 0x30 ; 48 - 1bda: 11 f0 breq .+4 ; 0x1be0 - ActiveConfiguration.ReadOnly = false; - return COMMAND_INFO_OK_ID; - } - } - - return COMMAND_ERR_INVALID_PARAM_ID; - 1bdc: 8a ec ldi r24, 0xCA ; 202 -} - 1bde: 08 95 ret - if (InParam[1] == '\0') { - if (InParam[0] == COMMAND_CHAR_TRUE) { - ActiveConfiguration.ReadOnly = true; - return COMMAND_INFO_OK_ID; - } else if (InParam[0] == COMMAND_CHAR_FALSE) { - ActiveConfiguration.ReadOnly = false; - 1be0: 10 92 fc 24 sts 0x24FC, r1 - return COMMAND_INFO_OK_ID; - 1be4: 84 e6 ldi r24, 0x64 ; 100 - 1be6: 08 95 ret - -CommandStatusIdType CommandSetReadOnly(const char* InParam) -{ - if (InParam[1] == '\0') { - if (InParam[0] == COMMAND_CHAR_TRUE) { - ActiveConfiguration.ReadOnly = true; - 1be8: 81 e0 ldi r24, 0x01 ; 1 - 1bea: 80 93 fc 24 sts 0x24FC, r24 - return COMMAND_INFO_OK_ID; - 1bee: 84 e6 ldi r24, 0x64 ; 100 - 1bf0: 08 95 ret - -00001bf2 : - return COMMAND_ERR_INVALID_PARAM_ID; -} - -CommandStatusIdType CommandExecUpload(char* OutMessage) -{ - XModemReceive(MemoryUploadBlock); - 1bf2: 8f e3 ldi r24, 0x3F ; 63 - 1bf4: 98 e0 ldi r25, 0x08 ; 8 - 1bf6: ec d0 rcall .+472 ; 0x1dd0 - return COMMAND_INFO_XMODEM_WAIT_ID; -} - 1bf8: 8e e6 ldi r24, 0x6E ; 110 - 1bfa: 08 95 ret - -00001bfc : - -CommandStatusIdType CommandExecDownload(char* OutMessage) -{ - XModemSend(MemoryDownloadBlock); - 1bfc: 88 e0 ldi r24, 0x08 ; 8 - 1bfe: 9a e0 ldi r25, 0x0A ; 10 - 1c00: ff d0 rcall .+510 ; 0x1e00 - return COMMAND_INFO_XMODEM_WAIT_ID; -} - 1c02: 8e e6 ldi r24, 0x6E ; 110 - 1c04: 08 95 ret - -00001c06 : - * enumerating the device once attached until \ref USB_Attach() is called. - */ - static inline void USB_Detach(void) ATTR_ALWAYS_INLINE; - static inline void USB_Detach(void) - { - USB.CTRLB &= ~USB_ATTACH_bm; - 1c06: e0 ec ldi r30, 0xC0 ; 192 - 1c08: f4 e0 ldi r31, 0x04 ; 4 - 1c0a: 81 81 ldd r24, Z+1 ; 0x01 - 1c0c: 8e 7f andi r24, 0xFE ; 254 - 1c0e: 81 83 std Z+1, r24 ; 0x01 - -CommandStatusIdType CommandExecReset(char* OutMessage) -{ - USB_Detach(); - USB_Disable(); - 1c10: 0e 94 93 20 call 0x4126 ; 0x4126 - - SystemReset(); - 1c14: 0e 94 4f 04 call 0x89e ; 0x89e - - return COMMAND_INFO_OK_ID; -} - 1c18: 84 e6 ldi r24, 0x64 ; 100 - 1c1a: 08 95 ret - -00001c1c : - 1c1c: e0 ec ldi r30, 0xC0 ; 192 - 1c1e: f4 e0 ldi r31, 0x04 ; 4 - 1c20: 81 81 ldd r24, Z+1 ; 0x01 - 1c22: 8e 7f andi r24, 0xFE ; 254 - 1c24: 81 83 std Z+1, r24 ; 0x01 - -#ifdef SUPPORT_FIRMWARE_UPGRADE -CommandStatusIdType CommandExecUpgrade(char* OutMessage) -{ - USB_Detach(); - USB_Disable(); - 1c26: 0e 94 93 20 call 0x4126 ; 0x4126 - - SystemEnterBootloader(); - 1c2a: 0e 94 56 04 call 0x8ac ; 0x8ac - - return COMMAND_INFO_OK_ID; -} - 1c2e: 84 e6 ldi r24, 0x64 ; 100 - 1c30: 08 95 ret - -00001c32 : -#endif - -CommandStatusIdType CommandGetMemSize(char* OutParam) -{ - snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%u"), ActiveConfiguration.MemorySize); - 1c32: e9 ef ldi r30, 0xF9 ; 249 - 1c34: f4 e2 ldi r31, 0x24 ; 36 - 1c36: 21 81 ldd r18, Z+1 ; 0x01 - 1c38: 2f 93 push r18 - 1c3a: 20 81 ld r18, Z - 1c3c: 2f 93 push r18 - 1c3e: 21 e7 ldi r18, 0x71 ; 113 - 1c40: 34 e0 ldi r19, 0x04 ; 4 - 1c42: 3f 93 push r19 - 1c44: 2f 93 push r18 - 1c46: 21 e0 ldi r18, 0x01 ; 1 - 1c48: 2f 93 push r18 - 1c4a: 1f 92 push r1 - 1c4c: 9f 93 push r25 - 1c4e: 8f 93 push r24 - 1c50: 0e 94 0f 24 call 0x481e ; 0x481e - - return COMMAND_INFO_OK_WITH_TEXT_ID; - 1c54: 8d b7 in r24, 0x3d ; 61 - 1c56: 9e b7 in r25, 0x3e ; 62 - 1c58: 08 96 adiw r24, 0x08 ; 8 - 1c5a: 8d bf out 0x3d, r24 ; 61 - 1c5c: 9e bf out 0x3e, r25 ; 62 -} - 1c5e: 85 e6 ldi r24, 0x65 ; 101 - 1c60: 08 95 ret - -00001c62 : - -CommandStatusIdType CommandGetUidSize(char* OutParam) -{ - snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%u"), ActiveConfiguration.UidSize); - 1c62: 20 91 fb 24 lds r18, 0x24FB - 1c66: 1f 92 push r1 - 1c68: 2f 93 push r18 - 1c6a: 2e e6 ldi r18, 0x6E ; 110 - 1c6c: 34 e0 ldi r19, 0x04 ; 4 - 1c6e: 3f 93 push r19 - 1c70: 2f 93 push r18 - 1c72: 21 e0 ldi r18, 0x01 ; 1 - 1c74: 2f 93 push r18 - 1c76: 1f 92 push r1 - 1c78: 9f 93 push r25 - 1c7a: 8f 93 push r24 - 1c7c: 0e 94 0f 24 call 0x481e ; 0x481e - - return COMMAND_INFO_OK_WITH_TEXT_ID; - 1c80: 8d b7 in r24, 0x3d ; 61 - 1c82: 9e b7 in r25, 0x3e ; 62 - 1c84: 08 96 adiw r24, 0x08 ; 8 - 1c86: 8d bf out 0x3d, r24 ; 61 - 1c88: 9e bf out 0x3e, r25 ; 62 -} - 1c8a: 85 e6 ldi r24, 0x65 ; 101 - 1c8c: 08 95 ret - -00001c8e : - -CommandStatusIdType CommandExecButton(char* OutMessage) -{ - ButtonGetActionList(OutMessage, TERMINAL_BUFFER_SIZE); - 1c8e: 60 e0 ldi r22, 0x00 ; 0 - 1c90: 71 e0 ldi r23, 0x01 ; 1 - 1c92: df dc rcall .-1602 ; 0x1652 - - return COMMAND_INFO_OK_WITH_TEXT_ID; -} - 1c94: 85 e6 ldi r24, 0x65 ; 101 - 1c96: 08 95 ret - -00001c98 : - -CommandStatusIdType CommandGetButton(char* OutParam) -{ - ButtonGetActionByName(OutParam, TERMINAL_BUFFER_SIZE); - 1c98: 60 e0 ldi r22, 0x00 ; 0 - 1c9a: 71 e0 ldi r23, 0x01 ; 1 - 1c9c: 13 dd rcall .-1498 ; 0x16c4 - - return COMMAND_INFO_OK_WITH_TEXT_ID; -} - 1c9e: 85 e6 ldi r24, 0x65 ; 101 - 1ca0: 08 95 ret - -00001ca2 : - -CommandStatusIdType CommandSetButton(const char* InParam) -{ - if (ButtonSetActionByName(InParam)) { - 1ca2: 1e dd rcall .-1476 ; 0x16e0 - 1ca4: 81 11 cpse r24, r1 - 1ca6: 02 c0 rjmp .+4 ; 0x1cac - SettingsSave(); - return COMMAND_INFO_OK_ID; - } else { - return COMMAND_ERR_INVALID_PARAM_ID; - 1ca8: 8a ec ldi r24, 0xCA ; 202 - } -} - 1caa: 08 95 ret -} - -CommandStatusIdType CommandSetButton(const char* InParam) -{ - if (ButtonSetActionByName(InParam)) { - SettingsSave(); - 1cac: 81 dd rcall .-1278 ; 0x17b0 - return COMMAND_INFO_OK_ID; - 1cae: 84 e6 ldi r24, 0x64 ; 100 - 1cb0: 08 95 ret - -00001cb2 : - } -} - -CommandStatusIdType CommandGetSetting(char* OutParam) -{ - SettingsGetActiveByName(OutParam, TERMINAL_BUFFER_SIZE); - 1cb2: 60 e0 ldi r22, 0x00 ; 0 - 1cb4: 71 e0 ldi r23, 0x01 ; 1 - 1cb6: 0f de rcall .-994 ; 0x18d6 - return COMMAND_INFO_OK_WITH_TEXT_ID; -} - 1cb8: 85 e6 ldi r24, 0x65 ; 101 - 1cba: 08 95 ret - -00001cbc : - -CommandStatusIdType CommandSetSetting(const char* InParam) -{ - if (SettingsSetActiveByName(InParam)) { - 1cbc: 13 de rcall .-986 ; 0x18e4 - 1cbe: 81 11 cpse r24, r1 - 1cc0: 02 c0 rjmp .+4 ; 0x1cc6 - SettingsSave(); - return COMMAND_INFO_OK_ID; - } else { - return COMMAND_ERR_INVALID_PARAM_ID; - 1cc2: 8a ec ldi r24, 0xCA ; 202 - } -} - 1cc4: 08 95 ret -} - -CommandStatusIdType CommandSetSetting(const char* InParam) -{ - if (SettingsSetActiveByName(InParam)) { - SettingsSave(); - 1cc6: 74 dd rcall .-1304 ; 0x17b0 - return COMMAND_INFO_OK_ID; - 1cc8: 84 e6 ldi r24, 0x64 ; 100 - 1cca: 08 95 ret - -00001ccc : - } -} - -CommandStatusIdType CommandExecClear(char* OutParam) -{ - MemoryClear(); - 1ccc: 0e 94 03 06 call 0xc06 ; 0xc06 - return COMMAND_INFO_OK_ID; -} - 1cd0: 84 e6 ldi r24, 0x64 ; 100 - 1cd2: 08 95 ret - -00001cd4 : - -CommandStatusIdType CommandExecHelp(char* OutMessage) -{ - 1cd4: df 92 push r13 - 1cd6: ef 92 push r14 - 1cd8: ff 92 push r15 - 1cda: 0f 93 push r16 - 1cdc: 1f 93 push r17 - 1cde: cf 93 push r28 - 1ce0: df 93 push r29 - 1ce2: 7c 01 movw r14, r24 - const CommandEntryType* EntryPtr = CommandTable; - uint16_t ByteCount = TERMINAL_BUFFER_SIZE - 1; /* Account for '\0' */ - 1ce4: cf ef ldi r28, 0xFF ; 255 - 1ce6: d0 e0 ldi r29, 0x00 ; 0 - return COMMAND_INFO_OK_ID; -} - -CommandStatusIdType CommandExecHelp(char* OutMessage) -{ - const CommandEntryType* EntryPtr = CommandTable; - 1ce8: 07 e9 ldi r16, 0x97 ; 151 - 1cea: 15 e0 ldi r17, 0x05 ; 5 - *OutMessage++ = c; - CommandName++; - ByteCount--; - } - - *OutMessage++ = ','; - 1cec: 8c e2 ldi r24, 0x2C ; 44 - 1cee: d8 2e mov r13, r24 -CommandStatusIdType CommandExecHelp(char* OutMessage) -{ - const CommandEntryType* EntryPtr = CommandTable; - uint16_t ByteCount = TERMINAL_BUFFER_SIZE - 1; /* Account for '\0' */ - - while(strcmp_P(COMMAND_LIST_END, EntryPtr->Command) != 0) { - 1cf0: b8 01 movw r22, r16 - 1cf2: 80 e9 ldi r24, 0x90 ; 144 - 1cf4: 90 e2 ldi r25, 0x20 ; 32 - 1cf6: 0e 94 ee 23 call 0x47dc ; 0x47dc - 1cfa: 89 2b or r24, r25 - 1cfc: 39 f1 breq .+78 ; 0x1d4c - const char* CommandName = EntryPtr->Command; - char c; - - while( (c = pgm_read_byte(CommandName)) != '\0' && ByteCount > 32) { - 1cfe: f8 01 movw r30, r16 - 1d00: 44 91 lpm r20, Z - 1d02: 44 23 and r20, r20 - 1d04: 79 f1 breq .+94 ; 0x1d64 - 1d06: c1 32 cpi r28, 0x21 ; 33 - 1d08: d1 05 cpc r29, r1 - 1d0a: 60 f1 brcs .+88 ; 0x1d64 - 1d0c: d7 01 movw r26, r14 - 1d0e: f8 01 movw r30, r16 - 1d10: 04 c0 rjmp .+8 ; 0x1d1a - 1d12: c0 32 cpi r28, 0x20 ; 32 - 1d14: d1 05 cpc r29, r1 - 1d16: 51 f0 breq .+20 ; 0x1d2c - 1d18: dc 01 movw r26, r24 - 1d1a: cd 01 movw r24, r26 - 1d1c: 01 96 adiw r24, 0x01 ; 1 - 1d1e: 9c 01 movw r18, r24 - *OutMessage++ = c; - 1d20: 4c 93 st X, r20 - CommandName++; - 1d22: 31 96 adiw r30, 0x01 ; 1 - ByteCount--; - 1d24: 21 97 sbiw r28, 0x01 ; 1 - - while(strcmp_P(COMMAND_LIST_END, EntryPtr->Command) != 0) { - const char* CommandName = EntryPtr->Command; - char c; - - while( (c = pgm_read_byte(CommandName)) != '\0' && ByteCount > 32) { - 1d26: 44 91 lpm r20, Z - 1d28: 41 11 cpse r20, r1 - 1d2a: f3 cf rjmp .-26 ; 0x1d12 - *OutMessage++ = c; - CommandName++; - ByteCount--; - } - - *OutMessage++ = ','; - 1d2c: 79 01 movw r14, r18 - 1d2e: 8f ef ldi r24, 0xFF ; 255 - 1d30: e8 1a sub r14, r24 - 1d32: f8 0a sbc r15, r24 - 1d34: f9 01 movw r30, r18 - 1d36: d0 82 st Z, r13 - ByteCount--; - 1d38: 21 97 sbiw r28, 0x01 ; 1 - - EntryPtr++; - 1d3a: 0a 5e subi r16, 0xEA ; 234 - 1d3c: 1f 4f sbci r17, 0xFF ; 255 -CommandStatusIdType CommandExecHelp(char* OutMessage) -{ - const CommandEntryType* EntryPtr = CommandTable; - uint16_t ByteCount = TERMINAL_BUFFER_SIZE - 1; /* Account for '\0' */ - - while(strcmp_P(COMMAND_LIST_END, EntryPtr->Command) != 0) { - 1d3e: b8 01 movw r22, r16 - 1d40: 80 e9 ldi r24, 0x90 ; 144 - 1d42: 90 e2 ldi r25, 0x20 ; 32 - 1d44: 0e 94 ee 23 call 0x47dc ; 0x47dc - 1d48: 89 2b or r24, r25 - 1d4a: c9 f6 brne .-78 ; 0x1cfe - ByteCount--; - - EntryPtr++; - } - - *--OutMessage = '\0'; - 1d4c: d7 01 movw r26, r14 - 1d4e: 11 97 sbiw r26, 0x01 ; 1 - 1d50: 1c 92 st X, r1 - - return COMMAND_INFO_OK_WITH_TEXT_ID; -} - 1d52: 85 e6 ldi r24, 0x65 ; 101 - 1d54: df 91 pop r29 - 1d56: cf 91 pop r28 - 1d58: 1f 91 pop r17 - 1d5a: 0f 91 pop r16 - 1d5c: ff 90 pop r15 - 1d5e: ef 90 pop r14 - 1d60: df 90 pop r13 - 1d62: 08 95 ret - - while(strcmp_P(COMMAND_LIST_END, EntryPtr->Command) != 0) { - const char* CommandName = EntryPtr->Command; - char c; - - while( (c = pgm_read_byte(CommandName)) != '\0' && ByteCount > 32) { - 1d64: 97 01 movw r18, r14 - 1d66: e2 cf rjmp .-60 ; 0x1d2c - -00001d68 : - - return COMMAND_INFO_OK_WITH_TEXT_ID; -} - -CommandStatusIdType CommandGetRssi(char* OutParam) -{ - 1d68: fc 01 movw r30, r24 -} - -static inline -uint16_t AntennaLevelGet(void) -{ - ADCA.CH0.CTRL |= ADC_CH_START_bm; - 1d6a: 20 91 20 02 lds r18, 0x0220 - 1d6e: 20 68 ori r18, 0x80 ; 128 - 1d70: 20 93 20 02 sts 0x0220, r18 - while( !(ADCA.CH0.INTFLAGS & ADC_CH_CHIF_bm) ); - 1d74: 20 91 23 02 lds r18, 0x0223 - 1d78: 20 ff sbrs r18, 0 - 1d7a: fc cf rjmp .-8 ; 0x1d74 - - ADCA.CH0.INTFLAGS = ADC_CH_CHIF_bm; - 1d7c: 81 e0 ldi r24, 0x01 ; 1 - 1d7e: 80 93 23 02 sts 0x0223, r24 - - int16_t Result = ADCA.CH0RES - ANTENNA_LEVEL_OFFSET; - 1d82: a0 91 10 02 lds r26, 0x0210 - 1d86: b0 91 11 02 lds r27, 0x0211 - 1d8a: ae 5b subi r26, 0xBE ; 190 - 1d8c: b1 09 sbc r27, r1 - 1d8e: b7 fd sbrc r27, 7 - 1d90: 1c c0 rjmp .+56 ; 0x1dca - if (Result < 0) Result = 0; - - return (uint16_t) (((uint32_t) Result * ANTENNA_LEVEL_NUMERATOR) / ANTENNA_LEVEL_DENOMINATOR); - 1d92: 29 e6 ldi r18, 0x69 ; 105 - 1d94: 37 e5 ldi r19, 0x57 ; 87 - 1d96: 4b e0 ldi r20, 0x0B ; 11 - 1d98: 50 e0 ldi r21, 0x00 ; 0 - 1d9a: 0e 94 6f 23 call 0x46de ; 0x46de <__mulshisi3> - 1d9e: aa 27 eor r26, r26 - 1da0: bb 27 eor r27, r27 - snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, - 1da2: 9f 93 push r25 - 1da4: 8f 93 push r24 - 1da6: 27 e6 ldi r18, 0x67 ; 103 - 1da8: 34 e0 ldi r19, 0x04 ; 4 - 1daa: 3f 93 push r19 - 1dac: 2f 93 push r18 - 1dae: 81 e0 ldi r24, 0x01 ; 1 - 1db0: 8f 93 push r24 - 1db2: 1f 92 push r1 - 1db4: ff 93 push r31 - 1db6: ef 93 push r30 - 1db8: 0e 94 0f 24 call 0x481e ; 0x481e - PSTR("%5u mV"), AntennaLevelGet()); - - - return COMMAND_INFO_OK_WITH_TEXT_ID; - 1dbc: 8d b7 in r24, 0x3d ; 61 - 1dbe: 9e b7 in r25, 0x3e ; 62 - 1dc0: 08 96 adiw r24, 0x08 ; 8 - 1dc2: 8d bf out 0x3d, r24 ; 61 - 1dc4: 9e bf out 0x3e, r25 ; 62 -} - 1dc6: 85 e6 ldi r24, 0x65 ; 101 - 1dc8: 08 95 ret - 1dca: a0 e0 ldi r26, 0x00 ; 0 - 1dcc: b0 e0 ldi r27, 0x00 ; 0 - 1dce: e1 cf rjmp .-62 ; 0x1d92 - -00001dd0 : - return Checksum; -} - -void XModemReceive(XModemCallbackType TheCallbackFunc) -{ - State = STATE_RECEIVE_INIT; - 1dd0: 21 e0 ldi r18, 0x01 ; 1 - 1dd2: 20 93 a2 24 sts 0x24A2, r18 - CurrentFrameNumber = FIRST_FRAME_NUMBER; - 1dd6: 20 93 a1 24 sts 0x24A1, r18 - RetryCount = RECV_INIT_COUNT; - 1dda: 24 e1 ldi r18, 0x14 ; 20 - 1ddc: 20 93 9e 24 sts 0x249E, r18 - RetryTimeout = RECV_INIT_TIMEOUT; - 1de0: 25 e0 ldi r18, 0x05 ; 5 - 1de2: 20 93 9d 24 sts 0x249D, r18 - BlockAddress = 0; - 1de6: 10 92 97 24 sts 0x2497, r1 - 1dea: 10 92 98 24 sts 0x2498, r1 - 1dee: 10 92 99 24 sts 0x2499, r1 - 1df2: 10 92 9a 24 sts 0x249A, r1 - - CallbackFunc = TheCallbackFunc; - 1df6: 80 93 95 24 sts 0x2495, r24 - 1dfa: 90 93 96 24 sts 0x2496, r25 - 1dfe: 08 95 ret - -00001e00 : -} - -void XModemSend(XModemCallbackType TheCallbackFunc) -{ - State = STATE_SEND_INIT; - 1e00: 27 e0 ldi r18, 0x07 ; 7 - 1e02: 20 93 a2 24 sts 0x24A2, r18 - RetryTimeout = SEND_INIT_TIMEOUT; - 1e06: 24 e6 ldi r18, 0x64 ; 100 - 1e08: 20 93 9d 24 sts 0x249D, r18 - BlockAddress = 0; - 1e0c: 10 92 97 24 sts 0x2497, r1 - 1e10: 10 92 98 24 sts 0x2498, r1 - 1e14: 10 92 99 24 sts 0x2499, r1 - 1e18: 10 92 9a 24 sts 0x249A, r1 - - CallbackFunc = TheCallbackFunc; - 1e1c: 80 93 95 24 sts 0x2495, r24 - 1e20: 90 93 96 24 sts 0x2496, r25 - 1e24: 08 95 ret - -00001e26 : -} - -bool XModemProcessByte(uint8_t Byte) -{ - 1e26: cf 93 push r28 - switch(State) { - 1e28: 40 91 a2 24 lds r20, 0x24A2 - 1e2c: 50 e0 ldi r21, 0x00 ; 0 - 1e2e: fa 01 movw r30, r20 - 1e30: 31 97 sbiw r30, 0x01 ; 1 - 1e32: e9 30 cpi r30, 0x09 ; 9 - 1e34: f1 05 cpc r31, r1 - 1e36: 20 f0 brcs .+8 ; 0x1e40 - /* Receive Ack */ - State = STATE_OFF; - break; - - default: - return false; - 1e38: c0 e0 ldi r28, 0x00 ; 0 - break; - } - - return true; -} - 1e3a: 8c 2f mov r24, r28 - 1e3c: cf 91 pop r28 - 1e3e: 08 95 ret - CallbackFunc = TheCallbackFunc; -} - -bool XModemProcessByte(uint8_t Byte) -{ - switch(State) { - 1e40: e2 50 subi r30, 0x02 ; 2 - 1e42: ff 4f sbci r31, 0xFF ; 255 - 1e44: 0c 94 69 23 jmp 0x46d2 ; 0x46d2 <__tablejump2__> - } - - break; - - case STATE_RECEIVE_PROCESS: - if (ReceivedFrameNumber == CurrentFrameNumber) { - 1e48: 20 91 a0 24 lds r18, 0x24A0 - 1e4c: 90 91 a1 24 lds r25, 0x24A1 - 1e50: 29 17 cp r18, r25 - 1e52: 09 f4 brne .+2 ; 0x1e56 - 1e54: dd c0 rjmp .+442 ; 0x2010 - } else { - /* Data seems to be damaged */ - TerminalSendByte(BYTE_NAK); - State = STATE_RECEIVE_WAIT; - } - } else if (ReceivedFrameNumber == (CurrentFrameNumber - 1)) { - 1e56: 30 e0 ldi r19, 0x00 ; 0 - 1e58: 89 2f mov r24, r25 - 1e5a: 90 e0 ldi r25, 0x00 ; 0 - 1e5c: 01 97 sbiw r24, 0x01 ; 1 - 1e5e: 28 17 cp r18, r24 - 1e60: 39 07 cpc r19, r25 - 1e62: 09 f4 brne .+2 ; 0x1e66 - 1e64: 20 c1 rjmp .+576 ; 0x20a6 -INLINE void TerminalSendByte(uint8_t Byte) { CDC_Device_SendByte(&TerminalHandle, Byte); } - 1e66: 68 e1 ldi r22, 0x18 ; 24 - 1e68: 81 e0 ldi r24, 0x01 ; 1 - 1e6a: 90 e2 ldi r25, 0x20 ; 32 - 1e6c: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - TerminalSendByte(BYTE_ACK); - State = STATE_RECEIVE_WAIT; - } else { - /* This frame is completely out of order. Just cancel */ - TerminalSendByte(BYTE_CAN); - State = STATE_OFF; - 1e70: 10 92 a2 24 sts 0x24A2, r1 - default: - return false; - break; - } - - return true; - 1e74: c1 e0 ldi r28, 0x01 ; 1 -} - 1e76: 8c 2f mov r24, r28 - 1e78: cf 91 pop r28 - 1e7a: 08 95 ret - - break; - - case STATE_SEND_INIT: - /* Start sending on NAK */ - if (Byte == BYTE_NAK) { - 1e7c: 85 31 cpi r24, 0x15 ; 21 - 1e7e: 09 f4 brne .+2 ; 0x1e82 - 1e80: 50 c0 rjmp .+160 ; 0x1f22 - } - - /* Fallthrough */ - - case STATE_SEND_WAIT: - if (Byte == BYTE_CAN) { - 1e82: 88 31 cpi r24, 0x18 ; 24 - 1e84: 09 f4 brne .+2 ; 0x1e88 - 1e86: 06 c1 rjmp .+524 ; 0x2094 - /* Cancel */ - TerminalSendByte(BYTE_ACK); - State = STATE_OFF; - } else if (Byte == BYTE_ACK) { - 1e88: 86 30 cpi r24, 0x06 ; 6 - 1e8a: 09 f4 brne .+2 ; 0x1e8e - 1e8c: 29 c1 rjmp .+594 ; 0x20e0 - BlockAddress += XMODEM_BLOCK_SIZE; - } else { - TerminalSendByte(BYTE_EOT); - State = STATE_SEND_EOT; - } - } else if (Byte == BYTE_NAK){ - 1e8e: 85 31 cpi r24, 0x15 ; 21 - 1e90: 09 f4 brne .+2 ; 0x1e94 - 1e92: 98 c0 rjmp .+304 ; 0x1fc4 - default: - return false; - break; - } - - return true; - 1e94: c1 e0 ldi r28, 0x01 ; 1 -} - 1e96: 8c 2f mov r24, r28 - 1e98: cf 91 pop r28 - 1e9a: 08 95 ret - - break; - - case STATE_RECEIVE_FRAMENUM1: - /* Store frame number */ - ReceivedFrameNumber = Byte; - 1e9c: 80 93 a0 24 sts 0x24A0, r24 - State = STATE_RECEIVE_FRAMENUM2; - 1ea0: 84 e0 ldi r24, 0x04 ; 4 - 1ea2: 80 93 a2 24 sts 0x24A2, r24 - default: - return false; - break; - } - - return true; - 1ea6: c1 e0 ldi r28, 0x01 ; 1 -} - 1ea8: 8c 2f mov r24, r28 - 1eaa: cf 91 pop r28 - 1eac: 08 95 ret - ReceivedFrameNumber = Byte; - State = STATE_RECEIVE_FRAMENUM2; - break; - - case STATE_RECEIVE_FRAMENUM2: - if (Byte == (255 - ReceivedFrameNumber)) { - 1eae: 90 e0 ldi r25, 0x00 ; 0 - 1eb0: 40 91 a0 24 lds r20, 0x24A0 - 1eb4: 2f ef ldi r18, 0xFF ; 255 - 1eb6: 30 e0 ldi r19, 0x00 ; 0 - 1eb8: 24 1b sub r18, r20 - 1eba: 31 09 sbc r19, r1 - 1ebc: 82 17 cp r24, r18 - 1ebe: 93 07 cpc r25, r19 - 1ec0: 31 f5 brne .+76 ; 0x1f0e - /* frame-number check passed. */ - State = STATE_RECEIVE_DATA; - 1ec2: 85 e0 ldi r24, 0x05 ; 5 - 1ec4: 80 93 a2 24 sts 0x24A2, r24 - default: - return false; - break; - } - - return true; - 1ec8: c1 e0 ldi r28, 0x01 ; 1 - 1eca: b7 cf rjmp .-146 ; 0x1e3a -bool XModemProcessByte(uint8_t Byte) -{ - switch(State) { - case STATE_RECEIVE_INIT: - case STATE_RECEIVE_WAIT: - if (Byte == BYTE_SOH) { - 1ecc: 81 30 cpi r24, 0x01 ; 1 - 1ece: 09 f4 brne .+2 ; 0x1ed2 - 1ed0: ec c0 rjmp .+472 ; 0x20aa - /* Next frame incoming */ - BufferIdx = 0; - Checksum = CHECKSUM_INIT_VALUE; - State = STATE_RECEIVE_FRAMENUM1; - } else if (Byte == BYTE_EOT) { - 1ed2: 84 30 cpi r24, 0x04 ; 4 - 1ed4: 09 f4 brne .+2 ; 0x1ed8 - 1ed6: de c0 rjmp .+444 ; 0x2094 - /* Transmission finished */ - TerminalSendByte(BYTE_ACK); - State = STATE_OFF; - } else if (Byte == BYTE_CAN) { - 1ed8: 88 31 cpi r24, 0x18 ; 24 - 1eda: 51 f2 breq .-108 ; 0x1e70 - default: - return false; - break; - } - - return true; - 1edc: c1 e0 ldi r28, 0x01 ; 1 - 1ede: db cf rjmp .-74 ; 0x1e96 - - break; - - case STATE_RECEIVE_DATA: - /* Process byte and update checksum */ - TerminalBuffer[BufferIdx++] = Byte; - 1ee0: 40 91 9b 24 lds r20, 0x249B - 1ee4: 50 91 9c 24 lds r21, 0x249C - 1ee8: 9a 01 movw r18, r20 - 1eea: 2f 5f subi r18, 0xFF ; 255 - 1eec: 3f 4f sbci r19, 0xFF ; 255 - 1eee: 20 93 9b 24 sts 0x249B, r18 - 1ef2: 30 93 9c 24 sts 0x249C, r19 - 1ef6: fa 01 movw r30, r20 - 1ef8: e0 5f subi r30, 0xF0 ; 240 - 1efa: fa 4d sbci r31, 0xDA ; 218 - 1efc: 80 83 st Z, r24 - - if (BufferIdx == XMODEM_BLOCK_SIZE) { - 1efe: 20 38 cpi r18, 0x80 ; 128 - 1f00: 31 05 cpc r19, r1 - 1f02: 41 f6 brne .-112 ; 0x1e94 - /* Block full */ - State = STATE_RECEIVE_PROCESS; - 1f04: 86 e0 ldi r24, 0x06 ; 6 - 1f06: 80 93 a2 24 sts 0x24A2, r24 - default: - return false; - break; - } - - return true; - 1f0a: c1 e0 ldi r28, 0x01 ; 1 - 1f0c: 96 cf rjmp .-212 ; 0x1e3a - 1f0e: 65 e1 ldi r22, 0x15 ; 21 - 1f10: 81 e0 ldi r24, 0x01 ; 1 - 1f12: 90 e2 ldi r25, 0x20 ; 32 - 1f14: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - State = STATE_RECEIVE_WAIT; - } - } else if (ReceivedFrameNumber == (CurrentFrameNumber - 1)) { - /* This is a retransmission */ - TerminalSendByte(BYTE_ACK); - State = STATE_RECEIVE_WAIT; - 1f18: 82 e0 ldi r24, 0x02 ; 2 - 1f1a: 80 93 a2 24 sts 0x24A2, r24 - default: - return false; - break; - } - - return true; - 1f1e: c1 e0 ldi r28, 0x01 ; 1 - 1f20: 8c cf rjmp .-232 ; 0x1e3a - 1f22: 81 e0 ldi r24, 0x01 ; 1 - /* Cancel */ - TerminalSendByte(BYTE_ACK); - State = STATE_OFF; - } else if (Byte == BYTE_ACK) { - /* Acknowledge. Proceed to next frame, get data and calc checksum */ - CurrentFrameNumber++; - 1f24: 80 93 a1 24 sts 0x24A1, r24 - - if (CallbackFunc(TerminalBuffer, BlockAddress, XMODEM_BLOCK_SIZE)) { - 1f28: 40 91 97 24 lds r20, 0x2497 - 1f2c: 50 91 98 24 lds r21, 0x2498 - 1f30: 60 91 99 24 lds r22, 0x2499 - 1f34: 70 91 9a 24 lds r23, 0x249A - 1f38: e0 91 95 24 lds r30, 0x2495 - 1f3c: f0 91 96 24 lds r31, 0x2496 - 1f40: 20 e8 ldi r18, 0x80 ; 128 - 1f42: 30 e0 ldi r19, 0x00 ; 0 - 1f44: 80 e1 ldi r24, 0x10 ; 16 - 1f46: 95 e2 ldi r25, 0x25 ; 37 - 1f48: 09 95 icall - 1f4a: c8 2f mov r28, r24 - 1f4c: 88 23 and r24, r24 - 1f4e: 09 f4 brne .+2 ; 0x1f52 - 1f50: b7 c0 rjmp .+366 ; 0x20c0 - 1f52: 61 e0 ldi r22, 0x01 ; 1 - 1f54: 81 e0 ldi r24, 0x01 ; 1 - 1f56: 90 e2 ldi r25, 0x20 ; 32 - 1f58: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - 1f5c: 60 91 a1 24 lds r22, 0x24A1 - 1f60: 81 e0 ldi r24, 0x01 ; 1 - 1f62: 90 e2 ldi r25, 0x20 ; 32 - 1f64: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - TerminalSendByte(BYTE_SOH); - TerminalSendByte(CurrentFrameNumber); - TerminalSendByte(255 - CurrentFrameNumber); - 1f68: 60 91 a1 24 lds r22, 0x24A1 - 1f6c: 60 95 com r22 - 1f6e: 81 e0 ldi r24, 0x01 ; 1 - 1f70: 90 e2 ldi r25, 0x20 ; 32 - 1f72: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - TerminalSendBlock(TerminalBuffer, XMODEM_BLOCK_SIZE); - 1f76: 60 e8 ldi r22, 0x80 ; 128 - 1f78: 70 e0 ldi r23, 0x00 ; 0 - 1f7a: 80 e1 ldi r24, 0x10 ; 16 - 1f7c: 95 e2 ldi r25, 0x25 ; 37 - 1f7e: d8 dc rcall .-1616 ; 0x1930 - 1f80: e0 e1 ldi r30, 0x10 ; 16 - 1f82: f5 e2 ldi r31, 0x25 ; 37 -static uint32_t BlockAddress; - -static XModemCallbackType CallbackFunc; - -static uint8_t CalcChecksum(const void* Buffer, uint16_t ByteCount) { - uint8_t Checksum = CHECKSUM_INIT_VALUE; - 1f84: 60 e0 ldi r22, 0x00 ; 0 - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - Checksum += *DataPtr++; - 1f86: 81 91 ld r24, Z+ - 1f88: 68 0f add r22, r24 - -static uint8_t CalcChecksum(const void* Buffer, uint16_t ByteCount) { - uint8_t Checksum = CHECKSUM_INIT_VALUE; - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - 1f8a: 85 e2 ldi r24, 0x25 ; 37 - 1f8c: e0 39 cpi r30, 0x90 ; 144 - 1f8e: f8 07 cpc r31, r24 - 1f90: d1 f7 brne .-12 ; 0x1f86 - 1f92: 81 e0 ldi r24, 0x01 ; 1 - 1f94: 90 e2 ldi r25, 0x20 ; 32 - 1f96: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - TerminalSendByte(CurrentFrameNumber); - TerminalSendByte(255 - CurrentFrameNumber); - TerminalSendBlock(TerminalBuffer, XMODEM_BLOCK_SIZE); - TerminalSendByte(CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE)); - - BlockAddress += XMODEM_BLOCK_SIZE; - 1f9a: 40 91 97 24 lds r20, 0x2497 - 1f9e: 50 91 98 24 lds r21, 0x2498 - 1fa2: 60 91 99 24 lds r22, 0x2499 - 1fa6: 70 91 9a 24 lds r23, 0x249A - 1faa: 40 58 subi r20, 0x80 ; 128 - 1fac: 5f 4f sbci r21, 0xFF ; 255 - 1fae: 6f 4f sbci r22, 0xFF ; 255 - 1fb0: 7f 4f sbci r23, 0xFF ; 255 - 1fb2: 40 93 97 24 sts 0x2497, r20 - 1fb6: 50 93 98 24 sts 0x2498, r21 - 1fba: 60 93 99 24 sts 0x2499, r22 - 1fbe: 70 93 9a 24 sts 0x249A, r23 - 1fc2: 3b cf rjmp .-394 ; 0x1e3a - 1fc4: 61 e0 ldi r22, 0x01 ; 1 - 1fc6: 81 e0 ldi r24, 0x01 ; 1 - 1fc8: 90 e2 ldi r25, 0x20 ; 32 - 1fca: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - 1fce: 60 91 a1 24 lds r22, 0x24A1 - 1fd2: 81 e0 ldi r24, 0x01 ; 1 - 1fd4: 90 e2 ldi r25, 0x20 ; 32 - 1fd6: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - } - } else if (Byte == BYTE_NAK){ - /* Resend frame */ - TerminalSendByte(BYTE_SOH); - TerminalSendByte(CurrentFrameNumber); - TerminalSendByte(255 - CurrentFrameNumber); - 1fda: 60 91 a1 24 lds r22, 0x24A1 - 1fde: 60 95 com r22 - 1fe0: 81 e0 ldi r24, 0x01 ; 1 - 1fe2: 90 e2 ldi r25, 0x20 ; 32 - 1fe4: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - TerminalSendBlock(TerminalBuffer, XMODEM_BLOCK_SIZE); - 1fe8: 60 e8 ldi r22, 0x80 ; 128 - 1fea: 70 e0 ldi r23, 0x00 ; 0 - 1fec: 80 e1 ldi r24, 0x10 ; 16 - 1fee: 95 e2 ldi r25, 0x25 ; 37 - 1ff0: 9f dc rcall .-1730 ; 0x1930 - 1ff2: e0 e1 ldi r30, 0x10 ; 16 - 1ff4: f5 e2 ldi r31, 0x25 ; 37 -static uint32_t BlockAddress; - -static XModemCallbackType CallbackFunc; - -static uint8_t CalcChecksum(const void* Buffer, uint16_t ByteCount) { - uint8_t Checksum = CHECKSUM_INIT_VALUE; - 1ff6: 60 e0 ldi r22, 0x00 ; 0 - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - Checksum += *DataPtr++; - 1ff8: 81 91 ld r24, Z+ - 1ffa: 68 0f add r22, r24 - -static uint8_t CalcChecksum(const void* Buffer, uint16_t ByteCount) { - uint8_t Checksum = CHECKSUM_INIT_VALUE; - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - 1ffc: 25 e2 ldi r18, 0x25 ; 37 - 1ffe: e0 39 cpi r30, 0x90 ; 144 - 2000: f2 07 cpc r31, r18 - 2002: d1 f7 brne .-12 ; 0x1ff8 - 2004: 81 e0 ldi r24, 0x01 ; 1 - 2006: 90 e2 ldi r25, 0x20 ; 32 - 2008: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - default: - return false; - break; - } - - return true; - 200c: c1 e0 ldi r28, 0x01 ; 1 - 200e: 43 cf rjmp .-378 ; 0x1e96 - 2010: e0 e1 ldi r30, 0x10 ; 16 - 2012: f5 e2 ldi r31, 0x25 ; 37 - } - - break; - - case STATE_RECEIVE_PROCESS: - if (ReceivedFrameNumber == CurrentFrameNumber) { - 2014: 90 e0 ldi r25, 0x00 ; 0 -static uint8_t CalcChecksum(const void* Buffer, uint16_t ByteCount) { - uint8_t Checksum = CHECKSUM_INIT_VALUE; - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - Checksum += *DataPtr++; - 2016: 21 91 ld r18, Z+ - 2018: 92 0f add r25, r18 - -static uint8_t CalcChecksum(const void* Buffer, uint16_t ByteCount) { - uint8_t Checksum = CHECKSUM_INIT_VALUE; - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - 201a: 25 e2 ldi r18, 0x25 ; 37 - 201c: e0 39 cpi r30, 0x90 ; 144 - 201e: f2 07 cpc r31, r18 - 2020: d1 f7 brne .-12 ; 0x2016 - - case STATE_RECEIVE_PROCESS: - if (ReceivedFrameNumber == CurrentFrameNumber) { - /* This is the expected frame. Calculate and verify checksum */ - - if (CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE) == Byte) { - 2022: 89 13 cpse r24, r25 - 2024: 74 cf rjmp .-280 ; 0x1f0e - /* Checksum is valid. Pass received data to callback function */ - if (CallbackFunc(TerminalBuffer, BlockAddress, XMODEM_BLOCK_SIZE)) { - 2026: 40 91 97 24 lds r20, 0x2497 - 202a: 50 91 98 24 lds r21, 0x2498 - 202e: 60 91 99 24 lds r22, 0x2499 - 2032: 70 91 9a 24 lds r23, 0x249A - 2036: e0 91 95 24 lds r30, 0x2495 - 203a: f0 91 96 24 lds r31, 0x2496 - 203e: 20 e8 ldi r18, 0x80 ; 128 - 2040: 30 e0 ldi r19, 0x00 ; 0 - 2042: 80 e1 ldi r24, 0x10 ; 16 - 2044: 95 e2 ldi r25, 0x25 ; 37 - 2046: 09 95 icall - 2048: c8 2f mov r28, r24 - 204a: 88 23 and r24, r24 - 204c: 09 f4 brne .+2 ; 0x2050 - 204e: 42 c0 rjmp .+132 ; 0x20d4 - /* Proceed to next frame and send ACK */ - CurrentFrameNumber++; - 2050: 80 91 a1 24 lds r24, 0x24A1 - 2054: 8f 5f subi r24, 0xFF ; 255 - 2056: 80 93 a1 24 sts 0x24A1, r24 - BlockAddress += XMODEM_BLOCK_SIZE; - 205a: 40 91 97 24 lds r20, 0x2497 - 205e: 50 91 98 24 lds r21, 0x2498 - 2062: 60 91 99 24 lds r22, 0x2499 - 2066: 70 91 9a 24 lds r23, 0x249A - 206a: 40 58 subi r20, 0x80 ; 128 - 206c: 5f 4f sbci r21, 0xFF ; 255 - 206e: 6f 4f sbci r22, 0xFF ; 255 - 2070: 7f 4f sbci r23, 0xFF ; 255 - 2072: 40 93 97 24 sts 0x2497, r20 - 2076: 50 93 98 24 sts 0x2498, r21 - 207a: 60 93 99 24 sts 0x2499, r22 - 207e: 70 93 9a 24 sts 0x249A, r23 -void EVENT_USB_Device_Connect(void); -void EVENT_USB_Device_Disconnect(void); -void EVENT_USB_Device_ConfigurationChanged(void); -void EVENT_USB_Device_ControlRequest(void); - -INLINE void TerminalSendChar(char c) { CDC_Device_SendByte(&TerminalHandle, c); } - 2082: 66 e0 ldi r22, 0x06 ; 6 - 2084: 81 e0 ldi r24, 0x01 ; 1 - 2086: 90 e2 ldi r25, 0x20 ; 32 - 2088: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - TerminalSendChar(BYTE_ACK); - State = STATE_RECEIVE_WAIT; - 208c: 82 e0 ldi r24, 0x02 ; 2 - 208e: 80 93 a2 24 sts 0x24A2, r24 - 2092: d3 ce rjmp .-602 ; 0x1e3a -INLINE void TerminalSendByte(uint8_t Byte) { CDC_Device_SendByte(&TerminalHandle, Byte); } - 2094: 66 e0 ldi r22, 0x06 ; 6 - 2096: 81 e0 ldi r24, 0x01 ; 1 - 2098: 90 e2 ldi r25, 0x20 ; 32 - 209a: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - Checksum = CHECKSUM_INIT_VALUE; - State = STATE_RECEIVE_FRAMENUM1; - } else if (Byte == BYTE_EOT) { - /* Transmission finished */ - TerminalSendByte(BYTE_ACK); - State = STATE_OFF; - 209e: 10 92 a2 24 sts 0x24A2, r1 - default: - return false; - break; - } - - return true; - 20a2: c1 e0 ldi r28, 0x01 ; 1 - 20a4: ca ce rjmp .-620 ; 0x1e3a - 20a6: 66 e0 ldi r22, 0x06 ; 6 - 20a8: 33 cf rjmp .-410 ; 0x1f10 - switch(State) { - case STATE_RECEIVE_INIT: - case STATE_RECEIVE_WAIT: - if (Byte == BYTE_SOH) { - /* Next frame incoming */ - BufferIdx = 0; - 20aa: 10 92 9b 24 sts 0x249B, r1 - 20ae: 10 92 9c 24 sts 0x249C, r1 - Checksum = CHECKSUM_INIT_VALUE; - 20b2: 10 92 9f 24 sts 0x249F, r1 - State = STATE_RECEIVE_FRAMENUM1; - 20b6: 83 e0 ldi r24, 0x03 ; 3 - 20b8: 80 93 a2 24 sts 0x24A2, r24 - default: - return false; - break; - } - - return true; - 20bc: c1 e0 ldi r28, 0x01 ; 1 - 20be: bd ce rjmp .-646 ; 0x1e3a - 20c0: 64 e0 ldi r22, 0x04 ; 4 - 20c2: 81 e0 ldi r24, 0x01 ; 1 - 20c4: 90 e2 ldi r25, 0x20 ; 32 - 20c6: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - TerminalSendByte(CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE)); - - BlockAddress += XMODEM_BLOCK_SIZE; - } else { - TerminalSendByte(BYTE_EOT); - State = STATE_SEND_EOT; - 20ca: 89 e0 ldi r24, 0x09 ; 9 - 20cc: 80 93 a2 24 sts 0x24A2, r24 - default: - return false; - break; - } - - return true; - 20d0: c1 e0 ldi r28, 0x01 ; 1 - 20d2: b3 ce rjmp .-666 ; 0x1e3a - 20d4: 68 e1 ldi r22, 0x18 ; 24 - 20d6: 81 e0 ldi r24, 0x01 ; 1 - 20d8: 90 e2 ldi r25, 0x20 ; 32 - 20da: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - 20de: c3 ce rjmp .-634 ; 0x1e66 - 20e0: 80 91 a1 24 lds r24, 0x24A1 - 20e4: 8f 5f subi r24, 0xFF ; 255 - 20e6: 1e cf rjmp .-452 ; 0x1f24 - -000020e8 : -} - -void XModemTick(void) -{ - /* Timeouts go here */ - switch(State) { - 20e8: 80 91 a2 24 lds r24, 0x24A2 - 20ec: 81 30 cpi r24, 0x01 ; 1 - 20ee: 71 f0 breq .+28 ; 0x210c - 20f0: 87 30 cpi r24, 0x07 ; 7 - 20f2: 59 f4 brne .+22 ; 0x210a - RetryTimeout = RECV_INIT_TIMEOUT; - } - break; - - case STATE_SEND_INIT: - if (RetryTimeout-- == 0) { - 20f4: 80 91 9d 24 lds r24, 0x249D - 20f8: 9f ef ldi r25, 0xFF ; 255 - 20fa: 98 0f add r25, r24 - 20fc: 90 93 9d 24 sts 0x249D, r25 - 2100: 81 11 cpse r24, r1 - 2102: 02 c0 rjmp .+4 ; 0x2108 - /* Abort */ - State = STATE_OFF; - 2104: 10 92 a2 24 sts 0x24A2, r1 - 2108: 08 95 ret - 210a: 08 95 ret -void XModemTick(void) -{ - /* Timeouts go here */ - switch(State) { - case STATE_RECEIVE_INIT: - if (RetryTimeout-- == 0) { - 210c: 80 91 9d 24 lds r24, 0x249D - 2110: 9f ef ldi r25, 0xFF ; 255 - 2112: 98 0f add r25, r24 - 2114: 90 93 9d 24 sts 0x249D, r25 - 2118: 81 11 cpse r24, r1 - 211a: f6 cf rjmp .-20 ; 0x2108 - if (RetryCount-- > 0) { - 211c: 80 91 9e 24 lds r24, 0x249E - 2120: 9f ef ldi r25, 0xFF ; 255 - 2122: 98 0f add r25, r24 - 2124: 90 93 9e 24 sts 0x249E, r25 - 2128: 81 11 cpse r24, r1 - 212a: 06 c0 rjmp .+12 ; 0x2138 - /* Put out communication request */ - TerminalSendChar(BYTE_NAK); - } else { - /* Just shut off after some time. */ - State = STATE_OFF; - 212c: 10 92 a2 24 sts 0x24A2, r1 - } - - RetryTimeout = RECV_INIT_TIMEOUT; - 2130: 85 e0 ldi r24, 0x05 ; 5 - 2132: 80 93 9d 24 sts 0x249D, r24 - 2136: 08 95 ret -void EVENT_USB_Device_Connect(void); -void EVENT_USB_Device_Disconnect(void); -void EVENT_USB_Device_ConfigurationChanged(void); -void EVENT_USB_Device_ControlRequest(void); - -INLINE void TerminalSendChar(char c) { CDC_Device_SendByte(&TerminalHandle, c); } - 2138: 65 e1 ldi r22, 0x15 ; 21 - 213a: 81 e0 ldi r24, 0x01 ; 1 - 213c: 90 e2 ldi r25, 0x20 ; 32 - 213e: 0e 94 e4 21 call 0x43c8 ; 0x43c8 - 2142: f6 cf rjmp .-20 ; 0x2130 - -00002144 : -void CommandLineInit(void) -{ - BufferIdx = 0; -} - -bool CommandLineProcessByte(uint8_t Byte) { - 2144: 1f 93 push r17 - 2146: cf 93 push r28 - 2148: df 93 push r29 - if (IS_CHARACTER(Byte)){ - 214a: 9f eb ldi r25, 0xBF ; 191 - 214c: 98 0f add r25, r24 - 214e: 9a 31 cpi r25, 0x1A ; 26 - 2150: 28 f0 brcs .+10 ; 0x215c - 2152: 9f e9 ldi r25, 0x9F ; 159 - 2154: 98 0f add r25, r24 - 2156: 9a 31 cpi r25, 0x1A ; 26 - 2158: c0 f4 brcc .+48 ; 0x218a - /* Store uppercase character */ - if (IS_LOWERCASE(Byte)) { - Byte = TO_UPPERCASE(Byte); - 215a: 80 52 subi r24, 0x20 ; 32 - } - - /* Prevent buffer overflow and account for '\0' */ - if (BufferIdx < (sizeof(TerminalBuffer) / sizeof(*TerminalBuffer) - 1)) { - 215c: 20 91 a3 24 lds r18, 0x24A3 - 2160: 30 91 a4 24 lds r19, 0x24A4 - 2164: 2f 3f cpi r18, 0xFF ; 255 - 2166: 31 05 cpc r19, r1 - 2168: 58 f4 brcc .+22 ; 0x2180 - TerminalBuffer[BufferIdx++] = Byte; - 216a: a9 01 movw r20, r18 - 216c: 4f 5f subi r20, 0xFF ; 255 - 216e: 5f 4f sbci r21, 0xFF ; 255 - 2170: 40 93 a3 24 sts 0x24A3, r20 - 2174: 50 93 a4 24 sts 0x24A4, r21 - 2178: f9 01 movw r30, r18 - 217a: e0 5f subi r30, 0xF0 ; 240 - 217c: fa 4d sbci r31, 0xDA ; 218 - 217e: 80 83 st Z, r24 - } else { - /* Ignore other chars */ - } - - return true; -} - 2180: 81 e0 ldi r24, 0x01 ; 1 - 2182: df 91 pop r29 - 2184: cf 91 pop r28 - 2186: 1f 91 pop r17 - 2188: 08 95 ret -{ - BufferIdx = 0; -} - -bool CommandLineProcessByte(uint8_t Byte) { - if (IS_CHARACTER(Byte)){ - 218a: 90 ed ldi r25, 0xD0 ; 208 - 218c: 98 0f add r25, r24 - 218e: 9a 30 cpi r25, 0x0A ; 10 - 2190: 28 f3 brcs .-54 ; 0x215c - 2192: 8f 35 cpi r24, 0x5F ; 95 - 2194: 19 f3 breq .-58 ; 0x215c - 2196: 98 2f mov r25, r24 - 2198: 9d 7f andi r25, 0xFD ; 253 - 219a: 9d 33 cpi r25, 0x3D ; 61 - 219c: f9 f2 breq .-66 ; 0x215c - - /* Prevent buffer overflow and account for '\0' */ - if (BufferIdx < (sizeof(TerminalBuffer) / sizeof(*TerminalBuffer) - 1)) { - TerminalBuffer[BufferIdx++] = Byte; - } - }else if (Byte == '\r') { - 219e: 8d 30 cpi r24, 0x0D ; 13 - 21a0: a9 f0 breq .+42 ; 0x21cc - /* Process on \r. Terminate string and decode. */ - TerminalBuffer[BufferIdx] = '\0'; - BufferIdx = 0; - - DecodeCommand(); - }else if (Byte == '\b') { - 21a2: 88 30 cpi r24, 0x08 ; 8 - 21a4: 39 f0 breq .+14 ; 0x21b4 - /* Backspace. Delete last character in buffer. */ - if (BufferIdx > 0) { - BufferIdx--; - } - } else if (Byte == 0x1B){ - 21a6: 8b 31 cpi r24, 0x1B ; 27 - 21a8: 59 f7 brne .-42 ; 0x2180 - /* Drop buffer on escape */ - BufferIdx = 0; - 21aa: 10 92 a3 24 sts 0x24A3, r1 - 21ae: 10 92 a4 24 sts 0x24A4, r1 - 21b2: e6 cf rjmp .-52 ; 0x2180 - BufferIdx = 0; - - DecodeCommand(); - }else if (Byte == '\b') { - /* Backspace. Delete last character in buffer. */ - if (BufferIdx > 0) { - 21b4: 80 91 a3 24 lds r24, 0x24A3 - 21b8: 90 91 a4 24 lds r25, 0x24A4 - 21bc: 00 97 sbiw r24, 0x00 ; 0 - 21be: 01 f3 breq .-64 ; 0x2180 - BufferIdx--; - 21c0: 01 97 sbiw r24, 0x01 ; 1 - 21c2: 80 93 a3 24 sts 0x24A3, r24 - 21c6: 90 93 a4 24 sts 0x24A4, r25 - 21ca: da cf rjmp .-76 ; 0x2180 - if (BufferIdx < (sizeof(TerminalBuffer) / sizeof(*TerminalBuffer) - 1)) { - TerminalBuffer[BufferIdx++] = Byte; - } - }else if (Byte == '\r') { - /* Process on \r. Terminate string and decode. */ - TerminalBuffer[BufferIdx] = '\0'; - 21cc: e0 91 a3 24 lds r30, 0x24A3 - 21d0: f0 91 a4 24 lds r31, 0x24A4 - 21d4: e0 5f subi r30, 0xF0 ; 240 - 21d6: fa 4d sbci r31, 0xDA ; 218 - 21d8: 10 82 st Z, r1 - BufferIdx = 0; - 21da: 10 92 a3 24 sts 0x24A3, r1 - 21de: 10 92 a4 24 sts 0x24A4, r1 - bool CommandFound = false; - CommandStatusIdType StatusId = COMMAND_ERR_UNKNOWN_CMD_ID; - char* pTerminalBuffer = (char*) TerminalBuffer; - - /* Do some sanity check first */ - if (!IS_COMMAND_DELIMITER(pTerminalBuffer[0])) { - 21e2: 80 91 10 25 lds r24, 0x2510 - 21e6: 88 23 and r24, r24 - 21e8: 09 f4 brne .+2 ; 0x21ec - 21ea: a0 c0 rjmp .+320 ; 0x232c - 21ec: 8d 7f andi r24, 0xFD ; 253 - 21ee: 8d 33 cpi r24, 0x3D ; 61 - 21f0: 09 f4 brne .+2 ; 0x21f4 - 21f2: 9c c0 rjmp .+312 ; 0x232c - 21f4: e1 e1 ldi r30, 0x11 ; 17 - 21f6: f5 e2 ldi r31, 0x25 ; 37 - 21f8: 04 c0 rjmp .+8 ; 0x2202 - char* pCommandDelimiter = pTerminalBuffer; - char CommandDelimiter = '\0'; - - /* Search for command delimiter, store it and replace with '\0' */ - while(!(IS_COMMAND_DELIMITER(*pCommandDelimiter))) - 21fa: 1f 33 cpi r17, 0x3F ; 63 - 21fc: 31 f0 breq .+12 ; 0x220a - 21fe: 1d 33 cpi r17, 0x3D ; 61 - 2200: 21 f0 breq .+8 ; 0x220a - pCommandDelimiter++; - 2202: ef 01 movw r28, r30 - if (!IS_COMMAND_DELIMITER(pTerminalBuffer[0])) { - char* pCommandDelimiter = pTerminalBuffer; - char CommandDelimiter = '\0'; - - /* Search for command delimiter, store it and replace with '\0' */ - while(!(IS_COMMAND_DELIMITER(*pCommandDelimiter))) - 2204: 11 91 ld r17, Z+ - 2206: 11 11 cpse r17, r1 - 2208: f8 cf rjmp .-16 ; 0x21fa - pCommandDelimiter++; - - CommandDelimiter = *pCommandDelimiter; - *pCommandDelimiter = '\0'; - 220a: 18 82 st Y, r1 - - /* Search in command table */ - for (i=0; i<(sizeof(CommandTable) / sizeof(*CommandTable)); i++) { - if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { - 220c: 67 e9 ldi r22, 0x97 ; 151 - 220e: 75 e0 ldi r23, 0x05 ; 5 - 2210: 80 e1 ldi r24, 0x10 ; 16 - 2212: 95 e2 ldi r25, 0x25 ; 37 - 2214: 0e 94 ee 23 call 0x47dc ; 0x47dc - 2218: 89 2b or r24, r25 - 221a: 09 f4 brne .+2 ; 0x221e - 221c: 36 c1 rjmp .+620 ; 0x248a - 221e: 6d ea ldi r22, 0xAD ; 173 - 2220: 75 e0 ldi r23, 0x05 ; 5 - 2222: 80 e1 ldi r24, 0x10 ; 16 - 2224: 95 e2 ldi r25, 0x25 ; 37 - 2226: 0e 94 ee 23 call 0x47dc ; 0x47dc - 222a: 89 2b or r24, r25 - 222c: 09 f4 brne .+2 ; 0x2230 - 222e: 2a c1 rjmp .+596 ; 0x2484 - 2230: 63 ec ldi r22, 0xC3 ; 195 - 2232: 75 e0 ldi r23, 0x05 ; 5 - 2234: 80 e1 ldi r24, 0x10 ; 16 - 2236: 95 e2 ldi r25, 0x25 ; 37 - 2238: 0e 94 ee 23 call 0x47dc ; 0x47dc - 223c: 89 2b or r24, r25 - 223e: 09 f4 brne .+2 ; 0x2242 - 2240: 1e c1 rjmp .+572 ; 0x247e - 2242: 69 ed ldi r22, 0xD9 ; 217 - 2244: 75 e0 ldi r23, 0x05 ; 5 - 2246: 80 e1 ldi r24, 0x10 ; 16 - 2248: 95 e2 ldi r25, 0x25 ; 37 - 224a: 0e 94 ee 23 call 0x47dc ; 0x47dc - 224e: 89 2b or r24, r25 - 2250: 09 f4 brne .+2 ; 0x2254 - 2252: 12 c1 rjmp .+548 ; 0x2478 - 2254: 6f ee ldi r22, 0xEF ; 239 - 2256: 75 e0 ldi r23, 0x05 ; 5 - 2258: 80 e1 ldi r24, 0x10 ; 16 - 225a: 95 e2 ldi r25, 0x25 ; 37 - 225c: 0e 94 ee 23 call 0x47dc ; 0x47dc - 2260: 89 2b or r24, r25 - 2262: 09 f4 brne .+2 ; 0x2266 - 2264: 06 c1 rjmp .+524 ; 0x2472 - 2266: 65 e0 ldi r22, 0x05 ; 5 - 2268: 76 e0 ldi r23, 0x06 ; 6 - 226a: 80 e1 ldi r24, 0x10 ; 16 - 226c: 95 e2 ldi r25, 0x25 ; 37 - 226e: 0e 94 ee 23 call 0x47dc ; 0x47dc - 2272: 89 2b or r24, r25 - 2274: 09 f4 brne .+2 ; 0x2278 - 2276: fa c0 rjmp .+500 ; 0x246c - 2278: 6b e1 ldi r22, 0x1B ; 27 - 227a: 76 e0 ldi r23, 0x06 ; 6 - 227c: 80 e1 ldi r24, 0x10 ; 16 - 227e: 95 e2 ldi r25, 0x25 ; 37 - 2280: 0e 94 ee 23 call 0x47dc ; 0x47dc - 2284: 89 2b or r24, r25 - 2286: 09 f4 brne .+2 ; 0x228a - 2288: ee c0 rjmp .+476 ; 0x2466 - 228a: 61 e3 ldi r22, 0x31 ; 49 - 228c: 76 e0 ldi r23, 0x06 ; 6 - 228e: 80 e1 ldi r24, 0x10 ; 16 - 2290: 95 e2 ldi r25, 0x25 ; 37 - 2292: 0e 94 ee 23 call 0x47dc ; 0x47dc - 2296: 89 2b or r24, r25 - 2298: 09 f4 brne .+2 ; 0x229c - 229a: e2 c0 rjmp .+452 ; 0x2460 - 229c: 67 e4 ldi r22, 0x47 ; 71 - 229e: 76 e0 ldi r23, 0x06 ; 6 - 22a0: 80 e1 ldi r24, 0x10 ; 16 - 22a2: 95 e2 ldi r25, 0x25 ; 37 - 22a4: 0e 94 ee 23 call 0x47dc ; 0x47dc - 22a8: 89 2b or r24, r25 - 22aa: 09 f4 brne .+2 ; 0x22ae - 22ac: d6 c0 rjmp .+428 ; 0x245a - 22ae: 6d e5 ldi r22, 0x5D ; 93 - 22b0: 76 e0 ldi r23, 0x06 ; 6 - 22b2: 80 e1 ldi r24, 0x10 ; 16 - 22b4: 95 e2 ldi r25, 0x25 ; 37 - 22b6: 0e 94 ee 23 call 0x47dc ; 0x47dc - 22ba: 89 2b or r24, r25 - 22bc: 09 f4 brne .+2 ; 0x22c0 - 22be: ca c0 rjmp .+404 ; 0x2454 - 22c0: 63 e7 ldi r22, 0x73 ; 115 - 22c2: 76 e0 ldi r23, 0x06 ; 6 - 22c4: 80 e1 ldi r24, 0x10 ; 16 - 22c6: 95 e2 ldi r25, 0x25 ; 37 - 22c8: 0e 94 ee 23 call 0x47dc ; 0x47dc - 22cc: 89 2b or r24, r25 - 22ce: 09 f4 brne .+2 ; 0x22d2 - 22d0: be c0 rjmp .+380 ; 0x244e - 22d2: 69 e8 ldi r22, 0x89 ; 137 - 22d4: 76 e0 ldi r23, 0x06 ; 6 - 22d6: 80 e1 ldi r24, 0x10 ; 16 - 22d8: 95 e2 ldi r25, 0x25 ; 37 - 22da: 0e 94 ee 23 call 0x47dc ; 0x47dc - 22de: 89 2b or r24, r25 - 22e0: 09 f4 brne .+2 ; 0x22e4 - 22e2: b2 c0 rjmp .+356 ; 0x2448 - 22e4: 6f e9 ldi r22, 0x9F ; 159 - 22e6: 76 e0 ldi r23, 0x06 ; 6 - 22e8: 80 e1 ldi r24, 0x10 ; 16 - 22ea: 95 e2 ldi r25, 0x25 ; 37 - 22ec: 0e 94 ee 23 call 0x47dc ; 0x47dc - 22f0: 89 2b or r24, r25 - 22f2: 09 f4 brne .+2 ; 0x22f6 - 22f4: a6 c0 rjmp .+332 ; 0x2442 - 22f6: 65 eb ldi r22, 0xB5 ; 181 - 22f8: 76 e0 ldi r23, 0x06 ; 6 - 22fa: 80 e1 ldi r24, 0x10 ; 16 - 22fc: 95 e2 ldi r25, 0x25 ; 37 - 22fe: 0e 94 ee 23 call 0x47dc ; 0x47dc - 2302: 89 2b or r24, r25 - 2304: 09 f4 brne .+2 ; 0x2308 - 2306: 9a c0 rjmp .+308 ; 0x243c - 2308: 6b ec ldi r22, 0xCB ; 203 - 230a: 76 e0 ldi r23, 0x06 ; 6 - 230c: 80 e1 ldi r24, 0x10 ; 16 - 230e: 95 e2 ldi r25, 0x25 ; 37 - 2310: 0e 94 ee 23 call 0x47dc ; 0x47dc - 2314: 89 2b or r24, r25 - 2316: 09 f4 brne .+2 ; 0x231a - 2318: 8e c0 rjmp .+284 ; 0x2436 - 231a: 61 ee ldi r22, 0xE1 ; 225 - 231c: 76 e0 ldi r23, 0x06 ; 6 - 231e: 80 e1 ldi r24, 0x10 ; 16 - 2320: 95 e2 ldi r25, 0x25 ; 37 - 2322: 0e 94 ee 23 call 0x47dc ; 0x47dc - 2326: 89 2b or r24, r25 - 2328: 09 f4 brne .+2 ; 0x232c - 232a: 52 c0 rjmp .+164 ; 0x23d0 - -static void DecodeCommand(void) -{ - uint8_t i; - bool CommandFound = false; - CommandStatusIdType StatusId = COMMAND_ERR_UNKNOWN_CMD_ID; - 232c: 88 ec ldi r24, 0xC8 ; 200 -} - -static void DecodeCommand(void) -{ - uint8_t i; - bool CommandFound = false; - 232e: c0 e0 ldi r28, 0x00 ; 0 -static const char* GetStatusMessageP(CommandStatusIdType StatusId) -{ - uint8_t i; - - for (i=0; i<(sizeof(StatusTable)/sizeof(*StatusTable)); i++) { - if (pgm_read_byte(&StatusTable[i].Id) == StatusId) - 2330: e1 ed ldi r30, 0xD1 ; 209 - 2332: f4 e0 ldi r31, 0x04 ; 4 - 2334: e4 91 lpm r30, Z - 2336: 8e 17 cp r24, r30 - 2338: 09 f4 brne .+2 ; 0x233c - 233a: 30 c0 rjmp .+96 ; 0x239c - 233c: e2 ef ldi r30, 0xF2 ; 242 - 233e: f4 e0 ldi r31, 0x04 ; 4 - 2340: e4 91 lpm r30, Z - 2342: 8e 17 cp r24, r30 - 2344: 09 f4 brne .+2 ; 0x2348 - 2346: 41 c0 rjmp .+130 ; 0x23ca - 2348: e3 e1 ldi r30, 0x13 ; 19 - 234a: f5 e0 ldi r31, 0x05 ; 5 - 234c: e4 91 lpm r30, Z - 234e: 8e 17 cp r24, r30 - 2350: 09 f4 brne .+2 ; 0x2354 - 2352: 38 c0 rjmp .+112 ; 0x23c4 - 2354: e4 e3 ldi r30, 0x34 ; 52 - 2356: f5 e0 ldi r31, 0x05 ; 5 - 2358: e4 91 lpm r30, Z - 235a: 8e 17 cp r24, r30 - 235c: 81 f1 breq .+96 ; 0x23be - 235e: e5 e5 ldi r30, 0x55 ; 85 - 2360: f5 e0 ldi r31, 0x05 ; 5 - 2362: e4 91 lpm r30, Z - 2364: 8e 17 cp r24, r30 - 2366: 41 f1 breq .+80 ; 0x23b8 - 2368: e6 e7 ldi r30, 0x76 ; 118 - 236a: f5 e0 ldi r31, 0x05 ; 5 - 236c: e4 91 lpm r30, Z - 236e: 8e 17 cp r24, r30 - 2370: 01 f1 breq .+64 ; 0x23b2 - return StatusTable[i].Message; - } - - return (void*) 0; - 2372: 80 e0 ldi r24, 0x00 ; 0 - 2374: 90 e0 ldi r25, 0x00 ; 0 - } - } - } - - /* Send command status message */ - TerminalSendStringP(GetStatusMessageP(StatusId)); - 2376: c8 da rcall .-2672 ; 0x1908 - TerminalSendStringP(PSTR(STATUS_MESSAGE_TRAILER)); - 2378: 8e ec ldi r24, 0xCE ; 206 - 237a: 94 e0 ldi r25, 0x04 ; 4 - 237c: c5 da rcall .-2678 ; 0x1908 - - if (CommandFound && (pTerminalBuffer[0] != '\0') ) { - 237e: cc 23 and r28, r28 - 2380: 09 f4 brne .+2 ; 0x2384 - 2382: fe ce rjmp .-516 ; 0x2180 - 2384: 80 91 10 25 lds r24, 0x2510 - 2388: 88 23 and r24, r24 - 238a: 09 f4 brne .+2 ; 0x238e - 238c: f9 ce rjmp .-526 ; 0x2180 - /* Send optional answer */ - TerminalSendString(pTerminalBuffer); - 238e: 80 e1 ldi r24, 0x10 ; 16 - 2390: 95 e2 ldi r25, 0x25 ; 37 - 2392: b5 da rcall .-2710 ; 0x18fe - TerminalSendStringP(PSTR(OPTIONAL_ANSWER_TRAILER)); - 2394: 8b ec ldi r24, 0xCB ; 203 - 2396: 94 e0 ldi r25, 0x04 ; 4 - 2398: b7 da rcall .-2706 ; 0x1908 - 239a: f2 ce rjmp .-540 ; 0x2180 -static const char* GetStatusMessageP(CommandStatusIdType StatusId) -{ - uint8_t i; - - for (i=0; i<(sizeof(StatusTable)/sizeof(*StatusTable)); i++) { - if (pgm_read_byte(&StatusTable[i].Id) == StatusId) - 239c: 20 e0 ldi r18, 0x00 ; 0 - 239e: 30 e0 ldi r19, 0x00 ; 0 - return StatusTable[i].Message; - 23a0: 41 e2 ldi r20, 0x21 ; 33 - 23a2: 42 9f mul r20, r18 - 23a4: c0 01 movw r24, r0 - 23a6: 43 9f mul r20, r19 - 23a8: 90 0d add r25, r0 - 23aa: 11 24 eor r1, r1 - 23ac: 8e 52 subi r24, 0x2E ; 46 - 23ae: 9b 4f sbci r25, 0xFB ; 251 - 23b0: e2 cf rjmp .-60 ; 0x2376 -static const char* GetStatusMessageP(CommandStatusIdType StatusId) -{ - uint8_t i; - - for (i=0; i<(sizeof(StatusTable)/sizeof(*StatusTable)); i++) { - if (pgm_read_byte(&StatusTable[i].Id) == StatusId) - 23b2: 25 e0 ldi r18, 0x05 ; 5 - 23b4: 30 e0 ldi r19, 0x00 ; 0 - 23b6: f4 cf rjmp .-24 ; 0x23a0 - 23b8: 24 e0 ldi r18, 0x04 ; 4 - 23ba: 30 e0 ldi r19, 0x00 ; 0 - 23bc: f1 cf rjmp .-30 ; 0x23a0 - 23be: 23 e0 ldi r18, 0x03 ; 3 - 23c0: 30 e0 ldi r19, 0x00 ; 0 - 23c2: ee cf rjmp .-36 ; 0x23a0 - 23c4: 22 e0 ldi r18, 0x02 ; 2 - 23c6: 30 e0 ldi r19, 0x00 ; 0 - 23c8: eb cf rjmp .-42 ; 0x23a0 - 23ca: 21 e0 ldi r18, 0x01 ; 1 - 23cc: 30 e0 ldi r19, 0x00 ; 0 - 23ce: e8 cf rjmp .-48 ; 0x23a0 - CommandDelimiter = *pCommandDelimiter; - *pCommandDelimiter = '\0'; - - /* Search in command table */ - for (i=0; i<(sizeof(CommandTable) / sizeof(*CommandTable)); i++) { - if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { - 23d0: 21 ee ldi r18, 0xE1 ; 225 - 23d2: 36 e0 ldi r19, 0x06 ; 6 - /* Command found. Clear buffer, and call appropriate function */ - char* pParam = ++pCommandDelimiter; - - pTerminalBuffer[0] = '\0'; - 23d4: 10 92 10 25 sts 0x2510, r1 -static CommandStatusIdType CallCommandFunc( - const CommandEntryType* CommandEntry, char CommandDelimiter, char* pParam) { - char* pTerminalBuffer = (char*) TerminalBuffer; - - /* Call appropriate function depending on CommandDelimiter */ - if (CommandDelimiter == CHAR_GET_MODE) { - 23d8: 1f 33 cpi r17, 0x3F ; 63 - 23da: 19 f1 breq .+70 ; 0x2422 - CommandGetFuncType GetFunc = pgm_read_ptr(&CommandEntry->GetFunc); - if (GetFunc != NO_FUNCTION) { - return GetFunc(pTerminalBuffer); - } - } else if (CommandDelimiter == CHAR_SET_MODE) { - 23dc: 1d 33 cpi r17, 0x3D ; 61 - 23de: 99 f0 breq .+38 ; 0x2406 - CommandSetFuncType SetFunc = pgm_read_ptr(&CommandEntry->SetFunc); - if (SetFunc != NO_FUNCTION) { - return SetFunc(pParam); - } - } else if (CommandDelimiter == CHAR_EXEC_MODE){ - 23e0: 11 23 and r17, r17 - 23e2: 19 f0 breq .+6 ; 0x23ea - } else { - /* This should not happen (TM) */ - } - - /* This delimiter has not been registered with this command */ - return COMMAND_ERR_INVALID_USAGE_ID; - 23e4: 89 ec ldi r24, 0xC9 ; 201 - if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { - /* Command found. Clear buffer, and call appropriate function */ - char* pParam = ++pCommandDelimiter; - - pTerminalBuffer[0] = '\0'; - CommandFound = true; - 23e6: c1 e0 ldi r28, 0x01 ; 1 - 23e8: a3 cf rjmp .-186 ; 0x2330 - CommandSetFuncType SetFunc = pgm_read_ptr(&CommandEntry->SetFunc); - if (SetFunc != NO_FUNCTION) { - return SetFunc(pParam); - } - } else if (CommandDelimiter == CHAR_EXEC_MODE){ - CommandExecFuncType ExecFunc = pgm_read_ptr(&CommandEntry->ExecFunc); - 23ea: 20 5f subi r18, 0xF0 ; 240 - 23ec: 3f 4f sbci r19, 0xFF ; 255 - 23ee: f9 01 movw r30, r18 - 23f0: 45 91 lpm r20, Z+ - 23f2: 54 91 lpm r21, Z - if (ExecFunc != NO_FUNCTION) { - 23f4: 41 15 cp r20, r1 - 23f6: 51 05 cpc r21, r1 - 23f8: a9 f3 breq .-22 ; 0x23e4 - return ExecFunc(pTerminalBuffer); - 23fa: 80 e1 ldi r24, 0x10 ; 16 - 23fc: 95 e2 ldi r25, 0x25 ; 37 - 23fe: fa 01 movw r30, r20 - 2400: 09 95 icall - if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { - /* Command found. Clear buffer, and call appropriate function */ - char* pParam = ++pCommandDelimiter; - - pTerminalBuffer[0] = '\0'; - CommandFound = true; - 2402: c1 e0 ldi r28, 0x01 ; 1 - 2404: 95 cf rjmp .-214 ; 0x2330 - CommandGetFuncType GetFunc = pgm_read_ptr(&CommandEntry->GetFunc); - if (GetFunc != NO_FUNCTION) { - return GetFunc(pTerminalBuffer); - } - } else if (CommandDelimiter == CHAR_SET_MODE) { - CommandSetFuncType SetFunc = pgm_read_ptr(&CommandEntry->SetFunc); - 2406: 2e 5e subi r18, 0xEE ; 238 - 2408: 3f 4f sbci r19, 0xFF ; 255 - 240a: f9 01 movw r30, r18 - 240c: 45 91 lpm r20, Z+ - 240e: 54 91 lpm r21, Z - if (SetFunc != NO_FUNCTION) { - 2410: 41 15 cp r20, r1 - 2412: 51 05 cpc r21, r1 - 2414: 39 f3 breq .-50 ; 0x23e4 - return SetFunc(pParam); - 2416: ce 01 movw r24, r28 - 2418: 01 96 adiw r24, 0x01 ; 1 - 241a: fa 01 movw r30, r20 - 241c: 09 95 icall - if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { - /* Command found. Clear buffer, and call appropriate function */ - char* pParam = ++pCommandDelimiter; - - pTerminalBuffer[0] = '\0'; - CommandFound = true; - 241e: c1 e0 ldi r28, 0x01 ; 1 - 2420: 87 cf rjmp .-242 ; 0x2330 - const CommandEntryType* CommandEntry, char CommandDelimiter, char* pParam) { - char* pTerminalBuffer = (char*) TerminalBuffer; - - /* Call appropriate function depending on CommandDelimiter */ - if (CommandDelimiter == CHAR_GET_MODE) { - CommandGetFuncType GetFunc = pgm_read_ptr(&CommandEntry->GetFunc); - 2422: 2c 5e subi r18, 0xEC ; 236 - 2424: 3f 4f sbci r19, 0xFF ; 255 - 2426: f9 01 movw r30, r18 - 2428: 45 91 lpm r20, Z+ - 242a: 54 91 lpm r21, Z - if (GetFunc != NO_FUNCTION) { - 242c: 41 15 cp r20, r1 - 242e: 51 05 cpc r21, r1 - 2430: 21 f7 brne .-56 ; 0x23fa - } else { - /* This should not happen (TM) */ - } - - /* This delimiter has not been registered with this command */ - return COMMAND_ERR_INVALID_USAGE_ID; - 2432: 89 ec ldi r24, 0xC9 ; 201 - 2434: d8 cf rjmp .-80 ; 0x23e6 - CommandDelimiter = *pCommandDelimiter; - *pCommandDelimiter = '\0'; - - /* Search in command table */ - for (i=0; i<(sizeof(CommandTable) / sizeof(*CommandTable)); i++) { - if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { - 2436: 2b ec ldi r18, 0xCB ; 203 - 2438: 36 e0 ldi r19, 0x06 ; 6 - 243a: cc cf rjmp .-104 ; 0x23d4 - 243c: 25 eb ldi r18, 0xB5 ; 181 - 243e: 36 e0 ldi r19, 0x06 ; 6 - 2440: c9 cf rjmp .-110 ; 0x23d4 - 2442: 2f e9 ldi r18, 0x9F ; 159 - 2444: 36 e0 ldi r19, 0x06 ; 6 - 2446: c6 cf rjmp .-116 ; 0x23d4 - 2448: 29 e8 ldi r18, 0x89 ; 137 - 244a: 36 e0 ldi r19, 0x06 ; 6 - 244c: c3 cf rjmp .-122 ; 0x23d4 - 244e: 23 e7 ldi r18, 0x73 ; 115 - 2450: 36 e0 ldi r19, 0x06 ; 6 - 2452: c0 cf rjmp .-128 ; 0x23d4 - 2454: 2d e5 ldi r18, 0x5D ; 93 - 2456: 36 e0 ldi r19, 0x06 ; 6 - 2458: bd cf rjmp .-134 ; 0x23d4 - 245a: 27 e4 ldi r18, 0x47 ; 71 - 245c: 36 e0 ldi r19, 0x06 ; 6 - 245e: ba cf rjmp .-140 ; 0x23d4 - 2460: 21 e3 ldi r18, 0x31 ; 49 - 2462: 36 e0 ldi r19, 0x06 ; 6 - 2464: b7 cf rjmp .-146 ; 0x23d4 - 2466: 2b e1 ldi r18, 0x1B ; 27 - 2468: 36 e0 ldi r19, 0x06 ; 6 - 246a: b4 cf rjmp .-152 ; 0x23d4 - 246c: 25 e0 ldi r18, 0x05 ; 5 - 246e: 36 e0 ldi r19, 0x06 ; 6 - 2470: b1 cf rjmp .-158 ; 0x23d4 - 2472: 2f ee ldi r18, 0xEF ; 239 - 2474: 35 e0 ldi r19, 0x05 ; 5 - 2476: ae cf rjmp .-164 ; 0x23d4 - 2478: 29 ed ldi r18, 0xD9 ; 217 - 247a: 35 e0 ldi r19, 0x05 ; 5 - 247c: ab cf rjmp .-170 ; 0x23d4 - 247e: 23 ec ldi r18, 0xC3 ; 195 - 2480: 35 e0 ldi r19, 0x05 ; 5 - 2482: a8 cf rjmp .-176 ; 0x23d4 - 2484: 2d ea ldi r18, 0xAD ; 173 - 2486: 35 e0 ldi r19, 0x05 ; 5 - 2488: a5 cf rjmp .-182 ; 0x23d4 - 248a: 27 e9 ldi r18, 0x97 ; 151 - 248c: 35 e0 ldi r19, 0x05 ; 5 - 248e: a2 cf rjmp .-188 ; 0x23d4 - -00002490 : - - return true; -} - -void CommandLineTick(void) -{ - 2490: 08 95 ret - -00002492 : -INLINE void CodecTask(void) { - ActiveConfiguration.CodecTaskFunc(); -} - -INLINE void CodecSetDemodPower(bool bOnOff) { - CODEC_DEMOD_POWER_PORT.DIRSET = CODEC_DEMOD_POWER_MASK; - 2492: a0 e2 ldi r26, 0x20 ; 32 - 2494: b6 e0 ldi r27, 0x06 ; 6 - 2496: 82 e0 ldi r24, 0x02 ; 2 - 2498: 11 96 adiw r26, 0x01 ; 1 - 249a: 8c 93 st X, r24 - 249c: 11 97 sbiw r26, 0x01 ; 1 - - if (bOnOff) { - CODEC_DEMOD_POWER_PORT.OUTSET = CODEC_DEMOD_POWER_MASK; - 249e: 15 96 adiw r26, 0x05 ; 5 - 24a0: 8c 93 st X, r24 - 24a2: 15 97 sbiw r26, 0x05 ; 5 -static void StartDemod(void) { - /* Activate Power for demodulator */ - CodecSetDemodPower(true); - - /* Configure sampling-timer free running and sync to first modulation-pause. */ - CODEC_TIMER_SAMPLING.CNT = 0; - 24a4: e0 e4 ldi r30, 0x40 ; 64 - 24a6: f8 e0 ldi r31, 0x08 ; 8 - 24a8: 10 a2 std Z+32, r1 ; 0x20 - 24aa: 11 a2 std Z+33, r1 ; 0x21 - CODEC_TIMER_SAMPLING.PER = SAMPLE_RATE_SYSTEM_CYCLES - 1; - 24ac: 8d e2 ldi r24, 0x2D ; 45 - 24ae: 91 e0 ldi r25, 0x01 ; 1 - 24b0: 86 a3 std Z+38, r24 ; 0x26 - 24b2: 97 a3 std Z+39, r25 ; 0x27 - CODEC_TIMER_SAMPLING.CCA = 0xFFFF; /* CCA Interrupt is not active! */ - 24b4: 8f ef ldi r24, 0xFF ; 255 - 24b6: 9f ef ldi r25, 0xFF ; 255 - 24b8: 80 a7 std Z+40, r24 ; 0x28 - 24ba: 91 a7 std Z+41, r25 ; 0x29 - CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_DIV1_gc; - 24bc: 81 e0 ldi r24, 0x01 ; 1 - 24be: 80 83 st Z, r24 - CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc; - 24c0: 98 e8 ldi r25, 0x88 ; 136 - 24c2: 93 83 std Z+3, r25 ; 0x03 - CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCAINTLVL_HI_gc; - 24c4: 93 e0 ldi r25, 0x03 ; 3 - 24c6: 97 83 std Z+7, r25 ; 0x07 - - /* Start looking out for modulation pause via interrupt. */ - CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0; - 24c8: 1a 96 adiw r26, 0x0a ; 10 - 24ca: 8c 93 st X, r24 - 24cc: 08 95 ret - -000024ce <__vector_34>: -} - -ISR(CODEC_DEMOD_IN_INT0_VECT) { - 24ce: 1f 92 push r1 - 24d0: 0f 92 push r0 - 24d2: 0f b6 in r0, 0x3f ; 63 - 24d4: 0f 92 push r0 - 24d6: 11 24 eor r1, r1 - 24d8: 8f 93 push r24 - 24da: 9f 93 push r25 - 24dc: ef 93 push r30 - 24de: ff 93 push r31 - /* This is the first edge of the first modulation-pause after StartDemod. - * Now we have time to prepare our timers and variables to start - * demodulating beginning from one bit-width after this edge. */ - CodecBufferPtr = CodecBuffer; - 24e0: 80 e1 ldi r24, 0x10 ; 16 - 24e2: 96 e2 ldi r25, 0x26 ; 38 - 24e4: 80 93 b1 24 sts 0x24B1, r24 - 24e8: 90 93 b2 24 sts 0x24B2, r25 - ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; - 24ec: 80 e9 ldi r24, 0x90 ; 144 - 24ee: 96 e2 ldi r25, 0x26 ; 38 - 24f0: 80 93 af 24 sts 0x24AF, r24 - 24f4: 90 93 b0 24 sts 0x24B0, r25 - DataRegister = 0; - 24f8: 10 92 aa 24 sts 0x24AA, r1 - SampleRegister = 0; - 24fc: 10 92 a9 24 sts 0x24A9, r1 - SamplePosition = 0; - 2500: 10 92 a5 24 sts 0x24A5, r1 - BitCount = 0; - 2504: 10 92 ad 24 sts 0x24AD, r1 - 2508: 10 92 ae 24 sts 0x24AE, r1 - IsParityBit = false; - 250c: 10 92 a8 24 sts 0x24A8, r1 - * XYZBUF mechanism of the xmega to automatically double the sampling rate on the - * next overflow. For this we have to temporarily deactivate the automatical alignment - * in order to catch next overflow event for updating the BUF registers. - * We want to sample the demodulated data stream in the first quarter of the half-bit - * where the pulsed miller encoded is located. */ - CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_OFF_gc; - 2510: e0 e4 ldi r30, 0x40 ; 64 - 2512: f8 e0 ldi r31, 0x08 ; 8 - 2514: 13 82 std Z+3, r1 ; 0x03 - CODEC_TIMER_SAMPLING.PERBUF = SAMPLE_RATE_SYSTEM_CYCLES/2 - 1; /* Half bit width */ - 2516: 86 e9 ldi r24, 0x96 ; 150 - 2518: 90 e0 ldi r25, 0x00 ; 0 - 251a: 86 ab std Z+54, r24 ; 0x36 - 251c: 97 ab std Z+55, r25 ; 0x37 - CODEC_TIMER_SAMPLING.CCABUF = SAMPLE_RATE_SYSTEM_CYCLES/8 - 10 - 1; /* Compensate for DIGFILT and ISR prolog */ - 251e: 8a e1 ldi r24, 0x1A ; 26 - 2520: 90 e0 ldi r25, 0x00 ; 0 - 2522: 80 af std Z+56, r24 ; 0x38 - 2524: 91 af std Z+57, r25 ; 0x39 - /* Setup Frame Delay Timer and wire to EVSYS. Frame delay time is - * measured from last change in RF field, therefore we use - * the event channel 1 (end of modulation pause) as the restart event. - * The preliminary frame delay time chosen here is irrelevant, because - * the correct FDT gets set automatically after demodulation. */ - CODEC_TIMER_LOADMOD.CNT = 0; - 2526: e0 e4 ldi r30, 0x40 ; 64 - 2528: f9 e0 ldi r31, 0x09 ; 9 - 252a: 10 a2 std Z+32, r1 ; 0x20 - 252c: 11 a2 std Z+33, r1 ; 0x21 - CODEC_TIMER_LOADMOD.PER = 0xFFFF; - 252e: 8f ef ldi r24, 0xFF ; 255 - 2530: 9f ef ldi r25, 0xFF ; 255 - 2532: 86 a3 std Z+38, r24 ; 0x26 - 2534: 97 a3 std Z+39, r25 ; 0x27 - CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH1_gc; - 2536: 89 e8 ldi r24, 0x89 ; 137 - 2538: 83 83 std Z+3, r24 ; 0x03 - CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_EVCH6_gc; - 253a: 8e e0 ldi r24, 0x0E ; 14 - 253c: 80 83 st Z, r24 - - /* Disable this interrupt */ - CODEC_DEMOD_IN_PORT.INT0MASK = 0; - 253e: e0 e2 ldi r30, 0x20 ; 32 - 2540: f6 e0 ldi r31, 0x06 ; 6 - 2542: 12 86 std Z+10, r1 ; 0x0a -} - 2544: ff 91 pop r31 - 2546: ef 91 pop r30 - 2548: 9f 91 pop r25 - 254a: 8f 91 pop r24 - 254c: 0f 90 pop r0 - 254e: 0f be out 0x3f, r0 ; 63 - 2550: 0f 90 pop r0 - 2552: 1f 90 pop r1 - 2554: 18 95 reti - -00002556 <__vector_22>: - -ISR(CODEC_TIMER_SAMPLING_CCA_VECT) { - 2556: 1f 92 push r1 - 2558: 0f 92 push r0 - 255a: 0f b6 in r0, 0x3f ; 63 - 255c: 0f 92 push r0 - 255e: 11 24 eor r1, r1 - 2560: 2f 93 push r18 - 2562: 3f 93 push r19 - 2564: 4f 93 push r20 - 2566: 8f 93 push r24 - 2568: 9f 93 push r25 - 256a: ef 93 push r30 - 256c: ff 93 push r31 - /* This interrupt gets called twice for every bit to sample it. */ - uint8_t SamplePin = CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK; - 256e: 90 91 28 06 lds r25, 0x0628 - uint8_t NewSampleRegister; - - /* Shift sampled bit into sampling register and hold a local copy for fast access. */ - NewSampleRegister = SampleRegister << 1; - 2572: 80 91 a9 24 lds r24, 0x24A9 - CODEC_DEMOD_IN_PORT.INT0MASK = 0; -} - -ISR(CODEC_TIMER_SAMPLING_CCA_VECT) { - /* This interrupt gets called twice for every bit to sample it. */ - uint8_t SamplePin = CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK; - 2576: 95 70 andi r25, 0x05 ; 5 - uint8_t NewSampleRegister; - - /* Shift sampled bit into sampling register and hold a local copy for fast access. */ - NewSampleRegister = SampleRegister << 1; - NewSampleRegister |= (!SamplePin ? 0x01 : 0x00); - 2578: 21 e0 ldi r18, 0x01 ; 1 - 257a: 09 f0 breq .+2 ; 0x257e <__vector_22+0x28> - 257c: 20 e0 ldi r18, 0x00 ; 0 - /* This interrupt gets called twice for every bit to sample it. */ - uint8_t SamplePin = CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK; - uint8_t NewSampleRegister; - - /* Shift sampled bit into sampling register and hold a local copy for fast access. */ - NewSampleRegister = SampleRegister << 1; - 257e: 88 0f add r24, r24 - NewSampleRegister |= (!SamplePin ? 0x01 : 0x00); - 2580: 82 2b or r24, r18 - SampleRegister = NewSampleRegister; - 2582: 80 93 a9 24 sts 0x24A9, r24 - - if (SamplePosition) { - 2586: 90 91 a5 24 lds r25, 0x24A5 - 258a: 99 23 and r25, r25 - 258c: c1 f1 breq .+112 ; 0x25fe <__vector_22+0xa8> - /* Analyze the sampling register after 2 samples. */ - if ((NewSampleRegister & 0x07) == 0x07) { - 258e: 98 2f mov r25, r24 - 2590: 97 70 andi r25, 0x07 ; 7 - 2592: 97 30 cpi r25, 0x07 ; 7 - 2594: 09 f4 brne .+2 ; 0x2598 <__vector_22+0x42> - 2596: 48 c0 rjmp .+144 ; 0x2628 <__vector_22+0xd2> - - /* Signal, that we have finished sampling */ - Flags.DemodFinished = 1; - } else { - /* Otherwise, we check the two sample bits from the bit before. */ - uint8_t BitSample = NewSampleRegister & 0xC; - 2598: 98 2f mov r25, r24 - 259a: 9c 70 andi r25, 0x0C ; 12 - uint8_t Bit = 0; - - if (BitSample != (0x0 << 2)) { - 259c: 81 f1 breq .+96 ; 0x25fe <__vector_22+0xa8> - /* We have a valid bit. decode and process it. */ - if (BitSample & (0x1 << 2)) { - 259e: 82 fb bst r24, 2 - 25a0: 88 27 eor r24, r24 - 25a2: 80 f9 bld r24, 0 - 25a4: 91 e0 ldi r25, 0x01 ; 1 - 25a6: 89 27 eor r24, r25 - } else { - /* 10 sequence -> This is a one bit */ - Bit = 1; - } - - LastBit = Bit; - 25a8: 80 93 a7 24 sts 0x24A7, r24 - - if (!IsParityBit) { - 25ac: 90 91 a8 24 lds r25, 0x24A8 - 25b0: 91 11 cpse r25, r1 - 25b2: 7f c0 rjmp .+254 ; 0x26b2 <__vector_22+0x15c> - /* This is a data bit, so shift it into the data register and - * hold a local copy of it. */ - uint8_t NewDataRegister = DataRegister >> 1; - 25b4: 90 91 aa 24 lds r25, 0x24AA - 25b8: 96 95 lsr r25 - NewDataRegister |= (Bit ? 0x80 : 0x00); - 25ba: 88 23 and r24, r24 - 25bc: 09 f4 brne .+2 ; 0x25c0 <__vector_22+0x6a> - 25be: 83 c0 rjmp .+262 ; 0x26c6 <__vector_22+0x170> - 25c0: 20 e8 ldi r18, 0x80 ; 128 - 25c2: 29 2b or r18, r25 - DataRegister = NewDataRegister; - 25c4: 20 93 aa 24 sts 0x24AA, r18 - - /* Update bitcount */ - uint16_t NewBitCount = ++BitCount; - 25c8: 80 91 ad 24 lds r24, 0x24AD - 25cc: 90 91 ae 24 lds r25, 0x24AE - 25d0: 01 96 adiw r24, 0x01 ; 1 - 25d2: 80 93 ad 24 sts 0x24AD, r24 - 25d6: 90 93 ae 24 sts 0x24AE, r25 - if ((NewBitCount & 0x07) == 0) { - 25da: 87 70 andi r24, 0x07 ; 7 - 25dc: 99 27 eor r25, r25 - 25de: 89 2b or r24, r25 - 25e0: 71 f4 brne .+28 ; 0x25fe <__vector_22+0xa8> - /* We have reached a byte boundary! Store the data register. */ - /* TODO: Prevent buffer overflow */ - *CodecBufferPtr++ = NewDataRegister; - 25e2: e0 91 b1 24 lds r30, 0x24B1 - 25e6: f0 91 b2 24 lds r31, 0x24B2 - 25ea: cf 01 movw r24, r30 - 25ec: 01 96 adiw r24, 0x01 ; 1 - 25ee: 80 93 b1 24 sts 0x24B1, r24 - 25f2: 90 93 b2 24 sts 0x24B2, r25 - 25f6: 20 83 st Z, r18 - - /* Store bit for determining FDT at EOC and enable parity - * handling on next bit. */ - IsParityBit = true; - 25f8: 81 e0 ldi r24, 0x01 ; 1 - 25fa: 80 93 a8 24 sts 0x24A8, r24 - } - } else { - /* On odd sample position just sample. */ - } - - SamplePosition = !SamplePosition; - 25fe: 80 91 a5 24 lds r24, 0x24A5 - 2602: 91 e0 ldi r25, 0x01 ; 1 - 2604: 89 27 eor r24, r25 - 2606: 80 93 a5 24 sts 0x24A5, r24 - - /* Make sure the sampling timer gets automatically aligned to the - * modulation pauses by using the RESTART event. - * This can be understood as a "poor mans PLL" and makes sure that we are - * never too far out the bit-grid while sampling. */ - CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc; - 260a: 88 e8 ldi r24, 0x88 ; 136 - 260c: 80 93 43 08 sts 0x0843, r24 -} - 2610: ff 91 pop r31 - 2612: ef 91 pop r30 - 2614: 9f 91 pop r25 - 2616: 8f 91 pop r24 - 2618: 4f 91 pop r20 - 261a: 3f 91 pop r19 - 261c: 2f 91 pop r18 - 261e: 0f 90 pop r0 - 2620: 0f be out 0x3f, r0 ; 63 - 2622: 0f 90 pop r0 - 2624: 1f 90 pop r1 - 2626: 18 95 reti - - if (SamplePosition) { - /* Analyze the sampling register after 2 samples. */ - if ((NewSampleRegister & 0x07) == 0x07) { - /* No carrier modulation for 3 sample points. EOC! */ - CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc; - 2628: 10 92 40 08 sts 0x0840, r1 - CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCAIF_bm; - 262c: 80 e1 ldi r24, 0x10 ; 16 - 262e: 80 93 4c 08 sts 0x084C, r24 - - /* By this time, the FDT timer is aligned to the last modulation - * edge of the reader. So we disable the auto-synchronization and - * let it count the frame delay time in the background, and generate - * an interrupt once it has reached the FDT. */ - CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc; - 2632: 10 92 43 09 sts 0x0943, r1 - - if (LastBit) { - 2636: 80 91 a7 24 lds r24, 0x24A7 - 263a: 88 23 and r24, r24 - 263c: e9 f1 breq .+122 ; 0x26b8 <__vector_22+0x162> - CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV1; - 263e: 8c eb ldi r24, 0xBC ; 188 - 2640: 94 e0 ldi r25, 0x04 ; 4 - 2642: 80 93 66 09 sts 0x0966, r24 - 2646: 90 93 67 09 sts 0x0967, r25 - } else { - CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV0; - } - - LoadModState = LOADMOD_FDT; - 264a: 10 92 a6 24 sts 0x24A6, r1 - - CODEC_TIMER_LOADMOD.INTFLAGS = TC1_OVFIF_bm; - 264e: 81 e0 ldi r24, 0x01 ; 1 - 2650: 80 93 4c 09 sts 0x094C, r24 - CODEC_TIMER_LOADMOD.INTCTRLA = TC_OVFINTLVL_HI_gc; - 2654: 83 e0 ldi r24, 0x03 ; 3 - 2656: 80 93 46 09 sts 0x0946, r24 - - /* Determine if we did not receive a multiple of 8 bits. - * If this is the case, right-align the remaining data and - * store it into the buffer. */ - uint8_t RemainingBits = BitCount % 8; - 265a: 80 91 ad 24 lds r24, 0x24AD - 265e: 90 91 ae 24 lds r25, 0x24AE - 2662: 87 70 andi r24, 0x07 ; 7 - if (RemainingBits != 0) { - 2664: 11 f1 breq .+68 ; 0x26aa <__vector_22+0x154> - uint8_t NewDataRegister = DataRegister; - 2666: 90 91 aa 24 lds r25, 0x24AA - - while (RemainingBits++ < 8) { - /* Pad with zeroes to right-align. */ - NewDataRegister >>= 1; - 266a: 96 95 lsr r25 - * store it into the buffer. */ - uint8_t RemainingBits = BitCount % 8; - if (RemainingBits != 0) { - uint8_t NewDataRegister = DataRegister; - - while (RemainingBits++ < 8) { - 266c: 22 e0 ldi r18, 0x02 ; 2 - 266e: 28 0f add r18, r24 - 2670: 87 30 cpi r24, 0x07 ; 7 - 2672: b1 f0 breq .+44 ; 0x26a0 <__vector_22+0x14a> - /* Pad with zeroes to right-align. */ - NewDataRegister >>= 1; - 2674: 96 95 lsr r25 - * store it into the buffer. */ - uint8_t RemainingBits = BitCount % 8; - if (RemainingBits != 0) { - uint8_t NewDataRegister = DataRegister; - - while (RemainingBits++ < 8) { - 2676: 43 e0 ldi r20, 0x03 ; 3 - 2678: 48 0f add r20, r24 - 267a: 28 30 cpi r18, 0x08 ; 8 - 267c: 88 f4 brcc .+34 ; 0x26a0 <__vector_22+0x14a> - /* Pad with zeroes to right-align. */ - NewDataRegister >>= 1; - 267e: 96 95 lsr r25 - * store it into the buffer. */ - uint8_t RemainingBits = BitCount % 8; - if (RemainingBits != 0) { - uint8_t NewDataRegister = DataRegister; - - while (RemainingBits++ < 8) { - 2680: 34 e0 ldi r19, 0x04 ; 4 - 2682: 38 0f add r19, r24 - 2684: 48 30 cpi r20, 0x08 ; 8 - 2686: 60 f4 brcc .+24 ; 0x26a0 <__vector_22+0x14a> - /* Pad with zeroes to right-align. */ - NewDataRegister >>= 1; - 2688: 96 95 lsr r25 - * store it into the buffer. */ - uint8_t RemainingBits = BitCount % 8; - if (RemainingBits != 0) { - uint8_t NewDataRegister = DataRegister; - - while (RemainingBits++ < 8) { - 268a: 25 e0 ldi r18, 0x05 ; 5 - 268c: 28 0f add r18, r24 - 268e: 38 30 cpi r19, 0x08 ; 8 - 2690: 38 f4 brcc .+14 ; 0x26a0 <__vector_22+0x14a> - /* Pad with zeroes to right-align. */ - NewDataRegister >>= 1; - 2692: 96 95 lsr r25 - * store it into the buffer. */ - uint8_t RemainingBits = BitCount % 8; - if (RemainingBits != 0) { - uint8_t NewDataRegister = DataRegister; - - while (RemainingBits++ < 8) { - 2694: 28 30 cpi r18, 0x08 ; 8 - 2696: 20 f4 brcc .+8 ; 0x26a0 <__vector_22+0x14a> - /* Pad with zeroes to right-align. */ - NewDataRegister >>= 1; - 2698: 96 95 lsr r25 - * store it into the buffer. */ - uint8_t RemainingBits = BitCount % 8; - if (RemainingBits != 0) { - uint8_t NewDataRegister = DataRegister; - - while (RemainingBits++ < 8) { - 269a: 81 30 cpi r24, 0x01 ; 1 - 269c: 09 f4 brne .+2 ; 0x26a0 <__vector_22+0x14a> - /* Pad with zeroes to right-align. */ - NewDataRegister >>= 1; - 269e: 96 95 lsr r25 - } - - /* TODO: Prevent buffer overflow */ - *CodecBufferPtr = NewDataRegister; - 26a0: e0 91 b1 24 lds r30, 0x24B1 - 26a4: f0 91 b2 24 lds r31, 0x24B2 - 26a8: 90 83 st Z, r25 - } - - /* Signal, that we have finished sampling */ - Flags.DemodFinished = 1; - 26aa: 81 e0 ldi r24, 0x01 ; 1 - 26ac: 80 93 b3 24 sts 0x24B3, r24 - 26b0: a6 cf rjmp .-180 ; 0x25fe <__vector_22+0xa8> - - } else { - /* This is a parity bit. Store it */ - /* TODO: Store parity and prevent overflow */ - //*ParityBufferPtr++ = Bit; - IsParityBit = false; - 26b2: 10 92 a8 24 sts 0x24A8, r1 - 26b6: a3 cf rjmp .-186 ; 0x25fe <__vector_22+0xa8> - CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc; - - if (LastBit) { - CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV1; - } else { - CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV0; - 26b8: 8c e7 ldi r24, 0x7C ; 124 - 26ba: 94 e0 ldi r25, 0x04 ; 4 - 26bc: 80 93 66 09 sts 0x0966, r24 - 26c0: 90 93 67 09 sts 0x0967, r25 - 26c4: c2 cf rjmp .-124 ; 0x264a <__vector_22+0xf4> - - if (!IsParityBit) { - /* This is a data bit, so shift it into the data register and - * hold a local copy of it. */ - uint8_t NewDataRegister = DataRegister >> 1; - NewDataRegister |= (Bit ? 0x80 : 0x00); - 26c6: 20 e0 ldi r18, 0x00 ; 0 - 26c8: 7c cf rjmp .-264 ; 0x25c2 <__vector_22+0x6c> - -000026ca <__vector_83>: - * This can be understood as a "poor mans PLL" and makes sure that we are - * never too far out the bit-grid while sampling. */ - CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc; -} - -ISR(CODEC_TIMER_OVF_VECT) { - 26ca: 1f 92 push r1 - 26cc: 0f 92 push r0 - 26ce: 0f b6 in r0, 0x3f ; 63 - 26d0: 0f 92 push r0 - 26d2: 11 24 eor r1, r1 - 26d4: 2f 93 push r18 - 26d6: 3f 93 push r19 - 26d8: 8f 93 push r24 - 26da: 9f 93 push r25 - 26dc: af 93 push r26 - 26de: bf 93 push r27 - 26e0: ef 93 push r30 - 26e2: ff 93 push r31 - /* Bit rate timer. Output a half bit on the output. */ - uint8_t Temp8; - uint16_t Temp16; - - switch (LoadModState) { - 26e4: 80 91 a6 24 lds r24, 0x24A6 - 26e8: 90 e0 ldi r25, 0x00 ; 0 - 26ea: 8b 30 cpi r24, 0x0B ; 11 - 26ec: 91 05 cpc r25, r1 - 26ee: 80 f5 brcc .+96 ; 0x2750 <__vector_83+0x86> - 26f0: fc 01 movw r30, r24 - 26f2: e9 5f subi r30, 0xF9 ; 249 - 26f4: fe 4f sbci r31, 0xFE ; 254 - 26f6: 0c 94 69 23 jmp 0x46d2 ; 0x46d2 <__tablejump2__> - - LoadModState = LOADMOD_PARITY1; - break; - - case LOADMOD_PARITY1: - if (*ParityBufferPtr) { - 26fa: e0 91 af 24 lds r30, 0x24AF - 26fe: f0 91 b0 24 lds r31, 0x24B0 - 2702: 80 81 ld r24, Z - 2704: 81 11 cpse r24, r1 - 2706: ac c0 rjmp .+344 ; 0x2860 <__vector_83+0x196> - CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; - } else { - CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; - 2708: 80 e4 ldi r24, 0x40 ; 64 - 270a: 80 93 45 06 sts 0x0645, r24 - } - - if (BitSent == BitCount) { - 270e: 20 91 ab 24 lds r18, 0x24AB - 2712: 30 91 ac 24 lds r19, 0x24AC - 2716: 80 91 ad 24 lds r24, 0x24AD - 271a: 90 91 ae 24 lds r25, 0x24AE - 271e: 28 17 cp r18, r24 - 2720: 39 07 cpc r19, r25 - 2722: 09 f4 brne .+2 ; 0x2726 <__vector_83+0x5c> - 2724: 6c c0 rjmp .+216 ; 0x27fe <__vector_83+0x134> - /* No data left */ - LoadModState = LOADMOD_STOP_BIT0; - } else { - /* Fetch next data and continue sending bits. */ - ParityBufferPtr++; - 2726: 31 96 adiw r30, 0x01 ; 1 - 2728: e0 93 af 24 sts 0x24AF, r30 - 272c: f0 93 b0 24 sts 0x24B0, r31 - DataRegister = *++CodecBufferPtr; - 2730: e0 91 b1 24 lds r30, 0x24B1 - 2734: f0 91 b2 24 lds r31, 0x24B2 - 2738: cf 01 movw r24, r30 - 273a: 01 96 adiw r24, 0x01 ; 1 - 273c: 80 93 b1 24 sts 0x24B1, r24 - 2740: 90 93 b2 24 sts 0x24B2, r25 - 2744: 81 81 ldd r24, Z+1 ; 0x01 - 2746: 80 93 aa 24 sts 0x24AA, r24 - LoadModState = LOADMOD_DATA0; - 274a: 84 e0 ldi r24, 0x04 ; 4 - 274c: 80 93 a6 24 sts 0x24A6, r24 - break; - - default: - break; - } -} - 2750: ff 91 pop r31 - 2752: ef 91 pop r30 - 2754: bf 91 pop r27 - 2756: af 91 pop r26 - 2758: 9f 91 pop r25 - 275a: 8f 91 pop r24 - 275c: 3f 91 pop r19 - 275e: 2f 91 pop r18 - 2760: 0f 90 pop r0 - 2762: 0f be out 0x3f, r0 ; 63 - 2764: 0f 90 pop r0 - 2766: 1f 90 pop r1 - 2768: 18 95 reti - break; - - case LOADMOD_START: - /* Application produced data. With this interrupt we are aligned to the bit-grid. - * Start subcarrier generation and align to bitrate. */ - CODEC_TIMER_LOADMOD.PER = ISO14443A_BIT_RATE_CYCLES / 2 - 1; - 276a: 8f e3 ldi r24, 0x3F ; 63 - 276c: 90 e0 ldi r25, 0x00 ; 0 - 276e: 80 93 66 09 sts 0x0966, r24 - 2772: 90 93 67 09 sts 0x0967, r25 - CODEC_SUBCARRIER_TIMER.CTRLA = TC_CLKSEL_EVCH6_gc; - 2776: 8e e0 ldi r24, 0x0E ; 14 - 2778: 80 93 00 08 sts 0x0800, r24 - - /* Fallthrough to first bit */ - - case LOADMOD_START_BIT0: - CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; - 277c: 80 e4 ldi r24, 0x40 ; 64 - 277e: 80 93 45 06 sts 0x0645, r24 - LoadModState = LOADMOD_START_BIT1; - 2782: 83 e0 ldi r24, 0x03 ; 3 - 2784: 80 93 a6 24 sts 0x24A6, r24 - break; - 2788: e3 cf rjmp .-58 ; 0x2750 <__vector_83+0x86> - - case LOADMOD_START_BIT1: - CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; - 278a: 80 e4 ldi r24, 0x40 ; 64 - 278c: 80 93 46 06 sts 0x0646, r24 - LoadModState = LOADMOD_DATA0; - 2790: 84 e0 ldi r24, 0x04 ; 4 - 2792: 80 93 a6 24 sts 0x24A6, r24 - - /* Fetch first byte */ - DataRegister = *CodecBufferPtr; - 2796: e0 91 b1 24 lds r30, 0x24B1 - 279a: f0 91 b2 24 lds r31, 0x24B2 - 279e: 80 81 ld r24, Z - 27a0: 80 93 aa 24 sts 0x24AA, r24 - break; - 27a4: d5 cf rjmp .-86 ; 0x2750 <__vector_83+0x86> - - case LOADMOD_DATA0: - if (DataRegister & 1) { - 27a6: 80 91 aa 24 lds r24, 0x24AA - 27aa: 80 fd sbrc r24, 0 - 27ac: 64 c0 rjmp .+200 ; 0x2876 <__vector_83+0x1ac> - CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; - } else { - CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; - 27ae: 80 e4 ldi r24, 0x40 ; 64 - 27b0: 80 93 46 06 sts 0x0646, r24 - } - - LoadModState = LOADMOD_DATA1; - 27b4: 85 e0 ldi r24, 0x05 ; 5 - 27b6: 80 93 a6 24 sts 0x24A6, r24 - break; - 27ba: ca cf rjmp .-108 ; 0x2750 <__vector_83+0x86> - - case LOADMOD_DATA1: - Temp8 = DataRegister; - 27bc: 80 91 aa 24 lds r24, 0x24AA - - if (Temp8 & 1) { - CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; - 27c0: 90 e4 ldi r25, 0x40 ; 64 - break; - - case LOADMOD_DATA1: - Temp8 = DataRegister; - - if (Temp8 & 1) { - 27c2: 80 fd sbrc r24, 0 - 27c4: 55 c0 rjmp .+170 ; 0x2870 <__vector_83+0x1a6> - CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; - } else { - CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; - 27c6: 90 93 45 06 sts 0x0645, r25 - } - - DataRegister = Temp8 >> 1; - 27ca: 86 95 lsr r24 - 27cc: 80 93 aa 24 sts 0x24AA, r24 - - Temp16 = BitSent; - 27d0: 80 91 ab 24 lds r24, 0x24AB - 27d4: 90 91 ac 24 lds r25, 0x24AC - BitSent = ++Temp16; - 27d8: 01 96 adiw r24, 0x01 ; 1 - 27da: 80 93 ab 24 sts 0x24AB, r24 - 27de: 90 93 ac 24 sts 0x24AC, r25 - - if ((Temp16 & 0x07) == 0) { - 27e2: 9c 01 movw r18, r24 - 27e4: 27 70 andi r18, 0x07 ; 7 - 27e6: 33 27 eor r19, r19 - 27e8: 23 2b or r18, r19 - 27ea: 09 f4 brne .+2 ; 0x27ee <__vector_83+0x124> - 27ec: 48 c0 rjmp .+144 ; 0x287e <__vector_83+0x1b4> - /* Byte boundary. Load parity bit and output it later. */ - LoadModState = LOADMOD_PARITY0; - break; - } - - if (Temp16 == BitCount) { - 27ee: 20 91 ad 24 lds r18, 0x24AD - 27f2: 30 91 ae 24 lds r19, 0x24AE - 27f6: 82 17 cp r24, r18 - 27f8: 93 07 cpc r25, r19 - 27fa: 09 f0 breq .+2 ; 0x27fe <__vector_83+0x134> - 27fc: a6 cf rjmp .-180 ; 0x274a <__vector_83+0x80> - CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; - } - - if (BitSent == BitCount) { - /* No data left */ - LoadModState = LOADMOD_STOP_BIT0; - 27fe: 88 e0 ldi r24, 0x08 ; 8 - 2800: 80 93 a6 24 sts 0x24A6, r24 - 2804: a5 cf rjmp .-182 ; 0x2750 <__vector_83+0x86> - LoadModState = LOADMOD_DATA0; - - break; - - case LOADMOD_PARITY0: - if (*ParityBufferPtr) { - 2806: e0 91 af 24 lds r30, 0x24AF - 280a: f0 91 b0 24 lds r31, 0x24B0 - 280e: 80 81 ld r24, Z - 2810: 81 11 cpse r24, r1 - 2812: 2a c0 rjmp .+84 ; 0x2868 <__vector_83+0x19e> - CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; - } else { - CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; - 2814: 80 e4 ldi r24, 0x40 ; 64 - 2816: 80 93 46 06 sts 0x0646, r24 - } - - LoadModState = LOADMOD_PARITY1; - 281a: 87 e0 ldi r24, 0x07 ; 7 - 281c: 80 93 a6 24 sts 0x24A6, r24 - break; - 2820: 97 cf rjmp .-210 ; 0x2750 <__vector_83+0x86> - } - - break; - - case LOADMOD_STOP_BIT0: - CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; - 2822: 80 e4 ldi r24, 0x40 ; 64 - 2824: 80 93 46 06 sts 0x0646, r24 - LoadModState = LOADMOD_STOP_BIT1; - 2828: 89 e0 ldi r24, 0x09 ; 9 - 282a: 80 93 a6 24 sts 0x24A6, r24 - break; - 282e: 90 cf rjmp .-224 ; 0x2750 <__vector_83+0x86> - - case LOADMOD_STOP_BIT1: - CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; - 2830: 80 e4 ldi r24, 0x40 ; 64 - 2832: 80 93 46 06 sts 0x0646, r24 - LoadModState = LOADMOD_FINISHED; - 2836: 8a e0 ldi r24, 0x0A ; 10 - 2838: 80 93 a6 24 sts 0x24A6, r24 - break; - 283c: 89 cf rjmp .-238 ; 0x2750 <__vector_83+0x86> - - case LOADMOD_FINISHED: - /* We have written all of our bits. Deactivate the loadmod - * timer. Also disable the bit-rate interrupt again. And - * stop the subcarrier divider. */ - CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; - 283e: 10 92 40 09 sts 0x0940, r1 - CODEC_TIMER_LOADMOD.INTCTRLA = 0; - 2842: 10 92 46 09 sts 0x0946, r1 - CODEC_SUBCARRIER_TIMER.CTRLA = TC_CLKSEL_OFF_gc; - 2846: 10 92 00 08 sts 0x0800, r1 - - /* Signal application that we have finished loadmod */ - Flags.LoadmodFinished = 1; - 284a: 81 e0 ldi r24, 0x01 ; 1 - 284c: 80 93 b4 24 sts 0x24B4, r24 - break; - 2850: 7f cf rjmp .-258 ; 0x2750 <__vector_83+0x86> - uint16_t Temp16; - - switch (LoadModState) { - case LOADMOD_FDT: - /* No data has been produced, but FDT has ended. Switch over to bit-grid aligning. */ - CODEC_TIMER_LOADMOD.PER = ISO14443A_BIT_GRID_CYCLES - 1; - 2852: 8f e7 ldi r24, 0x7F ; 127 - 2854: 90 e0 ldi r25, 0x00 ; 0 - 2856: 80 93 66 09 sts 0x0966, r24 - 285a: 90 93 67 09 sts 0x0967, r25 - break; - 285e: 78 cf rjmp .-272 ; 0x2750 <__vector_83+0x86> - LoadModState = LOADMOD_PARITY1; - break; - - case LOADMOD_PARITY1: - if (*ParityBufferPtr) { - CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; - 2860: 80 e4 ldi r24, 0x40 ; 64 - 2862: 80 93 46 06 sts 0x0646, r24 - 2866: 53 cf rjmp .-346 ; 0x270e <__vector_83+0x44> - - break; - - case LOADMOD_PARITY0: - if (*ParityBufferPtr) { - CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; - 2868: 80 e4 ldi r24, 0x40 ; 64 - 286a: 80 93 45 06 sts 0x0645, r24 - 286e: d5 cf rjmp .-86 ; 0x281a <__vector_83+0x150> - - case LOADMOD_DATA1: - Temp8 = DataRegister; - - if (Temp8 & 1) { - CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; - 2870: 90 93 46 06 sts 0x0646, r25 - 2874: aa cf rjmp .-172 ; 0x27ca <__vector_83+0x100> - DataRegister = *CodecBufferPtr; - break; - - case LOADMOD_DATA0: - if (DataRegister & 1) { - CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; - 2876: 80 e4 ldi r24, 0x40 ; 64 - 2878: 80 93 45 06 sts 0x0645, r24 - 287c: 9b cf rjmp .-202 ; 0x27b4 <__vector_83+0xea> - Temp16 = BitSent; - BitSent = ++Temp16; - - if ((Temp16 & 0x07) == 0) { - /* Byte boundary. Load parity bit and output it later. */ - LoadModState = LOADMOD_PARITY0; - 287e: 86 e0 ldi r24, 0x06 ; 6 - 2880: 80 93 a6 24 sts 0x24A6, r24 - break; - 2884: 65 cf rjmp .-310 ; 0x2750 <__vector_83+0x86> - -00002886 : - default: - break; - } -} - -void ISO14443ACodecInit(void) { - 2886: cf 93 push r28 - 2888: df 93 push r29 -static volatile LoadModStateType LoadModState; -static volatile bool SamplePosition; - -static void Initialize(void) { - /* Configure CARRIER input pin and route it to EVSYS */ - CODEC_CARRIER_IN_PORT.DIRCLR = CODEC_CARRIER_IN_MASK; - 288a: e0 e4 ldi r30, 0x40 ; 64 - 288c: f6 e0 ldi r31, 0x06 ; 6 - 288e: 84 e0 ldi r24, 0x04 ; 4 - 2890: 82 83 std Z+2, r24 ; 0x02 - CODEC_CARRIER_IN_PORT.CODEC_CARRIER_IN_PINCTRL = PORT_ISC_BOTHEDGES_gc; - 2892: 12 8a std Z+18, r1 ; 0x12 - EVSYS.CH6MUX = CODEC_CARRIER_IN_EVMUX; - 2894: c0 e8 ldi r28, 0x80 ; 128 - 2896: d1 e0 ldi r29, 0x01 ; 1 - 2898: 82 e6 ldi r24, 0x62 ; 98 - 289a: 8e 83 std Y+6, r24 ; 0x06 - - /* Configure two DEMOD pins for input. - * Configure event channel 0 for rising edge (begin of modulation pause) - * Configure event channel 1 for falling edge (end of modulation pause) */ - CODEC_DEMOD_IN_PORT.DIRCLR = CODEC_DEMOD_IN_MASK; - 289c: a0 e2 ldi r26, 0x20 ; 32 - 289e: b6 e0 ldi r27, 0x06 ; 6 - 28a0: 85 e0 ldi r24, 0x05 ; 5 - 28a2: 12 96 adiw r26, 0x02 ; 2 - 28a4: 8c 93 st X, r24 - 28a6: 12 97 sbiw r26, 0x02 ; 2 - CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL0 = PORT_ISC_RISING_gc; - 28a8: 81 e0 ldi r24, 0x01 ; 1 - 28aa: 50 96 adiw r26, 0x10 ; 16 - 28ac: 8c 93 st X, r24 - 28ae: 50 97 sbiw r26, 0x10 ; 16 - CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL1 = PORT_ISC_FALLING_gc; - 28b0: 82 e0 ldi r24, 0x02 ; 2 - 28b2: 52 96 adiw r26, 0x12 ; 18 - 28b4: 8c 93 st X, r24 - 28b6: 52 97 sbiw r26, 0x12 ; 18 - CODEC_DEMOD_IN_PORT.INT0MASK = 0; - 28b8: 1a 96 adiw r26, 0x0a ; 10 - 28ba: 1c 92 st X, r1 - 28bc: 1a 97 sbiw r26, 0x0a ; 10 - CODEC_DEMOD_IN_PORT.INTCTRL = PORT_INT0LVL_HI_gc; - 28be: 83 e0 ldi r24, 0x03 ; 3 - 28c0: 19 96 adiw r26, 0x09 ; 9 - 28c2: 8c 93 st X, r24 - EVSYS.CH0MUX = CODEC_DEMOD_IN_EVMUX0; - 28c4: 98 e5 ldi r25, 0x58 ; 88 - 28c6: 98 83 st Y, r25 - EVSYS.CH1MUX = CODEC_DEMOD_IN_EVMUX1; - 28c8: 9a e5 ldi r25, 0x5A ; 90 - 28ca: 99 83 std Y+1, r25 ; 0x01 - - /* Configure LOADMOD and SUBCARRIER output pins. - * Disable PSK modulation by setting pin to low. */ - CODEC_LOADMOD_PORT.DIRSET = CODEC_LOADMOD_MASK; - 28cc: 90 e4 ldi r25, 0x40 ; 64 - 28ce: 91 83 std Z+1, r25 ; 0x01 - CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; - 28d0: 96 83 std Z+6, r25 ; 0x06 - CODEC_SUBCARRIER_PORT.DIRSET = CODEC_SUBCARRIER_MASK; - 28d2: 81 83 std Z+1, r24 ; 0x01 - CODEC_SUBCARRIER_PORT.OUTCLR = CODEC_SUBCARRIER_MASK; - 28d4: 86 83 std Z+6, r24 ; 0x06 - - /* Configure subcarrier generation with 50% DC output using OOK */ - CODEC_SUBCARRIER_TIMER.PER = ISO14443A_SUBCARRIER_DIVIDER - 1; - 28d6: e0 e0 ldi r30, 0x00 ; 0 - 28d8: f8 e0 ldi r31, 0x08 ; 8 - 28da: 8f e0 ldi r24, 0x0F ; 15 - 28dc: 90 e0 ldi r25, 0x00 ; 0 - 28de: 86 a3 std Z+38, r24 ; 0x26 - 28e0: 97 a3 std Z+39, r25 ; 0x27 - CODEC_SUBCARRIER_TIMER.CODEC_SUBCARRIER_CC_OOK = ISO14443A_SUBCARRIER_DIVIDER/2; - 28e2: 88 e0 ldi r24, 0x08 ; 8 - 28e4: 90 e0 ldi r25, 0x00 ; 0 - 28e6: 82 a7 std Z+42, r24 ; 0x2a - 28e8: 93 a7 std Z+43, r25 ; 0x2b - CODEC_SUBCARRIER_TIMER.CTRLB = CODEC_SUBCARRIER_CCEN_OOK | TC_WGMODE_SINGLESLOPE_gc; - 28ea: 83 e2 ldi r24, 0x23 ; 35 - 28ec: 81 83 std Z+1, r24 ; 0x01 -void ISO14443ACodecInit(void) { - /* Initialize common peripherals and start listening - * for incoming data. */ - Initialize(); - StartDemod(); -} - 28ee: df 91 pop r29 - 28f0: cf 91 pop r28 - -void ISO14443ACodecInit(void) { - /* Initialize common peripherals and start listening - * for incoming data. */ - Initialize(); - StartDemod(); - 28f2: cf cd rjmp .-1122 ; 0x2492 - -000028f4 : -} - -void ISO14443ACodecTask(void) { - 28f4: cf 93 push r28 - 28f6: df 93 push r29 - if (Flags.DemodFinished) { - 28f8: 80 91 b3 24 lds r24, 0x24B3 - 28fc: 88 23 and r24, r24 - 28fe: c1 f0 breq .+48 ; 0x2930 - Flags.DemodFinished = 0; - 2900: 10 92 b3 24 sts 0x24B3, r1 -INLINE void CodecTask(void) { - ActiveConfiguration.CodecTaskFunc(); -} - -INLINE void CodecSetDemodPower(bool bOnOff) { - CODEC_DEMOD_POWER_PORT.DIRSET = CODEC_DEMOD_POWER_MASK; - 2904: 82 e0 ldi r24, 0x02 ; 2 - 2906: 80 93 21 06 sts 0x0621, r24 - - if (bOnOff) { - CODEC_DEMOD_POWER_PORT.OUTSET = CODEC_DEMOD_POWER_MASK; - } else { - CODEC_DEMOD_POWER_PORT.OUTCLR = CODEC_DEMOD_POWER_MASK; - 290a: 80 93 26 06 sts 0x0626, r24 - /* Reception finished. Process the received bytes */ - CodecSetDemodPower(false); - - uint16_t DemodBitCount = BitCount; - 290e: 60 91 ad 24 lds r22, 0x24AD - 2912: 70 91 ae 24 lds r23, 0x24AE - uint16_t AnswerBitCount = ISO14443A_APP_NO_RESPONSE; - - if (DemodBitCount > 0) { - 2916: 61 15 cp r22, r1 - 2918: 71 05 cpc r23, r1 - 291a: 89 f4 brne .+34 ; 0x293e -INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { - return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount); -} - -INLINE void ApplicationReset(void) { - ActiveConfiguration.ApplicationResetFunc(); - 291c: e0 91 ef 24 lds r30, 0x24EF - 2920: f0 91 f0 24 lds r31, 0x24F0 - 2924: 09 95 icall - CodecBufferPtr = CodecBuffer; - ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; - LoadModState = LOADMOD_START; - } else { - /* No data to be processed. Disable loadmodding and start listening again */ - CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; - 2926: 10 92 40 09 sts 0x0940, r1 - CODEC_TIMER_LOADMOD.INTCTRLA = 0; - 292a: 10 92 46 09 sts 0x0946, r1 - - StartDemod(); - 292e: b1 dd rcall .-1182 ; 0x2492 - } - } - - if (Flags.LoadmodFinished) { - 2930: 80 91 b4 24 lds r24, 0x24B4 - 2934: 81 11 cpse r24, r1 - 2936: 2a c0 rjmp .+84 ; 0x298c - Flags.LoadmodFinished = 0; - /* Load modulation has been finished. Stop it and start to listen - * for incoming data again. */ - StartDemod(); - } -} - 2938: df 91 pop r29 - 293a: cf 91 pop r28 - 293c: 08 95 ret -INLINE void ApplicationTask(void) { - ActiveConfiguration.ApplicationTaskFunc(); -} - -INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { - return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount); - 293e: e0 91 f3 24 lds r30, 0x24F3 - 2942: f0 91 f4 24 lds r31, 0x24F4 - 2946: 80 e1 ldi r24, 0x10 ; 16 - 2948: 96 e2 ldi r25, 0x26 ; 38 - 294a: 09 95 icall - - if (DemodBitCount > 0) { - /* Call application if we received data */ - AnswerBitCount = ApplicationProcess(CodecBuffer, DemodBitCount); - - if (AnswerBitCount & ISO14443A_APP_CUSTOM_PARITY) { - 294c: 94 ff sbrs r25, 4 - 294e: 23 c0 rjmp .+70 ; 0x2996 - /* Application has generated it's own parity bits. - * Clear this option bit. */ - AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; - 2950: 9f 7e andi r25, 0xEF ; 239 - } - } else { - ApplicationReset(); - } - - if (AnswerBitCount != ISO14443A_APP_NO_RESPONSE) { - 2952: 00 97 sbiw r24, 0x00 ; 0 - 2954: 41 f3 breq .-48 ; 0x2926 - BitCount = AnswerBitCount; - 2956: 80 93 ad 24 sts 0x24AD, r24 - 295a: 90 93 ae 24 sts 0x24AE, r25 - BitSent = 0; - 295e: 10 92 ab 24 sts 0x24AB, r1 - 2962: 10 92 ac 24 sts 0x24AC, r1 - CodecBufferPtr = CodecBuffer; - 2966: 80 e1 ldi r24, 0x10 ; 16 - 2968: 96 e2 ldi r25, 0x26 ; 38 - 296a: 80 93 b1 24 sts 0x24B1, r24 - 296e: 90 93 b2 24 sts 0x24B2, r25 - ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; - 2972: 80 e9 ldi r24, 0x90 ; 144 - 2974: 96 e2 ldi r25, 0x26 ; 38 - 2976: 80 93 af 24 sts 0x24AF, r24 - 297a: 90 93 b0 24 sts 0x24B0, r25 - LoadModState = LOADMOD_START; - 297e: 81 e0 ldi r24, 0x01 ; 1 - 2980: 80 93 a6 24 sts 0x24A6, r24 - - StartDemod(); - } - } - - if (Flags.LoadmodFinished) { - 2984: 80 91 b4 24 lds r24, 0x24B4 - 2988: 88 23 and r24, r24 - 298a: b1 f2 breq .-84 ; 0x2938 - Flags.LoadmodFinished = 0; - 298c: 10 92 b4 24 sts 0x24B4, r1 - /* Load modulation has been finished. Stop it and start to listen - * for incoming data again. */ - StartDemod(); - } -} - 2990: df 91 pop r29 - 2992: cf 91 pop r28 - - if (Flags.LoadmodFinished) { - Flags.LoadmodFinished = 0; - /* Load modulation has been finished. Stop it and start to listen - * for incoming data again. */ - StartDemod(); - 2994: 7e cd rjmp .-1284 ; 0x2492 - /* Application has generated it's own parity bits. - * Clear this option bit. */ - AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; - } else { - /* We have to generate the parity bits ourself */ - for (uint8_t i = 0; i < (AnswerBitCount / 8); i++) { - 2996: ac 01 movw r20, r24 - 2998: 56 95 lsr r21 - 299a: 47 95 ror r20 - 299c: 56 95 lsr r21 - 299e: 47 95 ror r20 - 29a0: 56 95 lsr r21 - 29a2: 47 95 ror r20 - 29a4: 41 15 cp r20, r1 - 29a6: 51 05 cpc r21, r1 - 29a8: a1 f2 breq .-88 ; 0x2952 - 29aa: 70 e0 ldi r23, 0x00 ; 0 - 29ac: 20 e0 ldi r18, 0x00 ; 0 - 29ae: 30 e0 ldi r19, 0x00 ; 0 - /* For each whole byte, generate a parity bit. */ - CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = - ODD_PARITY(CodecBuffer[i]); - 29b0: f9 01 movw r30, r18 - 29b2: e0 5f subi r30, 0xF0 ; 240 - 29b4: f9 4d sbci r31, 0xD9 ; 217 - 29b6: 60 81 ld r22, Z - 29b8: 06 2e mov r0, r22 - 29ba: 62 95 swap r22 - 29bc: 60 25 eor r22, r0 - 29be: 06 2e mov r0, r22 - 29c0: 66 95 lsr r22 - 29c2: 66 95 lsr r22 - 29c4: 60 25 eor r22, r0 - AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; - } else { - /* We have to generate the parity bits ourself */ - for (uint8_t i = 0; i < (AnswerBitCount / 8); i++) { - /* For each whole byte, generate a parity bit. */ - CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = - 29c6: e0 58 subi r30, 0x80 ; 128 - 29c8: ff 4f sbci r31, 0xFF ; 255 - ODD_PARITY(CodecBuffer[i]); - 29ca: 6f 5f subi r22, 0xFF ; 255 - 29cc: 66 95 lsr r22 - 29ce: 61 70 andi r22, 0x01 ; 1 - 29d0: c6 2f mov r28, r22 - 29d2: 20 e0 ldi r18, 0x00 ; 0 - 29d4: d2 2f mov r29, r18 - 29d6: 21 e0 ldi r18, 0x01 ; 1 - 29d8: c2 27 eor r28, r18 - 29da: c0 83 st Z, r28 - /* Application has generated it's own parity bits. - * Clear this option bit. */ - AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; - } else { - /* We have to generate the parity bits ourself */ - for (uint8_t i = 0; i < (AnswerBitCount / 8); i++) { - 29dc: 7f 5f subi r23, 0xFF ; 255 - 29de: 27 2f mov r18, r23 - 29e0: 30 e0 ldi r19, 0x00 ; 0 - 29e2: 24 17 cp r18, r20 - 29e4: 35 07 cpc r19, r21 - 29e6: 20 f3 brcs .-56 ; 0x29b0 - 29e8: b6 cf rjmp .-148 ; 0x2956 - -000029ea : - Block[11] = Block[3]; -} - -void MifareClassicAppInit1K(void) -{ - State = STATE_IDLE; - 29ea: 81 e0 ldi r24, 0x01 ; 1 - 29ec: 80 93 d1 24 sts 0x24D1, r24 - CardATQAValue = MFCLASSIC_1K_ATQA_VALUE; - 29f0: 84 e0 ldi r24, 0x04 ; 4 - 29f2: 90 e0 ldi r25, 0x00 ; 0 - 29f4: 80 93 b6 24 sts 0x24B6, r24 - 29f8: 90 93 b7 24 sts 0x24B7, r25 - CardSAKValue = MFCLASSIC_1K_SAK_CL1_VALUE; - 29fc: 88 e0 ldi r24, 0x08 ; 8 - 29fe: 80 93 b5 24 sts 0x24B5, r24 - 2a02: 08 95 ret - -00002a04 : -} - -void MifareClassicAppInit4K(void) -{ - State = STATE_IDLE; - 2a04: 81 e0 ldi r24, 0x01 ; 1 - 2a06: 80 93 d1 24 sts 0x24D1, r24 - CardATQAValue = MFCLASSIC_4K_ATQA_VALUE; - 2a0a: 82 e0 ldi r24, 0x02 ; 2 - 2a0c: 90 e0 ldi r25, 0x00 ; 0 - 2a0e: 80 93 b6 24 sts 0x24B6, r24 - 2a12: 90 93 b7 24 sts 0x24B7, r25 - CardSAKValue = MFCLASSIC_4K_SAK_CL1_VALUE; - 2a16: 88 e1 ldi r24, 0x18 ; 24 - 2a18: 80 93 b5 24 sts 0x24B5, r24 - 2a1c: 08 95 ret - -00002a1e : -} - -void MifareClassicAppReset(void) -{ - State = STATE_IDLE; - 2a1e: 81 e0 ldi r24, 0x01 ; 1 - 2a20: 80 93 d1 24 sts 0x24D1, r24 - 2a24: 08 95 ret - -00002a26 : -} - -void MifareClassicAppTask(void) -{ - 2a26: 08 95 ret - -00002a28 : - -} - -uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) -{ - 2a28: 7f 92 push r7 - 2a2a: 8f 92 push r8 - 2a2c: 9f 92 push r9 - 2a2e: af 92 push r10 - 2a30: bf 92 push r11 - 2a32: cf 92 push r12 - 2a34: df 92 push r13 - 2a36: ef 92 push r14 - 2a38: ff 92 push r15 - 2a3a: 0f 93 push r16 - 2a3c: 1f 93 push r17 - 2a3e: cf 93 push r28 - 2a40: df 93 push r29 - 2a42: cd b7 in r28, 0x3d ; 61 - 2a44: de b7 in r29, 0x3e ; 62 - 2a46: 2e 97 sbiw r28, 0x0e ; 14 - 2a48: cd bf out 0x3d, r28 ; 61 - 2a4a: de bf out 0x3e, r29 ; 62 - 2a4c: 8c 01 movw r16, r24 - switch(State) { - 2a4e: 40 91 d1 24 lds r20, 0x24D1 - 2a52: 50 e0 ldi r21, 0x00 ; 0 - 2a54: 4a 30 cpi r20, 0x0A ; 10 - 2a56: 51 05 cpc r21, r1 - 2a58: 98 f0 brcs .+38 ; 0x2a80 - - *BitCount = ISO14443A_SAK_FRAME_SIZE; - return true; - } else { - /* We have not been selected. Don't send anything. */ - *BitCount = 0; - 2a5a: 80 e0 ldi r24, 0x00 ; 0 - 2a5c: 90 e0 ldi r25, 0x00 ; 0 - break; - } - - /* No response has been sent, when we reach here */ - return ISO14443A_APP_NO_RESPONSE; -} - 2a5e: 2e 96 adiw r28, 0x0e ; 14 - 2a60: cd bf out 0x3d, r28 ; 61 - 2a62: de bf out 0x3e, r29 ; 62 - 2a64: df 91 pop r29 - 2a66: cf 91 pop r28 - 2a68: 1f 91 pop r17 - 2a6a: 0f 91 pop r16 - 2a6c: ff 90 pop r15 - 2a6e: ef 90 pop r14 - 2a70: df 90 pop r13 - 2a72: cf 90 pop r12 - 2a74: bf 90 pop r11 - 2a76: af 90 pop r10 - 2a78: 9f 90 pop r9 - 2a7a: 8f 90 pop r8 - 2a7c: 7f 90 pop r7 - 2a7e: 08 95 ret - -} - -uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) -{ - switch(State) { - 2a80: fa 01 movw r30, r20 - 2a82: ee 5e subi r30, 0xEE ; 238 - 2a84: fe 4f sbci r31, 0xFE ; 254 - 2a86: 0c 94 69 23 jmp 0x46d2 ; 0x46d2 <__tablejump2__> - 2a8a: 7c 01 movw r14, r24 - 2a8c: d1 2c mov r13, r1 - * check for CRC. Then write the data when ReadOnly mode is not - * activated. */ - - /* We receive 16 bytes of data to be written and 2 bytes CRCA. Decrypt */ - for (uint8_t i=0; i<(MEM_BYTES_PER_BLOCK + ISO14443A_CRCA_SIZE); i++) - Buffer[i] ^= Crypto1Byte(); - 2a8e: f7 01 movw r30, r14 - 2a90: c0 80 ld r12, Z - 2a92: 99 d5 rcall .+2866 ; 0x35c6 - 2a94: 8c 25 eor r24, r12 - 2a96: d7 01 movw r26, r14 - 2a98: 8d 93 st X+, r24 - 2a9a: 7d 01 movw r14, r26 - * sending the data to be written. Decrypt the data first and - * check for CRC. Then write the data when ReadOnly mode is not - * activated. */ - - /* We receive 16 bytes of data to be written and 2 bytes CRCA. Decrypt */ - for (uint8_t i=0; i<(MEM_BYTES_PER_BLOCK + ISO14443A_CRCA_SIZE); i++) - 2a9c: d3 94 inc r13 - 2a9e: b2 e1 ldi r27, 0x12 ; 18 - 2aa0: db 12 cpse r13, r27 - 2aa2: f5 cf rjmp .-22 ; 0x2a8e - Buffer[i] ^= Crypto1Byte(); - - if (ISO14443ACheckCRCA(Buffer, MEM_BYTES_PER_BLOCK)) { - 2aa4: 60 e1 ldi r22, 0x10 ; 16 - 2aa6: 70 e0 ldi r23, 0x00 ; 0 - 2aa8: c8 01 movw r24, r16 - 2aaa: e5 d3 rcall .+1994 ; 0x3276 - 2aac: 88 23 and r24, r24 - 2aae: 09 f4 brne .+2 ; 0x2ab2 - 2ab0: ec c1 rjmp .+984 ; 0x2e8a - if (!ActiveConfiguration.ReadOnly) { - 2ab2: 80 91 fc 24 lds r24, 0x24FC - 2ab6: 88 23 and r24, r24 - 2ab8: 09 f4 brne .+2 ; 0x2abc - 2aba: ed c1 rjmp .+986 ; 0x2e96 - MemoryWriteBlock(Buffer, CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); - } else { - /* Silently ignore in ReadOnly mode */ - } - - Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); - 2abc: 97 d5 rcall .+2862 ; 0x35ec - 2abe: 9a e0 ldi r25, 0x0A ; 10 - 2ac0: 98 27 eor r25, r24 - 2ac2: d8 01 movw r26, r16 - 2ac4: 9c 93 st X, r25 - } else { - /* CRC Error. */ - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - } - - State = STATE_AUTHED_IDLE; - 2ac6: 85 e0 ldi r24, 0x05 ; 5 - 2ac8: 80 93 d1 24 sts 0x24D1, r24 - return ACK_NAK_FRAME_SIZE; - 2acc: 84 e0 ldi r24, 0x04 ; 4 - 2ace: 90 e0 ldi r25, 0x00 ; 0 - 2ad0: c6 cf rjmp .-116 ; 0x2a5e - 2ad2: 7c 01 movw r14, r24 - -} - -uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) -{ - switch(State) { - 2ad4: 56 e0 ldi r21, 0x06 ; 6 - 2ad6: d5 2e mov r13, r21 - * decrypt the data and check CRC. Read data from the requested block - * address into the global block buffer and check for integrity. Then - * add or subtract according to issued command if necessary and store - * the block back into the global block buffer. */ - for (uint8_t i=0; i<(MEM_VALUE_SIZE + ISO14443A_CRCA_SIZE); i++) - Buffer[i] ^= Crypto1Byte(); - 2ad8: d7 01 movw r26, r14 - 2ada: cc 90 ld r12, X - 2adc: 74 d5 rcall .+2792 ; 0x35c6 - 2ade: 8c 25 eor r24, r12 - 2ae0: f7 01 movw r30, r14 - 2ae2: 81 93 st Z+, r24 - 2ae4: 7f 01 movw r14, r30 - 2ae6: da 94 dec r13 - * been issued earlier and the reader is now sending the data. First, - * decrypt the data and check CRC. Read data from the requested block - * address into the global block buffer and check for integrity. Then - * add or subtract according to issued command if necessary and store - * the block back into the global block buffer. */ - for (uint8_t i=0; i<(MEM_VALUE_SIZE + ISO14443A_CRCA_SIZE); i++) - 2ae8: b9 f7 brne .-18 ; 0x2ad8 - Buffer[i] ^= Crypto1Byte(); - - if (ISO14443ACheckCRCA(Buffer, MEM_VALUE_SIZE )) { - 2aea: 64 e0 ldi r22, 0x04 ; 4 - 2aec: 70 e0 ldi r23, 0x00 ; 0 - 2aee: c8 01 movw r24, r16 - 2af0: c2 d3 rcall .+1924 ; 0x3276 - 2af2: 81 11 cpse r24, r1 - 2af4: b0 c1 rjmp .+864 ; 0x2e56 - /* Not sure if this is the correct error code.. */ - Buffer[0] = NAK_OTHER_ERROR ^ Crypto1Nibble(); - } - } else { - /* CRC Error. */ - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - 2af6: 7a d5 rcall .+2804 ; 0x35ec - 2af8: 91 e0 ldi r25, 0x01 ; 1 - 2afa: 98 27 eor r25, r24 - 2afc: d8 01 movw r26, r16 - 2afe: 9c 93 st X, r25 - 2b00: e2 cf rjmp .-60 ; 0x2ac6 -uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) -{ - switch(State) { - case STATE_IDLE: - case STATE_HALT: - if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { - 2b02: 20 91 b6 24 lds r18, 0x24B6 - 2b06: 90 91 b7 24 lds r25, 0x24B7 -INLINE -bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue) -{ - uint8_t* DataPtr = (uint8_t*) Buffer; - - if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){ - 2b0a: d8 01 movw r26, r16 - 2b0c: 8c 91 ld r24, X - 2b0e: 86 32 cpi r24, 0x26 ; 38 - 2b10: 19 f0 breq .+6 ; 0x2b18 - 2b12: 82 35 cpi r24, 0x52 ; 82 - 2b14: 09 f0 breq .+2 ; 0x2b18 - 2b16: a1 cf rjmp .-190 ; 0x2a5a - DataPtr[0] = (ATQAValue >> 0) & 0x00FF; - 2b18: f8 01 movw r30, r16 - 2b1a: 20 83 st Z, r18 - DataPtr[1] = (ATQAValue >> 8) & 0x00FF; - 2b1c: 91 83 std Z+1, r25 ; 0x01 - } - break; - - case STATE_READY: - if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { - State = STATE_READY; - 2b1e: 82 e0 ldi r24, 0x02 ; 2 - 2b20: 80 93 d1 24 sts 0x24D1, r24 - - *BitCount = ISO14443A_ATQA_FRAME_SIZE; - 2b24: 80 e1 ldi r24, 0x10 ; 16 - 2b26: 90 e0 ldi r25, 0x00 ; 0 - return BitCount; - 2b28: 9a cf rjmp .-204 ; 0x2a5e - return BitCount; - } - break; - - case STATE_READY: - if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { - 2b2a: 20 91 b6 24 lds r18, 0x24B6 - 2b2e: 90 91 b7 24 lds r25, 0x24B7 -INLINE -bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue) -{ - uint8_t* DataPtr = (uint8_t*) Buffer; - - if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){ - 2b32: d8 01 movw r26, r16 - 2b34: 8c 91 ld r24, X - 2b36: 86 32 cpi r24, 0x26 ; 38 - 2b38: 79 f3 breq .-34 ; 0x2b18 - 2b3a: 82 35 cpi r24, 0x52 ; 82 - 2b3c: 69 f3 breq .-38 ; 0x2b18 - State = STATE_READY; - return BitCount; - } else if (Buffer[0] == ISO14443A_CMD_SELECT_CL1) { - 2b3e: 83 39 cpi r24, 0x93 ; 147 - 2b40: 09 f4 brne .+2 ; 0x2b44 - 2b42: cb c1 rjmp .+918 ; 0x2eda - * byte is supposed to be 0. */ - if (Buffer[1] == 0) { - if (ISO14443ACheckCRCA(Buffer, CMD_HALT_FRAME_SIZE)) { - /* According to ISO14443, we must not send anything - * in order to acknowledge the HALT command. */ - State = STATE_HALT; - 2b44: 10 92 d1 24 sts 0x24D1, r1 - return ISO14443A_APP_NO_RESPONSE; - 2b48: 80 e0 ldi r24, 0x00 ; 0 - 2b4a: 90 e0 ldi r25, 0x00 ; 0 - 2b4c: 88 cf rjmp .-240 ; 0x2a5e - - case STATE_AUTHING: - /* Reader delivers an encrypted nonce. We use it - * to setup the crypto1 LFSR in nonlinear feedback mode. - * Furthermore it delivers an encrypted answer. Decrypt and check it */ - Crypto1Auth(&Buffer[0]); - 2b4e: 16 d5 rcall .+2604 ; 0x357c - 2b50: 68 01 movw r12, r16 - 2b52: b4 e0 ldi r27, 0x04 ; 4 - 2b54: cb 0e add r12, r27 - 2b56: d1 1c adc r13, r1 - - for (uint8_t i=0; i<4; i++) - 2b58: b1 2c mov r11, r1 - Buffer[i+4] ^= Crypto1Byte(); - 2b5a: f6 01 movw r30, r12 - 2b5c: a0 80 ld r10, Z - 2b5e: 33 d5 rcall .+2662 ; 0x35c6 - 2b60: 8a 25 eor r24, r10 - 2b62: d6 01 movw r26, r12 - 2b64: 8d 93 st X+, r24 - 2b66: 6d 01 movw r12, r26 - /* Reader delivers an encrypted nonce. We use it - * to setup the crypto1 LFSR in nonlinear feedback mode. - * Furthermore it delivers an encrypted answer. Decrypt and check it */ - Crypto1Auth(&Buffer[0]); - - for (uint8_t i=0; i<4; i++) - 2b68: b3 94 inc r11 - 2b6a: b4 e0 ldi r27, 0x04 ; 4 - 2b6c: bb 12 cpse r11, r27 - 2b6e: f5 cf rjmp .-22 ; 0x2b5a - Buffer[i+4] ^= Crypto1Byte(); - - if ((Buffer[4] == ReaderResponse[0]) && - 2b70: f8 01 movw r30, r16 - 2b72: 94 81 ldd r25, Z+4 ; 0x04 - 2b74: 80 91 c9 24 lds r24, 0x24C9 - 2b78: 98 17 cp r25, r24 - 2b7a: 09 f4 brne .+2 ; 0x2b7e - 2b7c: 2e c1 rjmp .+604 ; 0x2dda - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - return ACK_NAK_FRAME_SIZE; - } - } else { - /* Unknown command. Enter HALT state */ - State = STATE_IDLE; - 2b7e: 81 e0 ldi r24, 0x01 ; 1 - 2b80: 80 93 d1 24 sts 0x24D1, r24 - /* Unknown state? Should never happen. */ - break; - } - - /* No response has been sent, when we reach here */ - return ISO14443A_APP_NO_RESPONSE; - 2b84: 80 e0 ldi r24, 0x00 ; 0 - 2b86: 90 e0 ldi r25, 0x00 ; 0 - } else { - /* Unknown command. Enter HALT state */ - State = STATE_IDLE; - } - - break; - 2b88: 6a cf rjmp .-300 ; 0x2a5e - -} - -uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) -{ - switch(State) { - 2b8a: 7c 01 movw r14, r24 - 2b8c: 74 e0 ldi r23, 0x04 ; 4 - 2b8e: b7 2e mov r11, r23 - - case STATE_AUTHED_IDLE: - /* In this state, all communication is encrypted. Thus we first have to encrypt - * the incoming data. */ - for (uint8_t i=0; i<4; i++) - Buffer[i] ^= Crypto1Byte(); - 2b90: d7 01 movw r26, r14 - 2b92: ac 90 ld r10, X - 2b94: 18 d5 rcall .+2608 ; 0x35c6 - 2b96: 8a 25 eor r24, r10 - 2b98: f7 01 movw r30, r14 - 2b9a: 81 93 st Z+, r24 - 2b9c: 7f 01 movw r14, r30 - 2b9e: ba 94 dec r11 - break; - - case STATE_AUTHED_IDLE: - /* In this state, all communication is encrypted. Thus we first have to encrypt - * the incoming data. */ - for (uint8_t i=0; i<4; i++) - 2ba0: b9 f7 brne .-18 ; 0x2b90 - Buffer[i] ^= Crypto1Byte(); - - if (Buffer[0] == CMD_READ) { - 2ba2: d8 01 movw r26, r16 - 2ba4: 8c 91 ld r24, X - 2ba6: 80 33 cpi r24, 0x30 ; 48 - 2ba8: 09 f4 brne .+2 ; 0x2bac - 2baa: 89 c1 rjmp .+786 ; 0x2ebe - * BITS_PER_BYTE) | ISO14443A_APP_CUSTOM_PARITY; - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - return ACK_NAK_FRAME_SIZE; - } - } else if (Buffer[0] == CMD_WRITE) { - 2bac: 80 3a cpi r24, 0xA0 ; 160 - 2bae: 09 f4 brne .+2 ; 0x2bb2 - 2bb0: cb c1 rjmp .+918 ; 0x2f48 - Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - } - return ACK_NAK_FRAME_SIZE; - } else if (Buffer[0] == CMD_DECREMENT) { - 2bb2: 80 3c cpi r24, 0xC0 ; 192 - 2bb4: 09 f4 brne .+2 ; 0x2bb8 - 2bb6: da c1 rjmp .+948 ; 0x2f6c - Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - } - return ACK_NAK_FRAME_SIZE; - } else if (Buffer[0] == CMD_INCREMENT) { - 2bb8: 81 3c cpi r24, 0xC1 ; 193 - 2bba: 09 f4 brne .+2 ; 0x2bbe - 2bbc: 75 c2 rjmp .+1258 ; 0x30a8 <__stack+0xa9> - Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - } - return ACK_NAK_FRAME_SIZE; - } else if (Buffer[0] == CMD_RESTORE) { - 2bbe: 82 3c cpi r24, 0xC2 ; 194 - 2bc0: 09 f4 brne .+2 ; 0x2bc4 - 2bc2: 80 c2 rjmp .+1280 ; 0x30c4 <__stack+0xc5> - Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - } - return ACK_NAK_FRAME_SIZE; - }else if (Buffer[0] == CMD_TRANSFER) { - 2bc4: 80 3b cpi r24, 0xB0 ; 176 - 2bc6: 09 f4 brne .+2 ; 0x2bca - 2bc8: 8e c2 rjmp .+1308 ; 0x30e6 <__stack+0xe7> - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - } - - return ACK_NAK_FRAME_SIZE; - } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B) ) { - 2bca: 80 56 subi r24, 0x60 ; 96 - 2bcc: 82 30 cpi r24, 0x02 ; 2 - 2bce: b8 f6 brcc .-82 ; 0x2b7e - if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { - 2bd0: 62 e0 ldi r22, 0x02 ; 2 - 2bd2: 70 e0 ldi r23, 0x00 ; 0 - 2bd4: c8 01 movw r24, r16 - 2bd6: 4f d3 rcall .+1694 ; 0x3276 - 2bd8: 88 23 and r24, r24 - 2bda: 09 f4 brne .+2 ; 0x2bde - 2bdc: 68 c1 rjmp .+720 ; 0x2eae - /* Nested authentication. */ - uint8_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; - 2bde: f8 01 movw r30, r16 - 2be0: 81 81 ldd r24, Z+1 ; 0x01 - 2be2: 8c 73 andi r24, 0x3C ; 60 - uint8_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); - 2be4: 90 81 ld r25, Z - 2be6: 90 36 cpi r25, 0x60 ; 96 - 2be8: 09 f4 brne .+2 ; 0x2bec - 2bea: eb c2 rjmp .+1494 ; 0x31c2 <__stack+0x1c3> - 2bec: 6a e3 ldi r22, 0x3A ; 58 - 2bee: 70 e0 ldi r23, 0x00 ; 0 - uint16_t KeyAddress = (uint16_t) SectorAddress * MEM_BYTES_PER_BLOCK + KeyOffset; - 2bf0: 7b 01 movw r14, r22 - 2bf2: f0 e1 ldi r31, 0x10 ; 16 - 2bf4: 8f 9f mul r24, r31 - 2bf6: e0 0c add r14, r0 - 2bf8: f1 1c adc r15, r1 - 2bfa: 11 24 eor r1, r1 - uint8_t Key[6]; - uint8_t Uid[4]; - uint8_t CardNonce[4]; - - /* Generate a random nonce and read UID and key from memory */ - RandomGetBuffer(CardNonce, sizeof(CardNonce)); - 2bfc: 64 e0 ldi r22, 0x04 ; 4 - 2bfe: ce 01 movw r24, r28 - 2c00: 07 96 adiw r24, 0x07 ; 7 - 2c02: 0e 94 2f 05 call 0xa5e ; 0xa5e - MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); - 2c06: 44 e0 ldi r20, 0x04 ; 4 - 2c08: 50 e0 ldi r21, 0x00 ; 0 - 2c0a: 60 e0 ldi r22, 0x00 ; 0 - 2c0c: 70 e0 ldi r23, 0x00 ; 0 - 2c0e: ce 01 movw r24, r28 - 2c10: 0b 96 adiw r24, 0x0b ; 11 - 2c12: 0e 94 d4 05 call 0xba8 ; 0xba8 - MemoryReadBlock(Key, KeyAddress, MEM_KEY_SIZE); - 2c16: 46 e0 ldi r20, 0x06 ; 6 - 2c18: 50 e0 ldi r21, 0x00 ; 0 - 2c1a: b7 01 movw r22, r14 - 2c1c: ce 01 movw r24, r28 - 2c1e: 01 96 adiw r24, 0x01 ; 1 - 2c20: 0e 94 d4 05 call 0xba8 ; 0xba8 - 2c24: 8f 81 ldd r24, Y+7 ; 0x07 - 2c26: 98 85 ldd r25, Y+8 ; 0x08 - 2c28: a9 85 ldd r26, Y+9 ; 0x09 - 2c2a: ba 85 ldd r27, Y+10 ; 0x0a - 2c2c: 80 93 c9 24 sts 0x24C9, r24 - 2c30: 90 93 ca 24 sts 0x24CA, r25 - 2c34: a0 93 cb 24 sts 0x24CB, r26 - 2c38: b0 93 cc 24 sts 0x24CC, r27 - - /* Precalculate the reader response from card-nonce */ - for (uint8_t i=0; i - 2c46: 80 91 c9 24 lds r24, 0x24C9 - 2c4a: 90 91 ca 24 lds r25, 0x24CA - 2c4e: a0 91 cb 24 lds r26, 0x24CB - 2c52: b0 91 cc 24 lds r27, 0x24CC - 2c56: 80 93 cd 24 sts 0x24CD, r24 - 2c5a: 90 93 ce 24 sts 0x24CE, r25 - 2c5e: a0 93 cf 24 sts 0x24CF, r26 - 2c62: b0 93 d0 24 sts 0x24D0, r27 - - /* Precalculate our response from the reader response */ - for (uint8_t i=0; i - - /* Setup crypto1 cipher. */ - Crypto1Setup(Key, Uid, CardNonce); - 2c70: ae 01 movw r20, r28 - 2c72: 49 5f subi r20, 0xF9 ; 249 - 2c74: 5f 4f sbci r21, 0xFF ; 255 - 2c76: be 01 movw r22, r28 - 2c78: 65 5f subi r22, 0xF5 ; 245 - 2c7a: 7f 4f sbci r23, 0xFF ; 255 - 2c7c: ce 01 movw r24, r28 - 2c7e: 01 96 adiw r24, 0x01 ; 1 - 2c80: b0 d3 rcall .+1888 ; 0x33e2 - 2c82: 8f 81 ldd r24, Y+7 ; 0x07 - 2c84: 98 85 ldd r25, Y+8 ; 0x08 - 2c86: a9 85 ldd r26, Y+9 ; 0x09 - 2c88: ba 85 ldd r27, Y+10 ; 0x0a - 2c8a: f8 01 movw r30, r16 - 2c8c: 80 83 st Z, r24 - 2c8e: 91 83 std Z+1, r25 ; 0x01 - 2c90: a2 83 std Z+2, r26 ; 0x02 - 2c92: b3 83 std Z+3, r27 ; 0x03 - for (uint8_t i=0; i - 2ca0: fc 01 movw r30, r24 - 2ca2: 80 81 ld r24, Z - 2ca4: 86 32 cpi r24, 0x26 ; 38 - 2ca6: d1 f0 breq .+52 ; 0x2cdc - 2ca8: 82 35 cpi r24, 0x52 ; 82 - 2caa: c1 f0 breq .+48 ; 0x2cdc - - case STATE_ACTIVE: - if (ISO14443AWakeUp(Buffer, &BitCount, MFCLASSIC_1K_ATQA_VALUE)) { - State = STATE_READY; - return BitCount; - } else if (Buffer[0] == CMD_HALT) { - 2cac: 80 35 cpi r24, 0x50 ; 80 - 2cae: 09 f1 breq .+66 ; 0x2cf2 - } - } else { - Buffer[0] = NAK_INVALID_ARG; - return ACK_NAK_FRAME_SIZE; - } - } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B)) { - 2cb0: 90 ea ldi r25, 0xA0 ; 160 - 2cb2: 98 0f add r25, r24 - 2cb4: 92 30 cpi r25, 0x02 ; 2 - 2cb6: 38 f1 brcs .+78 ; 0x2d06 - return CMD_AUTH_RB_FRAME_SIZE * BITS_PER_BYTE; - } else { - Buffer[0] = NAK_CRC_ERROR; - return ACK_NAK_FRAME_SIZE; - } - } else if ( (Buffer[0] == CMD_READ) || (Buffer[0] == CMD_WRITE) || (Buffer[0] == CMD_DECREMENT) - 2cb8: 98 2f mov r25, r24 - 2cba: 9f 77 andi r25, 0x7F ; 127 - 2cbc: 90 33 cpi r25, 0x30 ; 48 - 2cbe: 31 f0 breq .+12 ; 0x2ccc - 2cc0: 80 3a cpi r24, 0xA0 ; 160 - 2cc2: 21 f0 breq .+8 ; 0x2ccc - 2cc4: 80 5c subi r24, 0xC0 ; 192 - 2cc6: 83 30 cpi r24, 0x03 ; 3 - 2cc8: 08 f0 brcs .+2 ; 0x2ccc - 2cca: 59 cf rjmp .-334 ; 0x2b7e - || (Buffer[0] == CMD_INCREMENT) || (Buffer[0] == CMD_RESTORE) || (Buffer[0] == CMD_TRANSFER) ) { - State = STATE_IDLE; - 2ccc: 81 e0 ldi r24, 0x01 ; 1 - 2cce: 80 93 d1 24 sts 0x24D1, r24 - Buffer[0] = NAK_NOT_AUTHED; - 2cd2: 84 e0 ldi r24, 0x04 ; 4 - 2cd4: d8 01 movw r26, r16 - 2cd6: 8c 93 st X, r24 - return ACK_NAK_FRAME_SIZE; - 2cd8: 90 e0 ldi r25, 0x00 ; 0 - 2cda: c1 ce rjmp .-638 ; 0x2a5e - DataPtr[0] = (ATQAValue >> 0) & 0x00FF; - 2cdc: 84 e0 ldi r24, 0x04 ; 4 - 2cde: d8 01 movw r26, r16 - 2ce0: 8c 93 st X, r24 - DataPtr[1] = (ATQAValue >> 8) & 0x00FF; - 2ce2: 11 96 adiw r26, 0x01 ; 1 - 2ce4: 1c 92 st X, r1 - } - break; - - case STATE_ACTIVE: - if (ISO14443AWakeUp(Buffer, &BitCount, MFCLASSIC_1K_ATQA_VALUE)) { - State = STATE_READY; - 2ce6: 82 e0 ldi r24, 0x02 ; 2 - 2ce8: 80 93 d1 24 sts 0x24D1, r24 - - *BitCount = ISO14443A_ATQA_FRAME_SIZE; - 2cec: 80 e1 ldi r24, 0x10 ; 16 - 2cee: 90 e0 ldi r25, 0x00 ; 0 - return BitCount; - 2cf0: b6 ce rjmp .-660 ; 0x2a5e - } else if (Buffer[0] == CMD_HALT) { - /* Halts the tag. According to the ISO14443, the second - * byte is supposed to be 0. */ - if (Buffer[1] == 0) { - 2cf2: f8 01 movw r30, r16 - 2cf4: 81 81 ldd r24, Z+1 ; 0x01 - 2cf6: 88 23 and r24, r24 - 2cf8: 09 f4 brne .+2 ; 0x2cfc - 2cfa: 13 c2 rjmp .+1062 ; 0x3122 <__stack+0x123> - } else { - Buffer[0] = NAK_CRC_ERROR; - return ACK_NAK_FRAME_SIZE; - } - } else { - Buffer[0] = NAK_INVALID_ARG; - 2cfc: f8 01 movw r30, r16 - 2cfe: 10 82 st Z, r1 - return ACK_NAK_FRAME_SIZE; - 2d00: 84 e0 ldi r24, 0x04 ; 4 - 2d02: 90 e0 ldi r25, 0x00 ; 0 - 2d04: ac ce rjmp .-680 ; 0x2a5e - } - } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B)) { - if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { - 2d06: 62 e0 ldi r22, 0x02 ; 2 - 2d08: 70 e0 ldi r23, 0x00 ; 0 - 2d0a: c8 01 movw r24, r16 - 2d0c: b4 d2 rcall .+1384 ; 0x3276 - 2d0e: 88 23 and r24, r24 - 2d10: 09 f4 brne .+2 ; 0x2d14 - 2d12: 0d c2 rjmp .+1050 ; 0x312e <__stack+0x12f> - uint8_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; - 2d14: d8 01 movw r26, r16 - 2d16: 11 96 adiw r26, 0x01 ; 1 - 2d18: 2c 91 ld r18, X - 2d1a: 11 97 sbiw r26, 0x01 ; 1 - 2d1c: 2c 73 andi r18, 0x3C ; 60 - uint8_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); - 2d1e: 8c 91 ld r24, X - 2d20: 80 36 cpi r24, 0x60 ; 96 - 2d22: 09 f4 brne .+2 ; 0x2d26 - 2d24: 51 c2 rjmp .+1186 ; 0x31c8 <__stack+0x1c9> - 2d26: 8a e3 ldi r24, 0x3A ; 58 - 2d28: 90 e0 ldi r25, 0x00 ; 0 - uint16_t KeyAddress = (uint16_t) SectorAddress * MEM_BYTES_PER_BLOCK + KeyOffset; - 2d2a: 7c 01 movw r14, r24 - 2d2c: b0 e1 ldi r27, 0x10 ; 16 - 2d2e: 2b 9f mul r18, r27 - 2d30: e0 0c add r14, r0 - 2d32: f1 1c adc r15, r1 - 2d34: 11 24 eor r1, r1 - uint8_t Key[6]; - uint8_t Uid[4]; - uint8_t CardNonce[4]; - - /* Generate a random nonce and read UID and key from memory */ - RandomGetBuffer(CardNonce, sizeof(CardNonce)); - 2d36: 64 e0 ldi r22, 0x04 ; 4 - 2d38: ce 01 movw r24, r28 - 2d3a: 07 96 adiw r24, 0x07 ; 7 - 2d3c: 0e 94 2f 05 call 0xa5e ; 0xa5e - MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); - 2d40: 44 e0 ldi r20, 0x04 ; 4 - 2d42: 50 e0 ldi r21, 0x00 ; 0 - 2d44: 60 e0 ldi r22, 0x00 ; 0 - 2d46: 70 e0 ldi r23, 0x00 ; 0 - 2d48: ce 01 movw r24, r28 - 2d4a: 0b 96 adiw r24, 0x0b ; 11 - 2d4c: 0e 94 d4 05 call 0xba8 ; 0xba8 - MemoryReadBlock(Key, KeyAddress, MEM_KEY_SIZE); - 2d50: 46 e0 ldi r20, 0x06 ; 6 - 2d52: 50 e0 ldi r21, 0x00 ; 0 - 2d54: b7 01 movw r22, r14 - 2d56: ce 01 movw r24, r28 - 2d58: 01 96 adiw r24, 0x01 ; 1 - 2d5a: 0e 94 d4 05 call 0xba8 ; 0xba8 - 2d5e: 8f 81 ldd r24, Y+7 ; 0x07 - 2d60: 98 85 ldd r25, Y+8 ; 0x08 - 2d62: a9 85 ldd r26, Y+9 ; 0x09 - 2d64: ba 85 ldd r27, Y+10 ; 0x0a - 2d66: 80 93 c9 24 sts 0x24C9, r24 - 2d6a: 90 93 ca 24 sts 0x24CA, r25 - 2d6e: a0 93 cb 24 sts 0x24CB, r26 - 2d72: b0 93 cc 24 sts 0x24CC, r27 - - /* Precalculate the reader response from card-nonce */ - for (uint8_t i=0; i - 2d80: 80 91 c9 24 lds r24, 0x24C9 - 2d84: 90 91 ca 24 lds r25, 0x24CA - 2d88: a0 91 cb 24 lds r26, 0x24CB - 2d8c: b0 91 cc 24 lds r27, 0x24CC - 2d90: 80 93 cd 24 sts 0x24CD, r24 - 2d94: 90 93 ce 24 sts 0x24CE, r25 - 2d98: a0 93 cf 24 sts 0x24CF, r26 - 2d9c: b0 93 d0 24 sts 0x24D0, r27 - - /* Precalculate our response from the reader response */ - for (uint8_t i=0; i - - /* Respond with the random card nonce and expect further authentication - * form the reader in the next frame. */ - State = STATE_AUTHING; - 2daa: 84 e0 ldi r24, 0x04 ; 4 - 2dac: 80 93 d1 24 sts 0x24D1, r24 - 2db0: 8f 81 ldd r24, Y+7 ; 0x07 - 2db2: 98 85 ldd r25, Y+8 ; 0x08 - 2db4: a9 85 ldd r26, Y+9 ; 0x09 - 2db6: ba 85 ldd r27, Y+10 ; 0x0a - 2db8: f8 01 movw r30, r16 - 2dba: 80 83 st Z, r24 - 2dbc: 91 83 std Z+1, r25 ; 0x01 - 2dbe: a2 83 std Z+2, r26 ; 0x02 - 2dc0: b3 83 std Z+3, r27 ; 0x03 - - for (uint8_t i=0; i - - return CMD_AUTH_RB_FRAME_SIZE * BITS_PER_BYTE; - 2dd4: 80 e2 ldi r24, 0x20 ; 32 - 2dd6: 90 e0 ldi r25, 0x00 ; 0 - 2dd8: 42 ce rjmp .-892 ; 0x2a5e - Crypto1Auth(&Buffer[0]); - - for (uint8_t i=0; i<4; i++) - Buffer[i+4] ^= Crypto1Byte(); - - if ((Buffer[4] == ReaderResponse[0]) && - 2dda: 95 81 ldd r25, Z+5 ; 0x05 - 2ddc: 80 91 ca 24 lds r24, 0x24CA - 2de0: 98 13 cpse r25, r24 - 2de2: cd ce rjmp .-614 ; 0x2b7e - (Buffer[5] == ReaderResponse[1]) && - 2de4: 96 81 ldd r25, Z+6 ; 0x06 - 2de6: 80 91 cb 24 lds r24, 0x24CB - 2dea: 98 13 cpse r25, r24 - 2dec: c8 ce rjmp .-624 ; 0x2b7e - (Buffer[6] == ReaderResponse[2]) && - 2dee: 97 81 ldd r25, Z+7 ; 0x07 - 2df0: 80 91 cc 24 lds r24, 0x24CC - 2df4: 98 13 cpse r25, r24 - 2df6: c3 ce rjmp .-634 ; 0x2b7e - 2df8: 68 01 movw r12, r16 - 2dfa: 0d ec ldi r16, 0xCD ; 205 - 2dfc: 14 e2 ldi r17, 0x24 ; 36 - 2dfe: 5f 01 movw r10, r30 - 2e00: f0 e8 ldi r31, 0x80 ; 128 - 2e02: af 0e add r10, r31 - 2e04: b1 1c adc r11, r1 - 2e06: 48 01 movw r8, r16 - (Buffer[7] == ReaderResponse[3])) { - /* Reader is authenticated. Encrypt the precalculated card response - * and generate the parity bits. */ - for (uint8_t i=0; i - 2e10: 87 25 eor r24, r7 - 2e12: f6 01 movw r30, r12 - 2e14: 81 93 st Z+, r24 - 2e16: 6f 01 movw r12, r30 - Buffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = ODD_PARITY(CardResponse[i]) ^ Crypto1FilterOutput(); - 2e18: d4 01 movw r26, r8 - 2e1a: 9c 90 ld r9, X - 2e1c: 09 2c mov r0, r9 - 2e1e: 92 94 swap r9 - 2e20: 90 24 eor r9, r0 - 2e22: 09 2c mov r0, r9 - 2e24: 96 94 lsr r9 - 2e26: 96 94 lsr r9 - 2e28: 90 24 eor r9, r0 - 2e2a: a9 d2 rcall .+1362 ; 0x337e - 2e2c: 93 94 inc r9 - 2e2e: 91 fa bst r9, 1 - 2e30: ee 24 eor r14, r14 - 2e32: e0 f8 bld r14, 0 - 2e34: f1 2c mov r15, r1 - 2e36: b1 e0 ldi r27, 0x01 ; 1 - 2e38: eb 26 eor r14, r27 - 2e3a: 8e 25 eor r24, r14 - 2e3c: f5 01 movw r30, r10 - 2e3e: 81 93 st Z+, r24 - 2e40: 5f 01 movw r10, r30 - (Buffer[5] == ReaderResponse[1]) && - (Buffer[6] == ReaderResponse[2]) && - (Buffer[7] == ReaderResponse[3])) { - /* Reader is authenticated. Encrypt the precalculated card response - * and generate the parity bits. */ - for (uint8_t i=0; i - Buffer[i] = CardResponse[i] ^ Crypto1Byte(); - Buffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = ODD_PARITY(CardResponse[i]) ^ Crypto1FilterOutput(); - } - - State = STATE_AUTHED_IDLE; - 2e4a: 85 e0 ldi r24, 0x05 ; 5 - 2e4c: 80 93 d1 24 sts 0x24D1, r24 - - return (CMD_AUTH_BA_FRAME_SIZE * BITS_PER_BYTE) | ISO14443A_APP_CUSTOM_PARITY; - 2e50: 80 e2 ldi r24, 0x20 ; 32 - 2e52: 90 e1 ldi r25, 0x10 ; 16 - 2e54: 04 ce rjmp .-1016 ; 0x2a5e - * the block back into the global block buffer. */ - for (uint8_t i=0; i<(MEM_VALUE_SIZE + ISO14443A_CRCA_SIZE); i++) - Buffer[i] ^= Crypto1Byte(); - - if (ISO14443ACheckCRCA(Buffer, MEM_VALUE_SIZE )) { - MemoryReadBlock(BlockBuffer, (uint16_t) CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); - 2e56: 60 91 c8 24 lds r22, 0x24C8 - 2e5a: f0 e1 ldi r31, 0x10 ; 16 - 2e5c: 6f 9f mul r22, r31 - 2e5e: b0 01 movw r22, r0 - 2e60: 11 24 eor r1, r1 - 2e62: 40 e1 ldi r20, 0x10 ; 16 - 2e64: 50 e0 ldi r21, 0x00 ; 0 - 2e66: 88 eb ldi r24, 0xB8 ; 184 - 2e68: 94 e2 ldi r25, 0x24 ; 36 - 2e6a: 0e 94 d4 05 call 0xba8 ; 0xba8 - -INLINE bool CheckValueIntegrity(uint8_t* Block) -{ - /* Value Blocks contain a value stored three times, with - * the middle portion inverted. */ - if ( (Block[0] == (uint8_t) ~Block[4]) && (Block[0] == Block[8]) - 2e6e: 20 91 b8 24 lds r18, 0x24B8 - 2e72: 80 91 bc 24 lds r24, 0x24BC - 2e76: 80 95 com r24 - 2e78: 28 17 cp r18, r24 - 2e7a: 09 f4 brne .+2 ; 0x2e7e - 2e7c: 88 c0 rjmp .+272 ; 0x2f8e - State = STATE_AUTHED_IDLE; - /* No ACK response on value commands part 2 */ - return ISO14443A_APP_NO_RESPONSE; - } else { - /* Not sure if this is the correct error code.. */ - Buffer[0] = NAK_OTHER_ERROR ^ Crypto1Nibble(); - 2e7e: b6 d3 rcall .+1900 ; 0x35ec - 2e80: 96 e0 ldi r25, 0x06 ; 6 - 2e82: 98 27 eor r25, r24 - 2e84: f8 01 movw r30, r16 - 2e86: 90 83 st Z, r25 - 2e88: 1e ce rjmp .-964 ; 0x2ac6 - /* Silently ignore in ReadOnly mode */ - } - - Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - 2e8a: b0 d3 rcall .+1888 ; 0x35ec - 2e8c: 91 e0 ldi r25, 0x01 ; 1 - 2e8e: 98 27 eor r25, r24 - 2e90: f8 01 movw r30, r16 - 2e92: 90 83 st Z, r25 - 2e94: 18 ce rjmp .-976 ; 0x2ac6 - for (uint8_t i=0; i<(MEM_BYTES_PER_BLOCK + ISO14443A_CRCA_SIZE); i++) - Buffer[i] ^= Crypto1Byte(); - - if (ISO14443ACheckCRCA(Buffer, MEM_BYTES_PER_BLOCK)) { - if (!ActiveConfiguration.ReadOnly) { - MemoryWriteBlock(Buffer, CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); - 2e96: 60 91 c8 24 lds r22, 0x24C8 - 2e9a: e0 e1 ldi r30, 0x10 ; 16 - 2e9c: 6e 9f mul r22, r30 - 2e9e: b0 01 movw r22, r0 - 2ea0: 11 24 eor r1, r1 - 2ea2: 40 e1 ldi r20, 0x10 ; 16 - 2ea4: 50 e0 ldi r21, 0x00 ; 0 - 2ea6: c8 01 movw r24, r16 - 2ea8: 0e 94 ec 05 call 0xbd8 ; 0xbd8 - 2eac: 07 ce rjmp .-1010 ; 0x2abc - * form the reader in the next frame. */ - State = STATE_AUTHING; - - return CMD_AUTH_RB_FRAME_SIZE * BITS_PER_BYTE; - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - 2eae: 9e d3 rcall .+1852 ; 0x35ec - 2eb0: 91 e0 ldi r25, 0x01 ; 1 - 2eb2: 98 27 eor r25, r24 - 2eb4: d8 01 movw r26, r16 - 2eb6: 9c 93 st X, r25 - return ACK_NAK_FRAME_SIZE; - 2eb8: 84 e0 ldi r24, 0x04 ; 4 - 2eba: 90 e0 ldi r25, 0x00 ; 0 - 2ebc: d0 cd rjmp .-1120 ; 0x2a5e - * the incoming data. */ - for (uint8_t i=0; i<4; i++) - Buffer[i] ^= Crypto1Byte(); - - if (Buffer[0] == CMD_READ) { - if (ISO14443ACheckCRCA(Buffer, CMD_READ_FRAME_SIZE)) { - 2ebe: 62 e0 ldi r22, 0x02 ; 2 - 2ec0: 70 e0 ldi r23, 0x00 ; 0 - 2ec2: c8 01 movw r24, r16 - 2ec4: d8 d1 rcall .+944 ; 0x3276 - 2ec6: 81 11 cpse r24, r1 - 2ec8: 38 c1 rjmp .+624 ; 0x313a <__stack+0x13b> - if (ISO14443ACheckCRCA(Buffer, CMD_DECREMENT_FRAME_SIZE)) { - CurrentAddress = Buffer[1]; - State = STATE_RESTORE; - Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - 2eca: 90 d3 rcall .+1824 ; 0x35ec - 2ecc: 91 e0 ldi r25, 0x01 ; 1 - if (ISO14443ACheckCRCA(Buffer, CMD_WRITE_FRAME_SIZE)) { - /* Write command. Store the address and prepare for the upcoming data. - * Respond with ACK. */ - CurrentAddress = Buffer[1]; - State = STATE_WRITE; - Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); - 2ece: 98 27 eor r25, r24 - 2ed0: f8 01 movw r30, r16 - 2ed2: 90 83 st Z, r25 - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - } - return ACK_NAK_FRAME_SIZE; - 2ed4: 84 e0 ldi r24, 0x04 ; 4 - 2ed6: 90 e0 ldi r25, 0x00 ; 0 - 2ed8: c2 cd rjmp .-1148 ; 0x2a5e - State = STATE_READY; - return BitCount; - } else if (Buffer[0] == ISO14443A_CMD_SELECT_CL1) { - /* Load UID CL1 and perform anticollision */ - uint8_t UidCL1[4]; - MemoryReadBlock(UidCL1, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); - 2eda: 44 e0 ldi r20, 0x04 ; 4 - 2edc: 50 e0 ldi r21, 0x00 ; 0 - 2ede: 60 e0 ldi r22, 0x00 ; 0 - 2ee0: 70 e0 ldi r23, 0x00 ; 0 - 2ee2: ce 01 movw r24, r28 - 2ee4: 01 96 adiw r24, 0x01 ; 1 - 2ee6: 0e 94 d4 05 call 0xba8 ; 0xba8 - - if (ISO14443ASelect(Buffer, &BitCount, UidCL1, CardSAKValue)) { - 2eea: 90 91 b5 24 lds r25, 0x24B5 - uint8_t* DataPtr = (uint8_t*) Buffer; - uint8_t NVB = DataPtr[1]; - //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F; - //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F; - - switch (NVB) { - 2eee: d8 01 movw r26, r16 - 2ef0: 11 96 adiw r26, 0x01 ; 1 - 2ef2: 8c 91 ld r24, X - 2ef4: 80 32 cpi r24, 0x20 ; 32 - 2ef6: 09 f4 brne .+2 ; 0x2efa - 2ef8: 54 c1 rjmp .+680 ; 0x31a2 <__stack+0x1a3> - 2efa: 80 37 cpi r24, 0x70 ; 112 - 2efc: 09 f0 breq .+2 ; 0x2f00 - 2efe: ad cd rjmp .-1190 ; 0x2a5a - return false; - - case ISO14443A_NVB_AC_END: - /* End of anticollision procedure. - * Send SAK CLn if we are selected. */ - if ( (DataPtr[2] == UidCL[0]) && - 2f00: d8 01 movw r26, r16 - 2f02: 12 96 adiw r26, 0x02 ; 2 - 2f04: 2c 91 ld r18, X - 2f06: 12 97 sbiw r26, 0x02 ; 2 - 2f08: 89 81 ldd r24, Y+1 ; 0x01 - 2f0a: 28 13 cpse r18, r24 - 2f0c: a6 cd rjmp .-1204 ; 0x2a5a - 2f0e: 13 96 adiw r26, 0x03 ; 3 - 2f10: 2c 91 ld r18, X - 2f12: 13 97 sbiw r26, 0x03 ; 3 - 2f14: 8a 81 ldd r24, Y+2 ; 0x02 - 2f16: 28 13 cpse r18, r24 - 2f18: a0 cd rjmp .-1216 ; 0x2a5a - (DataPtr[3] == UidCL[1]) && - 2f1a: 14 96 adiw r26, 0x04 ; 4 - 2f1c: 2c 91 ld r18, X - 2f1e: 14 97 sbiw r26, 0x04 ; 4 - 2f20: 8b 81 ldd r24, Y+3 ; 0x03 - 2f22: 28 13 cpse r18, r24 - 2f24: 9a cd rjmp .-1228 ; 0x2a5a - (DataPtr[4] == UidCL[2]) && - 2f26: 15 96 adiw r26, 0x05 ; 5 - 2f28: 2c 91 ld r18, X - 2f2a: 15 97 sbiw r26, 0x05 ; 5 - 2f2c: 8c 81 ldd r24, Y+4 ; 0x04 - 2f2e: 28 13 cpse r18, r24 - 2f30: 94 cd rjmp .-1240 ; 0x2a5a - (DataPtr[5] == UidCL[3]) ) { - - DataPtr[0] = SAKValue; - 2f32: 9c 93 st X, r25 - ISO14443AAppendCRCA(Buffer, 1); - 2f34: 61 e0 ldi r22, 0x01 ; 1 - 2f36: 70 e0 ldi r23, 0x00 ; 0 - 2f38: c8 01 movw r24, r16 - 2f3a: 6f d1 rcall .+734 ; 0x321a - State = STATE_ACTIVE; - 2f3c: 83 e0 ldi r24, 0x03 ; 3 - 2f3e: 80 93 d1 24 sts 0x24D1, r24 - - *BitCount = ISO14443A_SAK_FRAME_SIZE; - 2f42: 88 e1 ldi r24, 0x18 ; 24 - 2f44: 90 e0 ldi r25, 0x00 ; 0 - 2f46: 8b cd rjmp .-1258 ; 0x2a5e - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - return ACK_NAK_FRAME_SIZE; - } - } else if (Buffer[0] == CMD_WRITE) { - if (ISO14443ACheckCRCA(Buffer, CMD_WRITE_FRAME_SIZE)) { - 2f48: 62 e0 ldi r22, 0x02 ; 2 - 2f4a: 70 e0 ldi r23, 0x00 ; 0 - 2f4c: c8 01 movw r24, r16 - 2f4e: 93 d1 rcall .+806 ; 0x3276 - 2f50: 88 23 and r24, r24 - 2f52: 09 f4 brne .+2 ; 0x2f56 - 2f54: ac cf rjmp .-168 ; 0x2eae - /* Write command. Store the address and prepare for the upcoming data. - * Respond with ACK. */ - CurrentAddress = Buffer[1]; - 2f56: d8 01 movw r26, r16 - 2f58: 11 96 adiw r26, 0x01 ; 1 - 2f5a: 8c 91 ld r24, X - 2f5c: 80 93 c8 24 sts 0x24C8, r24 - State = STATE_WRITE; - 2f60: 86 e0 ldi r24, 0x06 ; 6 - 2f62: 80 93 d1 24 sts 0x24D1, r24 - Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); - 2f66: 42 d3 rcall .+1668 ; 0x35ec - 2f68: 9a e0 ldi r25, 0x0A ; 10 - 2f6a: b1 cf rjmp .-158 ; 0x2ece - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - } - return ACK_NAK_FRAME_SIZE; - } else if (Buffer[0] == CMD_DECREMENT) { - if (ISO14443ACheckCRCA(Buffer, CMD_DECREMENT_FRAME_SIZE)) { - 2f6c: 62 e0 ldi r22, 0x02 ; 2 - 2f6e: 70 e0 ldi r23, 0x00 ; 0 - 2f70: c8 01 movw r24, r16 - 2f72: 81 d1 rcall .+770 ; 0x3276 - 2f74: 88 23 and r24, r24 - 2f76: 09 f4 brne .+2 ; 0x2f7a - 2f78: a8 cf rjmp .-176 ; 0x2eca - CurrentAddress = Buffer[1]; - 2f7a: f8 01 movw r30, r16 - 2f7c: 81 81 ldd r24, Z+1 ; 0x01 - 2f7e: 80 93 c8 24 sts 0x24C8, r24 - State = STATE_DECREMENT; - 2f82: 88 e0 ldi r24, 0x08 ; 8 - 2f84: 80 93 d1 24 sts 0x24D1, r24 - Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); - 2f88: 31 d3 rcall .+1634 ; 0x35ec - 2f8a: 9a e0 ldi r25, 0x0A ; 10 - 2f8c: 92 cf rjmp .-220 ; 0x2eb2 - -INLINE bool CheckValueIntegrity(uint8_t* Block) -{ - /* Value Blocks contain a value stored three times, with - * the middle portion inverted. */ - if ( (Block[0] == (uint8_t) ~Block[4]) && (Block[0] == Block[8]) - 2f8e: 80 91 c0 24 lds r24, 0x24C0 - 2f92: 28 13 cpse r18, r24 - 2f94: 74 cf rjmp .-280 ; 0x2e7e - && (Block[1] == (uint8_t) ~Block[5]) && (Block[1] == Block[9]) - 2f96: e0 91 b9 24 lds r30, 0x24B9 - 2f9a: 80 91 bd 24 lds r24, 0x24BD - 2f9e: 80 95 com r24 - 2fa0: e8 13 cpse r30, r24 - 2fa2: 6d cf rjmp .-294 ; 0x2e7e - 2fa4: 80 91 c1 24 lds r24, 0x24C1 - 2fa8: e8 13 cpse r30, r24 - 2faa: 69 cf rjmp .-302 ; 0x2e7e - && (Block[2] == (uint8_t) ~Block[6]) && (Block[2] == Block[10]) - 2fac: 80 91 ba 24 lds r24, 0x24BA - 2fb0: 90 91 be 24 lds r25, 0x24BE - 2fb4: 90 95 com r25 - 2fb6: 89 13 cpse r24, r25 - 2fb8: 62 cf rjmp .-316 ; 0x2e7e - 2fba: 90 91 c2 24 lds r25, 0x24C2 - 2fbe: 89 13 cpse r24, r25 - 2fc0: 5e cf rjmp .-324 ; 0x2e7e - && (Block[3] == (uint8_t) ~Block[7]) && (Block[3] == Block[11]) - 2fc2: 30 91 bb 24 lds r19, 0x24BB - 2fc6: 90 91 bf 24 lds r25, 0x24BF - 2fca: 90 95 com r25 - 2fcc: 39 13 cpse r19, r25 - 2fce: 57 cf rjmp .-338 ; 0x2e7e - 2fd0: 90 91 c3 24 lds r25, 0x24C3 - 2fd4: 39 13 cpse r19, r25 - 2fd6: 53 cf rjmp .-346 ; 0x2e7e - && (Block[12] == (uint8_t) ~Block[13]) - 2fd8: 40 91 c4 24 lds r20, 0x24C4 - 2fdc: 90 91 c5 24 lds r25, 0x24C5 - 2fe0: 90 95 com r25 - 2fe2: 49 13 cpse r20, r25 - 2fe4: 4c cf rjmp .-360 ; 0x2e7e - && (Block[12] == Block[14]) - 2fe6: 90 91 c6 24 lds r25, 0x24C6 - 2fea: 49 13 cpse r20, r25 - 2fec: 48 cf rjmp .-368 ; 0x2e7e - && (Block[14] == (uint8_t) ~Block[15])) { - 2fee: 90 91 c7 24 lds r25, 0x24C7 - 2ff2: 90 95 com r25 - 2ff4: 49 13 cpse r20, r25 - 2ff6: 43 cf rjmp .-378 ; 0x2e7e -} - -INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) -{ - *Value = 0; - *Value |= ((uint32_t) Block[0] << 0); - 2ff8: d8 01 movw r26, r16 - 2ffa: 9c 91 ld r25, X - *Value |= ((uint32_t) Block[1] << 8); - 2ffc: 11 96 adiw r26, 0x01 ; 1 - 2ffe: fc 91 ld r31, X - 3000: 11 97 sbiw r26, 0x01 ; 1 - *Value |= ((uint32_t) Block[2] << 16); - 3002: 12 96 adiw r26, 0x02 ; 2 - 3004: 4c 91 ld r20, X - 3006: 12 97 sbiw r26, 0x02 ; 2 - 3008: 50 e0 ldi r21, 0x00 ; 0 - 300a: 60 e0 ldi r22, 0x00 ; 0 - 300c: 70 e0 ldi r23, 0x00 ; 0 - 300e: ba 01 movw r22, r20 - 3010: 55 27 eor r21, r21 - 3012: 44 27 eor r20, r20 - -INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) -{ - *Value = 0; - *Value |= ((uint32_t) Block[0] << 0); - *Value |= ((uint32_t) Block[1] << 8); - 3014: 5f 2b or r21, r31 - *Value |= ((uint32_t) Block[2] << 16); - 3016: 49 2b or r20, r25 - *Value |= ((uint32_t) Block[3] << 24); - 3018: 13 96 adiw r26, 0x03 ; 3 - 301a: 9c 91 ld r25, X - 301c: 79 2b or r23, r25 -INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) -{ - *Value = 0; - *Value |= ((uint32_t) Block[0] << 0); - *Value |= ((uint32_t) Block[1] << 8); - *Value |= ((uint32_t) Block[2] << 16); - 301e: 90 e0 ldi r25, 0x00 ; 0 - 3020: a0 e0 ldi r26, 0x00 ; 0 - 3022: b0 e0 ldi r27, 0x00 ; 0 - 3024: dc 01 movw r26, r24 - 3026: 99 27 eor r25, r25 - 3028: 88 27 eor r24, r24 - -INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) -{ - *Value = 0; - *Value |= ((uint32_t) Block[0] << 0); - *Value |= ((uint32_t) Block[1] << 8); - 302a: 9e 2b or r25, r30 - *Value |= ((uint32_t) Block[2] << 16); - 302c: 82 2b or r24, r18 - *Value |= ((uint32_t) Block[3] << 24); - 302e: b3 2b or r27, r19 - uint32_t BlockValue; - - ValueFromBlock(&ParamValue, Buffer); - ValueFromBlock(&BlockValue, BlockBuffer); - - if (State == STATE_DECREMENT) { - 3030: 20 91 d1 24 lds r18, 0x24D1 - 3034: 28 30 cpi r18, 0x08 ; 8 - 3036: 09 f4 brne .+2 ; 0x303a <__stack+0x3b> - 3038: 6f c0 rjmp .+222 ; 0x3118 <__stack+0x119> - BlockValue -= ParamValue; - } else if (State == STATE_INCREMENT) { - 303a: 27 30 cpi r18, 0x07 ; 7 - 303c: 21 f4 brne .+8 ; 0x3046 <__stack+0x47> - BlockValue += ParamValue; - 303e: 84 0f add r24, r20 - 3040: 95 1f adc r25, r21 - 3042: a6 1f adc r26, r22 - 3044: b7 1f adc r27, r23 - *Value |= ((uint32_t) Block[3] << 24); -} - -INLINE void ValueToBlock(uint8_t* Block, uint32_t Value) -{ - Block[0] = (uint8_t) (Value >> 0); - 3046: 80 93 b8 24 sts 0x24B8, r24 - Block[1] = (uint8_t) (Value >> 8); - 304a: c9 2e mov r12, r25 - 304c: da 2e mov r13, r26 - 304e: eb 2e mov r14, r27 - 3050: ff 24 eor r15, r15 - 3052: c0 92 b9 24 sts 0x24B9, r12 - Block[2] = (uint8_t) (Value >> 16); - 3056: 8d 01 movw r16, r26 - 3058: 22 27 eor r18, r18 - 305a: 33 27 eor r19, r19 - 305c: 00 93 ba 24 sts 0x24BA, r16 - Block[3] = (uint8_t) (Value >> 24); - 3060: 4b 2f mov r20, r27 - 3062: 55 27 eor r21, r21 - 3064: 66 27 eor r22, r22 - 3066: 77 27 eor r23, r23 - 3068: 40 93 bb 24 sts 0x24BB, r20 - Block[4] = ~Block[0]; - 306c: e8 2f mov r30, r24 - 306e: e0 95 com r30 - 3070: e0 93 bc 24 sts 0x24BC, r30 - Block[5] = ~Block[1]; - 3074: ec 2d mov r30, r12 - 3076: e0 95 com r30 - 3078: e0 93 bd 24 sts 0x24BD, r30 - Block[6] = ~Block[2]; - 307c: e0 2f mov r30, r16 - 307e: e0 95 com r30 - 3080: e0 93 be 24 sts 0x24BE, r30 - Block[7] = ~Block[3]; - 3084: e4 2f mov r30, r20 - 3086: e0 95 com r30 - 3088: e0 93 bf 24 sts 0x24BF, r30 - Block[8] = Block[0]; - 308c: 80 93 c0 24 sts 0x24C0, r24 - Block[9] = Block[1]; - 3090: c0 92 c1 24 sts 0x24C1, r12 - Block[10] = Block[2]; - 3094: 00 93 c2 24 sts 0x24C2, r16 - Block[11] = Block[3]; - 3098: 40 93 c3 24 sts 0x24C3, r20 - /* Do nothing */ - } - - ValueToBlock(BlockBuffer, BlockValue); - - State = STATE_AUTHED_IDLE; - 309c: 85 e0 ldi r24, 0x05 ; 5 - 309e: 80 93 d1 24 sts 0x24D1, r24 - /* No ACK response on value commands part 2 */ - return ISO14443A_APP_NO_RESPONSE; - 30a2: 80 e0 ldi r24, 0x00 ; 0 - 30a4: 90 e0 ldi r25, 0x00 ; 0 - 30a6: db cc rjmp .-1610 ; 0x2a5e - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - } - return ACK_NAK_FRAME_SIZE; - } else if (Buffer[0] == CMD_INCREMENT) { - if (ISO14443ACheckCRCA(Buffer, CMD_DECREMENT_FRAME_SIZE)) { - 30a8: 62 e0 ldi r22, 0x02 ; 2 - 30aa: 70 e0 ldi r23, 0x00 ; 0 - 30ac: c8 01 movw r24, r16 - 30ae: e3 d0 rcall .+454 ; 0x3276 - 30b0: 88 23 and r24, r24 - 30b2: 09 f4 brne .+2 ; 0x30b6 <__stack+0xb7> - 30b4: fc ce rjmp .-520 ; 0x2eae - CurrentAddress = Buffer[1]; - 30b6: d8 01 movw r26, r16 - 30b8: 11 96 adiw r26, 0x01 ; 1 - 30ba: 8c 91 ld r24, X - 30bc: 80 93 c8 24 sts 0x24C8, r24 - State = STATE_INCREMENT; - 30c0: 87 e0 ldi r24, 0x07 ; 7 - 30c2: 4f cf rjmp .-354 ; 0x2f62 - } else { - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - } - return ACK_NAK_FRAME_SIZE; - } else if (Buffer[0] == CMD_RESTORE) { - if (ISO14443ACheckCRCA(Buffer, CMD_DECREMENT_FRAME_SIZE)) { - 30c4: 62 e0 ldi r22, 0x02 ; 2 - 30c6: 70 e0 ldi r23, 0x00 ; 0 - 30c8: c8 01 movw r24, r16 - 30ca: d5 d0 rcall .+426 ; 0x3276 - 30cc: 88 23 and r24, r24 - 30ce: 09 f4 brne .+2 ; 0x30d2 <__stack+0xd3> - 30d0: fc ce rjmp .-520 ; 0x2eca - CurrentAddress = Buffer[1]; - 30d2: f8 01 movw r30, r16 - 30d4: 81 81 ldd r24, Z+1 ; 0x01 - 30d6: 80 93 c8 24 sts 0x24C8, r24 - State = STATE_RESTORE; - 30da: 89 e0 ldi r24, 0x09 ; 9 - 30dc: 80 93 d1 24 sts 0x24D1, r24 - Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); - 30e0: 85 d2 rcall .+1290 ; 0x35ec - 30e2: 9a e0 ldi r25, 0x0A ; 10 - 30e4: e6 ce rjmp .-564 ; 0x2eb2 - Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); - } - return ACK_NAK_FRAME_SIZE; - }else if (Buffer[0] == CMD_TRANSFER) { - /* Write back the global block buffer to the desired block address */ - if (ISO14443ACheckCRCA(Buffer, CMD_TRANSFER_FRAME_SIZE)) { - 30e6: 62 e0 ldi r22, 0x02 ; 2 - 30e8: 70 e0 ldi r23, 0x00 ; 0 - 30ea: c8 01 movw r24, r16 - 30ec: c4 d0 rcall .+392 ; 0x3276 - 30ee: 88 23 and r24, r24 - 30f0: 09 f4 brne .+2 ; 0x30f4 <__stack+0xf5> - 30f2: dd ce rjmp .-582 ; 0x2eae - if (!ActiveConfiguration.ReadOnly) { - 30f4: 80 91 fc 24 lds r24, 0x24FC - 30f8: 81 11 cpse r24, r1 - 30fa: 35 cf rjmp .-406 ; 0x2f66 - MemoryWriteBlock(BlockBuffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK ); - 30fc: d8 01 movw r26, r16 - 30fe: 11 96 adiw r26, 0x01 ; 1 - 3100: 6c 91 ld r22, X - 3102: b0 e1 ldi r27, 0x10 ; 16 - 3104: 6b 9f mul r22, r27 - 3106: b0 01 movw r22, r0 - 3108: 11 24 eor r1, r1 - 310a: 40 e1 ldi r20, 0x10 ; 16 - 310c: 50 e0 ldi r21, 0x00 ; 0 - 310e: 88 eb ldi r24, 0xB8 ; 184 - 3110: 94 e2 ldi r25, 0x24 ; 36 - 3112: 0e 94 ec 05 call 0xbd8 ; 0xbd8 - 3116: 27 cf rjmp .-434 ; 0x2f66 - - ValueFromBlock(&ParamValue, Buffer); - ValueFromBlock(&BlockValue, BlockBuffer); - - if (State == STATE_DECREMENT) { - BlockValue -= ParamValue; - 3118: 84 1b sub r24, r20 - 311a: 95 0b sbc r25, r21 - 311c: a6 0b sbc r26, r22 - 311e: b7 0b sbc r27, r23 - 3120: 92 cf rjmp .-220 ; 0x3046 <__stack+0x47> - return BitCount; - } else if (Buffer[0] == CMD_HALT) { - /* Halts the tag. According to the ISO14443, the second - * byte is supposed to be 0. */ - if (Buffer[1] == 0) { - if (ISO14443ACheckCRCA(Buffer, CMD_HALT_FRAME_SIZE)) { - 3122: 62 e0 ldi r22, 0x02 ; 2 - 3124: 70 e0 ldi r23, 0x00 ; 0 - 3126: c8 01 movw r24, r16 - 3128: a6 d0 rcall .+332 ; 0x3276 - 312a: 81 11 cpse r24, r1 - 312c: 0b cd rjmp .-1514 ; 0x2b44 - /* According to ISO14443, we must not send anything - * in order to acknowledge the HALT command. */ - State = STATE_HALT; - return ISO14443A_APP_NO_RESPONSE; - } else { - Buffer[0] = NAK_CRC_ERROR; - 312e: 81 e0 ldi r24, 0x01 ; 1 - 3130: d8 01 movw r26, r16 - 3132: 8c 93 st X, r24 - return ACK_NAK_FRAME_SIZE; - 3134: 84 e0 ldi r24, 0x04 ; 4 - 3136: 90 e0 ldi r25, 0x00 ; 0 - 3138: 92 cc rjmp .-1756 ; 0x2a5e - Buffer[i] ^= Crypto1Byte(); - - if (Buffer[0] == CMD_READ) { - if (ISO14443ACheckCRCA(Buffer, CMD_READ_FRAME_SIZE)) { - /* Read command. Read data from memory and append CRCA. */ - MemoryReadBlock(Buffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); - 313a: f8 01 movw r30, r16 - 313c: 61 81 ldd r22, Z+1 ; 0x01 - 313e: f0 e1 ldi r31, 0x10 ; 16 - 3140: 6f 9f mul r22, r31 - 3142: b0 01 movw r22, r0 - 3144: 11 24 eor r1, r1 - 3146: 40 e1 ldi r20, 0x10 ; 16 - 3148: 50 e0 ldi r21, 0x00 ; 0 - 314a: c8 01 movw r24, r16 - 314c: 0e 94 d4 05 call 0xba8 ; 0xba8 - ISO14443AAppendCRCA(Buffer, MEM_BYTES_PER_BLOCK); - 3150: 60 e1 ldi r22, 0x10 ; 16 - 3152: 70 e0 ldi r23, 0x00 ; 0 - 3154: c8 01 movw r24, r16 - 3156: 61 d0 rcall .+194 ; 0x321a - 3158: 78 01 movw r14, r16 - 315a: 30 e8 ldi r19, 0x80 ; 128 - 315c: e3 0e add r14, r19 - 315e: f1 1c adc r15, r1 - 3160: 62 e1 ldi r22, 0x12 ; 18 - 3162: a6 2e mov r10, r22 - - /* Encrypt and calculate parity bits. */ - for (uint8_t i=0; i<(ISO14443A_CRCA_SIZE + MEM_BYTES_PER_BLOCK); i++) { - uint8_t Plain = Buffer[i]; - 3164: d8 01 movw r26, r16 - 3166: bc 90 ld r11, X - Buffer[i] = Plain ^ Crypto1Byte(); - 3168: 2e d2 rcall .+1116 ; 0x35c6 - 316a: 8b 25 eor r24, r11 - 316c: f8 01 movw r30, r16 - 316e: 81 93 st Z+, r24 - 3170: 8f 01 movw r16, r30 - Buffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = ODD_PARITY(Plain) ^ Crypto1FilterOutput(); - 3172: 0b 2c mov r0, r11 - 3174: b2 94 swap r11 - 3176: b0 24 eor r11, r0 - 3178: 0b 2c mov r0, r11 - 317a: b6 94 lsr r11 - 317c: b6 94 lsr r11 - 317e: b0 24 eor r11, r0 - 3180: fe d0 rcall .+508 ; 0x337e - 3182: b3 94 inc r11 - 3184: b1 fa bst r11, 1 - 3186: cc 24 eor r12, r12 - 3188: c0 f8 bld r12, 0 - 318a: d1 2c mov r13, r1 - 318c: f1 e0 ldi r31, 0x01 ; 1 - 318e: cf 26 eor r12, r31 - 3190: 8c 25 eor r24, r12 - 3192: d7 01 movw r26, r14 - 3194: 8d 93 st X+, r24 - 3196: 7d 01 movw r14, r26 - 3198: aa 94 dec r10 - /* Read command. Read data from memory and append CRCA. */ - MemoryReadBlock(Buffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); - ISO14443AAppendCRCA(Buffer, MEM_BYTES_PER_BLOCK); - - /* Encrypt and calculate parity bits. */ - for (uint8_t i=0; i<(ISO14443A_CRCA_SIZE + MEM_BYTES_PER_BLOCK); i++) { - 319a: 21 f7 brne .-56 ; 0x3164 <__stack+0x165> - uint8_t Plain = Buffer[i]; - Buffer[i] = Plain ^ Crypto1Byte(); - Buffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = ODD_PARITY(Plain) ^ Crypto1FilterOutput(); - } - - return ( (CMD_READ_RESPONSE_FRAME_SIZE + ISO14443A_CRCA_SIZE ) - 319c: 80 e9 ldi r24, 0x90 ; 144 - 319e: 90 e1 ldi r25, 0x10 ; 16 - 31a0: 5e cc rjmp .-1860 ; 0x2a5e - - switch (NVB) { - case ISO14443A_NVB_AC_START: - /* Start of anticollision procedure. - * Send whole UID CLn + BCC */ - DataPtr[0] = UidCL[0]; - 31a2: 89 81 ldd r24, Y+1 ; 0x01 - 31a4: f8 01 movw r30, r16 - 31a6: 80 83 st Z, r24 - DataPtr[1] = UidCL[1]; - 31a8: 3a 81 ldd r19, Y+2 ; 0x02 - 31aa: 31 83 std Z+1, r19 ; 0x01 - DataPtr[2] = UidCL[2]; - 31ac: 2b 81 ldd r18, Y+3 ; 0x03 - 31ae: 22 83 std Z+2, r18 ; 0x02 - DataPtr[3] = UidCL[3]; - 31b0: 9c 81 ldd r25, Y+4 ; 0x04 - 31b2: 93 83 std Z+3, r25 ; 0x03 - DataPtr[4] = ISO14443A_CALC_BCC(DataPtr); - 31b4: 83 27 eor r24, r19 - 31b6: 82 27 eor r24, r18 - 31b8: 89 27 eor r24, r25 - 31ba: 84 83 std Z+4, r24 ; 0x04 - - *BitCount = ISO14443A_CL_FRAME_SIZE; - 31bc: 88 e2 ldi r24, 0x28 ; 40 - 31be: 90 e0 ldi r25, 0x00 ; 0 - 31c0: 4e cc rjmp .-1892 ; 0x2a5e - return ACK_NAK_FRAME_SIZE; - } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B) ) { - if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { - /* Nested authentication. */ - uint8_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; - uint8_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); - 31c2: 60 e3 ldi r22, 0x30 ; 48 - 31c4: 70 e0 ldi r23, 0x00 ; 0 - 31c6: 14 cd rjmp .-1496 ; 0x2bf0 - return ACK_NAK_FRAME_SIZE; - } - } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B)) { - if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { - uint8_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; - uint8_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); - 31c8: 80 e3 ldi r24, 0x30 ; 48 - 31ca: 90 e0 ldi r25, 0x00 ; 0 - 31cc: ae cd rjmp .-1188 ; 0x2d2a - -000031ce : - return ISO14443A_APP_NO_RESPONSE; -} - -void MifareClassicGetUid(ConfigurationUidType Uid) -{ - MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); - 31ce: 44 e0 ldi r20, 0x04 ; 4 - 31d0: 50 e0 ldi r21, 0x00 ; 0 - 31d2: 60 e0 ldi r22, 0x00 ; 0 - 31d4: 70 e0 ldi r23, 0x00 ; 0 - 31d6: 0c 94 d4 05 jmp 0xba8 ; 0xba8 - -000031da : -} - -void MifareClassicSetUid(ConfigurationUidType Uid) -{ - 31da: cf 93 push r28 - 31dc: df 93 push r29 - 31de: 1f 92 push r1 - 31e0: cd b7 in r28, 0x3d ; 61 - 31e2: de b7 in r29, 0x3e ; 62 - uint8_t BCC = Uid[0] ^ Uid[1] ^ Uid[2] ^ Uid[3]; - 31e4: fc 01 movw r30, r24 - 31e6: 21 81 ldd r18, Z+1 ; 0x01 - 31e8: 30 81 ld r19, Z - 31ea: 23 27 eor r18, r19 - 31ec: 32 81 ldd r19, Z+2 ; 0x02 - 31ee: 23 27 eor r18, r19 - 31f0: 33 81 ldd r19, Z+3 ; 0x03 - 31f2: 23 27 eor r18, r19 - 31f4: 29 83 std Y+1, r18 ; 0x01 - - MemoryWriteBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); - 31f6: 44 e0 ldi r20, 0x04 ; 4 - 31f8: 50 e0 ldi r21, 0x00 ; 0 - 31fa: 60 e0 ldi r22, 0x00 ; 0 - 31fc: 70 e0 ldi r23, 0x00 ; 0 - 31fe: 0e 94 ec 05 call 0xbd8 ; 0xbd8 - MemoryWriteBlock(&BCC, MEM_UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE); - 3202: 41 e0 ldi r20, 0x01 ; 1 - 3204: 50 e0 ldi r21, 0x00 ; 0 - 3206: 64 e0 ldi r22, 0x04 ; 4 - 3208: 70 e0 ldi r23, 0x00 ; 0 - 320a: ce 01 movw r24, r28 - 320c: 01 96 adiw r24, 0x01 ; 1 - 320e: 0e 94 ec 05 call 0xbd8 ; 0xbd8 -} - 3212: 0f 90 pop r0 - 3214: df 91 pop r29 - 3216: cf 91 pop r28 - 3218: 08 95 ret - -0000321a : - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ - -#include "ISO14443-3A.h" - -void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { - 321a: fc 01 movw r30, r24 - uint16_t Checksum = 0x6363; - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - 321c: 61 15 cp r22, r1 - 321e: 71 05 cpc r23, r1 - 3220: 39 f1 breq .+78 ; 0x3270 - 3222: 68 0f add r22, r24 - 3224: 79 1f adc r23, r25 - */ - -#include "ISO14443-3A.h" - -void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { - uint16_t Checksum = 0x6363; - 3226: 23 e6 ldi r18, 0x63 ; 99 - 3228: 33 e6 ldi r19, 0x63 ; 99 - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - uint8_t Byte = *DataPtr++; - 322a: 41 91 ld r20, Z+ - - Byte ^= (uint8_t) (Checksum & 0x00FF); - 322c: 42 27 eor r20, r18 - Byte ^= Byte << 4; - 322e: 50 e1 ldi r21, 0x10 ; 16 - 3230: 45 9f mul r20, r21 - 3232: c0 01 movw r24, r0 - 3234: 11 24 eor r1, r1 - 3236: a4 2f mov r26, r20 - 3238: a8 27 eor r26, r24 - - Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ - 323a: 8a 2f mov r24, r26 - 323c: 90 e0 ldi r25, 0x00 ; 0 - 323e: 58 2f mov r21, r24 - 3240: 44 27 eor r20, r20 - ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); - 3242: 88 0f add r24, r24 - 3244: 99 1f adc r25, r25 - 3246: 88 0f add r24, r24 - 3248: 99 1f adc r25, r25 - 324a: 88 0f add r24, r24 - 324c: 99 1f adc r25, r25 - uint8_t Byte = *DataPtr++; - - Byte ^= (uint8_t) (Checksum & 0x00FF); - Byte ^= Byte << 4; - - Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ - 324e: 48 27 eor r20, r24 - 3250: 59 27 eor r21, r25 - 3252: 23 2f mov r18, r19 - 3254: 33 27 eor r19, r19 - 3256: 24 27 eor r18, r20 - 3258: 35 27 eor r19, r21 - ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); - 325a: a2 95 swap r26 - 325c: af 70 andi r26, 0x0F ; 15 - uint8_t Byte = *DataPtr++; - - Byte ^= (uint8_t) (Checksum & 0x00FF); - Byte ^= Byte << 4; - - Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ - 325e: 2a 27 eor r18, r26 - -void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { - uint16_t Checksum = 0x6363; - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - 3260: e6 17 cp r30, r22 - 3262: f7 07 cpc r31, r23 - 3264: 11 f7 brne .-60 ; 0x322a - 3266: 92 2f mov r25, r18 - 3268: 83 2f mov r24, r19 - - Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ - ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); - } - - *DataPtr++ = (Checksum >> 0) & 0x00FF; - 326a: 90 83 st Z, r25 - *DataPtr = (Checksum >> 8) & 0x00FF; - 326c: 81 83 std Z+1, r24 ; 0x01 - 326e: 08 95 ret - -void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { - uint16_t Checksum = 0x6363; - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - 3270: 83 e6 ldi r24, 0x63 ; 99 - 3272: 93 e6 ldi r25, 0x63 ; 99 - 3274: fa cf rjmp .-12 ; 0x326a - -00003276 : - *DataPtr++ = (Checksum >> 0) & 0x00FF; - *DataPtr = (Checksum >> 8) & 0x00FF; -} - -bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) -{ - 3276: fc 01 movw r30, r24 - uint16_t Checksum = 0x6363; - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - 3278: 61 15 cp r22, r1 - 327a: 71 05 cpc r23, r1 - 327c: a9 f1 breq .+106 ; 0x32e8 - 327e: 68 0f add r22, r24 - 3280: 79 1f adc r23, r25 - *DataPtr = (Checksum >> 8) & 0x00FF; -} - -bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) -{ - uint16_t Checksum = 0x6363; - 3282: 23 e6 ldi r18, 0x63 ; 99 - 3284: 33 e6 ldi r19, 0x63 ; 99 - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - uint8_t Byte = *DataPtr++; - 3286: 41 91 ld r20, Z+ - - Byte ^= (uint8_t) (Checksum & 0x00FF); - 3288: 42 27 eor r20, r18 - Byte ^= Byte << 4; - 328a: 50 e1 ldi r21, 0x10 ; 16 - 328c: 45 9f mul r20, r21 - 328e: c0 01 movw r24, r0 - 3290: 11 24 eor r1, r1 - 3292: a4 2f mov r26, r20 - 3294: a8 27 eor r26, r24 - - Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ - 3296: 8a 2f mov r24, r26 - 3298: 90 e0 ldi r25, 0x00 ; 0 - 329a: 58 2f mov r21, r24 - 329c: 44 27 eor r20, r20 - ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); - 329e: 88 0f add r24, r24 - 32a0: 99 1f adc r25, r25 - 32a2: 88 0f add r24, r24 - 32a4: 99 1f adc r25, r25 - 32a6: 88 0f add r24, r24 - 32a8: 99 1f adc r25, r25 - uint8_t Byte = *DataPtr++; - - Byte ^= (uint8_t) (Checksum & 0x00FF); - Byte ^= Byte << 4; - - Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ - 32aa: 48 27 eor r20, r24 - 32ac: 59 27 eor r21, r25 - 32ae: 23 2f mov r18, r19 - 32b0: 33 27 eor r19, r19 - 32b2: 24 27 eor r18, r20 - 32b4: 35 27 eor r19, r21 - ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); - 32b6: a2 95 swap r26 - 32b8: af 70 andi r26, 0x0F ; 15 - uint8_t Byte = *DataPtr++; - - Byte ^= (uint8_t) (Checksum & 0x00FF); - Byte ^= Byte << 4; - - Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ - 32ba: 2a 27 eor r18, r26 -bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) -{ - uint16_t Checksum = 0x6363; - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - 32bc: e6 17 cp r30, r22 - 32be: f7 07 cpc r31, r23 - 32c0: 11 f7 brne .-60 ; 0x3286 - 32c2: a9 01 movw r20, r18 - 32c4: 55 27 eor r21, r21 - - Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ - ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); - } - - return (DataPtr[0] == ((Checksum >> 0) & 0xFF)) && (DataPtr[1] == ((Checksum >> 8) & 0xFF)); - 32c6: 80 81 ld r24, Z - 32c8: 90 e0 ldi r25, 0x00 ; 0 - 32ca: 84 17 cp r24, r20 - 32cc: 95 07 cpc r25, r21 - 32ce: 11 f0 breq .+4 ; 0x32d4 - 32d0: 80 e0 ldi r24, 0x00 ; 0 -} - 32d2: 08 95 ret - - Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ - ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); - } - - return (DataPtr[0] == ((Checksum >> 0) & 0xFF)) && (DataPtr[1] == ((Checksum >> 8) & 0xFF)); - 32d4: 41 81 ldd r20, Z+1 ; 0x01 - 32d6: 50 e0 ldi r21, 0x00 ; 0 - 32d8: 23 2f mov r18, r19 - 32da: 33 27 eor r19, r19 - 32dc: 81 e0 ldi r24, 0x01 ; 1 - 32de: 42 17 cp r20, r18 - 32e0: 53 07 cpc r21, r19 - 32e2: b9 f3 breq .-18 ; 0x32d2 - 32e4: 80 e0 ldi r24, 0x00 ; 0 - 32e6: f5 cf rjmp .-22 ; 0x32d2 -bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) -{ - uint16_t Checksum = 0x6363; - uint8_t* DataPtr = (uint8_t*) Buffer; - - while(ByteCount--) { - 32e8: 43 e6 ldi r20, 0x63 ; 99 - 32ea: 50 e0 ldi r21, 0x00 ; 0 - *DataPtr = (Checksum >> 8) & 0x00FF; -} - -bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) -{ - uint16_t Checksum = 0x6363; - 32ec: 23 e6 ldi r18, 0x63 ; 99 - 32ee: 33 e6 ldi r19, 0x63 ; 99 - 32f0: ea cf rjmp .-44 ; 0x32c6 - -000032f2 : -/* Split Crypto1 state into even and odd bits to speed up the output filter network */ -static uint8_t StateEven[LFSR_SIZE/2] = {0}; -static uint8_t StateOdd[LFSR_SIZE/2] = {0}; - -/* Proceed LFSR by one clock cycle */ -static void Crypto1LFSR(uint8_t In) { - 32f2: cf 93 push r28 - uint8_t Feedback = 0; - - /* Calculate feedback according to LFSR taps. XOR all 6 state bytes - * into a single bit. */ - Feedback ^= StateEven[0] & (uint8_t) (LFSR_MASK_EVEN >> 0); - 32f4: b0 91 d5 24 lds r27, 0x24D5 - Feedback ^= StateEven[1] & (uint8_t) (LFSR_MASK_EVEN >> 8); - 32f8: c0 91 d6 24 lds r28, 0x24D6 - Feedback ^= StateEven[2] & (uint8_t) (LFSR_MASK_EVEN >> 16); - 32fc: 40 91 d7 24 lds r20, 0x24D7 - - Feedback ^= StateOdd[0] & (uint8_t) (LFSR_MASK_ODD >> 0); - 3300: a0 91 d2 24 lds r26, 0x24D2 - Feedback ^= StateOdd[1] & (uint8_t) (LFSR_MASK_ODD >> 8); - 3304: f0 91 d3 24 lds r31, 0x24D3 - Feedback ^= StateOdd[2] & (uint8_t) (LFSR_MASK_ODD >> 16); - 3308: e0 91 d4 24 lds r30, 0x24D4 - uint8_t Feedback = 0; - - /* Calculate feedback according to LFSR taps. XOR all 6 state bytes - * into a single bit. */ - Feedback ^= StateEven[0] & (uint8_t) (LFSR_MASK_EVEN >> 0); - Feedback ^= StateEven[1] & (uint8_t) (LFSR_MASK_EVEN >> 8); - 330c: 9c 2f mov r25, r28 - 330e: 90 71 andi r25, 0x10 ; 16 -static void Crypto1LFSR(uint8_t In) { - uint8_t Feedback = 0; - - /* Calculate feedback according to LFSR taps. XOR all 6 state bytes - * into a single bit. */ - Feedback ^= StateEven[0] & (uint8_t) (LFSR_MASK_EVEN >> 0); - 3310: 2b 2f mov r18, r27 - 3312: 21 7e andi r18, 0xE1 ; 225 - Feedback ^= StateEven[1] & (uint8_t) (LFSR_MASK_EVEN >> 8); - 3314: 92 27 eor r25, r18 - Feedback ^= StateEven[2] & (uint8_t) (LFSR_MASK_EVEN >> 16); - 3316: 24 2f mov r18, r20 - 3318: 20 72 andi r18, 0x20 ; 32 - 331a: 92 27 eor r25, r18 - - Feedback ^= StateOdd[0] & (uint8_t) (LFSR_MASK_ODD >> 0); - 331c: 2a 2f mov r18, r26 - 331e: 24 79 andi r18, 0x94 ; 148 - 3320: 92 27 eor r25, r18 - Feedback ^= StateOdd[1] & (uint8_t) (LFSR_MASK_ODD >> 8); - 3322: 2f 2f mov r18, r31 - 3324: 23 77 andi r18, 0x73 ; 115 - 3326: 92 27 eor r25, r18 - Feedback ^= StateOdd[2] & (uint8_t) (LFSR_MASK_ODD >> 16); - 3328: 2e 2f mov r18, r30 - 332a: 2a 73 andi r18, 0x3A ; 58 - 332c: 92 27 eor r25, r18 - - Feedback ^= Feedback >> 4; - 332e: 39 2f mov r19, r25 - 3330: 32 95 swap r19 - 3332: 3f 70 andi r19, 0x0F ; 15 - 3334: 39 27 eor r19, r25 - Feedback ^= Feedback >> 2; - 3336: 23 2f mov r18, r19 - 3338: 26 95 lsr r18 - 333a: 26 95 lsr r18 - 333c: 23 27 eor r18, r19 - Feedback ^= Feedback >> 1; - 333e: 92 2f mov r25, r18 - 3340: 96 95 lsr r25 - * - the new odd state becomes the old even state right-shifted by 1. - * For shifting the even state, we convert it into a 32 bit int first */ - uint32_t Temp = 0; - Temp |= ((uint32_t) StateEven[0] << 0); - Temp |= ((uint32_t) StateEven[1] << 8); - Temp |= ((uint32_t) StateEven[2] << 16); - 3342: 50 e0 ldi r21, 0x00 ; 0 - 3344: 60 e0 ldi r22, 0x00 ; 0 - 3346: 70 e0 ldi r23, 0x00 ; 0 - 3348: ba 01 movw r22, r20 - 334a: 55 27 eor r21, r21 - 334c: 44 27 eor r20, r20 - * - the new even state becomes the old odd state - * - the new odd state becomes the old even state right-shifted by 1. - * For shifting the even state, we convert it into a 32 bit int first */ - uint32_t Temp = 0; - Temp |= ((uint32_t) StateEven[0] << 0); - Temp |= ((uint32_t) StateEven[1] << 8); - 334e: 5c 2b or r21, r28 - Temp |= ((uint32_t) StateEven[2] << 16); - 3350: 4b 2b or r20, r27 - - /* Proceed LFSR. Try to force compiler not to shift the unneded upper bits. */ - Temp = (Temp >> 1) & 0x00FFFFFF; - 3352: 76 95 lsr r23 - 3354: 67 95 ror r22 - 3356: 57 95 ror r21 - 3358: 47 95 ror r20 - Feedback ^= StateOdd[1] & (uint8_t) (LFSR_MASK_ODD >> 8); - Feedback ^= StateOdd[2] & (uint8_t) (LFSR_MASK_ODD >> 16); - - Feedback ^= Feedback >> 4; - Feedback ^= Feedback >> 2; - Feedback ^= Feedback >> 1; - 335a: 92 27 eor r25, r18 - - /* Proceed LFSR. Try to force compiler not to shift the unneded upper bits. */ - Temp = (Temp >> 1) & 0x00FFFFFF; - - /* Calculate MSBit of even state as input bit to LFSR */ - if ( (Feedback & 0x01) ^ In ) { - 335c: 91 70 andi r25, 0x01 ; 1 - 335e: 98 13 cpse r25, r24 - Temp |= (uint32_t) 1 << (8 * LFSR_SIZE/2 - 1); - 3360: 60 68 ori r22, 0x80 ; 128 - } - - /* Convert even state back into byte array and swap odd/even state - * as explained above. */ - StateEven[0] = StateOdd[0]; - 3362: a0 93 d5 24 sts 0x24D5, r26 - StateEven[1] = StateOdd[1]; - 3366: f0 93 d6 24 sts 0x24D6, r31 - StateEven[2] = StateOdd[2]; - 336a: e0 93 d7 24 sts 0x24D7, r30 - - StateOdd[0] = (uint8_t) (Temp >> 0); - 336e: 40 93 d2 24 sts 0x24D2, r20 - StateOdd[1] = (uint8_t) (Temp >> 8); - 3372: 50 93 d3 24 sts 0x24D3, r21 - StateOdd[2] = (uint8_t) (Temp >> 16); - 3376: 60 93 d4 24 sts 0x24D4, r22 -} - 337a: cf 91 pop r28 - 337c: 08 95 ret - -0000337e : - -uint8_t Crypto1FilterOutput(void) { - 337e: cf 93 push r28 - 3380: df 93 push r29 - * 5 bits that are used to lookup the output bit. - */ - uint8_t Sum = 0; - - Sum |= TableAB[0][(StateOdd[0] >> 4) & 0x0F]; - Sum |= TableAB[1][(StateOdd[1] >> 0) & 0x0F]; - 3382: a0 91 d3 24 lds r26, 0x24D3 - 3386: ea 2f mov r30, r26 - 3388: ef 70 andi r30, 0x0F ; 15 - 338a: f0 e0 ldi r31, 0x00 ; 0 - 338c: e0 5c subi r30, 0xC0 ; 192 - 338e: ff 4d sbci r31, 0xDF ; 223 - * can simply be ORed together to produce the resulting - * 5 bits that are used to lookup the output bit. - */ - uint8_t Sum = 0; - - Sum |= TableAB[0][(StateOdd[0] >> 4) & 0x0F]; - 3390: c0 91 d2 24 lds r28, 0x24D2 - 3394: c2 95 swap r28 - 3396: cf 70 andi r28, 0x0F ; 15 - 3398: d0 e0 ldi r29, 0x00 ; 0 - 339a: c0 5c subi r28, 0xC0 ; 192 - 339c: df 4d sbci r29, 0xDF ; 223 - Sum |= TableAB[1][(StateOdd[1] >> 0) & 0x0F]; - 339e: e0 89 ldd r30, Z+16 ; 0x10 - 33a0: 88 81 ld r24, Y - 33a2: e8 2b or r30, r24 - Sum |= TableAB[2][(StateOdd[1] >> 4) & 0x0F]; - 33a4: a2 95 swap r26 - 33a6: af 70 andi r26, 0x0F ; 15 - 33a8: b0 e0 ldi r27, 0x00 ; 0 - 33aa: a0 5c subi r26, 0xC0 ; 192 - 33ac: bf 4d sbci r27, 0xDF ; 223 - 33ae: 90 96 adiw r26, 0x20 ; 32 - 33b0: 8c 91 ld r24, X - 33b2: e8 2b or r30, r24 - Sum |= TableAB[3][(StateOdd[2] >> 0) & 0x0F]; - 33b4: a0 91 d4 24 lds r26, 0x24D4 - 33b8: ca 2f mov r28, r26 - 33ba: cf 70 andi r28, 0x0F ; 15 - 33bc: d0 e0 ldi r29, 0x00 ; 0 - 33be: c0 5c subi r28, 0xC0 ; 192 - 33c0: df 4d sbci r29, 0xDF ; 223 - 33c2: 88 a9 ldd r24, Y+48 ; 0x30 - 33c4: e8 2b or r30, r24 - Sum |= TableAB[4][(StateOdd[2] >> 4) & 0x0F]; - 33c6: a2 95 swap r26 - 33c8: af 70 andi r26, 0x0F ; 15 - 33ca: b0 e0 ldi r27, 0x00 ; 0 - 33cc: a0 58 subi r26, 0x80 ; 128 - 33ce: bf 4d sbci r27, 0xDF ; 223 - 33d0: 8c 91 ld r24, X - 33d2: e8 2b or r30, r24 - - return TableC[Sum]; - 33d4: f0 e0 ldi r31, 0x00 ; 0 - 33d6: e0 5e subi r30, 0xE0 ; 224 - 33d8: ff 4d sbci r31, 0xDF ; 223 -} - 33da: 80 81 ld r24, Z - 33dc: df 91 pop r29 - 33de: cf 91 pop r28 - 33e0: 08 95 ret - -000033e2 : - -void Crypto1Setup(uint8_t Key[6], uint8_t Uid[4], uint8_t CardNonce[4]) -{ - 33e2: af 92 push r10 - 33e4: bf 92 push r11 - 33e6: cf 92 push r12 - 33e8: df 92 push r13 - 33ea: ef 92 push r14 - 33ec: ff 92 push r15 - 33ee: 0f 93 push r16 - 33f0: 1f 93 push r17 - 33f2: cf 93 push r28 - 33f4: df 93 push r29 - 33f6: 5b 01 movw r10, r22 - 33f8: ea 01 movw r28, r20 - 33fa: dc 01 movw r26, r24 - 33fc: 11 96 adiw r26, 0x01 ; 1 - 33fe: 45 ed ldi r20, 0xD5 ; 213 - 3400: 54 e2 ldi r21, 0x24 ; 36 - 3402: 62 ed ldi r22, 0xD2 ; 210 - 3404: 74 e2 ldi r23, 0x24 ; 36 - 3406: cd 01 movw r24, r26 - 3408: 01 97 sbiw r24, 0x01 ; 1 - * The inner loop generates 8 even and 8 odd bits from 16 key bits and - * the outer loop stores them. */ - for (i=0; i<(LFSR_SIZE/2); i++) { - uint8_t EvenByte = 0; - uint8_t OddByte = 0; - uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; - 340a: fc 01 movw r30, r24 - 340c: 20 81 ld r18, Z - 340e: 8c 91 ld r24, X - 3410: 30 e0 ldi r19, 0x00 ; 0 - 3412: 38 2b or r19, r24 - 3414: 20 ff sbrs r18, 0 - 3416: b0 c0 rjmp .+352 ; 0x3578 - 3418: 00 e4 ldi r16, 0x40 ; 64 - 341a: 21 ff sbrs r18, 1 - 341c: ab c0 rjmp .+342 ; 0x3574 - 341e: 10 e4 ldi r17, 0x40 ; 64 - - if (KeyWord & (1<<1)) { - OddByte |= 0x80; - } - - KeyWord >>= 2; - 3420: c9 01 movw r24, r18 - 3422: 96 95 lsr r25 - 3424: 87 95 ror r24 - 3426: 96 95 lsr r25 - 3428: 87 95 ror r24 - for (j=0; j<8; j++) { - EvenByte >>= 1; - OddByte >>= 1; - - if (KeyWord & (1<<0)) { - EvenByte |= 0x80; - 342a: 30 2f mov r19, r16 - 342c: 30 68 ori r19, 0x80 ; 128 - 342e: 80 ff sbrs r24, 0 - 3430: 30 2f mov r19, r16 - } - - if (KeyWord & (1<<1)) { - OddByte |= 0x80; - 3432: 21 2f mov r18, r17 - 3434: 20 68 ori r18, 0x80 ; 128 - 3436: 81 ff sbrs r24, 1 - 3438: 21 2f mov r18, r17 - } - - KeyWord >>= 2; - 343a: 96 95 lsr r25 - 343c: 87 95 ror r24 - 343e: 96 95 lsr r25 - 3440: 87 95 ror r24 - uint8_t OddByte = 0; - uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; - uint8_t j; - - for (j=0; j<8; j++) { - EvenByte >>= 1; - 3442: 36 95 lsr r19 - OddByte >>= 1; - 3444: 26 95 lsr r18 - - if (KeyWord & (1<<0)) { - EvenByte |= 0x80; - 3446: 13 2f mov r17, r19 - 3448: 10 68 ori r17, 0x80 ; 128 - 344a: 80 fd sbrc r24, 0 - 344c: 31 2f mov r19, r17 - } - - if (KeyWord & (1<<1)) { - OddByte |= 0x80; - 344e: 12 2f mov r17, r18 - 3450: 10 68 ori r17, 0x80 ; 128 - 3452: 81 fd sbrc r24, 1 - 3454: 21 2f mov r18, r17 - } - - KeyWord >>= 2; - 3456: 96 95 lsr r25 - 3458: 87 95 ror r24 - 345a: 96 95 lsr r25 - 345c: 87 95 ror r24 - uint8_t OddByte = 0; - uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; - uint8_t j; - - for (j=0; j<8; j++) { - EvenByte >>= 1; - 345e: 36 95 lsr r19 - OddByte >>= 1; - 3460: 26 95 lsr r18 - - if (KeyWord & (1<<0)) { - EvenByte |= 0x80; - 3462: 13 2f mov r17, r19 - 3464: 10 68 ori r17, 0x80 ; 128 - 3466: 80 fd sbrc r24, 0 - 3468: 31 2f mov r19, r17 - } - - if (KeyWord & (1<<1)) { - OddByte |= 0x80; - 346a: 12 2f mov r17, r18 - 346c: 10 68 ori r17, 0x80 ; 128 - 346e: 81 fd sbrc r24, 1 - 3470: 21 2f mov r18, r17 - } - - KeyWord >>= 2; - 3472: 96 95 lsr r25 - 3474: 87 95 ror r24 - 3476: 96 95 lsr r25 - 3478: 87 95 ror r24 - uint8_t OddByte = 0; - uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; - uint8_t j; - - for (j=0; j<8; j++) { - EvenByte >>= 1; - 347a: 36 95 lsr r19 - OddByte >>= 1; - 347c: 26 95 lsr r18 - - if (KeyWord & (1<<0)) { - EvenByte |= 0x80; - 347e: 13 2f mov r17, r19 - 3480: 10 68 ori r17, 0x80 ; 128 - 3482: 80 fd sbrc r24, 0 - 3484: 31 2f mov r19, r17 - } - - if (KeyWord & (1<<1)) { - OddByte |= 0x80; - 3486: 12 2f mov r17, r18 - 3488: 10 68 ori r17, 0x80 ; 128 - 348a: 81 fd sbrc r24, 1 - 348c: 21 2f mov r18, r17 - } - - KeyWord >>= 2; - 348e: 96 95 lsr r25 - 3490: 87 95 ror r24 - 3492: 96 95 lsr r25 - 3494: 87 95 ror r24 - uint8_t OddByte = 0; - uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; - uint8_t j; - - for (j=0; j<8; j++) { - EvenByte >>= 1; - 3496: 36 95 lsr r19 - OddByte >>= 1; - 3498: 26 95 lsr r18 - - if (KeyWord & (1<<0)) { - EvenByte |= 0x80; - 349a: 13 2f mov r17, r19 - 349c: 10 68 ori r17, 0x80 ; 128 - 349e: 80 fd sbrc r24, 0 - 34a0: 31 2f mov r19, r17 - } - - if (KeyWord & (1<<1)) { - OddByte |= 0x80; - 34a2: 12 2f mov r17, r18 - 34a4: 10 68 ori r17, 0x80 ; 128 - 34a6: 81 fd sbrc r24, 1 - 34a8: 21 2f mov r18, r17 - } - - KeyWord >>= 2; - 34aa: 96 95 lsr r25 - 34ac: 87 95 ror r24 - 34ae: 96 95 lsr r25 - 34b0: 87 95 ror r24 - uint8_t OddByte = 0; - uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; - uint8_t j; - - for (j=0; j<8; j++) { - EvenByte >>= 1; - 34b2: 36 95 lsr r19 - OddByte >>= 1; - 34b4: 26 95 lsr r18 - - if (KeyWord & (1<<0)) { - EvenByte |= 0x80; - 34b6: 13 2f mov r17, r19 - 34b8: 10 68 ori r17, 0x80 ; 128 - 34ba: 80 fd sbrc r24, 0 - 34bc: 31 2f mov r19, r17 - } - - if (KeyWord & (1<<1)) { - OddByte |= 0x80; - 34be: 12 2f mov r17, r18 - 34c0: 10 68 ori r17, 0x80 ; 128 - 34c2: 81 fd sbrc r24, 1 - 34c4: 21 2f mov r18, r17 - } - - KeyWord >>= 2; - 34c6: 96 95 lsr r25 - 34c8: 87 95 ror r24 - 34ca: 96 95 lsr r25 - 34cc: 87 95 ror r24 - uint8_t OddByte = 0; - uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; - uint8_t j; - - for (j=0; j<8; j++) { - EvenByte >>= 1; - 34ce: 36 95 lsr r19 - OddByte >>= 1; - 34d0: 26 95 lsr r18 - - if (KeyWord & (1<<0)) { - EvenByte |= 0x80; - 34d2: 03 2f mov r16, r19 - 34d4: 00 68 ori r16, 0x80 ; 128 - } - - if (KeyWord & (1<<1)) { - OddByte |= 0x80; - 34d6: 12 2f mov r17, r18 - 34d8: 10 68 ori r17, 0x80 ; 128 - 34da: 80 fd sbrc r24, 0 - 34dc: 30 2f mov r19, r16 - } - - KeyWord >>= 2; - } - - StateEven[i] = EvenByte; - 34de: fa 01 movw r30, r20 - 34e0: 31 93 st Z+, r19 - 34e2: af 01 movw r20, r30 - 34e4: 81 fd sbrc r24, 1 - 34e6: 21 2f mov r18, r17 - StateOdd[i] = OddByte; - 34e8: fb 01 movw r30, r22 - 34ea: 21 93 st Z+, r18 - 34ec: bf 01 movw r22, r30 - 34ee: 12 96 adiw r26, 0x02 ; 2 - - /* Again, one trade off when splitting up the state into even/odd parts - * is that loading the key into the state becomes a little more difficult. - * The inner loop generates 8 even and 8 odd bits from 16 key bits and - * the outer loop stores them. */ - for (i=0; i<(LFSR_SIZE/2); i++) { - 34f0: f4 e2 ldi r31, 0x24 ; 36 - 34f2: 48 3d cpi r20, 0xD8 ; 216 - 34f4: 5f 07 cpc r21, r31 - 34f6: 09 f0 breq .+2 ; 0x34fa - 34f8: 86 cf rjmp .-244 ; 0x3406 - /* Use Uid XOR CardNonce as feed-in and do 32 clocks on the - * Crypto1 LFSR.*/ - uint32_t Temp = 0; - - Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; - Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; - 34fa: f5 01 movw r30, r10 - 34fc: 81 81 ldd r24, Z+1 ; 0x01 - 34fe: 99 81 ldd r25, Y+1 ; 0x01 - 3500: 89 27 eor r24, r25 - Temp |= (uint32_t) (Uid[2] ^ CardNonce[2]) << 16; - 3502: c2 80 ldd r12, Z+2 ; 0x02 - 3504: 9a 81 ldd r25, Y+2 ; 0x02 - 3506: c9 26 eor r12, r25 - 3508: d1 2c mov r13, r1 - 350a: e1 2c mov r14, r1 - 350c: f1 2c mov r15, r1 - 350e: 76 01 movw r14, r12 - 3510: dd 24 eor r13, r13 - 3512: cc 24 eor r12, r12 - /* Use Uid XOR CardNonce as feed-in and do 32 clocks on the - * Crypto1 LFSR.*/ - uint32_t Temp = 0; - - Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; - Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; - 3514: d8 2a or r13, r24 - - /* Use Uid XOR CardNonce as feed-in and do 32 clocks on the - * Crypto1 LFSR.*/ - uint32_t Temp = 0; - - Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; - 3516: 80 81 ld r24, Z - 3518: 98 81 ld r25, Y - 351a: 89 27 eor r24, r25 - Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; - Temp |= (uint32_t) (Uid[2] ^ CardNonce[2]) << 16; - 351c: c8 2a or r12, r24 - Temp |= (uint32_t) (Uid[3] ^ CardNonce[3]) << 24; - 351e: 83 81 ldd r24, Z+3 ; 0x03 - 3520: 9b 81 ldd r25, Y+3 ; 0x03 - 3522: 89 27 eor r24, r25 - 3524: f8 2a or r15, r24 - 3526: 10 e2 ldi r17, 0x20 ; 32 - - for (i=0; i<32; i++) { - uint8_t Out = Crypto1FilterOutput(); - 3528: 2a df rcall .-428 ; 0x337e - 352a: 08 2f mov r16, r24 - - Crypto1LFSR(Temp & 0x01); - 352c: 8c 2d mov r24, r12 - 352e: 81 70 andi r24, 0x01 ; 1 - 3530: e0 de rcall .-576 ; 0x32f2 - Temp >>= 1; - 3532: f6 94 lsr r15 - 3534: e7 94 ror r14 - 3536: d7 94 ror r13 - 3538: c7 94 ror r12 - - /* Store the keystream for later use */ - if (Out) { - 353a: 00 23 and r16, r16 - 353c: 11 f0 breq .+4 ; 0x3542 - Temp |= (uint32_t) 1 << 31; - 353e: 68 94 set - 3540: f7 f8 bld r15, 7 - 3542: 11 50 subi r17, 0x01 ; 1 - Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; - Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; - Temp |= (uint32_t) (Uid[2] ^ CardNonce[2]) << 16; - Temp |= (uint32_t) (Uid[3] ^ CardNonce[3]) << 24; - - for (i=0; i<32; i++) { - 3544: 89 f7 brne .-30 ; 0x3528 - } - - /* Crypto1 state register is now set up to be used for authentication. - * In case of nested authentication, we need to use the produced keystream - * to encrypt the CardNonce. For this case we do the encryption in-place. */ - CardNonce[0] ^= (uint8_t) (Temp >> 0); - 3546: 88 81 ld r24, Y - 3548: 8c 25 eor r24, r12 - 354a: 88 83 st Y, r24 - CardNonce[1] ^= (uint8_t) (Temp >> 8); - 354c: 89 81 ldd r24, Y+1 ; 0x01 - 354e: 8d 25 eor r24, r13 - 3550: 89 83 std Y+1, r24 ; 0x01 - CardNonce[2] ^= (uint8_t) (Temp >> 16); - 3552: 8a 81 ldd r24, Y+2 ; 0x02 - 3554: 8e 25 eor r24, r14 - 3556: 8a 83 std Y+2, r24 ; 0x02 - CardNonce[3] ^= (uint8_t) (Temp >> 24); - 3558: 8b 81 ldd r24, Y+3 ; 0x03 - 355a: 8f 25 eor r24, r15 - 355c: 8b 83 std Y+3, r24 ; 0x03 -} - 355e: df 91 pop r29 - 3560: cf 91 pop r28 - 3562: 1f 91 pop r17 - 3564: 0f 91 pop r16 - 3566: ff 90 pop r15 - 3568: ef 90 pop r14 - 356a: df 90 pop r13 - 356c: cf 90 pop r12 - 356e: bf 90 pop r11 - 3570: af 90 pop r10 - 3572: 08 95 ret - 3574: 10 e0 ldi r17, 0x00 ; 0 - 3576: 54 cf rjmp .-344 ; 0x3420 - 3578: 00 e0 ldi r16, 0x00 ; 0 - 357a: 4f cf rjmp .-354 ; 0x341a - -0000357c : - -void Crypto1Auth(uint8_t EncryptedReaderNonce[4]) -{ - 357c: cf 92 push r12 - 357e: df 92 push r13 - 3580: ef 92 push r14 - 3582: ff 92 push r15 - 3584: cf 93 push r28 - 3586: fc 01 movw r30, r24 - uint32_t Temp = 0; - - /* For ease of processing, we convert the encrypted reader nonce - * into a 32 bit integer */ - Temp |= (uint32_t) EncryptedReaderNonce[0] << 0; - Temp |= (uint32_t) EncryptedReaderNonce[1] << 8; - 3588: 81 81 ldd r24, Z+1 ; 0x01 - Temp |= (uint32_t) EncryptedReaderNonce[2] << 16; - 358a: c2 80 ldd r12, Z+2 ; 0x02 - 358c: d1 2c mov r13, r1 - 358e: e1 2c mov r14, r1 - 3590: f1 2c mov r15, r1 - 3592: 76 01 movw r14, r12 - 3594: dd 24 eor r13, r13 - 3596: cc 24 eor r12, r12 - uint32_t Temp = 0; - - /* For ease of processing, we convert the encrypted reader nonce - * into a 32 bit integer */ - Temp |= (uint32_t) EncryptedReaderNonce[0] << 0; - Temp |= (uint32_t) EncryptedReaderNonce[1] << 8; - 3598: d8 2a or r13, r24 -{ - uint32_t Temp = 0; - - /* For ease of processing, we convert the encrypted reader nonce - * into a 32 bit integer */ - Temp |= (uint32_t) EncryptedReaderNonce[0] << 0; - 359a: 80 81 ld r24, Z - Temp |= (uint32_t) EncryptedReaderNonce[1] << 8; - Temp |= (uint32_t) EncryptedReaderNonce[2] << 16; - 359c: c8 2a or r12, r24 - Temp |= (uint32_t) EncryptedReaderNonce[3] << 24; - 359e: 83 81 ldd r24, Z+3 ; 0x03 - 35a0: f8 2a or r15, r24 - 35a2: c0 e2 ldi r28, 0x20 ; 32 - uint8_t i; - - for (i=0; i<32; i++) { - /* Decrypt one output bit of the given encrypted nonce using the - * filter output as keystream. */ - uint8_t Out = Crypto1FilterOutput(); - 35a4: ec de rcall .-552 ; 0x337e - uint8_t Bit = Out ^ (Temp & 0x01); - 35a6: 9c 2d mov r25, r12 - 35a8: 91 70 andi r25, 0x01 ; 1 - - /* Feed back the bit to load the LFSR with the (decrypted) nonce */ - Crypto1LFSR(Bit); - 35aa: 89 27 eor r24, r25 - 35ac: a2 de rcall .-700 ; 0x32f2 - Temp >>= 1; - 35ae: f6 94 lsr r15 - 35b0: e7 94 ror r14 - 35b2: d7 94 ror r13 - 35b4: c7 94 ror r12 - 35b6: c1 50 subi r28, 0x01 ; 1 - Temp |= (uint32_t) EncryptedReaderNonce[2] << 16; - Temp |= (uint32_t) EncryptedReaderNonce[3] << 24; - - uint8_t i; - - for (i=0; i<32; i++) { - 35b8: a9 f7 brne .-22 ; 0x35a4 - - /* Feed back the bit to load the LFSR with the (decrypted) nonce */ - Crypto1LFSR(Bit); - Temp >>= 1; - } -} - 35ba: cf 91 pop r28 - 35bc: ff 90 pop r15 - 35be: ef 90 pop r14 - 35c0: df 90 pop r13 - 35c2: cf 90 pop r12 - 35c4: 08 95 ret - -000035c6 : - -uint8_t Crypto1Byte(void) -{ - 35c6: 1f 93 push r17 - 35c8: cf 93 push r28 - 35ca: df 93 push r29 - 35cc: d8 e0 ldi r29, 0x08 ; 8 - uint8_t KeyStream = 0; - 35ce: c0 e0 ldi r28, 0x00 ; 0 - /* Generate 8 keystream-bits */ - for (i=0; i<8; i++) { - - /* Calculate output of function-network and cycle LFSR with no - * additional input, thus linearly! */ - uint8_t Out = Crypto1FilterOutput(); - 35d0: d6 de rcall .-596 ; 0x337e - 35d2: 18 2f mov r17, r24 - Crypto1LFSR(0); - 35d4: 80 e0 ldi r24, 0x00 ; 0 - 35d6: 8d de rcall .-742 ; 0x32f2 - - /* Store keystream bit */ - KeyStream >>= 1; - 35d8: c6 95 lsr r28 - - if (Out) { - 35da: 11 11 cpse r17, r1 - KeyStream |= (1<<7); - 35dc: c0 68 ori r28, 0x80 ; 128 - 35de: d1 50 subi r29, 0x01 ; 1 -{ - uint8_t KeyStream = 0; - uint8_t i; - - /* Generate 8 keystream-bits */ - for (i=0; i<8; i++) { - 35e0: b9 f7 brne .-18 ; 0x35d0 - KeyStream |= (1<<7); - } - } - - return KeyStream; -} - 35e2: 8c 2f mov r24, r28 - 35e4: df 91 pop r29 - 35e6: cf 91 pop r28 - 35e8: 1f 91 pop r17 - 35ea: 08 95 ret - -000035ec : - -uint8_t Crypto1Nibble(void) -{ - 35ec: 1f 93 push r17 - 35ee: cf 93 push r28 - 35f0: df 93 push r29 - 35f2: d4 e0 ldi r29, 0x04 ; 4 - uint8_t KeyStream = 0; - 35f4: c0 e0 ldi r28, 0x00 ; 0 - /* Generate 4 keystream-bits */ - for (i=0; i<4; i++) { - - /* Calculate output of function-network and cycle LFSR with no - * additional input, thus linearly! */ - uint8_t Out = Crypto1FilterOutput(); - 35f6: c3 de rcall .-634 ; 0x337e - 35f8: 18 2f mov r17, r24 - Crypto1LFSR(0); - 35fa: 80 e0 ldi r24, 0x00 ; 0 - 35fc: 7a de rcall .-780 ; 0x32f2 - - /* Store keystream bit */ - KeyStream >>= 1; - 35fe: c6 95 lsr r28 - - if (Out) { - 3600: 11 11 cpse r17, r1 - KeyStream |= (1<<3); - 3602: c8 60 ori r28, 0x08 ; 8 - 3604: d1 50 subi r29, 0x01 ; 1 -{ - uint8_t KeyStream = 0; - uint8_t i; - - /* Generate 4 keystream-bits */ - for (i=0; i<4; i++) { - 3606: b9 f7 brne .-18 ; 0x35f6 - KeyStream |= (1<<3); - } - } - - return KeyStream; -} - 3608: 8c 2f mov r24, r28 - 360a: df 91 pop r29 - 360c: cf 91 pop r28 - 360e: 1f 91 pop r17 - 3610: 08 95 ret - -00003612 : - -void Crypto1PRNG(uint8_t State[4], uint16_t ClockCount) -{ - 3612: 8f 92 push r8 - 3614: 9f 92 push r9 - 3616: af 92 push r10 - 3618: bf 92 push r11 - 361a: cf 92 push r12 - 361c: df 92 push r13 - 361e: ef 92 push r14 - 3620: ff 92 push r15 - 3622: 0f 93 push r16 - 3624: 1f 93 push r17 - 3626: fc 01 movw r30, r24 - while(ClockCount--) { - 3628: cb 01 movw r24, r22 - 362a: 01 97 sbiw r24, 0x01 ; 1 - 362c: 67 2b or r22, r23 - 362e: b1 f1 breq .+108 ; 0x369c - 3630: b2 81 ldd r27, Z+2 ; 0x02 - 3632: a0 81 ld r26, Z - 3634: 81 80 ldd r8, Z+1 ; 0x01 - 3636: 03 81 ldd r16, Z+3 ; 0x03 - 3638: 02 c0 rjmp .+4 ; 0x363e - 363a: a4 2f mov r26, r20 - 363c: bc 2d mov r27, r12 - * XOR all tapped bits to a single feedback bit. */ - uint8_t Feedback = 0; - - Feedback ^= State[0] & (uint8_t) (PRNG_MASK >> 0); - Feedback ^= State[1] & (uint8_t) (PRNG_MASK >> 8); - Feedback ^= State[2] & (uint8_t) (PRNG_MASK >> 16); - 363e: 2b 2f mov r18, r27 - 3640: 2d 72 andi r18, 0x2D ; 45 - Feedback ^= State[3] & (uint8_t) (PRNG_MASK >> 24); - - Feedback ^= Feedback >> 4; - 3642: 32 2f mov r19, r18 - 3644: 32 95 swap r19 - 3646: 3f 70 andi r19, 0x0F ; 15 - 3648: 32 27 eor r19, r18 - Feedback ^= Feedback >> 2; - 364a: 23 2f mov r18, r19 - 364c: 26 95 lsr r18 - 364e: 26 95 lsr r18 - 3650: 23 27 eor r18, r19 - Feedback ^= Feedback >> 1; - 3652: 32 2f mov r19, r18 - 3654: 36 95 lsr r19 - uint32_t Temp = 0; - - Temp |= (uint32_t) State[0] << 0; - Temp |= (uint32_t) State[1] << 8; - Temp |= (uint32_t) State[2] << 16; - Temp |= (uint32_t) State[3] << 24; - 3656: 40 2f mov r20, r16 - 3658: 50 e0 ldi r21, 0x00 ; 0 - 365a: 60 e0 ldi r22, 0x00 ; 0 - 365c: 70 e0 ldi r23, 0x00 ; 0 - 365e: 74 2f mov r23, r20 - 3660: 66 27 eor r22, r22 - 3662: 55 27 eor r21, r21 - 3664: 44 27 eor r20, r20 - - /* For ease of processing convert the state into a 32 bit integer first */ - uint32_t Temp = 0; - - Temp |= (uint32_t) State[0] << 0; - Temp |= (uint32_t) State[1] << 8; - 3666: 58 29 or r21, r8 - Temp |= (uint32_t) State[2] << 16; - 3668: 4a 2b or r20, r26 - Temp |= (uint32_t) State[3] << 24; - 366a: 6b 2b or r22, r27 - - /* Cycle LFSR and feed back. */ - Temp >>= 1; - 366c: 76 95 lsr r23 - 366e: 67 95 ror r22 - 3670: 57 95 ror r21 - 3672: 47 95 ror r20 - Feedback ^= State[2] & (uint8_t) (PRNG_MASK >> 16); - Feedback ^= State[3] & (uint8_t) (PRNG_MASK >> 24); - - Feedback ^= Feedback >> 4; - Feedback ^= Feedback >> 2; - Feedback ^= Feedback >> 1; - 3674: 32 27 eor r19, r18 - Temp |= (uint32_t) State[3] << 24; - - /* Cycle LFSR and feed back. */ - Temp >>= 1; - - if (Feedback & 0x01) { - 3676: 30 fd sbrc r19, 0 - Temp |= (uint32_t) 1 << (8 * PRNG_SIZE - 1); - 3678: 70 68 ori r23, 0x80 ; 128 - } - - /* Store back state */ - State[0] = (uint8_t) (Temp >> 0); - State[1] = (uint8_t) (Temp >> 8); - 367a: 85 2e mov r8, r21 - 367c: 96 2e mov r9, r22 - 367e: a7 2e mov r10, r23 - 3680: bb 24 eor r11, r11 - State[2] = (uint8_t) (Temp >> 16); - 3682: 6b 01 movw r12, r22 - 3684: ee 24 eor r14, r14 - 3686: ff 24 eor r15, r15 - State[3] = (uint8_t) (Temp >> 24); - 3688: 07 2f mov r16, r23 - 368a: 11 27 eor r17, r17 - 368c: 22 27 eor r18, r18 - 368e: 33 27 eor r19, r19 - return KeyStream; -} - -void Crypto1PRNG(uint8_t State[4], uint16_t ClockCount) -{ - while(ClockCount--) { - 3690: 01 97 sbiw r24, 0x01 ; 1 - 3692: 98 f6 brcc .-90 ; 0x363a - 3694: 40 83 st Z, r20 - 3696: 81 82 std Z+1, r8 ; 0x01 - 3698: c2 82 std Z+2, r12 ; 0x02 - 369a: 03 83 std Z+3, r16 ; 0x03 - State[2] = (uint8_t) (Temp >> 16); - State[3] = (uint8_t) (Temp >> 24); - } - - -} - 369c: 1f 91 pop r17 - 369e: 0f 91 pop r16 - 36a0: ff 90 pop r15 - 36a2: ef 90 pop r14 - 36a4: df 90 pop r13 - 36a6: cf 90 pop r12 - 36a8: bf 90 pop r11 - 36aa: af 90 pop r10 - 36ac: 9f 90 pop r9 - 36ae: 8f 90 pop r8 - 36b0: 08 95 ret - -000036b2 : -#if !defined(NO_DEVICE_REMOTE_WAKEUP) -bool USB_Device_RemoteWakeupEnabled; -#endif - -void USB_Device_ProcessControlRequest(void) -{ - 36b2: 0f 93 push r16 - 36b4: 1f 93 push r17 - 36b6: cf 93 push r28 - 36b8: df 93 push r29 - 36ba: cd b7 in r28, 0x3d ; 61 - 36bc: de b7 in r29, 0x3e ; 62 - 36be: ea 97 sbiw r28, 0x3a ; 58 - 36c0: cd bf out 0x3d, r28 ; 61 - 36c2: de bf out 0x3e, r29 ; 62 - 36c4: 05 e1 ldi r16, 0x15 ; 21 - 36c6: 17 e2 ldi r17, 0x27 ; 39 - USB_ControlRequest.wLength = Endpoint_Read_16_LE(); - #else - uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest; - - for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++) - *(RequestHeader++) = Endpoint_Read_8(); - 36c8: f7 d2 rcall .+1518 ; 0x3cb8 - 36ca: f8 01 movw r30, r16 - 36cc: 81 93 st Z+, r24 - 36ce: 8f 01 movw r16, r30 - USB_ControlRequest.wIndex = Endpoint_Read_16_LE(); - USB_ControlRequest.wLength = Endpoint_Read_16_LE(); - #else - uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest; - - for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++) - 36d0: f7 e2 ldi r31, 0x27 ; 39 - 36d2: 0d 31 cpi r16, 0x1D ; 29 - 36d4: 1f 07 cpc r17, r31 - 36d6: c1 f7 brne .-16 ; 0x36c8 - *(RequestHeader++) = Endpoint_Read_8(); - #endif - - EVENT_USB_Device_ControlRequest(); - 36d8: 0e 94 10 0d call 0x1a20 ; 0x1a20 - - if (Endpoint_IsSETUPReceived()) - 36dc: 6b d3 rcall .+1750 ; 0x3db4 - 36de: 88 23 and r24, r24 - 36e0: 49 f0 breq .+18 ; 0x36f4 - { - uint8_t bmRequestType = USB_ControlRequest.bmRequestType; - 36e2: 30 91 15 27 lds r19, 0x2715 - - switch (USB_ControlRequest.bRequest) - 36e6: 20 91 16 27 lds r18, 0x2716 - 36ea: 82 2f mov r24, r18 - 36ec: 90 e0 ldi r25, 0x00 ; 0 - 36ee: 8a 30 cpi r24, 0x0A ; 10 - 36f0: 91 05 cpc r25, r1 - 36f2: 68 f0 brcs .+26 ; 0x370e - default: - break; - } - } - - if (Endpoint_IsSETUPReceived()) - 36f4: 5f d3 rcall .+1726 ; 0x3db4 - 36f6: 88 23 and r24, r24 - 36f8: 11 f0 breq .+4 ; 0x36fe - { - Endpoint_ClearSETUP(); - 36fa: 75 d3 rcall .+1770 ; 0x3de6 - Endpoint_StallTransaction(); - 36fc: a0 d3 rcall .+1856 ; 0x3e3e - } -} - 36fe: ea 96 adiw r28, 0x3a ; 58 - 3700: cd bf out 0x3d, r28 ; 61 - 3702: de bf out 0x3e, r29 ; 62 - 3704: df 91 pop r29 - 3706: cf 91 pop r28 - 3708: 1f 91 pop r17 - 370a: 0f 91 pop r16 - 370c: 08 95 ret - - if (Endpoint_IsSETUPReceived()) - { - uint8_t bmRequestType = USB_ControlRequest.bmRequestType; - - switch (USB_ControlRequest.bRequest) - 370e: fc 01 movw r30, r24 - 3710: e4 5e subi r30, 0xE4 ; 228 - 3712: fe 4f sbci r31, 0xFE ; 254 - 3714: de c7 rjmp .+4028 ; 0x46d2 <__tablejump2__> - if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) - USB_Device_GetConfiguration(); - - break; - case REQ_SetConfiguration: - if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) - 3716: 31 11 cpse r19, r1 - 3718: ed cf rjmp .-38 ; 0x36f4 -} - -static void USB_Device_SetConfiguration(void) -{ - #if defined(FIXED_NUM_CONFIGURATIONS) - if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS) - 371a: 80 91 17 27 lds r24, 0x2717 - 371e: 82 30 cpi r24, 0x02 ; 2 - 3720: 48 f7 brcc .-46 ; 0x36f4 - if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations) - return; - #endif - #endif - - Endpoint_ClearSETUP(); - 3722: 61 d3 rcall .+1730 ; 0x3de6 - - USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue; - 3724: 80 91 17 27 lds r24, 0x2717 - 3728: 80 93 10 27 sts 0x2710, r24 - - Endpoint_ClearStatusStage(); - 372c: 93 d4 rcall .+2342 ; 0x4054 - - if (USB_Device_ConfigurationNumber) - 372e: 80 91 10 27 lds r24, 0x2710 - 3732: 88 23 and r24, r24 - 3734: 09 f4 brne .+2 ; 0x3738 - 3736: d1 c0 rjmp .+418 ; 0x38da - USB_DeviceState = DEVICE_STATE_Configured; - 3738: 84 e0 ldi r24, 0x04 ; 4 - 373a: 80 93 14 27 sts 0x2714, r24 - else - USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered; - - EVENT_USB_Device_ConfigurationChanged(); - 373e: 0e 94 0c 0d call 0x1a18 ; 0x1a18 - 3742: d8 cf rjmp .-80 ; 0x36f4 - USB_Device_GetDescriptor(); - } - - break; - case REQ_GetConfiguration: - if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) - 3744: 30 38 cpi r19, 0x80 ; 128 - 3746: b1 f6 brne .-84 ; 0x36f4 - EVENT_USB_Device_ConfigurationChanged(); -} - -static void USB_Device_GetConfiguration(void) -{ - Endpoint_ClearSETUP(); - 3748: 4e d3 rcall .+1692 ; 0x3de6 - - Endpoint_Write_8(USB_Device_ConfigurationNumber); - 374a: 80 91 10 27 lds r24, 0x2710 - 374e: c4 d2 rcall .+1416 ; 0x3cd8 - Endpoint_ClearIN(); - 3750: 8b d2 rcall .+1302 ; 0x3c68 - - Endpoint_ClearStatusStage(); - 3752: 80 d4 rcall .+2304 ; 0x4054 - 3754: cf cf rjmp .-98 ; 0x36f4 - if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) - USB_Device_SetAddress(); - - break; - case REQ_GetDescriptor: - if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) || - 3756: 30 58 subi r19, 0x80 ; 128 - 3758: 32 30 cpi r19, 0x02 ; 2 - 375a: 60 f6 brcc .-104 ; 0x36f4 - !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS)) - uint8_t DescriptorAddressSpace; - #endif - - #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) - if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL)) - 375c: 80 91 17 27 lds r24, 0x2717 - 3760: 90 91 18 27 lds r25, 0x2718 - 3764: 8c 3d cpi r24, 0xDC ; 220 - 3766: e3 e0 ldi r30, 0x03 ; 3 - 3768: 9e 07 cpc r25, r30 - 376a: 09 f4 brne .+2 ; 0x376e - 376c: 88 c0 rjmp .+272 ; 0x387e - USB_Device_GetInternalSerialDescriptor(); - return; - } - #endif - - if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex, - 376e: ae 01 movw r20, r28 - 3770: 4f 5f subi r20, 0xFF ; 255 - 3772: 5f 4f sbci r21, 0xFF ; 255 - 3774: 60 91 19 27 lds r22, 0x2719 - 3778: 0e 94 d4 03 call 0x7a8 ; 0x7a8 - 377c: 8c 01 movw r16, r24 - 377e: 00 97 sbiw r24, 0x00 ; 0 - 3780: 09 f4 brne .+2 ; 0x3784 - 3782: b8 cf rjmp .-144 ; 0x36f4 - )) == NO_DESCRIPTOR) - { - return; - } - - Endpoint_ClearSETUP(); - 3784: 30 d3 rcall .+1632 ; 0x3de6 - #if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE) - Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize); - #elif defined(USE_EEPROM_DESCRIPTORS) - Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize); - #elif defined(USE_FLASH_DESCRIPTORS) - Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize); - 3786: b8 01 movw r22, r16 - 3788: 89 81 ldd r24, Y+1 ; 0x01 - 378a: 9a 81 ldd r25, Y+2 ; 0x02 - 378c: c1 d1 rcall .+898 ; 0x3b10 - Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize); - else - Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize); - #endif - - Endpoint_ClearOUT(); - 378e: 85 d2 rcall .+1290 ; 0x3c9a - 3790: b1 cf rjmp .-158 ; 0x36f4 - USB_Device_ClearSetFeature(); - } - - break; - case REQ_SetAddress: - if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) - 3792: 31 11 cpse r19, r1 - 3794: af cf rjmp .-162 ; 0x36f4 - } -} - -static void USB_Device_SetAddress(void) -{ - uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F); - 3796: 10 91 17 27 lds r17, 0x2717 - 379a: 1f 77 andi r17, 0x7F ; 127 - - USB_Device_SetDeviceAddress(DeviceAddress); - - Endpoint_ClearSETUP(); - 379c: 24 d3 rcall .+1608 ; 0x3de6 - - Endpoint_ClearStatusStage(); - 379e: 5a d4 rcall .+2228 ; 0x4054 - - while (!(Endpoint_IsINReady())); - 37a0: e4 d2 rcall .+1480 ; 0x3d6a - 37a2: 88 23 and r24, r24 - 37a4: e9 f3 breq .-6 ; 0x37a0 - } - - static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; - static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) - { - USB.ADDR = Address; - 37a6: 10 93 c3 04 sts 0x04C3, r17 - - USB_Device_EnableDeviceAddress(DeviceAddress); - - USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default; - 37aa: 11 11 cpse r17, r1 - 37ac: 66 c0 rjmp .+204 ; 0x387a - 37ae: 82 e0 ldi r24, 0x02 ; 2 - 37b0: 80 93 14 27 sts 0x2714, r24 - 37b4: 9f cf rjmp .-194 ; 0x36f4 - } - - break; - case REQ_ClearFeature: - case REQ_SetFeature: - if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) || - 37b6: 33 23 and r19, r19 - 37b8: 09 f4 brne .+2 ; 0x37bc - 37ba: 4b c0 rjmp .+150 ; 0x3852 - 37bc: 32 30 cpi r19, 0x02 ; 2 - 37be: 09 f0 breq .+2 ; 0x37c2 - 37c0: 99 cf rjmp .-206 ; 0x36f4 - - break; - #endif - #if !defined(CONTROL_ONLY_DEVICE) - case REQREC_ENDPOINT: - if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_EndpointHalt) - 37c2: 80 91 17 27 lds r24, 0x2717 - 37c6: 81 11 cpse r24, r1 - 37c8: 24 c0 rjmp .+72 ; 0x3812 - { - uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK); - 37ca: 10 91 19 27 lds r17, 0x2719 - 37ce: 1f 70 andi r17, 0x0F ; 15 - - if (EndpointIndex == ENDPOINT_CONTROLEP) - 37d0: 09 f4 brne .+2 ; 0x37d4 - 37d2: 90 cf rjmp .-224 ; 0x36f4 - return; - - Endpoint_SelectEndpoint(EndpointIndex); - 37d4: 81 2f mov r24, r17 - 37d6: 90 d2 rcall .+1312 ; 0x3cf8 - - if (Endpoint_IsEnabled()) - { - if (USB_ControlRequest.bRequest == REQ_SetFeature) - 37d8: 80 91 16 27 lds r24, 0x2716 - 37dc: 83 30 cpi r24, 0x03 ; 3 - 37de: 09 f4 brne .+2 ; 0x37e2 - 37e0: 86 c0 rjmp .+268 ; 0x38ee - * \ingroup Group_EndpointPacketManagement_XMEGA - */ - static inline void Endpoint_ClearStall(void) ATTR_ALWAYS_INLINE; - static inline void Endpoint_ClearStall(void) - { - USB_Endpoint_SelectedHandle->CTRL &= ~USB_EP_STALL_bm; - 37e2: a0 91 1f 27 lds r26, 0x271F - 37e6: b0 91 20 27 lds r27, 0x2720 - 37ea: 11 96 adiw r26, 0x01 ; 1 - 37ec: 8c 91 ld r24, X - 37ee: 11 97 sbiw r26, 0x01 ; 1 - 37f0: 8b 7f andi r24, 0xFB ; 251 - 37f2: 11 96 adiw r26, 0x01 ; 1 - 37f4: 8c 93 st X, r24 - static inline void Endpoint_ResetEndpoint(const uint8_t Address) - { - if (Address & ENDPOINT_DIR_IN) - USB_Endpoint_FIFOs[Address & ENDPOINT_EPNUM_MASK].IN.Position = 0; - else - USB_Endpoint_FIFOs[Address & ENDPOINT_EPNUM_MASK].OUT.Position = 0; - 37f6: 24 e8 ldi r18, 0x84 ; 132 - 37f8: 12 9f mul r17, r18 - 37fa: f0 01 movw r30, r0 - 37fc: 11 24 eor r1, r1 - 37fe: ed 59 subi r30, 0x9D ; 157 - 3800: f8 4d sbci r31, 0xD8 ; 216 - 3802: 10 82 st Z, r1 - - /** Resets the data toggle of the currently selected endpoint. */ - static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE; - static inline void Endpoint_ResetDataToggle(void) - { - USB_Endpoint_SelectedHandle->STATUS &= ~USB_EP_TOGGLE_bm; - 3804: e0 91 1f 27 lds r30, 0x271F - 3808: f0 91 20 27 lds r31, 0x2720 - 380c: 80 81 ld r24, Z - 380e: 8e 7f andi r24, 0xFE ; 254 - 3810: 80 83 st Z, r24 - #endif - default: - return; - } - - Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); - 3812: 80 e0 ldi r24, 0x00 ; 0 - 3814: 71 d2 rcall .+1250 ; 0x3cf8 - - Endpoint_ClearSETUP(); - 3816: e7 d2 rcall .+1486 ; 0x3de6 - - Endpoint_ClearStatusStage(); - 3818: 1d d4 rcall .+2106 ; 0x4054 - 381a: 6c cf rjmp .-296 ; 0x36f4 - uint8_t bmRequestType = USB_ControlRequest.bmRequestType; - - switch (USB_ControlRequest.bRequest) - { - case REQ_GetStatus: - if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) || - 381c: 30 38 cpi r19, 0x80 ; 128 - 381e: 29 f1 breq .+74 ; 0x386a - 3820: 32 38 cpi r19, 0x82 ; 130 - 3822: 09 f0 breq .+2 ; 0x3826 - 3824: 67 cf rjmp .-306 ; 0x36f4 - CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED; - #endif - break; - case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT): - #if !defined(CONTROL_ONLY_DEVICE) - Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK); - 3826: 80 91 19 27 lds r24, 0x2719 - 382a: 8f 70 andi r24, 0x0F ; 15 - 382c: 65 d2 rcall .+1226 ; 0x3cf8 - * \return Boolean \c true if the currently selected endpoint is stalled, \c false otherwise. - */ - static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; - static inline bool Endpoint_IsStalled(void) - { - return ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_STALL_bm) ? true : false); - 382e: e0 91 1f 27 lds r30, 0x271F - 3832: f0 91 20 27 lds r31, 0x2720 - 3836: 11 81 ldd r17, Z+1 ; 0x01 - 3838: 12 fb bst r17, 2 - 383a: 11 27 eor r17, r17 - 383c: 10 f9 bld r17, 0 - - CurrentStatus = Endpoint_IsStalled(); - - Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); - 383e: 80 e0 ldi r24, 0x00 ; 0 - 3840: 5b d2 rcall .+1206 ; 0x3cf8 - break; - default: - return; - } - - Endpoint_ClearSETUP(); - 3842: d1 d2 rcall .+1442 ; 0x3de6 - * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. - */ - static inline void Endpoint_Write_16_LE(const uint16_t Data) ATTR_ALWAYS_INLINE; - static inline void Endpoint_Write_16_LE(const uint16_t Data) - { - Endpoint_Write_8(Data & 0xFF); - 3844: 81 2f mov r24, r17 - 3846: 48 d2 rcall .+1168 ; 0x3cd8 - Endpoint_Write_8(Data >> 8); - 3848: 80 e0 ldi r24, 0x00 ; 0 - 384a: 46 d2 rcall .+1164 ; 0x3cd8 - - Endpoint_Write_16_LE(CurrentStatus); - Endpoint_ClearIN(); - 384c: 0d d2 rcall .+1050 ; 0x3c68 - - Endpoint_ClearStatusStage(); - 384e: 02 d4 rcall .+2052 ; 0x4054 - 3850: 51 cf rjmp .-350 ; 0x36f4 -{ - switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) - { - #if !defined(NO_DEVICE_REMOTE_WAKEUP) - case REQREC_DEVICE: - if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup) - 3852: 80 91 17 27 lds r24, 0x2717 - 3856: 81 30 cpi r24, 0x01 ; 1 - 3858: 09 f0 breq .+2 ; 0x385c - 385a: 4c cf rjmp .-360 ; 0x36f4 - USB_Device_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature); - 385c: 81 e0 ldi r24, 0x01 ; 1 - 385e: 23 30 cpi r18, 0x03 ; 3 - 3860: 09 f0 breq .+2 ; 0x3864 - 3862: 80 e0 ldi r24, 0x00 ; 0 - 3864: 80 93 12 27 sts 0x2712, r24 - 3868: d4 cf rjmp .-88 ; 0x3812 - Endpoint_ClearOUT(); -} - -static void USB_Device_GetStatus(void) -{ - uint8_t CurrentStatus = 0; - 386a: 10 91 11 27 lds r17, 0x2711 - if (USB_Device_CurrentlySelfPowered) - CurrentStatus |= FEATURE_SELFPOWERED_ENABLED; - #endif - - #if !defined(NO_DEVICE_REMOTE_WAKEUP) - if (USB_Device_RemoteWakeupEnabled) - 386e: 80 91 12 27 lds r24, 0x2712 - 3872: 88 23 and r24, r24 - 3874: 31 f3 breq .-52 ; 0x3842 - CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED; - 3876: 12 60 ori r17, 0x02 ; 2 - 3878: e4 cf rjmp .-56 ; 0x3842 - - while (!(Endpoint_IsINReady())); - - USB_Device_EnableDeviceAddress(DeviceAddress); - - USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default; - 387a: 83 e0 ldi r24, 0x03 ; 3 - 387c: 99 cf rjmp .-206 ; 0x37b0 - { - USB_Descriptor_Header_t Header; - uint16_t UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4]; - } SignatureDescriptor; - - SignatureDescriptor.Header.Type = DTYPE_String; - 387e: 83 e0 ldi r24, 0x03 ; 3 - 3880: 8a 83 std Y+2, r24 ; 0x02 - SignatureDescriptor.Header.Size = USB_STRING_LEN(INTERNAL_SERIAL_LENGTH_BITS / 4); - 3882: 8a e3 ldi r24, 0x3A ; 58 - 3884: 89 83 std Y+1, r24 ; 0x01 - #if (ARCH == ARCH_AVR8) - return SREG; - #elif (ARCH == ARCH_UC3) - return __builtin_mfsr(AVR32_SR); - #elif (ARCH == ARCH_XMEGA) - return SREG; - 3886: 5f b7 in r21, 0x3f ; 63 - #if (ARCH == ARCH_AVR8) - cli(); - #elif (ARCH == ARCH_UC3) - __builtin_ssrf(AVR32_SR_GM_OFFSET); - #elif (ARCH == ARCH_XMEGA) - cli(); - 3888: f8 94 cli - #endif - - GCC_MEMORY_BARRIER(); - 388a: de 01 movw r26, r28 - 388c: 13 96 adiw r26, 0x03 ; 3 - uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); - GlobalInterruptDisable(); - - uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS; - - for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) - 388e: 20 e0 ldi r18, 0x00 ; 0 - static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) - { - uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); - GlobalInterruptDisable(); - - uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS; - 3890: 38 e0 ldi r19, 0x08 ; 8 - - for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) - { - uint8_t SerialByte; - - NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; - 3892: 42 e0 ldi r20, 0x02 ; 2 - 3894: 07 c0 rjmp .+14 ; 0x38a4 - SigReadAddress++; - } - - SerialByte &= 0x0F; - - UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ? - 3896: 90 e0 ldi r25, 0x00 ; 0 - 3898: c7 96 adiw r24, 0x37 ; 55 - 389a: 8d 93 st X+, r24 - 389c: 9d 93 st X+, r25 - uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); - GlobalInterruptDisable(); - - uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS; - - for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) - 389e: 2f 5f subi r18, 0xFF ; 255 - 38a0: 2c 31 cpi r18, 0x1C ; 28 - 38a2: 91 f0 breq .+36 ; 0x38c8 - { - uint8_t SerialByte; - - NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; - 38a4: 40 93 ca 01 sts 0x01CA, r20 - SerialByte = pgm_read_byte(SigReadAddress); - 38a8: e3 2f mov r30, r19 - 38aa: f0 e0 ldi r31, 0x00 ; 0 - 38ac: 84 91 lpm r24, Z - NVM.CMD = 0; - 38ae: 10 92 ca 01 sts 0x01CA, r1 - - if (SerialCharNum & 0x01) - 38b2: 20 ff sbrs r18, 0 - 38b4: 03 c0 rjmp .+6 ; 0x38bc - { - SerialByte >>= 4; - 38b6: 82 95 swap r24 - 38b8: 8f 70 andi r24, 0x0F ; 15 - SigReadAddress++; - 38ba: 3f 5f subi r19, 0xFF ; 255 - } - - SerialByte &= 0x0F; - 38bc: 8f 70 andi r24, 0x0F ; 15 - - UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ? - 38be: 8a 30 cpi r24, 0x0A ; 10 - 38c0: 50 f7 brcc .-44 ; 0x3896 - 38c2: 90 e0 ldi r25, 0x00 ; 0 - 38c4: c0 96 adiw r24, 0x30 ; 48 - 38c6: e9 cf rjmp .-46 ; 0x389a - if (GlobalIntState & AVR32_SR_GM) - __builtin_ssrf(AVR32_SR_GM_OFFSET); - else - __builtin_csrf(AVR32_SR_GM_OFFSET); - #elif (ARCH == ARCH_XMEGA) - SREG = GlobalIntState; - 38c8: 5f bf out 0x3f, r21 ; 63 - - USB_Device_GetSerialString(SignatureDescriptor.UnicodeString); - - Endpoint_ClearSETUP(); - 38ca: 8d d2 rcall .+1306 ; 0x3de6 - - Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor)); - 38cc: 6a e3 ldi r22, 0x3A ; 58 - 38ce: 70 e0 ldi r23, 0x00 ; 0 - 38d0: ce 01 movw r24, r28 - 38d2: 01 96 adiw r24, 0x01 ; 1 - 38d4: 88 d0 rcall .+272 ; 0x39e6 - Endpoint_ClearOUT(); - 38d6: e1 d1 rcall .+962 ; 0x3c9a - 38d8: 0d cf rjmp .-486 ; 0x36f4 - } - - static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; - static inline bool USB_Device_IsAddressSet(void) - { - return ((USB.ADDR != 0) ? true : false); - 38da: 80 91 c3 04 lds r24, 0x04C3 - Endpoint_ClearStatusStage(); - - if (USB_Device_ConfigurationNumber) - USB_DeviceState = DEVICE_STATE_Configured; - else - USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered; - 38de: 88 23 and r24, r24 - 38e0: 21 f0 breq .+8 ; 0x38ea - 38e2: 84 e0 ldi r24, 0x04 ; 4 - 38e4: 80 93 14 27 sts 0x2714, r24 - 38e8: 2a cf rjmp .-428 ; 0x373e - 38ea: 81 e0 ldi r24, 0x01 ; 1 - 38ec: fb cf rjmp .-10 ; 0x38e4 - - if (Endpoint_IsEnabled()) - { - if (USB_ControlRequest.bRequest == REQ_SetFeature) - { - Endpoint_StallTransaction(); - 38ee: a7 d2 rcall .+1358 ; 0x3e3e - 38f0: 90 cf rjmp .-224 ; 0x3812 - -000038f2 : -#define __INCLUDE_FROM_EVENTS_C -#define __INCLUDE_FROM_USB_DRIVER -#include "Events.h" - -void USB_Event_Stub(void) -{ - 38f2: 08 95 ret - -000038f4 : -#if defined(USB_CAN_BE_DEVICE) && !defined(DEVICE_STATE_AS_GPIOR) -volatile uint8_t USB_DeviceState; -#endif - -void USB_USBTask(void) -{ - 38f4: cf 93 push r28 -} - -#if defined(USB_CAN_BE_DEVICE) -static void USB_DeviceTask(void) -{ - if (USB_DeviceState == DEVICE_STATE_Unattached) - 38f6: 80 91 14 27 lds r24, 0x2714 - 38fa: 81 11 cpse r24, r1 - 38fc: 02 c0 rjmp .+4 ; 0x3902 - #elif defined(USB_CAN_BE_HOST) - USB_HostTask(); - #elif defined(USB_CAN_BE_DEVICE) - USB_DeviceTask(); - #endif -} - 38fe: cf 91 pop r28 - 3900: 08 95 ret - * \return Index of the currently selected endpoint. - */ - static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; - static inline uint8_t Endpoint_GetCurrentEndpoint(void) - { - return USB_Endpoint_SelectedEndpoint; - 3902: c0 91 21 27 lds r28, 0x2721 - if (USB_DeviceState == DEVICE_STATE_Unattached) - return; - - uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint(); - - Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); - 3906: 80 e0 ldi r24, 0x00 ; 0 - 3908: f7 d1 rcall .+1006 ; 0x3cf8 - - if (Endpoint_IsSETUPReceived()) - 390a: 54 d2 rcall .+1192 ; 0x3db4 - 390c: 81 11 cpse r24, r1 - 390e: 03 c0 rjmp .+6 ; 0x3916 - USB_Device_ProcessControlRequest(); - - Endpoint_SelectEndpoint(PrevEndpoint); - 3910: 8c 2f mov r24, r28 - #elif defined(USB_CAN_BE_HOST) - USB_HostTask(); - #elif defined(USB_CAN_BE_DEVICE) - USB_DeviceTask(); - #endif -} - 3912: cf 91 pop r28 - Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); - - if (Endpoint_IsSETUPReceived()) - USB_Device_ProcessControlRequest(); - - Endpoint_SelectEndpoint(PrevEndpoint); - 3914: f1 c1 rjmp .+994 ; 0x3cf8 - uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint(); - - Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); - - if (Endpoint_IsSETUPReceived()) - USB_Device_ProcessControlRequest(); - 3916: cd de rcall .-614 ; 0x36b2 - - Endpoint_SelectEndpoint(PrevEndpoint); - 3918: 8c 2f mov r24, r28 - #elif defined(USB_CAN_BE_HOST) - USB_HostTask(); - #elif defined(USB_CAN_BE_DEVICE) - USB_DeviceTask(); - #endif -} - 391a: cf 91 pop r28 - Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); - - if (Endpoint_IsSETUPReceived()) - USB_Device_ProcessControlRequest(); - - Endpoint_SelectEndpoint(PrevEndpoint); - 391c: ed c1 rjmp .+986 ; 0x3cf8 - -0000391e : - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - return ENDPOINT_RWCSTREAM_BusSuspended; - } - - return ENDPOINT_RWCSTREAM_NoError; -} - 391e: cf 92 push r12 - 3920: df 92 push r13 - 3922: ef 92 push r14 - 3924: ff 92 push r15 - 3926: 0f 93 push r16 - 3928: 1f 93 push r17 - 392a: cf 93 push r28 - 392c: df 93 push r29 - 392e: 8c 01 movw r16, r24 - 3930: eb 01 movw r28, r22 - 3932: 7a 01 movw r14, r20 - 3934: a5 d3 rcall .+1866 ; 0x4080 - 3936: 81 11 cpse r24, r1 - 3938: 25 c0 rjmp .+74 ; 0x3984 - 393a: e1 14 cp r14, r1 - 393c: f1 04 cpc r15, r1 - 393e: 81 f1 breq .+96 ; 0x39a0 - 3940: f7 01 movw r30, r14 - 3942: 80 81 ld r24, Z - 3944: 91 81 ldd r25, Z+1 ; 0x01 - 3946: c8 1b sub r28, r24 - 3948: d9 0b sbc r29, r25 - 394a: 08 0f add r16, r24 - 394c: 19 1f adc r17, r25 - 394e: 20 97 sbiw r28, 0x00 ; 0 - 3950: 09 f4 brne .+2 ; 0x3954 - 3952: 3b c0 rjmp .+118 ; 0x39ca - 3954: c1 2c mov r12, r1 - 3956: d1 2c mov r13, r1 - 3958: 20 91 1d 27 lds r18, 0x271D - 395c: 30 91 1e 27 lds r19, 0x271E - 3960: f9 01 movw r30, r18 - 3962: ef 5b subi r30, 0xBF ; 191 - 3964: ff 4f sbci r31, 0xFF ; 255 - 3966: 90 81 ld r25, Z - 3968: 31 97 sbiw r30, 0x01 ; 1 - 396a: 80 81 ld r24, Z - 396c: 98 17 cp r25, r24 - 396e: 78 f1 brcs .+94 ; 0x39ce - 3970: 7b d1 rcall .+758 ; 0x3c68 - 3972: c0 df rcall .-128 ; 0x38f4 - 3974: f7 01 movw r30, r14 - 3976: 80 81 ld r24, Z - 3978: 91 81 ldd r25, Z+1 ; 0x01 - 397a: 8c 0d add r24, r12 - 397c: 9d 1d adc r25, r13 - 397e: 80 83 st Z, r24 - 3980: 91 83 std Z+1, r25 ; 0x01 - 3982: 85 e0 ldi r24, 0x05 ; 5 - 3984: df 91 pop r29 - 3986: cf 91 pop r28 - 3988: 1f 91 pop r17 - 398a: 0f 91 pop r16 - 398c: ff 90 pop r15 - 398e: ef 90 pop r14 - 3990: df 90 pop r13 - 3992: cf 90 pop r12 - 3994: 08 95 ret - 3996: 68 d1 rcall .+720 ; 0x3c68 - 3998: ad df rcall .-166 ; 0x38f4 - 399a: 72 d3 rcall .+1764 ; 0x4080 - 399c: 81 11 cpse r24, r1 - 399e: f2 cf rjmp .-28 ; 0x3984 - 39a0: 20 97 sbiw r28, 0x00 ; 0 - 39a2: 99 f0 breq .+38 ; 0x39ca - 39a4: 20 91 1d 27 lds r18, 0x271D - 39a8: 30 91 1e 27 lds r19, 0x271E - 39ac: f9 01 movw r30, r18 - 39ae: ef 5b subi r30, 0xBF ; 191 - 39b0: ff 4f sbci r31, 0xFF ; 255 - 39b2: 90 81 ld r25, Z - 39b4: 31 97 sbiw r30, 0x01 ; 1 - 39b6: 80 81 ld r24, Z - 39b8: 98 17 cp r25, r24 - 39ba: 68 f7 brcc .-38 ; 0x3996 - 39bc: f8 01 movw r30, r16 - 39be: 81 91 ld r24, Z+ - 39c0: 8f 01 movw r16, r30 - 39c2: 8a d1 rcall .+788 ; 0x3cd8 - 39c4: 21 97 sbiw r28, 0x01 ; 1 - 39c6: 20 97 sbiw r28, 0x00 ; 0 - 39c8: 69 f7 brne .-38 ; 0x39a4 - 39ca: 80 e0 ldi r24, 0x00 ; 0 - 39cc: db cf rjmp .-74 ; 0x3984 - 39ce: f8 01 movw r30, r16 - 39d0: 81 91 ld r24, Z+ - 39d2: 8f 01 movw r16, r30 - 39d4: 81 d1 rcall .+770 ; 0x3cd8 - 39d6: ff ef ldi r31, 0xFF ; 255 - 39d8: cf 1a sub r12, r31 - 39da: df 0a sbc r13, r31 - 39dc: cc 15 cp r28, r12 - 39de: dd 05 cpc r29, r13 - 39e0: 09 f0 breq .+2 ; 0x39e4 - 39e2: ba cf rjmp .-140 ; 0x3958 - 39e4: f2 cf rjmp .-28 ; 0x39ca - -000039e6 : - 39e6: cf 92 push r12 - 39e8: df 92 push r13 - 39ea: ef 92 push r14 - 39ec: ff 92 push r15 - 39ee: 0f 93 push r16 - 39f0: 1f 93 push r17 - 39f2: cf 93 push r28 - 39f4: df 93 push r29 - 39f6: 6c 01 movw r12, r24 - 39f8: 8b 01 movw r16, r22 - 39fa: 80 91 21 27 lds r24, 0x2721 - 39fe: 80 68 ori r24, 0x80 ; 128 - 3a00: 7b d1 rcall .+758 ; 0x3cf8 - 3a02: c0 91 1b 27 lds r28, 0x271B - 3a06: d0 91 1c 27 lds r29, 0x271C - 3a0a: c0 17 cp r28, r16 - 3a0c: d1 07 cpc r29, r17 - 3a0e: 28 f0 brcs .+10 ; 0x3a1a - 3a10: 01 15 cp r16, r1 - 3a12: 11 05 cpc r17, r1 - 3a14: 09 f4 brne .+2 ; 0x3a18 - 3a16: 6f c0 rjmp .+222 ; 0x3af6 - 3a18: e8 01 movw r28, r16 - 3a1a: 10 e0 ldi r17, 0x00 ; 0 - 3a1c: 20 97 sbiw r28, 0x00 ; 0 - 3a1e: 39 f5 brne .+78 ; 0x3a6e - 3a20: 11 11 cpse r17, r1 - 3a22: 0c c0 rjmp .+24 ; 0x3a3c - 3a24: 2f c0 rjmp .+94 ; 0x3a84 - 3a26: 85 30 cpi r24, 0x05 ; 5 - 3a28: 91 f1 breq .+100 ; 0x3a8e - 3a2a: c4 d1 rcall .+904 ; 0x3db4 - 3a2c: 81 11 cpse r24, r1 - 3a2e: 31 c0 rjmp .+98 ; 0x3a92 - 3a30: a8 d1 rcall .+848 ; 0x3d82 - 3a32: 81 11 cpse r24, r1 - 3a34: 27 c0 rjmp .+78 ; 0x3a84 - 3a36: 99 d1 rcall .+818 ; 0x3d6a - 3a38: 81 11 cpse r24, r1 - 3a3a: 2d c0 rjmp .+90 ; 0x3a96 - 3a3c: 80 91 14 27 lds r24, 0x2714 - 3a40: 81 11 cpse r24, r1 - 3a42: f1 cf rjmp .-30 ; 0x3a26 - 3a44: 82 e0 ldi r24, 0x02 ; 2 - 3a46: df 91 pop r29 - 3a48: cf 91 pop r28 - 3a4a: 1f 91 pop r17 - 3a4c: 0f 91 pop r16 - 3a4e: ff 90 pop r15 - 3a50: ef 90 pop r14 - 3a52: df 90 pop r13 - 3a54: cf 90 pop r12 - 3a56: 08 95 ret - 3a58: 85 30 cpi r24, 0x05 ; 5 - 3a5a: c9 f0 breq .+50 ; 0x3a8e - 3a5c: ab d1 rcall .+854 ; 0x3db4 - 3a5e: 81 11 cpse r24, r1 - 3a60: 18 c0 rjmp .+48 ; 0x3a92 - 3a62: 8f d1 rcall .+798 ; 0x3d82 - 3a64: 81 11 cpse r24, r1 - 3a66: 0e c0 rjmp .+28 ; 0x3a84 - 3a68: 80 d1 rcall .+768 ; 0x3d6a - 3a6a: 81 11 cpse r24, r1 - 3a6c: 14 c0 rjmp .+40 ; 0x3a96 - 3a6e: 80 91 14 27 lds r24, 0x2714 - 3a72: 81 11 cpse r24, r1 - 3a74: f1 cf rjmp .-30 ; 0x3a58 - 3a76: e6 cf rjmp .-52 ; 0x3a44 - 3a78: 80 91 14 27 lds r24, 0x2714 - 3a7c: 88 23 and r24, r24 - 3a7e: 11 f3 breq .-60 ; 0x3a44 - 3a80: 85 30 cpi r24, 0x05 ; 5 - 3a82: 29 f0 breq .+10 ; 0x3a8e - 3a84: 7e d1 rcall .+764 ; 0x3d82 - 3a86: 88 23 and r24, r24 - 3a88: b9 f3 breq .-18 ; 0x3a78 - 3a8a: 80 e0 ldi r24, 0x00 ; 0 - 3a8c: dc cf rjmp .-72 ; 0x3a46 - 3a8e: 83 e0 ldi r24, 0x03 ; 3 - 3a90: da cf rjmp .-76 ; 0x3a46 - 3a92: 81 e0 ldi r24, 0x01 ; 1 - 3a94: d8 cf rjmp .-80 ; 0x3a46 - 3a96: 80 91 21 27 lds r24, 0x2721 - 3a9a: 87 fd sbrc r24, 7 - 3a9c: 30 c0 rjmp .+96 ; 0x3afe - 3a9e: 20 91 1d 27 lds r18, 0x271D - 3aa2: 30 91 1e 27 lds r19, 0x271E - 3aa6: f9 01 movw r30, r18 - 3aa8: e0 5c subi r30, 0xC0 ; 192 - 3aaa: ff 4f sbci r31, 0xFF ; 255 - 3aac: e0 80 ld r14, Z - 3aae: 31 96 adiw r30, 0x01 ; 1 - 3ab0: 80 81 ld r24, Z - 3ab2: f1 2c mov r15, r1 - 3ab4: e8 1a sub r14, r24 - 3ab6: f1 08 sbc r15, r1 - 3ab8: 20 97 sbiw r28, 0x00 ; 0 - 3aba: a9 f0 breq .+42 ; 0x3ae6 - 3abc: 88 e0 ldi r24, 0x08 ; 8 - 3abe: e8 16 cp r14, r24 - 3ac0: f1 04 cpc r15, r1 - 3ac2: 88 f4 brcc .+34 ; 0x3ae6 - 3ac4: 86 01 movw r16, r12 - 3ac6: 04 c0 rjmp .+8 ; 0x3ad0 - 3ac8: 88 e0 ldi r24, 0x08 ; 8 - 3aca: e8 16 cp r14, r24 - 3acc: f1 04 cpc r15, r1 - 3ace: 59 f0 breq .+22 ; 0x3ae6 - 3ad0: f8 01 movw r30, r16 - 3ad2: 81 91 ld r24, Z+ - 3ad4: 8f 01 movw r16, r30 - 3ad6: 00 d1 rcall .+512 ; 0x3cd8 - 3ad8: 68 01 movw r12, r16 - 3ada: 21 97 sbiw r28, 0x01 ; 1 - 3adc: ff ef ldi r31, 0xFF ; 255 - 3ade: ef 1a sub r14, r31 - 3ae0: ff 0a sbc r15, r31 - 3ae2: 20 97 sbiw r28, 0x00 ; 0 - 3ae4: 89 f7 brne .-30 ; 0x3ac8 - 3ae6: 11 e0 ldi r17, 0x01 ; 1 - 3ae8: e8 e0 ldi r30, 0x08 ; 8 - 3aea: ee 16 cp r14, r30 - 3aec: f1 04 cpc r15, r1 - 3aee: 09 f0 breq .+2 ; 0x3af2 - 3af0: 10 e0 ldi r17, 0x00 ; 0 - 3af2: ba d0 rcall .+372 ; 0x3c68 - 3af4: 93 cf rjmp .-218 ; 0x3a1c - 3af6: b8 d0 rcall .+368 ; 0x3c68 - 3af8: c0 e0 ldi r28, 0x00 ; 0 - 3afa: d0 e0 ldi r29, 0x00 ; 0 - 3afc: 8e cf rjmp .-228 ; 0x3a1a - 3afe: e0 91 1d 27 lds r30, 0x271D - 3b02: f0 91 1e 27 lds r31, 0x271E - 3b06: ef 5b subi r30, 0xBF ; 191 - 3b08: ff 4f sbci r31, 0xFF ; 255 - 3b0a: e0 80 ld r14, Z - 3b0c: f1 2c mov r15, r1 - 3b0e: d4 cf rjmp .-88 ; 0x3ab8 - -00003b10 : - -#if defined(TEMPLATE_FUNC_NAME) - -uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer, - uint16_t Length) -{ - 3b10: df 92 push r13 - 3b12: ef 92 push r14 - 3b14: ff 92 push r15 - 3b16: 0f 93 push r16 - 3b18: 1f 93 push r17 - 3b1a: cf 93 push r28 - 3b1c: df 93 push r29 - 3b1e: f8 2e mov r15, r24 - 3b20: e9 2e mov r14, r25 - 3b22: 8b 01 movw r16, r22 - uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); - bool LastPacketFull = false; - - Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); - 3b24: 80 91 21 27 lds r24, 0x2721 - 3b28: 80 68 ori r24, 0x80 ; 128 - 3b2a: e6 d0 rcall .+460 ; 0x3cf8 - - if (Length > USB_ControlRequest.wLength) - 3b2c: c0 91 1b 27 lds r28, 0x271B - 3b30: d0 91 1c 27 lds r29, 0x271C - 3b34: c0 17 cp r28, r16 - 3b36: d1 07 cpc r29, r17 - 3b38: 28 f0 brcs .+10 ; 0x3b44 - Length = USB_ControlRequest.wLength; - else if (!(Length)) - 3b3a: 01 15 cp r16, r1 - 3b3c: 11 05 cpc r17, r1 - 3b3e: 09 f4 brne .+2 ; 0x3b42 - 3b40: 86 c0 rjmp .+268 ; 0x3c4e - 3b42: e8 01 movw r28, r16 - 3b44: 0f 2d mov r16, r15 - 3b46: 1e 2d mov r17, r14 - 3b48: d1 2c mov r13, r1 - 3b4a: 20 97 sbiw r28, 0x00 ; 0 - 3b4c: 39 f5 brne .+78 ; 0x3b9c - 3b4e: d1 10 cpse r13, r1 - 3b50: 0d c0 rjmp .+26 ; 0x3b6c - 3b52: 2f c0 rjmp .+94 ; 0x3bb2 - { - uint8_t USB_DeviceState_LCL = USB_DeviceState; - - if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) - return ENDPOINT_RWCSTREAM_DeviceDisconnected; - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - 3b54: 85 30 cpi r24, 0x05 ; 5 - 3b56: 09 f4 brne .+2 ; 0x3b5a - 3b58: 38 c0 rjmp .+112 ; 0x3bca - return ENDPOINT_RWCSTREAM_BusSuspended; - else if (Endpoint_IsSETUPReceived()) - 3b5a: 2c d1 rcall .+600 ; 0x3db4 - 3b5c: 81 11 cpse r24, r1 - 3b5e: 3e c0 rjmp .+124 ; 0x3bdc - return ENDPOINT_RWCSTREAM_HostAborted; - else if (Endpoint_IsOUTReceived()) - 3b60: 10 d1 rcall .+544 ; 0x3d82 - 3b62: 81 11 cpse r24, r1 - 3b64: 26 c0 rjmp .+76 ; 0x3bb2 - break; - - if (Endpoint_IsINReady()) - 3b66: 01 d1 rcall .+514 ; 0x3d6a - 3b68: 81 11 cpse r24, r1 - 3b6a: 41 c0 rjmp .+130 ; 0x3bee - else if (!(Length)) - Endpoint_ClearIN(); - - while (Length || LastPacketFull) - { - uint8_t USB_DeviceState_LCL = USB_DeviceState; - 3b6c: 80 91 14 27 lds r24, 0x2714 - - if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) - 3b70: 81 11 cpse r24, r1 - 3b72: f0 cf rjmp .-32 ; 0x3b54 - return ENDPOINT_RWCSTREAM_DeviceDisconnected; - 3b74: 82 e0 ldi r24, 0x02 ; 2 - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - return ENDPOINT_RWCSTREAM_BusSuspended; - } - - return ENDPOINT_RWCSTREAM_NoError; -} - 3b76: df 91 pop r29 - 3b78: cf 91 pop r28 - 3b7a: 1f 91 pop r17 - 3b7c: 0f 91 pop r16 - 3b7e: ff 90 pop r15 - 3b80: ef 90 pop r14 - 3b82: df 90 pop r13 - 3b84: 08 95 ret - { - uint8_t USB_DeviceState_LCL = USB_DeviceState; - - if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) - return ENDPOINT_RWCSTREAM_DeviceDisconnected; - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - 3b86: 85 30 cpi r24, 0x05 ; 5 - 3b88: 01 f1 breq .+64 ; 0x3bca - return ENDPOINT_RWCSTREAM_BusSuspended; - else if (Endpoint_IsSETUPReceived()) - 3b8a: 14 d1 rcall .+552 ; 0x3db4 - 3b8c: 81 11 cpse r24, r1 - 3b8e: 26 c0 rjmp .+76 ; 0x3bdc - return ENDPOINT_RWCSTREAM_HostAborted; - else if (Endpoint_IsOUTReceived()) - 3b90: f8 d0 rcall .+496 ; 0x3d82 - 3b92: 81 11 cpse r24, r1 - 3b94: 0e c0 rjmp .+28 ; 0x3bb2 - break; - - if (Endpoint_IsINReady()) - 3b96: e9 d0 rcall .+466 ; 0x3d6a - 3b98: 81 11 cpse r24, r1 - 3b9a: 29 c0 rjmp .+82 ; 0x3bee - else if (!(Length)) - Endpoint_ClearIN(); - - while (Length || LastPacketFull) - { - uint8_t USB_DeviceState_LCL = USB_DeviceState; - 3b9c: 80 91 14 27 lds r24, 0x2714 - - if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) - 3ba0: 81 11 cpse r24, r1 - 3ba2: f1 cf rjmp .-30 ; 0x3b86 - 3ba4: e7 cf rjmp .-50 ; 0x3b74 - } - } - - while (!(Endpoint_IsOUTReceived())) - { - uint8_t USB_DeviceState_LCL = USB_DeviceState; - 3ba6: 80 91 14 27 lds r24, 0x2714 - - if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) - 3baa: 88 23 and r24, r24 - 3bac: 19 f3 breq .-58 ; 0x3b74 - return ENDPOINT_RWCSTREAM_DeviceDisconnected; - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - 3bae: 85 30 cpi r24, 0x05 ; 5 - 3bb0: 61 f0 breq .+24 ; 0x3bca - LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); - Endpoint_ClearIN(); - } - } - - while (!(Endpoint_IsOUTReceived())) - 3bb2: e7 d0 rcall .+462 ; 0x3d82 - 3bb4: 88 23 and r24, r24 - 3bb6: b9 f3 breq .-18 ; 0x3ba6 - return ENDPOINT_RWCSTREAM_DeviceDisconnected; - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - return ENDPOINT_RWCSTREAM_BusSuspended; - } - - return ENDPOINT_RWCSTREAM_NoError; - 3bb8: 80 e0 ldi r24, 0x00 ; 0 -} - 3bba: df 91 pop r29 - 3bbc: cf 91 pop r28 - 3bbe: 1f 91 pop r17 - 3bc0: 0f 91 pop r16 - 3bc2: ff 90 pop r15 - 3bc4: ef 90 pop r14 - 3bc6: df 90 pop r13 - 3bc8: 08 95 ret - uint8_t USB_DeviceState_LCL = USB_DeviceState; - - if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) - return ENDPOINT_RWCSTREAM_DeviceDisconnected; - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - return ENDPOINT_RWCSTREAM_BusSuspended; - 3bca: 83 e0 ldi r24, 0x03 ; 3 - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - return ENDPOINT_RWCSTREAM_BusSuspended; - } - - return ENDPOINT_RWCSTREAM_NoError; -} - 3bcc: df 91 pop r29 - 3bce: cf 91 pop r28 - 3bd0: 1f 91 pop r17 - 3bd2: 0f 91 pop r16 - 3bd4: ff 90 pop r15 - 3bd6: ef 90 pop r14 - 3bd8: df 90 pop r13 - 3bda: 08 95 ret - if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) - return ENDPOINT_RWCSTREAM_DeviceDisconnected; - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - return ENDPOINT_RWCSTREAM_BusSuspended; - else if (Endpoint_IsSETUPReceived()) - return ENDPOINT_RWCSTREAM_HostAborted; - 3bdc: 81 e0 ldi r24, 0x01 ; 1 - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - return ENDPOINT_RWCSTREAM_BusSuspended; - } - - return ENDPOINT_RWCSTREAM_NoError; -} - 3bde: df 91 pop r29 - 3be0: cf 91 pop r28 - 3be2: 1f 91 pop r17 - 3be4: 0f 91 pop r16 - 3be6: ff 90 pop r15 - 3be8: ef 90 pop r14 - 3bea: df 90 pop r13 - 3bec: 08 95 ret - * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. - */ - static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; - static inline uint16_t Endpoint_BytesInEndpoint(void) - { - if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) - 3bee: 80 91 21 27 lds r24, 0x2721 - 3bf2: 87 fd sbrc r24, 7 - 3bf4: 30 c0 rjmp .+96 ; 0x3c56 - return USB_Endpoint_SelectedFIFO->Position; - else - return (USB_Endpoint_SelectedFIFO->Length - USB_Endpoint_SelectedFIFO->Position); - 3bf6: 80 91 1d 27 lds r24, 0x271D - 3bfa: 90 91 1e 27 lds r25, 0x271E - 3bfe: fc 01 movw r30, r24 - 3c00: e0 5c subi r30, 0xC0 ; 192 - 3c02: ff 4f sbci r31, 0xFF ; 255 - 3c04: e0 80 ld r14, Z - 3c06: 31 96 adiw r30, 0x01 ; 1 - 3c08: 80 81 ld r24, Z - 3c0a: f1 2c mov r15, r1 - 3c0c: e8 1a sub r14, r24 - 3c0e: f1 08 sbc r15, r1 - - if (Endpoint_IsINReady()) - { - uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint(); - - while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize)) - 3c10: 20 97 sbiw r28, 0x00 ; 0 - 3c12: a1 f0 breq .+40 ; 0x3c3c - 3c14: 88 e0 ldi r24, 0x08 ; 8 - 3c16: e8 16 cp r14, r24 - 3c18: f1 04 cpc r15, r1 - 3c1a: 28 f0 brcs .+10 ; 0x3c26 - 3c1c: 0f c0 rjmp .+30 ; 0x3c3c - 3c1e: 88 e0 ldi r24, 0x08 ; 8 - 3c20: e8 16 cp r14, r24 - 3c22: f1 04 cpc r15, r1 - 3c24: 59 f0 breq .+22 ; 0x3c3c - { - TEMPLATE_TRANSFER_BYTE(DataStream); - 3c26: f8 01 movw r30, r16 - 3c28: 84 91 lpm r24, Z - 3c2a: 56 d0 rcall .+172 ; 0x3cd8 - TEMPLATE_BUFFER_MOVE(DataStream, 1); - 3c2c: 0f 5f subi r16, 0xFF ; 255 - 3c2e: 1f 4f sbci r17, 0xFF ; 255 - Length--; - 3c30: 21 97 sbiw r28, 0x01 ; 1 - BytesInEndpoint++; - 3c32: ff ef ldi r31, 0xFF ; 255 - 3c34: ef 1a sub r14, r31 - 3c36: ff 0a sbc r15, r31 - - if (Endpoint_IsINReady()) - { - uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint(); - - while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize)) - 3c38: 20 97 sbiw r28, 0x00 ; 0 - 3c3a: 89 f7 brne .-30 ; 0x3c1e - TEMPLATE_BUFFER_MOVE(DataStream, 1); - Length--; - BytesInEndpoint++; - } - - LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); - 3c3c: dd 24 eor r13, r13 - 3c3e: d3 94 inc r13 - 3c40: e8 e0 ldi r30, 0x08 ; 8 - 3c42: ee 16 cp r14, r30 - 3c44: f1 04 cpc r15, r1 - 3c46: 09 f0 breq .+2 ; 0x3c4a - 3c48: d1 2c mov r13, r1 - Endpoint_ClearIN(); - 3c4a: 0e d0 rcall .+28 ; 0x3c68 - 3c4c: 7e cf rjmp .-260 ; 0x3b4a - Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); - - if (Length > USB_ControlRequest.wLength) - Length = USB_ControlRequest.wLength; - else if (!(Length)) - Endpoint_ClearIN(); - 3c4e: 0c d0 rcall .+24 ; 0x3c68 - 3c50: c0 e0 ldi r28, 0x00 ; 0 - 3c52: d0 e0 ldi r29, 0x00 ; 0 - 3c54: 77 cf rjmp .-274 ; 0x3b44 - */ - static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; - static inline uint16_t Endpoint_BytesInEndpoint(void) - { - if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) - return USB_Endpoint_SelectedFIFO->Position; - 3c56: e0 91 1d 27 lds r30, 0x271D - 3c5a: f0 91 1e 27 lds r31, 0x271E - 3c5e: ef 5b subi r30, 0xBF ; 191 - 3c60: ff 4f sbci r31, 0xFF ; 255 - 3c62: e0 80 ld r14, Z - 3c64: f1 2c mov r15, r1 - 3c66: d4 cf rjmp .-88 ; 0x3c10 - -00003c68 : - USB_Endpoint_SelectedFIFO->Position = 0; -} - -void Endpoint_ClearIN(void) -{ - USB_Endpoint_SelectedHandle->CNT = USB_Endpoint_SelectedFIFO->Position; - 3c68: e0 91 1f 27 lds r30, 0x271F - 3c6c: f0 91 20 27 lds r31, 0x2720 - 3c70: a0 91 1d 27 lds r26, 0x271D - 3c74: b0 91 1e 27 lds r27, 0x271E - 3c78: af 5b subi r26, 0xBF ; 191 - 3c7a: bf 4f sbci r27, 0xFF ; 255 - 3c7c: 8c 91 ld r24, X - 3c7e: 90 e0 ldi r25, 0x00 ; 0 - 3c80: 82 83 std Z+2, r24 ; 0x02 - 3c82: 93 83 std Z+3, r25 ; 0x03 - USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm); - 3c84: 80 81 ld r24, Z - 3c86: 8d 79 andi r24, 0x9D ; 157 - 3c88: 80 83 st Z, r24 - USB_Endpoint_SelectedFIFO->Position = 0; - 3c8a: e0 91 1d 27 lds r30, 0x271D - 3c8e: f0 91 1e 27 lds r31, 0x271E - 3c92: ef 5b subi r30, 0xBF ; 191 - 3c94: ff 4f sbci r31, 0xFF ; 255 - 3c96: 10 82 st Z, r1 - 3c98: 08 95 ret - -00003c9a : -} - -void Endpoint_ClearOUT(void) -{ - USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm); - 3c9a: e0 91 1f 27 lds r30, 0x271F - 3c9e: f0 91 20 27 lds r31, 0x2720 - 3ca2: 80 81 ld r24, Z - 3ca4: 8d 79 andi r24, 0x9D ; 157 - 3ca6: 80 83 st Z, r24 - USB_Endpoint_SelectedFIFO->Position = 0; - 3ca8: e0 91 1d 27 lds r30, 0x271D - 3cac: f0 91 1e 27 lds r31, 0x271E - 3cb0: ef 5b subi r30, 0xBF ; 191 - 3cb2: ff 4f sbci r31, 0xFF ; 255 - 3cb4: 10 82 st Z, r1 - 3cb6: 08 95 ret - -00003cb8 : - } -} - -uint8_t Endpoint_Read_8(void) -{ - return USB_Endpoint_SelectedFIFO->Data[USB_Endpoint_SelectedFIFO->Position++]; - 3cb8: 80 91 1d 27 lds r24, 0x271D - 3cbc: 90 91 1e 27 lds r25, 0x271E - 3cc0: fc 01 movw r30, r24 - 3cc2: ef 5b subi r30, 0xBF ; 191 - 3cc4: ff 4f sbci r31, 0xFF ; 255 - 3cc6: 20 81 ld r18, Z - 3cc8: 31 e0 ldi r19, 0x01 ; 1 - 3cca: 32 0f add r19, r18 - 3ccc: 30 83 st Z, r19 - 3cce: fc 01 movw r30, r24 - 3cd0: e2 0f add r30, r18 - 3cd2: f1 1d adc r31, r1 - 3cd4: 80 81 ld r24, Z -} - 3cd6: 08 95 ret - -00003cd8 : - -void Endpoint_Write_8(const uint8_t Data) -{ - USB_Endpoint_SelectedFIFO->Data[USB_Endpoint_SelectedFIFO->Position++] = Data; - 3cd8: 20 91 1d 27 lds r18, 0x271D - 3cdc: 30 91 1e 27 lds r19, 0x271E - 3ce0: f9 01 movw r30, r18 - 3ce2: ef 5b subi r30, 0xBF ; 191 - 3ce4: ff 4f sbci r31, 0xFF ; 255 - 3ce6: 90 81 ld r25, Z - 3ce8: 41 e0 ldi r20, 0x01 ; 1 - 3cea: 49 0f add r20, r25 - 3cec: 40 83 st Z, r20 - 3cee: f9 01 movw r30, r18 - 3cf0: e9 0f add r30, r25 - 3cf2: f1 1d adc r31, r1 - 3cf4: 80 83 st Z, r24 - 3cf6: 08 95 ret - -00003cf8 : - -void Endpoint_SelectEndpoint(const uint8_t Address) -{ - uint8_t EndpointNumber = (Address & ENDPOINT_EPNUM_MASK); - - USB_Endpoint_SelectedEndpoint = Address; - 3cf8: 80 93 21 27 sts 0x2721, r24 - USB_Endpoint_SelectedFIFO->Data[USB_Endpoint_SelectedFIFO->Position++] = Data; -} - -void Endpoint_SelectEndpoint(const uint8_t Address) -{ - uint8_t EndpointNumber = (Address & ENDPOINT_EPNUM_MASK); - 3cfc: 28 2f mov r18, r24 - 3cfe: 2f 70 andi r18, 0x0F ; 15 - - USB_Endpoint_SelectedEndpoint = Address; - - Endpoint_FIFOPair_t* EndpointFIFOPair = &USB_Endpoint_FIFOs[EndpointNumber]; - 3d00: 62 2f mov r22, r18 - 3d02: 70 e0 ldi r23, 0x00 ; 0 - 3d04: 94 e8 ldi r25, 0x84 ; 132 - 3d06: 29 9f mul r18, r25 - 3d08: 90 01 movw r18, r0 - 3d0a: 11 24 eor r1, r1 - 3d0c: 2e 5d subi r18, 0xDE ; 222 - 3d0e: 38 4d sbci r19, 0xD8 ; 216 - USB_EndpointTable_t* EndpointTable = (USB_EndpointTable_t*)USB.EPPTR; - 3d10: 40 91 c6 04 lds r20, 0x04C6 - 3d14: 50 91 c7 04 lds r21, 0x04C7 - - if (Address & ENDPOINT_DIR_IN) - 3d18: 87 fd sbrc r24, 7 - 3d1a: 12 c0 rjmp .+36 ; 0x3d40 - USB_Endpoint_SelectedFIFO = &EndpointFIFOPair->IN; - USB_Endpoint_SelectedHandle = &EndpointTable->Endpoints[EndpointNumber].IN; - } - else - { - USB_Endpoint_SelectedFIFO = &EndpointFIFOPair->OUT; - 3d1c: 20 93 1d 27 sts 0x271D, r18 - 3d20: 30 93 1e 27 sts 0x271E, r19 - USB_Endpoint_SelectedHandle = &EndpointTable->Endpoints[EndpointNumber].OUT; - 3d24: cb 01 movw r24, r22 - 3d26: 82 95 swap r24 - 3d28: 92 95 swap r25 - 3d2a: 90 7f andi r25, 0xF0 ; 240 - 3d2c: 98 27 eor r25, r24 - 3d2e: 80 7f andi r24, 0xF0 ; 240 - 3d30: 98 27 eor r25, r24 - 3d32: 84 0f add r24, r20 - 3d34: 95 1f adc r25, r21 - 3d36: 80 93 1f 27 sts 0x271F, r24 - 3d3a: 90 93 20 27 sts 0x2720, r25 - 3d3e: 08 95 ret - Endpoint_FIFOPair_t* EndpointFIFOPair = &USB_Endpoint_FIFOs[EndpointNumber]; - USB_EndpointTable_t* EndpointTable = (USB_EndpointTable_t*)USB.EPPTR; - - if (Address & ENDPOINT_DIR_IN) - { - USB_Endpoint_SelectedFIFO = &EndpointFIFOPair->IN; - 3d40: 2e 5b subi r18, 0xBE ; 190 - 3d42: 3f 4f sbci r19, 0xFF ; 255 - 3d44: 20 93 1d 27 sts 0x271D, r18 - 3d48: 30 93 1e 27 sts 0x271E, r19 - USB_Endpoint_SelectedHandle = &EndpointTable->Endpoints[EndpointNumber].IN; - 3d4c: 62 95 swap r22 - 3d4e: 72 95 swap r23 - 3d50: 70 7f andi r23, 0xF0 ; 240 - 3d52: 76 27 eor r23, r22 - 3d54: 60 7f andi r22, 0xF0 ; 240 - 3d56: 76 27 eor r23, r22 - 3d58: 68 5f subi r22, 0xF8 ; 248 - 3d5a: 7f 4f sbci r23, 0xFF ; 255 - 3d5c: 64 0f add r22, r20 - 3d5e: 75 1f adc r23, r21 - 3d60: 60 93 1f 27 sts 0x271F, r22 - 3d64: 70 93 20 27 sts 0x2720, r23 - 3d68: 08 95 ret - -00003d6a : -volatile USB_EP_t* USB_Endpoint_SelectedHandle; -volatile Endpoint_FIFO_t* USB_Endpoint_SelectedFIFO; - -bool Endpoint_IsINReady(void) -{ - Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); - 3d6a: 80 91 21 27 lds r24, 0x2721 - 3d6e: 80 68 ori r24, 0x80 ; 128 - 3d70: c3 df rcall .-122 ; 0x3cf8 - - return ((USB_Endpoint_SelectedHandle->STATUS & USB_EP_BUSNACK0_bm) ? true : false); - 3d72: e0 91 1f 27 lds r30, 0x271F - 3d76: f0 91 20 27 lds r31, 0x2720 - 3d7a: 80 81 ld r24, Z -} - 3d7c: 86 95 lsr r24 - 3d7e: 81 70 andi r24, 0x01 ; 1 - 3d80: 08 95 ret - -00003d82 : - -bool Endpoint_IsOUTReceived(void) -{ - Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); - 3d82: 80 91 21 27 lds r24, 0x2721 - 3d86: 8f 77 andi r24, 0x7F ; 127 - 3d88: b7 df rcall .-146 ; 0x3cf8 - - if (USB_Endpoint_SelectedHandle->STATUS & USB_EP_TRNCOMPL0_bm) - 3d8a: e0 91 1f 27 lds r30, 0x271F - 3d8e: f0 91 20 27 lds r31, 0x2720 - 3d92: 80 81 ld r24, Z - 3d94: 85 ff sbrs r24, 5 - 3d96: 0c c0 rjmp .+24 ; 0x3db0 - { - USB_Endpoint_SelectedFIFO->Length = USB_Endpoint_SelectedHandle->CNT; - 3d98: 20 91 1d 27 lds r18, 0x271D - 3d9c: 30 91 1e 27 lds r19, 0x271E - 3da0: 82 81 ldd r24, Z+2 ; 0x02 - 3da2: 93 81 ldd r25, Z+3 ; 0x03 - 3da4: f9 01 movw r30, r18 - 3da6: e0 5c subi r30, 0xC0 ; 192 - 3da8: ff 4f sbci r31, 0xFF ; 255 - 3daa: 80 83 st Z, r24 - return true; - 3dac: 81 e0 ldi r24, 0x01 ; 1 - 3dae: 08 95 ret - } - - return false; - 3db0: 80 e0 ldi r24, 0x00 ; 0 -} - 3db2: 08 95 ret - -00003db4 : - -bool Endpoint_IsSETUPReceived(void) -{ - Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); - 3db4: 80 91 21 27 lds r24, 0x2721 - 3db8: 8f 77 andi r24, 0x7F ; 127 - 3dba: 9e df rcall .-196 ; 0x3cf8 - - if (USB_Endpoint_SelectedHandle->STATUS & USB_EP_SETUP_bm) - 3dbc: e0 91 1f 27 lds r30, 0x271F - 3dc0: f0 91 20 27 lds r31, 0x2720 - 3dc4: 80 81 ld r24, Z - 3dc6: 84 ff sbrs r24, 4 - 3dc8: 0c c0 rjmp .+24 ; 0x3de2 - { - USB_Endpoint_SelectedFIFO->Length = USB_Endpoint_SelectedHandle->CNT; - 3dca: 20 91 1d 27 lds r18, 0x271D - 3dce: 30 91 1e 27 lds r19, 0x271E - 3dd2: 82 81 ldd r24, Z+2 ; 0x02 - 3dd4: 93 81 ldd r25, Z+3 ; 0x03 - 3dd6: f9 01 movw r30, r18 - 3dd8: e0 5c subi r30, 0xC0 ; 192 - 3dda: ff 4f sbci r31, 0xFF ; 255 - 3ddc: 80 83 st Z, r24 - return true; - 3dde: 81 e0 ldi r24, 0x01 ; 1 - 3de0: 08 95 ret - } - - return false; - 3de2: 80 e0 ldi r24, 0x00 ; 0 -} - 3de4: 08 95 ret - -00003de6 : - -void Endpoint_ClearSETUP(void) -{ - Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); - 3de6: 80 91 21 27 lds r24, 0x2721 - 3dea: 8f 77 andi r24, 0x7F ; 127 - 3dec: 85 df rcall .-246 ; 0x3cf8 - USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_SETUP_bm | USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm); - 3dee: e0 91 1f 27 lds r30, 0x271F - 3df2: f0 91 20 27 lds r31, 0x2720 - 3df6: 80 81 ld r24, Z - 3df8: 8d 78 andi r24, 0x8D ; 141 - 3dfa: 80 83 st Z, r24 - USB_Endpoint_SelectedHandle->STATUS |= USB_EP_TOGGLE_bm; - 3dfc: e0 91 1f 27 lds r30, 0x271F - 3e00: f0 91 20 27 lds r31, 0x2720 - 3e04: 80 81 ld r24, Z - 3e06: 81 60 ori r24, 0x01 ; 1 - 3e08: 80 83 st Z, r24 - USB_Endpoint_SelectedFIFO->Position = 0; - 3e0a: e0 91 1d 27 lds r30, 0x271D - 3e0e: f0 91 1e 27 lds r31, 0x271E - 3e12: ef 5b subi r30, 0xBF ; 191 - 3e14: ff 4f sbci r31, 0xFF ; 255 - 3e16: 10 82 st Z, r1 - - Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); - 3e18: 80 91 21 27 lds r24, 0x2721 - 3e1c: 80 68 ori r24, 0x80 ; 128 - 3e1e: 6c df rcall .-296 ; 0x3cf8 - USB_Endpoint_SelectedHandle->STATUS |= USB_EP_TOGGLE_bm; - 3e20: e0 91 1f 27 lds r30, 0x271F - 3e24: f0 91 20 27 lds r31, 0x2720 - 3e28: 80 81 ld r24, Z - 3e2a: 81 60 ori r24, 0x01 ; 1 - 3e2c: 80 83 st Z, r24 - USB_Endpoint_SelectedFIFO->Position = 0; - 3e2e: e0 91 1d 27 lds r30, 0x271D - 3e32: f0 91 1e 27 lds r31, 0x271E - 3e36: ef 5b subi r30, 0xBF ; 191 - 3e38: ff 4f sbci r31, 0xFF ; 255 - 3e3a: 10 82 st Z, r1 - 3e3c: 08 95 ret - -00003e3e : - USB_Endpoint_SelectedFIFO->Position = 0; -} - -void Endpoint_StallTransaction(void) -{ - USB_Endpoint_SelectedHandle->CTRL |= USB_EP_STALL_bm; - 3e3e: e0 91 1f 27 lds r30, 0x271F - 3e42: f0 91 20 27 lds r31, 0x2720 - 3e46: 81 81 ldd r24, Z+1 ; 0x01 - 3e48: 84 60 ori r24, 0x04 ; 4 - 3e4a: 81 83 std Z+1, r24 ; 0x01 - - if ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_TYPE_gm) == USB_EP_TYPE_CONTROL_gc) - 3e4c: e0 91 1f 27 lds r30, 0x271F - 3e50: f0 91 20 27 lds r31, 0x2720 - 3e54: 81 81 ldd r24, Z+1 ; 0x01 - 3e56: 80 7c andi r24, 0xC0 ; 192 - 3e58: 80 34 cpi r24, 0x40 ; 64 - 3e5a: 09 f0 breq .+2 ; 0x3e5e - 3e5c: 08 95 ret - { - Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint ^ ENDPOINT_DIR_IN); - 3e5e: 80 91 21 27 lds r24, 0x2721 - 3e62: 80 58 subi r24, 0x80 ; 128 - 3e64: 49 df rcall .-366 ; 0x3cf8 - USB_Endpoint_SelectedHandle->CTRL |= USB_EP_STALL_bm; - 3e66: e0 91 1f 27 lds r30, 0x271F - 3e6a: f0 91 20 27 lds r31, 0x2720 - 3e6e: 81 81 ldd r24, Z+1 ; 0x01 - 3e70: 84 60 ori r24, 0x04 ; 4 - 3e72: 81 83 std Z+1, r24 ; 0x01 - 3e74: 08 95 ret - -00003e76 : -} - -bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Address, - const uint8_t Config, - const uint8_t Size) -{ - 3e76: 1f 93 push r17 - 3e78: cf 93 push r28 - 3e7a: df 93 push r29 - 3e7c: 00 d0 rcall .+0 ; 0x3e7e - 3e7e: cd b7 in r28, 0x3d ; 61 - 3e80: de b7 in r29, 0x3e ; 62 - 3e82: 18 2f mov r17, r24 - Endpoint_SelectEndpoint(Address); - 3e84: 4a 83 std Y+2, r20 ; 0x02 - 3e86: 69 83 std Y+1, r22 ; 0x01 - 3e88: 37 df rcall .-402 ; 0x3cf8 - - USB_Endpoint_SelectedHandle->CTRL = 0; - 3e8a: e0 91 1f 27 lds r30, 0x271F - 3e8e: f0 91 20 27 lds r31, 0x2720 - 3e92: 11 82 std Z+1, r1 ; 0x01 - USB_Endpoint_SelectedHandle->STATUS = (Address & ENDPOINT_DIR_IN) ? USB_EP_BUSNACK0_bm : 0; - 3e94: e0 91 1f 27 lds r30, 0x271F - 3e98: f0 91 20 27 lds r31, 0x2720 - 3e9c: 4a 81 ldd r20, Y+2 ; 0x02 - 3e9e: 69 81 ldd r22, Y+1 ; 0x01 - 3ea0: 17 fd sbrc r17, 7 - 3ea2: 20 c0 rjmp .+64 ; 0x3ee4 - 3ea4: 10 82 st Z, r1 - USB_Endpoint_SelectedHandle->CTRL = Config; - 3ea6: e0 91 1f 27 lds r30, 0x271F - 3eaa: f0 91 20 27 lds r31, 0x2720 - 3eae: 61 83 std Z+1, r22 ; 0x01 - USB_Endpoint_SelectedHandle->CNT = 0; - 3eb0: e0 91 1f 27 lds r30, 0x271F - 3eb4: f0 91 20 27 lds r31, 0x2720 - 3eb8: 12 82 std Z+2, r1 ; 0x02 - 3eba: 13 82 std Z+3, r1 ; 0x03 - USB_Endpoint_SelectedHandle->DATAPTR = (intptr_t)USB_Endpoint_SelectedFIFO->Data; - 3ebc: 80 91 1d 27 lds r24, 0x271D - 3ec0: 90 91 1e 27 lds r25, 0x271E - 3ec4: 84 83 std Z+4, r24 ; 0x04 - 3ec6: 95 83 std Z+5, r25 ; 0x05 - - USB_Endpoint_SelectedFIFO->Length = (Address & ENDPOINT_DIR_IN) ? Size : 0; - 3ec8: 40 e0 ldi r20, 0x00 ; 0 - 3eca: fc 01 movw r30, r24 - 3ecc: e0 5c subi r30, 0xC0 ; 192 - 3ece: ff 4f sbci r31, 0xFF ; 255 - 3ed0: 40 83 st Z, r20 - USB_Endpoint_SelectedFIFO->Position = 0; - 3ed2: 31 96 adiw r30, 0x01 ; 1 - 3ed4: 10 82 st Z, r1 - - return true; -} - 3ed6: 81 e0 ldi r24, 0x01 ; 1 - 3ed8: 0f 90 pop r0 - 3eda: 0f 90 pop r0 - 3edc: df 91 pop r29 - 3ede: cf 91 pop r28 - 3ee0: 1f 91 pop r17 - 3ee2: 08 95 ret - const uint8_t Size) -{ - Endpoint_SelectEndpoint(Address); - - USB_Endpoint_SelectedHandle->CTRL = 0; - USB_Endpoint_SelectedHandle->STATUS = (Address & ENDPOINT_DIR_IN) ? USB_EP_BUSNACK0_bm : 0; - 3ee4: 82 e0 ldi r24, 0x02 ; 2 - 3ee6: 80 83 st Z, r24 - USB_Endpoint_SelectedHandle->CTRL = Config; - 3ee8: e0 91 1f 27 lds r30, 0x271F - 3eec: f0 91 20 27 lds r31, 0x2720 - 3ef0: 61 83 std Z+1, r22 ; 0x01 - USB_Endpoint_SelectedHandle->CNT = 0; - 3ef2: e0 91 1f 27 lds r30, 0x271F - 3ef6: f0 91 20 27 lds r31, 0x2720 - 3efa: 12 82 std Z+2, r1 ; 0x02 - 3efc: 13 82 std Z+3, r1 ; 0x03 - USB_Endpoint_SelectedHandle->DATAPTR = (intptr_t)USB_Endpoint_SelectedFIFO->Data; - 3efe: 80 91 1d 27 lds r24, 0x271D - 3f02: 90 91 1e 27 lds r25, 0x271E - 3f06: 84 83 std Z+4, r24 ; 0x04 - 3f08: 95 83 std Z+5, r25 ; 0x05 - 3f0a: df cf rjmp .-66 ; 0x3eca - -00003f0c : - } -} - -bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, - const uint8_t Entries) -{ - 3f0c: cf 92 push r12 - 3f0e: df 92 push r13 - 3f10: ef 92 push r14 - 3f12: ff 92 push r15 - 3f14: 0f 93 push r16 - 3f16: 1f 93 push r17 - 3f18: cf 93 push r28 - 3f1a: df 93 push r29 - 3f1c: 1f 92 push r1 - 3f1e: cd b7 in r28, 0x3d ; 61 - 3f20: de b7 in r29, 0x3e ; 62 - 3f22: f6 2e mov r15, r22 - for (uint8_t i = 0; i < Entries; i++) - 3f24: 66 23 and r22, r22 - 3f26: 09 f4 brne .+2 ; 0x3f2a - 3f28: 3e c0 rjmp .+124 ; 0x3fa6 - 3f2a: 6c 01 movw r12, r24 - 3f2c: 00 e0 ldi r16, 0x00 ; 0 - { - if (!(Table[i].Address)) - 3f2e: d6 01 movw r26, r12 - 3f30: 1c 91 ld r17, X - 3f32: 11 23 and r17, r17 - 3f34: 91 f1 breq .+100 ; 0x3f9a - continue; - - if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks))) - 3f36: d6 01 movw r26, r12 - 3f38: 11 96 adiw r26, 0x01 ; 1 - 3f3a: ed 91 ld r30, X+ - 3f3c: fc 91 ld r31, X - 3f3e: 12 97 sbiw r26, 0x02 ; 2 - 3f40: 13 96 adiw r26, 0x03 ; 3 - 3f42: 8c 91 ld r24, X - 3f44: 13 97 sbiw r26, 0x03 ; 3 - static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address, - const uint8_t Type, - const uint16_t Size, - const uint8_t Banks) - { - uint8_t EPConfigMask = (USB_EP_INTDSBL_bm | ((Banks > 1) ? USB_EP_PINGPONG_bm : 0) | Endpoint_BytesToEPSizeMask(Size)); - 3f46: 14 96 adiw r26, 0x04 ; 4 - 3f48: 9c 91 ld r25, X - 3f4a: 92 30 cpi r25, 0x02 ; 2 - 3f4c: 08 f4 brcc .+2 ; 0x3f50 - 3f4e: 45 c0 rjmp .+138 ; 0x3fda - 3f50: 98 e1 ldi r25, 0x18 ; 24 - 3f52: 48 e1 ldi r20, 0x18 ; 24 - static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) - { - uint8_t MaskVal = 0; - uint16_t CheckBytes = 8; - - while (CheckBytes < Bytes) - 3f54: e9 30 cpi r30, 0x09 ; 9 - 3f56: f1 05 cpc r31, r1 - 3f58: 50 f0 brcs .+20 ; 0x3f6e - static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST - ATTR_ALWAYS_INLINE; - static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) - { - uint8_t MaskVal = 0; - uint16_t CheckBytes = 8; - 3f5a: 28 e0 ldi r18, 0x08 ; 8 - 3f5c: 30 e0 ldi r19, 0x00 ; 0 - /* Inline Functions: */ - static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST - ATTR_ALWAYS_INLINE; - static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) - { - uint8_t MaskVal = 0; - 3f5e: 90 e0 ldi r25, 0x00 ; 0 - uint16_t CheckBytes = 8; - - while (CheckBytes < Bytes) - { - MaskVal++; - 3f60: 9f 5f subi r25, 0xFF ; 255 - CheckBytes <<= 1; - 3f62: 22 0f add r18, r18 - 3f64: 33 1f adc r19, r19 - static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) - { - uint8_t MaskVal = 0; - uint16_t CheckBytes = 8; - - while (CheckBytes < Bytes) - 3f66: 2e 17 cp r18, r30 - 3f68: 3f 07 cpc r19, r31 - 3f6a: d0 f3 brcs .-12 ; 0x3f60 - 3f6c: 94 2b or r25, r20 - const uint16_t Size, - const uint8_t Banks) - { - uint8_t EPConfigMask = (USB_EP_INTDSBL_bm | ((Banks > 1) ? USB_EP_PINGPONG_bm : 0) | Endpoint_BytesToEPSizeMask(Size)); - - if ((Address & ENDPOINT_EPNUM_MASK) >= ENDPOINT_TOTAL_ENDPOINTS) - 3f6e: 21 2f mov r18, r17 - 3f70: 2f 70 andi r18, 0x0F ; 15 - 3f72: 30 e0 ldi r19, 0x00 ; 0 - 3f74: 26 30 cpi r18, 0x06 ; 6 - 3f76: 31 05 cpc r19, r1 - 3f78: 9c f5 brge .+102 ; 0x3fe0 - return false; - - // TODO - Fix once limitations are lifted - EPConfigMask &= ~USB_EP_PINGPONG_bm; - 3f7a: 9f 7e andi r25, 0xEF ; 239 - if (Size > 64) - 3f7c: e1 34 cpi r30, 0x41 ; 65 - 3f7e: f1 05 cpc r31, r1 - 3f80: 78 f5 brcc .+94 ; 0x3fe0 - return false; - - switch (Type) - 3f82: 88 23 and r24, r24 - 3f84: 01 f1 breq .+64 ; 0x3fc6 - 3f86: 81 30 cpi r24, 0x01 ; 1 - 3f88: c9 f4 brne .+50 ; 0x3fbc - { - case EP_TYPE_CONTROL: - EPConfigMask |= USB_EP_TYPE_CONTROL_gc; - break; - case EP_TYPE_ISOCHRONOUS: - EPConfigMask |= USB_EP_TYPE_ISOCHRONOUS_gc; - 3f8a: 90 6c ori r25, 0xC0 ; 192 - 3f8c: ee 2e mov r14, r30 - } - - if (Type == EP_TYPE_CONTROL) - Endpoint_ConfigureEndpoint_PRV(Address ^ ENDPOINT_DIR_IN, EPConfigMask, Size); - - return Endpoint_ConfigureEndpoint_PRV(Address, EPConfigMask, Size); - 3f8e: 4e 2d mov r20, r14 - 3f90: 69 2f mov r22, r25 - 3f92: 81 2f mov r24, r17 - 3f94: 70 df rcall .-288 ; 0x3e76 - 3f96: 88 23 and r24, r24 - 3f98: 19 f1 breq .+70 ; 0x3fe0 -} - -bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, - const uint8_t Entries) -{ - for (uint8_t i = 0; i < Entries; i++) - 3f9a: 0f 5f subi r16, 0xFF ; 255 - 3f9c: b5 e0 ldi r27, 0x05 ; 5 - 3f9e: cb 0e add r12, r27 - 3fa0: d1 1c adc r13, r1 - 3fa2: 0f 11 cpse r16, r15 - 3fa4: c4 cf rjmp .-120 ; 0x3f2e - { - return false; - } - } - - return true; - 3fa6: 81 e0 ldi r24, 0x01 ; 1 -} - 3fa8: 0f 90 pop r0 - 3faa: df 91 pop r29 - 3fac: cf 91 pop r28 - 3fae: 1f 91 pop r17 - 3fb0: 0f 91 pop r16 - 3fb2: ff 90 pop r15 - 3fb4: ef 90 pop r14 - 3fb6: df 90 pop r13 - 3fb8: cf 90 pop r12 - 3fba: 08 95 ret - break; - case EP_TYPE_ISOCHRONOUS: - EPConfigMask |= USB_EP_TYPE_ISOCHRONOUS_gc; - break; - default: - EPConfigMask |= USB_EP_TYPE_BULK_gc; - 3fbc: 90 68 ori r25, 0x80 ; 128 - break; - } - - if (Type == EP_TYPE_CONTROL) - 3fbe: 88 23 and r24, r24 - 3fc0: 19 f0 breq .+6 ; 0x3fc8 - 3fc2: ee 2e mov r14, r30 - 3fc4: e4 cf rjmp .-56 ; 0x3f8e - return false; - - switch (Type) - { - case EP_TYPE_CONTROL: - EPConfigMask |= USB_EP_TYPE_CONTROL_gc; - 3fc6: 90 64 ori r25, 0x40 ; 64 - EPConfigMask |= USB_EP_TYPE_BULK_gc; - break; - } - - if (Type == EP_TYPE_CONTROL) - Endpoint_ConfigureEndpoint_PRV(Address ^ ENDPOINT_DIR_IN, EPConfigMask, Size); - 3fc8: ee 2e mov r14, r30 - 3fca: 4e 2f mov r20, r30 - 3fcc: 69 2f mov r22, r25 - 3fce: 80 e8 ldi r24, 0x80 ; 128 - 3fd0: 81 0f add r24, r17 - 3fd2: 99 83 std Y+1, r25 ; 0x01 - 3fd4: 50 df rcall .-352 ; 0x3e76 - 3fd6: 99 81 ldd r25, Y+1 ; 0x01 - 3fd8: da cf rjmp .-76 ; 0x3f8e - static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address, - const uint8_t Type, - const uint16_t Size, - const uint8_t Banks) - { - uint8_t EPConfigMask = (USB_EP_INTDSBL_bm | ((Banks > 1) ? USB_EP_PINGPONG_bm : 0) | Endpoint_BytesToEPSizeMask(Size)); - 3fda: 98 e0 ldi r25, 0x08 ; 8 - 3fdc: 48 e0 ldi r20, 0x08 ; 8 - 3fde: ba cf rjmp .-140 ; 0x3f54 - if (!(Table[i].Address)) - continue; - - if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks))) - { - return false; - 3fe0: 80 e0 ldi r24, 0x00 ; 0 - 3fe2: e2 cf rjmp .-60 ; 0x3fa8 - -00003fe4 : - -void Endpoint_ClearEndpoints(void) -{ - for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) - { - ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; - 3fe4: e0 ec ldi r30, 0xC0 ; 192 - 3fe6: f4 e0 ldi r31, 0x04 ; 4 - 3fe8: a6 81 ldd r26, Z+6 ; 0x06 - 3fea: b7 81 ldd r27, Z+7 ; 0x07 - 3fec: 19 96 adiw r26, 0x09 ; 9 - 3fee: 1c 92 st X, r1 - ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; - 3ff0: a6 81 ldd r26, Z+6 ; 0x06 - 3ff2: b7 81 ldd r27, Z+7 ; 0x07 - 3ff4: 11 96 adiw r26, 0x01 ; 1 - 3ff6: 1c 92 st X, r1 - -void Endpoint_ClearEndpoints(void) -{ - for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) - { - ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; - 3ff8: a6 81 ldd r26, Z+6 ; 0x06 - 3ffa: b7 81 ldd r27, Z+7 ; 0x07 - 3ffc: 59 96 adiw r26, 0x19 ; 25 - 3ffe: 1c 92 st X, r1 - ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; - 4000: a6 81 ldd r26, Z+6 ; 0x06 - 4002: b7 81 ldd r27, Z+7 ; 0x07 - 4004: 51 96 adiw r26, 0x11 ; 17 - 4006: 1c 92 st X, r1 - -void Endpoint_ClearEndpoints(void) -{ - for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) - { - ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; - 4008: a6 81 ldd r26, Z+6 ; 0x06 - 400a: b7 81 ldd r27, Z+7 ; 0x07 - 400c: 99 96 adiw r26, 0x29 ; 41 - 400e: 1c 92 st X, r1 - ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; - 4010: a6 81 ldd r26, Z+6 ; 0x06 - 4012: b7 81 ldd r27, Z+7 ; 0x07 - 4014: 91 96 adiw r26, 0x21 ; 33 - 4016: 1c 92 st X, r1 - -void Endpoint_ClearEndpoints(void) -{ - for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) - { - ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; - 4018: a6 81 ldd r26, Z+6 ; 0x06 - 401a: b7 81 ldd r27, Z+7 ; 0x07 - 401c: d9 96 adiw r26, 0x39 ; 57 - 401e: 1c 92 st X, r1 - ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; - 4020: a6 81 ldd r26, Z+6 ; 0x06 - 4022: b7 81 ldd r27, Z+7 ; 0x07 - 4024: d1 96 adiw r26, 0x31 ; 49 - 4026: 1c 92 st X, r1 - -void Endpoint_ClearEndpoints(void) -{ - for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) - { - ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; - 4028: a6 81 ldd r26, Z+6 ; 0x06 - 402a: b7 81 ldd r27, Z+7 ; 0x07 - 402c: a7 5b subi r26, 0xB7 ; 183 - 402e: bf 4f sbci r27, 0xFF ; 255 - 4030: 1c 92 st X, r1 - ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; - 4032: a6 81 ldd r26, Z+6 ; 0x06 - 4034: b7 81 ldd r27, Z+7 ; 0x07 - 4036: af 5b subi r26, 0xBF ; 191 - 4038: bf 4f sbci r27, 0xFF ; 255 - 403a: 1c 92 st X, r1 - -void Endpoint_ClearEndpoints(void) -{ - for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) - { - ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; - 403c: a6 81 ldd r26, Z+6 ; 0x06 - 403e: b7 81 ldd r27, Z+7 ; 0x07 - 4040: a7 5a subi r26, 0xA7 ; 167 - 4042: bf 4f sbci r27, 0xFF ; 255 - 4044: 1c 92 st X, r1 - ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; - 4046: 06 80 ldd r0, Z+6 ; 0x06 - 4048: f7 81 ldd r31, Z+7 ; 0x07 - 404a: e0 2d mov r30, r0 - 404c: ef 5a subi r30, 0xAF ; 175 - 404e: ff 4f sbci r31, 0xFF ; 255 - 4050: 10 82 st Z, r1 - 4052: 08 95 ret - -00004054 : - } -} - -void Endpoint_ClearStatusStage(void) -{ - if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) - 4054: 80 91 15 27 lds r24, 0x2715 - 4058: 87 ff sbrs r24, 7 - 405a: 05 c0 rjmp .+10 ; 0x4066 - 405c: 0c c0 rjmp .+24 ; 0x4076 - } - else - { - while (!(Endpoint_IsINReady())) - { - if (USB_DeviceState == DEVICE_STATE_Unattached) - 405e: 80 91 14 27 lds r24, 0x2714 - 4062: 88 23 and r24, r24 - 4064: 61 f0 breq .+24 ; 0x407e - - Endpoint_ClearOUT(); - } - else - { - while (!(Endpoint_IsINReady())) - 4066: 81 de rcall .-766 ; 0x3d6a - 4068: 88 23 and r24, r24 - 406a: c9 f3 breq .-14 ; 0x405e - { - if (USB_DeviceState == DEVICE_STATE_Unattached) - return; - } - - Endpoint_ClearIN(); - 406c: fd cd rjmp .-1030 ; 0x3c68 -{ - if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) - { - while (!(Endpoint_IsOUTReceived())) - { - if (USB_DeviceState == DEVICE_STATE_Unattached) - 406e: 80 91 14 27 lds r24, 0x2714 - 4072: 88 23 and r24, r24 - 4074: 21 f0 breq .+8 ; 0x407e - -void Endpoint_ClearStatusStage(void) -{ - if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) - { - while (!(Endpoint_IsOUTReceived())) - 4076: 85 de rcall .-758 ; 0x3d82 - 4078: 88 23 and r24, r24 - 407a: c9 f3 breq .-14 ; 0x406e - { - if (USB_DeviceState == DEVICE_STATE_Unattached) - return; - } - - Endpoint_ClearOUT(); - 407c: 0e ce rjmp .-996 ; 0x3c9a - 407e: 08 95 ret - -00004080 : - } -} - -#if !defined(CONTROL_ONLY_DEVICE) -uint8_t Endpoint_WaitUntilReady(void) -{ - 4080: 1f 93 push r17 - 4082: cf 93 push r28 - 4084: df 93 push r29 - * \return Current USB frame number from the USB controller. - */ - static inline uint16_t USB_Device_GetFrameNumber(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; - static inline uint16_t USB_Device_GetFrameNumber(void) - { - return ((USB_EndpointTable_t*)USB.EPPTR)->FrameNum; - 4086: e0 91 c6 04 lds r30, 0x04C6 - 408a: f0 91 c7 04 lds r31, 0x04C7 - 408e: e0 5a subi r30, 0xA0 ; 160 - 4090: ff 4f sbci r31, 0xFF ; 255 - 4092: c0 81 ld r28, Z - 4094: d1 81 ldd r29, Z+1 ; 0x01 - #if (USB_STREAM_TIMEOUT_MS < 0xFF) - uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; - 4096: 14 e6 ldi r17, 0x64 ; 100 - * \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask. - */ - static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; - static inline uint8_t Endpoint_GetEndpointDirection(void) - { - return (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN); - 4098: 80 91 21 27 lds r24, 0x2721 - 409c: 80 78 andi r24, 0x80 ; 128 - - uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber(); - - for (;;) - { - if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) - 409e: 80 38 cpi r24, 0x80 ; 128 - 40a0: 31 f1 breq .+76 ; 0x40ee - if (Endpoint_IsINReady()) - return ENDPOINT_READYWAIT_NoError; - } - else - { - if (Endpoint_IsOUTReceived()) - 40a2: 6f de rcall .-802 ; 0x3d82 - 40a4: 81 11 cpse r24, r1 - 40a6: 26 c0 rjmp .+76 ; 0x40f4 - return ENDPOINT_READYWAIT_NoError; - } - - uint8_t USB_DeviceState_LCL = USB_DeviceState; - 40a8: 80 91 14 27 lds r24, 0x2714 - - if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) - 40ac: 88 23 and r24, r24 - 40ae: 39 f1 breq .+78 ; 0x40fe - return ENDPOINT_READYWAIT_DeviceDisconnected; - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - 40b0: 85 30 cpi r24, 0x05 ; 5 - 40b2: 51 f1 breq .+84 ; 0x4108 - * \return Boolean \c true if the currently selected endpoint is stalled, \c false otherwise. - */ - static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; - static inline bool Endpoint_IsStalled(void) - { - return ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_STALL_bm) ? true : false); - 40b4: e0 91 1f 27 lds r30, 0x271F - 40b8: f0 91 20 27 lds r31, 0x2720 - 40bc: 81 81 ldd r24, Z+1 ; 0x01 - return ENDPOINT_READYWAIT_BusSuspended; - else if (Endpoint_IsStalled()) - 40be: 82 fd sbrc r24, 2 - 40c0: 28 c0 rjmp .+80 ; 0x4112 - 40c2: e0 91 c6 04 lds r30, 0x04C6 - 40c6: f0 91 c7 04 lds r31, 0x04C7 - 40ca: e0 5a subi r30, 0xA0 ; 160 - 40cc: ff 4f sbci r31, 0xFF ; 255 - 40ce: 80 81 ld r24, Z - 40d0: 91 81 ldd r25, Z+1 ; 0x01 - return ENDPOINT_READYWAIT_EndpointStalled; - - uint16_t CurrentFrameNumber = USB_Device_GetFrameNumber(); - - if (CurrentFrameNumber != PreviousFrameNumber) - 40d2: c8 17 cp r28, r24 - 40d4: d9 07 cpc r29, r25 - 40d6: 01 f3 breq .-64 ; 0x4098 - { - PreviousFrameNumber = CurrentFrameNumber; - - if (!(TimeoutMSRem--)) - 40d8: 2f ef ldi r18, 0xFF ; 255 - 40da: 21 0f add r18, r17 - 40dc: 11 23 and r17, r17 - 40de: f1 f0 breq .+60 ; 0x411c - 40e0: ec 01 movw r28, r24 - 40e2: 12 2f mov r17, r18 - * \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask. - */ - static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; - static inline uint8_t Endpoint_GetEndpointDirection(void) - { - return (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN); - 40e4: 80 91 21 27 lds r24, 0x2721 - 40e8: 80 78 andi r24, 0x80 ; 128 - - uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber(); - - for (;;) - { - if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) - 40ea: 80 38 cpi r24, 0x80 ; 128 - 40ec: d1 f6 brne .-76 ; 0x40a2 - { - if (Endpoint_IsINReady()) - 40ee: 3d de rcall .-902 ; 0x3d6a - 40f0: 88 23 and r24, r24 - 40f2: d1 f2 breq .-76 ; 0x40a8 - return ENDPOINT_READYWAIT_NoError; - 40f4: 80 e0 ldi r24, 0x00 ; 0 - - if (!(TimeoutMSRem--)) - return ENDPOINT_READYWAIT_Timeout; - } - } -} - 40f6: df 91 pop r29 - 40f8: cf 91 pop r28 - 40fa: 1f 91 pop r17 - 40fc: 08 95 ret - } - - uint8_t USB_DeviceState_LCL = USB_DeviceState; - - if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) - return ENDPOINT_READYWAIT_DeviceDisconnected; - 40fe: 82 e0 ldi r24, 0x02 ; 2 - - if (!(TimeoutMSRem--)) - return ENDPOINT_READYWAIT_Timeout; - } - } -} - 4100: df 91 pop r29 - 4102: cf 91 pop r28 - 4104: 1f 91 pop r17 - 4106: 08 95 ret - uint8_t USB_DeviceState_LCL = USB_DeviceState; - - if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) - return ENDPOINT_READYWAIT_DeviceDisconnected; - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - return ENDPOINT_READYWAIT_BusSuspended; - 4108: 83 e0 ldi r24, 0x03 ; 3 - - if (!(TimeoutMSRem--)) - return ENDPOINT_READYWAIT_Timeout; - } - } -} - 410a: df 91 pop r29 - 410c: cf 91 pop r28 - 410e: 1f 91 pop r17 - 4110: 08 95 ret - if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) - return ENDPOINT_READYWAIT_DeviceDisconnected; - else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) - return ENDPOINT_READYWAIT_BusSuspended; - else if (Endpoint_IsStalled()) - return ENDPOINT_READYWAIT_EndpointStalled; - 4112: 81 e0 ldi r24, 0x01 ; 1 - - if (!(TimeoutMSRem--)) - return ENDPOINT_READYWAIT_Timeout; - } - } -} - 4114: df 91 pop r29 - 4116: cf 91 pop r28 - 4118: 1f 91 pop r17 - 411a: 08 95 ret - if (CurrentFrameNumber != PreviousFrameNumber) - { - PreviousFrameNumber = CurrentFrameNumber; - - if (!(TimeoutMSRem--)) - return ENDPOINT_READYWAIT_Timeout; - 411c: 84 e0 ldi r24, 0x04 ; 4 - } - } -} - 411e: df 91 pop r29 - 4120: cf 91 pop r28 - 4122: 1f 91 pop r17 - 4124: 08 95 ret - -00004126 : - USB_ResetInterface(); -} - -void USB_Disable(void) -{ - USB_INT_DisableAllInterrupts(); - 4126: 62 d0 rcall .+196 ; 0x41ec - USB_INT_ClearAllInterrupts(); - 4128: 68 d0 rcall .+208 ; 0x41fa - * enumerating the device once attached until \ref USB_Attach() is called. - */ - static inline void USB_Detach(void) ATTR_ALWAYS_INLINE; - static inline void USB_Detach(void) - { - USB.CTRLB &= ~USB_ATTACH_bm; - 412a: e0 ec ldi r30, 0xC0 ; 192 - 412c: f4 e0 ldi r31, 0x04 ; 4 - 412e: 81 81 ldd r24, Z+1 ; 0x01 - 4130: 8e 7f andi r24, 0xFE ; 254 - 4132: 81 83 std Z+1, r24 ; 0x01 - } - - static inline void USB_Controller_Disable(void) ATTR_ALWAYS_INLINE; - static inline void USB_Controller_Disable(void) - { - USB.CTRLA &= ~USB_ENABLE_bm; - 4134: 80 81 ld r24, Z - 4136: 8f 77 andi r24, 0x7F ; 127 - 4138: 80 83 st Z, r24 - - USB_Detach(); - USB_Controller_Disable(); - - USB_IsInitialized = false; - 413a: 10 92 13 27 sts 0x2713, r1 - 413e: 08 95 ret - -00004140 : -} - -void USB_ResetInterface(void) -{ - 4140: cf 93 push r28 - 4142: df 93 push r29 - #if defined(USB_DEVICE_OPT_FULLSPEED) - if (USB_Options & USB_DEVICE_OPT_LOWSPEED) - CLK.USBCTRL = (((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp); - else - CLK.USBCTRL = (((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp); - 4144: e0 e4 ldi r30, 0x40 ; 64 - 4146: f0 e0 ldi r31, 0x00 ; 0 - 4148: 14 82 std Z+4, r1 ; 0x04 - #else - CLK.USBCTRL = (((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp); - #endif - - if (USB_Options & USB_OPT_PLLCLKSRC) - CLK.USBCTRL |= (CLK_USBSRC_PLL_gc | CLK_USBSEN_bm); - 414a: 84 81 ldd r24, Z+4 ; 0x04 - 414c: 81 60 ori r24, 0x01 ; 1 - 414e: 84 83 std Z+4, r24 ; 0x04 - else - CLK.USBCTRL |= (CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm); - - USB_Device_SetDeviceAddress(0); - - USB_INT_DisableAllInterrupts(); - 4150: 4d d0 rcall .+154 ; 0x41ec - USB_INT_ClearAllInterrupts(); - 4152: 53 d0 rcall .+166 ; 0x41fa - } - - static inline void USB_Controller_Reset(void) ATTR_ALWAYS_INLINE; - static inline void USB_Controller_Reset(void) - { - USB.CTRLA &= ~USB_ENABLE_bm; - 4154: c0 ec ldi r28, 0xC0 ; 192 - 4156: d4 e0 ldi r29, 0x04 ; 4 - 4158: 88 81 ld r24, Y - 415a: 8f 77 andi r24, 0x7F ; 127 - 415c: 88 83 st Y, r24 - USB.CTRLA |= USB_ENABLE_bm; - 415e: 88 81 ld r24, Y - 4160: 80 68 ori r24, 0x80 ; 128 - 4162: 88 83 st Y, r24 -} - -#if defined(USB_CAN_BE_DEVICE) -static void USB_Init_Device(void) -{ - USB_DeviceState = DEVICE_STATE_Unattached; - 4164: 10 92 14 27 sts 0x2714, r1 - USB_Device_ConfigurationNumber = 0; - 4168: 10 92 10 27 sts 0x2710, r1 - - #if !defined(NO_DEVICE_REMOTE_WAKEUP) - USB_Device_RemoteWakeupEnabled = false; - 416c: 10 92 12 27 sts 0x2712, r1 - #endif - - #if !defined(NO_DEVICE_SELF_POWER) - USB_Device_CurrentlySelfPowered = false; - 4170: 10 92 11 27 sts 0x2711, r1 - } - - static inline void USB_Device_SetFullSpeed(void) ATTR_ALWAYS_INLINE; - static inline void USB_Device_SetFullSpeed(void) - { - USB.CTRLA |= USB_SPEED_bm; - 4174: 88 81 ld r24, Y - 4176: 80 64 ori r24, 0x40 ; 64 - 4178: 88 83 st Y, r24 - EPConfigMask |= USB_EP_TYPE_BULK_gc; - break; - } - - if (Type == EP_TYPE_CONTROL) - Endpoint_ConfigureEndpoint_PRV(Address ^ ENDPOINT_DIR_IN, EPConfigMask, Size); - 417a: 48 e0 ldi r20, 0x08 ; 8 - 417c: 68 e4 ldi r22, 0x48 ; 72 - 417e: 80 e8 ldi r24, 0x80 ; 128 - 4180: 7a de rcall .-780 ; 0x3e76 - - return Endpoint_ConfigureEndpoint_PRV(Address, EPConfigMask, Size); - 4182: 48 e0 ldi r20, 0x08 ; 8 - 4184: 68 e4 ldi r22, 0x48 ; 72 - 4186: 80 e0 ldi r24, 0x00 ; 0 - 4188: 76 de rcall .-788 ; 0x3e76 - static inline void USB_INT_Enable(const uint8_t Interrupt) - { - switch (Interrupt) - { - case USB_INT_BUSEVENTI: - USB.INTCTRLA |= USB_BUSEVIE_bm; - 418a: 88 85 ldd r24, Y+8 ; 0x08 - 418c: 80 64 ori r24, 0x40 ; 64 - 418e: 88 87 std Y+8, r24 ; 0x08 - * register and despite the datasheet making no mention of its requirement in host mode. - */ - static inline void USB_Attach(void) ATTR_ALWAYS_INLINE; - static inline void USB_Attach(void) - { - USB.CTRLB |= USB_ATTACH_bm; - 4190: 89 81 ldd r24, Y+1 ; 0x01 - 4192: 81 60 ori r24, 0x01 ; 1 - 4194: 89 83 std Y+1, r24 ; 0x01 - USB_INT_DisableAllInterrupts(); - USB_INT_ClearAllInterrupts(); - - USB_Controller_Reset(); - USB_Init_Device(); -} - 4196: df 91 pop r29 - 4198: cf 91 pop r28 - 419a: 08 95 ret - -0000419c : - #if (ARCH == ARCH_AVR8) - return SREG; - #elif (ARCH == ARCH_UC3) - return __builtin_mfsr(AVR32_SR); - #elif (ARCH == ARCH_XMEGA) - return SREG; - 419c: 2f b7 in r18, 0x3f ; 63 - #if (ARCH == ARCH_AVR8) - cli(); - #elif (ARCH == ARCH_UC3) - __builtin_ssrf(AVR32_SR_GM_OFFSET); - #elif (ARCH == ARCH_XMEGA) - cli(); - 419e: f8 94 cli - #endif - - uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); - GlobalInterruptDisable(); - - NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; - 41a0: 82 e0 ldi r24, 0x02 ; 2 - 41a2: e0 ec ldi r30, 0xC0 ; 192 - 41a4: f1 e0 ldi r31, 0x01 ; 1 - 41a6: 82 87 std Z+10, r24 ; 0x0a - USB.CAL0 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL0)); - 41a8: ea e1 ldi r30, 0x1A ; 26 - 41aa: f0 e0 ldi r31, 0x00 ; 0 - 41ac: e4 91 lpm r30, Z - 41ae: a0 ec ldi r26, 0xC0 ; 192 - 41b0: b4 e0 ldi r27, 0x04 ; 4 - 41b2: da 96 adiw r26, 0x3a ; 58 - 41b4: ec 93 st X, r30 - 41b6: da 97 sbiw r26, 0x3a ; 58 - USB.CAL1 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL1)); - 41b8: eb e1 ldi r30, 0x1B ; 27 - 41ba: f0 e0 ldi r31, 0x00 ; 0 - 41bc: e4 91 lpm r30, Z - 41be: db 96 adiw r26, 0x3b ; 59 - 41c0: ec 93 st X, r30 - 41c2: db 97 sbiw r26, 0x3b ; 59 - NVM.CMD = NVM_CMD_NO_OPERATION_gc; - 41c4: e0 ec ldi r30, 0xC0 ; 192 - 41c6: f1 e0 ldi r31, 0x01 ; 1 - 41c8: 12 86 std Z+10, r1 ; 0x0a - - /* Ugly workaround to ensure an aligned table, since __BIGGEST_ALIGNMENT__ == 1 for the 8-bit AVR-GCC toolchain */ - USB.EPPTR = ((intptr_t)&USB_EndpointTable[1] & ~(1 << 0)); - 41ca: 8b e3 ldi r24, 0x3B ; 59 - 41cc: 9a e2 ldi r25, 0x2A ; 42 - 41ce: 8e 7f andi r24, 0xFE ; 254 - 41d0: 16 96 adiw r26, 0x06 ; 6 - 41d2: 8d 93 st X+, r24 - 41d4: 9c 93 st X, r25 - 41d6: 17 97 sbiw r26, 0x07 ; 7 - USB.CTRLA = (USB_STFRNUM_bm | ((ENDPOINT_TOTAL_ENDPOINTS - 1) << USB_MAXEP_gp)); - 41d8: 85 e1 ldi r24, 0x15 ; 21 - 41da: 8c 93 st X, r24 - - if ((USB_Options & USB_OPT_BUSEVENT_PRIHIGH) == USB_OPT_BUSEVENT_PRIHIGH) - USB.INTCTRLA = (3 << USB_INTLVL_gp); - else if ((USB_Options & USB_OPT_BUSEVENT_PRIMED) == USB_OPT_BUSEVENT_PRIMED) - USB.INTCTRLA = (2 << USB_INTLVL_gp); - 41dc: 82 e0 ldi r24, 0x02 ; 2 - 41de: 18 96 adiw r26, 0x08 ; 8 - 41e0: 8c 93 st X, r24 - if (GlobalIntState & AVR32_SR_GM) - __builtin_ssrf(AVR32_SR_GM_OFFSET); - else - __builtin_csrf(AVR32_SR_GM_OFFSET); - #elif (ARCH == ARCH_XMEGA) - SREG = GlobalIntState; - 41e2: 2f bf out 0x3f, r18 ; 63 - - #if defined(USB_CAN_BE_BOTH) - USB_CurrentMode = Mode; - #endif - - USB_IsInitialized = true; - 41e4: 81 e0 ldi r24, 0x01 ; 1 - 41e6: 80 93 13 27 sts 0x2713, r24 - - USB_ResetInterface(); - 41ea: aa cf rjmp .-172 ; 0x4140 - -000041ec : -#define __INCLUDE_FROM_USB_DRIVER -#include "../USBInterrupt.h" - -void USB_INT_DisableAllInterrupts(void) -{ - USB.INTCTRLA &= USB_INTLVL_gm; - 41ec: e0 ec ldi r30, 0xC0 ; 192 - 41ee: f4 e0 ldi r31, 0x04 ; 4 - 41f0: 80 85 ldd r24, Z+8 ; 0x08 - 41f2: 83 70 andi r24, 0x03 ; 3 - 41f4: 80 87 std Z+8, r24 ; 0x08 - USB.INTCTRLB = 0; - 41f6: 11 86 std Z+9, r1 ; 0x09 - 41f8: 08 95 ret - -000041fa : -} - -void USB_INT_ClearAllInterrupts(void) -{ - USB.INTFLAGSACLR = 0xFF; - 41fa: e0 ec ldi r30, 0xC0 ; 192 - 41fc: f4 e0 ldi r31, 0x04 ; 4 - 41fe: 8f ef ldi r24, 0xFF ; 255 - 4200: 82 87 std Z+10, r24 ; 0x0a - USB.INTFLAGSBCLR = 0xFF; - 4202: 84 87 std Z+12, r24 ; 0x0c - 4204: 08 95 ret - -00004206 <__vector_125>: -} - -ISR(USB_BUSEVENT_vect) -{ - 4206: 1f 92 push r1 - 4208: 0f 92 push r0 - 420a: 0f b6 in r0, 0x3f ; 63 - 420c: 0f 92 push r0 - 420e: 11 24 eor r1, r1 - 4210: 2f 93 push r18 - 4212: 3f 93 push r19 - 4214: 4f 93 push r20 - 4216: 5f 93 push r21 - 4218: 6f 93 push r22 - 421a: 7f 93 push r23 - 421c: 8f 93 push r24 - 421e: 9f 93 push r25 - 4220: af 93 push r26 - 4222: bf 93 push r27 - 4224: ef 93 push r30 - 4226: ff 93 push r31 - case USB_INT_BUSEVENTI_Resume: - return ((USB.INTFLAGSACLR & USB_RESUMEIF_bm) ? true : false); - case USB_INT_BUSEVENTI_Reset: - return ((USB.INTFLAGSACLR & USB_RSTIF_bm) ? true : false); - case USB_INT_SOFI: - return ((USB.INTFLAGSACLR & USB_SOFIF_bm) ? true : false); - 4228: 80 91 ca 04 lds r24, 0x04CA - #if !defined(NO_SOF_EVENTS) - if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI)) - 422c: 87 fd sbrc r24, 7 - 422e: 4d c0 rjmp .+154 ; 0x42ca <__vector_125+0xc4> - static inline bool USB_INT_HasOccurred(const uint8_t Interrupt) - { - switch (Interrupt) - { - case USB_INT_BUSEVENTI_Suspend: - return ((USB.INTFLAGSACLR & USB_SUSPENDIF_bm) ? true : false); - 4230: 80 91 ca 04 lds r24, 0x04CA - - EVENT_USB_Device_StartOfFrame(); - } - #endif - - if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Suspend)) - 4234: 86 fd sbrc r24, 6 - 4236: 41 c0 rjmp .+130 ; 0x42ba <__vector_125+0xb4> - case USB_INT_BUSEVENTI_Resume: - return ((USB.INTFLAGSACLR & USB_RESUMEIF_bm) ? true : false); - 4238: 80 91 ca 04 lds r24, 0x04CA - USB_DeviceState = DEVICE_STATE_Suspended; - EVENT_USB_Device_Suspend(); - #endif - } - - if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Resume)) - 423c: 85 ff sbrs r24, 5 - 423e: 0c c0 rjmp .+24 ; 0x4258 <__vector_125+0x52> - { - case USB_INT_BUSEVENTI_Suspend: - USB.INTFLAGSACLR = USB_SUSPENDIF_bm; - break; - case USB_INT_BUSEVENTI_Resume: - USB.INTFLAGSACLR = USB_RESUMEIF_bm; - 4240: 80 e2 ldi r24, 0x20 ; 32 - 4242: 80 93 ca 04 sts 0x04CA, r24 - { - USB_INT_Clear(USB_INT_BUSEVENTI_Resume); - - if (USB_Device_ConfigurationNumber) - 4246: 80 91 10 27 lds r24, 0x2710 - 424a: 88 23 and r24, r24 - 424c: 71 f1 breq .+92 ; 0x42aa <__vector_125+0xa4> - USB_DeviceState = DEVICE_STATE_Configured; - 424e: 84 e0 ldi r24, 0x04 ; 4 - 4250: 80 93 14 27 sts 0x2714, r24 - else - USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Addressed : DEVICE_STATE_Powered; - - #if !defined(NO_LIMITED_CONTROLLER_CONNECT) - EVENT_USB_Device_Connect(); - 4254: 0e 94 02 0d call 0x1a04 ; 0x1a04 - case USB_INT_BUSEVENTI_Suspend: - return ((USB.INTFLAGSACLR & USB_SUSPENDIF_bm) ? true : false); - case USB_INT_BUSEVENTI_Resume: - return ((USB.INTFLAGSACLR & USB_RESUMEIF_bm) ? true : false); - case USB_INT_BUSEVENTI_Reset: - return ((USB.INTFLAGSACLR & USB_RSTIF_bm) ? true : false); - 4258: 80 91 ca 04 lds r24, 0x04CA - #else - EVENT_USB_Device_WakeUp(); - #endif - } - - if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Reset)) - 425c: 84 ff sbrs r24, 4 - 425e: 14 c0 rjmp .+40 ; 0x4288 <__vector_125+0x82> - break; - case USB_INT_BUSEVENTI_Resume: - USB.INTFLAGSACLR = USB_RESUMEIF_bm; - break; - case USB_INT_BUSEVENTI_Reset: - USB.INTFLAGSACLR = USB_RSTIF_bm; - 4260: 80 e1 ldi r24, 0x10 ; 16 - 4262: 80 93 ca 04 sts 0x04CA, r24 - { - USB_INT_Clear(USB_INT_BUSEVENTI_Reset); - - USB_DeviceState = DEVICE_STATE_Default; - 4266: 82 e0 ldi r24, 0x02 ; 2 - 4268: 80 93 14 27 sts 0x2714, r24 - USB_Device_ConfigurationNumber = 0; - 426c: 10 92 10 27 sts 0x2710, r1 - } - - static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; - static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) - { - USB.ADDR = Address; - 4270: 10 92 c3 04 sts 0x04C3, r1 - - USB_Device_EnableDeviceAddress(0); - - Endpoint_ClearEndpoints(); - 4274: b7 de rcall .-658 ; 0x3fe4 - EPConfigMask |= USB_EP_TYPE_BULK_gc; - break; - } - - if (Type == EP_TYPE_CONTROL) - Endpoint_ConfigureEndpoint_PRV(Address ^ ENDPOINT_DIR_IN, EPConfigMask, Size); - 4276: 48 e0 ldi r20, 0x08 ; 8 - 4278: 68 e4 ldi r22, 0x48 ; 72 - 427a: 80 e8 ldi r24, 0x80 ; 128 - 427c: fc dd rcall .-1032 ; 0x3e76 - - return Endpoint_ConfigureEndpoint_PRV(Address, EPConfigMask, Size); - 427e: 48 e0 ldi r20, 0x08 ; 8 - 4280: 68 e4 ldi r22, 0x48 ; 72 - 4282: 80 e0 ldi r24, 0x00 ; 0 - 4284: f8 dd rcall .-1040 ; 0x3e76 - Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, - USB_Device_ControlEndpointSize, 1); - - EVENT_USB_Device_Reset(); - 4286: 35 db rcall .-2454 ; 0x38f2 - } -} - 4288: ff 91 pop r31 - 428a: ef 91 pop r30 - 428c: bf 91 pop r27 - 428e: af 91 pop r26 - 4290: 9f 91 pop r25 - 4292: 8f 91 pop r24 - 4294: 7f 91 pop r23 - 4296: 6f 91 pop r22 - 4298: 5f 91 pop r21 - 429a: 4f 91 pop r20 - 429c: 3f 91 pop r19 - 429e: 2f 91 pop r18 - 42a0: 0f 90 pop r0 - 42a2: 0f be out 0x3f, r0 ; 63 - 42a4: 0f 90 pop r0 - 42a6: 1f 90 pop r1 - 42a8: 18 95 reti - } - - static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; - static inline bool USB_Device_IsAddressSet(void) - { - return ((USB.ADDR != 0) ? true : false); - 42aa: 80 91 c3 04 lds r24, 0x04C3 - USB_INT_Clear(USB_INT_BUSEVENTI_Resume); - - if (USB_Device_ConfigurationNumber) - USB_DeviceState = DEVICE_STATE_Configured; - else - USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Addressed : DEVICE_STATE_Powered; - 42ae: 81 11 cpse r24, r1 - 42b0: 15 c0 rjmp .+42 ; 0x42dc <__vector_125+0xd6> - 42b2: 81 e0 ldi r24, 0x01 ; 1 - 42b4: 80 93 14 27 sts 0x2714, r24 - 42b8: cd cf rjmp .-102 ; 0x4254 <__vector_125+0x4e> - static inline void USB_INT_Clear(const uint8_t Interrupt) - { - switch (Interrupt) - { - case USB_INT_BUSEVENTI_Suspend: - USB.INTFLAGSACLR = USB_SUSPENDIF_bm; - 42ba: 80 e4 ldi r24, 0x40 ; 64 - 42bc: 80 93 ca 04 sts 0x04CA, r24 - if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Suspend)) - { - USB_INT_Clear(USB_INT_BUSEVENTI_Suspend); - - #if !defined(NO_LIMITED_CONTROLLER_CONNECT) - USB_DeviceState = DEVICE_STATE_Unattached; - 42c0: 10 92 14 27 sts 0x2714, r1 - EVENT_USB_Device_Disconnect(); - 42c4: 0e 94 07 0d call 0x1a0e ; 0x1a0e - 42c8: b7 cf rjmp .-146 ; 0x4238 <__vector_125+0x32> - switch (Interrupt) - { - case USB_INT_BUSEVENTI: - return ((USB.INTCTRLA & USB_BUSEVIE_bm) ? true : false); - case USB_INT_SOFI: - return ((USB.INTCTRLA & USB_SOFIE_bm) ? true : false); - 42ca: 80 91 c8 04 lds r24, 0x04C8 -} - -ISR(USB_BUSEVENT_vect) -{ - #if !defined(NO_SOF_EVENTS) - if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI)) - 42ce: 87 ff sbrs r24, 7 - 42d0: af cf rjmp .-162 ; 0x4230 <__vector_125+0x2a> - break; - case USB_INT_BUSEVENTI_Reset: - USB.INTFLAGSACLR = USB_RSTIF_bm; - break; - case USB_INT_SOFI: - USB.INTFLAGSACLR = USB_SOFIF_bm; - 42d2: 80 e8 ldi r24, 0x80 ; 128 - 42d4: 80 93 ca 04 sts 0x04CA, r24 - { - USB_INT_Clear(USB_INT_SOFI); - - EVENT_USB_Device_StartOfFrame(); - 42d8: 0c db rcall .-2536 ; 0x38f2 - 42da: aa cf rjmp .-172 ; 0x4230 <__vector_125+0x2a> - USB_INT_Clear(USB_INT_BUSEVENTI_Resume); - - if (USB_Device_ConfigurationNumber) - USB_DeviceState = DEVICE_STATE_Configured; - else - USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Addressed : DEVICE_STATE_Powered; - 42dc: 83 e0 ldi r24, 0x03 ; 3 - 42de: ea cf rjmp .-44 ; 0x42b4 <__vector_125+0xae> - -000042e0 : - -void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, - FILE* const Stream) -{ - *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW); - fdev_set_udata(Stream, CDCInterfaceInfo); - 42e0: cf 93 push r28 - 42e2: df 93 push r29 - 42e4: ec 01 movw r28, r24 - 42e6: fc 01 movw r30, r24 - 42e8: 70 96 adiw r30, 0x10 ; 16 - 42ea: 8b e0 ldi r24, 0x0B ; 11 - 42ec: df 01 movw r26, r30 - 42ee: 1d 92 st X+, r1 - 42f0: 8a 95 dec r24 - 42f2: e9 f7 brne .-6 ; 0x42ee - 42f4: 82 e0 ldi r24, 0x02 ; 2 - 42f6: 8c 83 std Y+4, r24 ; 0x04 - 42f8: 89 87 std Y+9, r24 ; 0x09 - 42fa: 83 e0 ldi r24, 0x03 ; 3 - 42fc: 8e 87 std Y+14, r24 ; 0x0e - 42fe: 61 e0 ldi r22, 0x01 ; 1 - 4300: ce 01 movw r24, r28 - 4302: 01 96 adiw r24, 0x01 ; 1 - 4304: 03 de rcall .-1018 ; 0x3f0c - 4306: 81 11 cpse r24, r1 - 4308: 04 c0 rjmp .+8 ; 0x4312 - 430a: 80 e0 ldi r24, 0x00 ; 0 - 430c: df 91 pop r29 - 430e: cf 91 pop r28 - 4310: 08 95 ret - 4312: 61 e0 ldi r22, 0x01 ; 1 - 4314: ce 01 movw r24, r28 - 4316: 06 96 adiw r24, 0x06 ; 6 - 4318: f9 dd rcall .-1038 ; 0x3f0c - 431a: 88 23 and r24, r24 - 431c: b1 f3 breq .-20 ; 0x430a - 431e: 61 e0 ldi r22, 0x01 ; 1 - 4320: ce 01 movw r24, r28 - 4322: 0b 96 adiw r24, 0x0b ; 11 - 4324: df 91 pop r29 - 4326: cf 91 pop r28 - 4328: f1 cd rjmp .-1054 ; 0x3f0c - -0000432a : - 432a: cf 93 push r28 - 432c: df 93 push r29 - 432e: eb 01 movw r28, r22 - 4330: 20 91 14 27 lds r18, 0x2714 - 4334: 24 30 cpi r18, 0x04 ; 4 - 4336: 21 f0 breq .+8 ; 0x4340 - 4338: 82 e0 ldi r24, 0x02 ; 2 - 433a: df 91 pop r29 - 433c: cf 91 pop r28 - 433e: 08 95 ret - 4340: fc 01 movw r30, r24 - 4342: 44 89 ldd r20, Z+20 ; 0x14 - 4344: 55 89 ldd r21, Z+21 ; 0x15 - 4346: 66 89 ldd r22, Z+22 ; 0x16 - 4348: 77 89 ldd r23, Z+23 ; 0x17 - 434a: 45 2b or r20, r21 - 434c: 46 2b or r20, r22 - 434e: 47 2b or r20, r23 - 4350: 99 f3 breq .-26 ; 0x4338 - 4352: 81 81 ldd r24, Z+1 ; 0x01 - 4354: d1 dc rcall .-1630 ; 0x3cf8 - 4356: fe 01 movw r30, r28 - 4358: 01 90 ld r0, Z+ - 435a: 00 20 and r0, r0 - 435c: e9 f7 brne .-6 ; 0x4358 - 435e: bf 01 movw r22, r30 - 4360: 61 50 subi r22, 0x01 ; 1 - 4362: 71 09 sbc r23, r1 - 4364: 6c 1b sub r22, r28 - 4366: 7d 0b sbc r23, r29 - 4368: 40 e0 ldi r20, 0x00 ; 0 - 436a: 50 e0 ldi r21, 0x00 ; 0 - 436c: ce 01 movw r24, r28 - 436e: df 91 pop r29 - 4370: cf 91 pop r28 - 4372: d5 ca rjmp .-2646 ; 0x391e - -00004374 : - 4374: ef 92 push r14 - 4376: ff 92 push r15 - 4378: 0f 93 push r16 - 437a: 1f 93 push r17 - 437c: cf 93 push r28 - 437e: df 93 push r29 - 4380: eb 01 movw r28, r22 - 4382: 7a 01 movw r14, r20 - 4384: 20 91 14 27 lds r18, 0x2714 - 4388: 24 30 cpi r18, 0x04 ; 4 - 438a: 41 f0 breq .+16 ; 0x439c - 438c: 82 e0 ldi r24, 0x02 ; 2 - 438e: df 91 pop r29 - 4390: cf 91 pop r28 - 4392: 1f 91 pop r17 - 4394: 0f 91 pop r16 - 4396: ff 90 pop r15 - 4398: ef 90 pop r14 - 439a: 08 95 ret - 439c: fc 01 movw r30, r24 - 439e: 04 89 ldd r16, Z+20 ; 0x14 - 43a0: 15 89 ldd r17, Z+21 ; 0x15 - 43a2: 26 89 ldd r18, Z+22 ; 0x16 - 43a4: 37 89 ldd r19, Z+23 ; 0x17 - 43a6: 01 2b or r16, r17 - 43a8: 02 2b or r16, r18 - 43aa: 03 2b or r16, r19 - 43ac: 79 f3 breq .-34 ; 0x438c - 43ae: 81 81 ldd r24, Z+1 ; 0x01 - 43b0: a3 dc rcall .-1722 ; 0x3cf8 - 43b2: 40 e0 ldi r20, 0x00 ; 0 - 43b4: 50 e0 ldi r21, 0x00 ; 0 - 43b6: b7 01 movw r22, r14 - 43b8: ce 01 movw r24, r28 - 43ba: df 91 pop r29 - 43bc: cf 91 pop r28 - 43be: 1f 91 pop r17 - 43c0: 0f 91 pop r16 - 43c2: ff 90 pop r15 - 43c4: ef 90 pop r14 - 43c6: ab ca rjmp .-2730 ; 0x391e - -000043c8 : - 43c8: 0f 93 push r16 - 43ca: 1f 93 push r17 - 43cc: cf 93 push r28 - 43ce: df 93 push r29 - 43d0: 1f 92 push r1 - 43d2: cd b7 in r28, 0x3d ; 61 - 43d4: de b7 in r29, 0x3e ; 62 - 43d6: 20 91 14 27 lds r18, 0x2714 - 43da: 24 30 cpi r18, 0x04 ; 4 - 43dc: 39 f0 breq .+14 ; 0x43ec - 43de: 82 e0 ldi r24, 0x02 ; 2 - 43e0: 0f 90 pop r0 - 43e2: df 91 pop r29 - 43e4: cf 91 pop r28 - 43e6: 1f 91 pop r17 - 43e8: 0f 91 pop r16 - 43ea: 08 95 ret - 43ec: fc 01 movw r30, r24 - 43ee: 04 89 ldd r16, Z+20 ; 0x14 - 43f0: 15 89 ldd r17, Z+21 ; 0x15 - 43f2: 26 89 ldd r18, Z+22 ; 0x16 - 43f4: 37 89 ldd r19, Z+23 ; 0x17 - 43f6: 01 2b or r16, r17 - 43f8: 02 2b or r16, r18 - 43fa: 03 2b or r16, r19 - 43fc: 81 f3 breq .-32 ; 0x43de - 43fe: 81 81 ldd r24, Z+1 ; 0x01 - 4400: 69 83 std Y+1, r22 ; 0x01 - 4402: 7a dc rcall .-1804 ; 0x3cf8 - 4404: 20 91 1d 27 lds r18, 0x271D - 4408: 30 91 1e 27 lds r19, 0x271E - 440c: f9 01 movw r30, r18 - 440e: ef 5b subi r30, 0xBF ; 191 - 4410: ff 4f sbci r31, 0xFF ; 255 - 4412: 90 81 ld r25, Z - 4414: 31 97 sbiw r30, 0x01 ; 1 - 4416: 80 81 ld r24, Z - 4418: 69 81 ldd r22, Y+1 ; 0x01 - 441a: 98 17 cp r25, r24 - 441c: 30 f0 brcs .+12 ; 0x442a - 441e: 69 83 std Y+1, r22 ; 0x01 - 4420: 23 dc rcall .-1978 ; 0x3c68 - 4422: 2e de rcall .-932 ; 0x4080 - 4424: 69 81 ldd r22, Y+1 ; 0x01 - 4426: 81 11 cpse r24, r1 - 4428: db cf rjmp .-74 ; 0x43e0 - 442a: 86 2f mov r24, r22 - 442c: 55 dc rcall .-1878 ; 0x3cd8 - 442e: 80 e0 ldi r24, 0x00 ; 0 - 4430: d7 cf rjmp .-82 ; 0x43e0 - -00004432 : - 4432: cf 93 push r28 - 4434: df 93 push r29 - 4436: 20 91 14 27 lds r18, 0x2714 - 443a: 24 30 cpi r18, 0x04 ; 4 - 443c: 21 f0 breq .+8 ; 0x4446 - 443e: 82 e0 ldi r24, 0x02 ; 2 - 4440: df 91 pop r29 - 4442: cf 91 pop r28 - 4444: 08 95 ret - 4446: fc 01 movw r30, r24 - 4448: 44 89 ldd r20, Z+20 ; 0x14 - 444a: 55 89 ldd r21, Z+21 ; 0x15 - 444c: 66 89 ldd r22, Z+22 ; 0x16 - 444e: 77 89 ldd r23, Z+23 ; 0x17 - 4450: 45 2b or r20, r21 - 4452: 46 2b or r20, r22 - 4454: 47 2b or r20, r23 - 4456: 99 f3 breq .-26 ; 0x443e - 4458: 81 81 ldd r24, Z+1 ; 0x01 - 445a: 4e dc rcall .-1892 ; 0x3cf8 - 445c: 80 91 21 27 lds r24, 0x2721 - 4460: 20 91 1d 27 lds r18, 0x271D - 4464: 30 91 1e 27 lds r19, 0x271E - 4468: f9 01 movw r30, r18 - 446a: 87 fd sbrc r24, 7 - 446c: 1b c0 rjmp .+54 ; 0x44a4 - 446e: e0 5c subi r30, 0xC0 ; 192 - 4470: ff 4f sbci r31, 0xFF ; 255 - 4472: 80 81 ld r24, Z - 4474: 31 96 adiw r30, 0x01 ; 1 - 4476: 40 81 ld r20, Z - 4478: 90 e0 ldi r25, 0x00 ; 0 - 447a: 84 1b sub r24, r20 - 447c: 91 09 sbc r25, r1 - 447e: 89 2b or r24, r25 - 4480: 11 f4 brne .+4 ; 0x4486 - 4482: 80 e0 ldi r24, 0x00 ; 0 - 4484: dd cf rjmp .-70 ; 0x4440 - 4486: f9 01 movw r30, r18 - 4488: ef 5b subi r30, 0xBF ; 191 - 448a: ff 4f sbci r31, 0xFF ; 255 - 448c: d0 81 ld r29, Z - 448e: 31 97 sbiw r30, 0x01 ; 1 - 4490: c0 81 ld r28, Z - 4492: ea db rcall .-2092 ; 0x3c68 - 4494: dc 17 cp r29, r28 - 4496: a8 f3 brcs .-22 ; 0x4482 - 4498: f3 dd rcall .-1050 ; 0x4080 - 449a: 81 11 cpse r24, r1 - 449c: d1 cf rjmp .-94 ; 0x4440 - 449e: e4 db rcall .-2104 ; 0x3c68 - 44a0: 80 e0 ldi r24, 0x00 ; 0 - 44a2: ce cf rjmp .-100 ; 0x4440 - 44a4: ef 5b subi r30, 0xBF ; 191 - 44a6: ff 4f sbci r31, 0xFF ; 255 - 44a8: 80 81 ld r24, Z - 44aa: 90 e0 ldi r25, 0x00 ; 0 - 44ac: e8 cf rjmp .-48 ; 0x447e - -000044ae : - 44ae: cf 93 push r28 - 44b0: df 93 push r29 - 44b2: ec 01 movw r28, r24 - 44b4: 80 91 14 27 lds r24, 0x2714 - 44b8: 84 30 cpi r24, 0x04 ; 4 - 44ba: 19 f0 breq .+6 ; 0x44c2 - 44bc: df 91 pop r29 - 44be: cf 91 pop r28 - 44c0: 08 95 ret - 44c2: 4c 89 ldd r20, Y+20 ; 0x14 - 44c4: 5d 89 ldd r21, Y+21 ; 0x15 - 44c6: 6e 89 ldd r22, Y+22 ; 0x16 - 44c8: 7f 89 ldd r23, Y+23 ; 0x17 - 44ca: 45 2b or r20, r21 - 44cc: 46 2b or r20, r22 - 44ce: 47 2b or r20, r23 - 44d0: a9 f3 breq .-22 ; 0x44bc - 44d2: 89 81 ldd r24, Y+1 ; 0x01 - 44d4: 11 dc rcall .-2014 ; 0x3cf8 - 44d6: 49 dc rcall .-1902 ; 0x3d6a - 44d8: 88 23 and r24, r24 - 44da: 81 f3 breq .-32 ; 0x44bc - 44dc: ce 01 movw r24, r28 - 44de: df 91 pop r29 - 44e0: cf 91 pop r28 - 44e2: a7 cf rjmp .-178 ; 0x4432 - -000044e4 : - 44e4: cf 93 push r28 - 44e6: df 93 push r29 - 44e8: 20 91 14 27 lds r18, 0x2714 - 44ec: 24 30 cpi r18, 0x04 ; 4 - 44ee: a9 f5 brne .+106 ; 0x455a - 44f0: fc 01 movw r30, r24 - 44f2: 44 89 ldd r20, Z+20 ; 0x14 - 44f4: 55 89 ldd r21, Z+21 ; 0x15 - 44f6: 66 89 ldd r22, Z+22 ; 0x16 - 44f8: 77 89 ldd r23, Z+23 ; 0x17 - 44fa: 45 2b or r20, r21 - 44fc: 46 2b or r20, r22 - 44fe: 47 2b or r20, r23 - 4500: 61 f1 breq .+88 ; 0x455a - 4502: 86 81 ldd r24, Z+6 ; 0x06 - 4504: f9 db rcall .-2062 ; 0x3cf8 - 4506: 3d dc rcall .-1926 ; 0x3d82 - 4508: 88 23 and r24, r24 - 450a: 39 f1 breq .+78 ; 0x455a - 450c: 80 91 21 27 lds r24, 0x2721 - 4510: 40 91 1d 27 lds r20, 0x271D - 4514: 50 91 1e 27 lds r21, 0x271E - 4518: fa 01 movw r30, r20 - 451a: 87 fd sbrc r24, 7 - 451c: 3a c0 rjmp .+116 ; 0x4592 - 451e: e0 5c subi r30, 0xC0 ; 192 - 4520: ff 4f sbci r31, 0xFF ; 255 - 4522: 80 81 ld r24, Z - 4524: 31 96 adiw r30, 0x01 ; 1 - 4526: 20 81 ld r18, Z - 4528: 90 e0 ldi r25, 0x00 ; 0 - 452a: 82 1b sub r24, r18 - 452c: 91 09 sbc r25, r1 - 452e: 89 2b or r24, r25 - 4530: c9 f4 brne .+50 ; 0x4564 - 4532: cf ef ldi r28, 0xFF ; 255 - 4534: df ef ldi r29, 0xFF ; 255 - 4536: 80 91 21 27 lds r24, 0x2721 - 453a: fa 01 movw r30, r20 - 453c: 87 fd sbrc r24, 7 - 453e: 1e c0 rjmp .+60 ; 0x457c - 4540: e0 5c subi r30, 0xC0 ; 192 - 4542: ff 4f sbci r31, 0xFF ; 255 - 4544: 20 81 ld r18, Z - 4546: 31 96 adiw r30, 0x01 ; 1 - 4548: 80 81 ld r24, Z - 454a: 30 e0 ldi r19, 0x00 ; 0 - 454c: 28 1b sub r18, r24 - 454e: 31 09 sbc r19, r1 - 4550: d9 f0 breq .+54 ; 0x4588 - 4552: ce 01 movw r24, r28 - 4554: df 91 pop r29 - 4556: cf 91 pop r28 - 4558: 08 95 ret - 455a: 8f ef ldi r24, 0xFF ; 255 - 455c: 9f ef ldi r25, 0xFF ; 255 - 455e: df 91 pop r29 - 4560: cf 91 pop r28 - 4562: 08 95 ret - 4564: a9 db rcall .-2222 ; 0x3cb8 - 4566: c8 2f mov r28, r24 - 4568: d0 e0 ldi r29, 0x00 ; 0 - 456a: 40 91 1d 27 lds r20, 0x271D - 456e: 50 91 1e 27 lds r21, 0x271E - 4572: 80 91 21 27 lds r24, 0x2721 - 4576: fa 01 movw r30, r20 - 4578: 87 ff sbrs r24, 7 - 457a: e2 cf rjmp .-60 ; 0x4540 - 457c: ef 5b subi r30, 0xBF ; 191 - 457e: ff 4f sbci r31, 0xFF ; 255 - 4580: 20 81 ld r18, Z - 4582: 30 e0 ldi r19, 0x00 ; 0 - 4584: 23 2b or r18, r19 - 4586: 29 f7 brne .-54 ; 0x4552 - 4588: 88 db rcall .-2288 ; 0x3c9a - 458a: ce 01 movw r24, r28 - 458c: df 91 pop r29 - 458e: cf 91 pop r28 - 4590: 08 95 ret - 4592: ef 5b subi r30, 0xBF ; 191 - 4594: ff 4f sbci r31, 0xFF ; 255 - 4596: 80 81 ld r24, Z - 4598: 90 e0 ldi r25, 0x00 ; 0 - 459a: c9 cf rjmp .-110 ; 0x452e - -0000459c : - return ReceivedByte; -} -#endif - -void CDC_Device_Event_Stub(void) -{ - 459c: 08 95 ret - -0000459e : -#define __INCLUDE_FROM_CDC_DRIVER -#define __INCLUDE_FROM_CDC_DEVICE_C -#include "CDCClassDevice.h" - -void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) -{ - 459e: ff 92 push r15 - 45a0: 0f 93 push r16 - 45a2: 1f 93 push r17 - 45a4: cf 93 push r28 - 45a6: df 93 push r29 - 45a8: ec 01 movw r28, r24 - if (!(Endpoint_IsSETUPReceived())) - 45aa: 04 dc rcall .-2040 ; 0x3db4 - 45ac: 88 23 and r24, r24 - 45ae: 49 f0 breq .+18 ; 0x45c2 - return; - - if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber) - 45b0: 88 81 ld r24, Y - 45b2: 90 e0 ldi r25, 0x00 ; 0 - 45b4: 20 91 19 27 lds r18, 0x2719 - 45b8: 30 91 1a 27 lds r19, 0x271A - 45bc: 28 17 cp r18, r24 - 45be: 39 07 cpc r19, r25 - 45c0: 31 f0 breq .+12 ; 0x45ce - EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); - } - - break; - } -} - 45c2: df 91 pop r29 - 45c4: cf 91 pop r28 - 45c6: 1f 91 pop r17 - 45c8: 0f 91 pop r16 - 45ca: ff 90 pop r15 - 45cc: 08 95 ret - return; - - if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber) - return; - - switch (USB_ControlRequest.bRequest) - 45ce: 80 91 16 27 lds r24, 0x2716 - 45d2: 81 32 cpi r24, 0x21 ; 33 - 45d4: 09 f4 brne .+2 ; 0x45d8 - 45d6: 48 c0 rjmp .+144 ; 0x4668 - 45d8: a0 f0 brcs .+40 ; 0x4602 - 45da: 82 32 cpi r24, 0x22 ; 34 - 45dc: 09 f4 brne .+2 ; 0x45e0 - 45de: 65 c0 rjmp .+202 ; 0x46aa - 45e0: 83 32 cpi r24, 0x23 ; 35 - 45e2: 79 f7 brne .-34 ; 0x45c2 - EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); - } - - break; - case CDC_REQ_SendBreak: - if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) - 45e4: 80 91 15 27 lds r24, 0x2715 - 45e8: 81 32 cpi r24, 0x21 ; 33 - 45ea: 59 f7 brne .-42 ; 0x45c2 - { - Endpoint_ClearSETUP(); - 45ec: fc db rcall .-2056 ; 0x3de6 - Endpoint_ClearStatusStage(); - 45ee: 32 dd rcall .-1436 ; 0x4054 - - EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); - 45f0: 60 91 17 27 lds r22, 0x2717 - 45f4: ce 01 movw r24, r28 - } - - break; - } -} - 45f6: df 91 pop r29 - 45f8: cf 91 pop r28 - 45fa: 1f 91 pop r17 - 45fc: 0f 91 pop r16 - 45fe: ff 90 pop r15 - if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) - { - Endpoint_ClearSETUP(); - Endpoint_ClearStatusStage(); - - EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); - 4600: cd cf rjmp .-102 ; 0x459c - return; - - if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber) - return; - - switch (USB_ControlRequest.bRequest) - 4602: 80 32 cpi r24, 0x20 ; 32 - 4604: f1 f6 brne .-68 ; 0x45c2 - Endpoint_ClearStatusStage(); - } - - break; - case CDC_REQ_SetLineEncoding: - if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) - 4606: 80 91 15 27 lds r24, 0x2715 - 460a: 81 32 cpi r24, 0x21 ; 33 - 460c: d1 f6 brne .-76 ; 0x45c2 - { - Endpoint_ClearSETUP(); - 460e: eb db rcall .-2090 ; 0x3de6 - - while (!(Endpoint_IsOUTReceived())) - 4610: 04 c0 rjmp .+8 ; 0x461a - { - if (USB_DeviceState == DEVICE_STATE_Unattached) - 4612: 80 91 14 27 lds r24, 0x2714 - 4616: 88 23 and r24, r24 - 4618: a1 f2 breq .-88 ; 0x45c2 - case CDC_REQ_SetLineEncoding: - if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) - { - Endpoint_ClearSETUP(); - - while (!(Endpoint_IsOUTReceived())) - 461a: b3 db rcall .-2202 ; 0x3d82 - 461c: 88 23 and r24, r24 - 461e: c9 f3 breq .-14 ; 0x4612 - * \return Next four bytes in the currently selected endpoint's FIFO buffer. - */ - static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; - static inline uint32_t Endpoint_Read_32_LE(void) - { - uint32_t Byte0 = Endpoint_Read_8(); - 4620: 4b db rcall .-2410 ; 0x3cb8 - 4622: 08 2f mov r16, r24 - uint32_t Byte1 = Endpoint_Read_8(); - 4624: 49 db rcall .-2414 ; 0x3cb8 - 4626: 18 2f mov r17, r24 - uint32_t Byte2 = Endpoint_Read_8(); - 4628: 47 db rcall .-2418 ; 0x3cb8 - 462a: f8 2e mov r15, r24 - uint32_t Byte3 = Endpoint_Read_8(); - 462c: 45 db rcall .-2422 ; 0x3cb8 - static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; - static inline uint32_t Endpoint_Read_32_LE(void) - { - uint32_t Byte0 = Endpoint_Read_8(); - uint32_t Byte1 = Endpoint_Read_8(); - uint32_t Byte2 = Endpoint_Read_8(); - 462e: 4f 2d mov r20, r15 - 4630: 50 e0 ldi r21, 0x00 ; 0 - 4632: 60 e0 ldi r22, 0x00 ; 0 - 4634: 70 e0 ldi r23, 0x00 ; 0 - uint32_t Byte3 = Endpoint_Read_8(); - - return ((Byte3 << 24) | (Byte2 << 16) | (Byte1 << 8) | Byte0); - 4636: ba 01 movw r22, r20 - 4638: 55 27 eor r21, r21 - 463a: 44 27 eor r20, r20 - 463c: 78 2b or r23, r24 - 463e: 40 2b or r20, r16 - 4640: 51 2b or r21, r17 - { - if (USB_DeviceState == DEVICE_STATE_Unattached) - return; - } - - CDCInterfaceInfo->State.LineEncoding.BaudRateBPS = Endpoint_Read_32_LE(); - 4642: 4c 8b std Y+20, r20 ; 0x14 - 4644: 5d 8b std Y+21, r21 ; 0x15 - 4646: 6e 8b std Y+22, r22 ; 0x16 - 4648: 7f 8b std Y+23, r23 ; 0x17 - CDCInterfaceInfo->State.LineEncoding.CharFormat = Endpoint_Read_8(); - 464a: 36 db rcall .-2452 ; 0x3cb8 - 464c: 88 8f std Y+24, r24 ; 0x18 - CDCInterfaceInfo->State.LineEncoding.ParityType = Endpoint_Read_8(); - 464e: 34 db rcall .-2456 ; 0x3cb8 - 4650: 89 8f std Y+25, r24 ; 0x19 - CDCInterfaceInfo->State.LineEncoding.DataBits = Endpoint_Read_8(); - 4652: 32 db rcall .-2460 ; 0x3cb8 - 4654: 8a 8f std Y+26, r24 ; 0x1a - - Endpoint_ClearOUT(); - 4656: 21 db rcall .-2494 ; 0x3c9a - Endpoint_ClearStatusStage(); - 4658: fd dc rcall .-1542 ; 0x4054 - - EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo); - 465a: ce 01 movw r24, r28 - EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); - } - - break; - } -} - 465c: df 91 pop r29 - 465e: cf 91 pop r28 - 4660: 1f 91 pop r17 - 4662: 0f 91 pop r16 - 4664: ff 90 pop r15 - CDCInterfaceInfo->State.LineEncoding.DataBits = Endpoint_Read_8(); - - Endpoint_ClearOUT(); - Endpoint_ClearStatusStage(); - - EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo); - 4666: 9a cf rjmp .-204 ; 0x459c - return; - - switch (USB_ControlRequest.bRequest) - { - case CDC_REQ_GetLineEncoding: - if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) - 4668: 80 91 15 27 lds r24, 0x2715 - 466c: 81 3a cpi r24, 0xA1 ; 161 - 466e: 09 f0 breq .+2 ; 0x4672 - 4670: a8 cf rjmp .-176 ; 0x45c2 - { - Endpoint_ClearSETUP(); - 4672: b9 db rcall .-2190 ; 0x3de6 - - while (!(Endpoint_IsINReady())); - 4674: 7a db rcall .-2316 ; 0x3d6a - 4676: 88 23 and r24, r24 - 4678: e9 f3 breq .-6 ; 0x4674 - - Endpoint_Write_32_LE(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); - 467a: 8c 89 ldd r24, Y+20 ; 0x14 - 467c: fd 88 ldd r15, Y+21 ; 0x15 - 467e: 0e 89 ldd r16, Y+22 ; 0x16 - 4680: 1f 89 ldd r17, Y+23 ; 0x17 - * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. - */ - static inline void Endpoint_Write_32_LE(const uint32_t Data) ATTR_ALWAYS_INLINE; - static inline void Endpoint_Write_32_LE(const uint32_t Data) - { - Endpoint_Write_8(Data & 0xFF); - 4682: 2a db rcall .-2476 ; 0x3cd8 - Endpoint_Write_8(Data >> 8); - 4684: 8f 2d mov r24, r15 - 4686: 28 db rcall .-2480 ; 0x3cd8 - Endpoint_Write_8(Data >> 16); - 4688: 80 2f mov r24, r16 - 468a: 26 db rcall .-2484 ; 0x3cd8 - Endpoint_Write_8(Data >> 24); - 468c: 81 2f mov r24, r17 - 468e: 24 db rcall .-2488 ; 0x3cd8 - Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.CharFormat); - 4690: 88 8d ldd r24, Y+24 ; 0x18 - 4692: 22 db rcall .-2492 ; 0x3cd8 - Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.ParityType); - 4694: 89 8d ldd r24, Y+25 ; 0x19 - 4696: 20 db rcall .-2496 ; 0x3cd8 - Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.DataBits); - 4698: 8a 8d ldd r24, Y+26 ; 0x1a - 469a: 1e db rcall .-2500 ; 0x3cd8 - - Endpoint_ClearIN(); - 469c: e5 da rcall .-2614 ; 0x3c68 - EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); - } - - break; - } -} - 469e: df 91 pop r29 - 46a0: cf 91 pop r28 - 46a2: 1f 91 pop r17 - 46a4: 0f 91 pop r16 - 46a6: ff 90 pop r15 - Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.CharFormat); - Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.ParityType); - Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.DataBits); - - Endpoint_ClearIN(); - Endpoint_ClearStatusStage(); - 46a8: d5 cc rjmp .-1622 ; 0x4054 - EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo); - } - - break; - case CDC_REQ_SetControlLineState: - if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) - 46aa: 80 91 15 27 lds r24, 0x2715 - 46ae: 81 32 cpi r24, 0x21 ; 33 - 46b0: 09 f0 breq .+2 ; 0x46b4 - 46b2: 87 cf rjmp .-242 ; 0x45c2 - { - Endpoint_ClearSETUP(); - 46b4: 98 db rcall .-2256 ; 0x3de6 - Endpoint_ClearStatusStage(); - 46b6: ce dc rcall .-1636 ; 0x4054 - - CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue; - 46b8: 80 91 17 27 lds r24, 0x2717 - 46bc: 90 91 18 27 lds r25, 0x2718 - 46c0: 88 8b std Y+16, r24 ; 0x10 - 46c2: 99 8b std Y+17, r25 ; 0x11 - - EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); - 46c4: ce 01 movw r24, r28 - EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); - } - - break; - } -} - 46c6: df 91 pop r29 - 46c8: cf 91 pop r28 - 46ca: 1f 91 pop r17 - 46cc: 0f 91 pop r16 - 46ce: ff 90 pop r15 - Endpoint_ClearSETUP(); - Endpoint_ClearStatusStage(); - - CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue; - - EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); - 46d0: 65 cf rjmp .-310 ; 0x459c - -000046d2 <__tablejump2__>: - 46d2: ee 0f add r30, r30 - 46d4: ff 1f adc r31, r31 - -000046d6 <__tablejump__>: - 46d6: 05 90 lpm r0, Z+ - 46d8: f4 91 lpm r31, Z - 46da: e0 2d mov r30, r0 - 46dc: 09 94 ijmp - -000046de <__mulshisi3>: - 46de: b7 ff sbrs r27, 7 - 46e0: 04 c0 rjmp .+8 ; 0x46ea <__muluhisi3> - -000046e2 <__mulohisi3>: - 46e2: 03 d0 rcall .+6 ; 0x46ea <__muluhisi3> - 46e4: 82 1b sub r24, r18 - 46e6: 93 0b sbc r25, r19 - 46e8: 08 95 ret - -000046ea <__muluhisi3>: - 46ea: 09 d0 rcall .+18 ; 0x46fe <__umulhisi3> - 46ec: a5 9f mul r26, r21 - 46ee: 90 0d add r25, r0 - 46f0: b4 9f mul r27, r20 - 46f2: 90 0d add r25, r0 - 46f4: a4 9f mul r26, r20 - 46f6: 80 0d add r24, r0 - 46f8: 91 1d adc r25, r1 - 46fa: 11 24 eor r1, r1 - 46fc: 08 95 ret - -000046fe <__umulhisi3>: - 46fe: a2 9f mul r26, r18 - 4700: b0 01 movw r22, r0 - 4702: b3 9f mul r27, r19 - 4704: c0 01 movw r24, r0 - 4706: a3 9f mul r26, r19 - 4708: 70 0d add r23, r0 - 470a: 81 1d adc r24, r1 - 470c: 11 24 eor r1, r1 - 470e: 91 1d adc r25, r1 - 4710: b2 9f mul r27, r18 - 4712: 70 0d add r23, r0 - 4714: 81 1d adc r24, r1 - 4716: 11 24 eor r1, r1 - 4718: 91 1d adc r25, r1 - 471a: 08 95 ret - -0000471c : - 471c: 8f 92 push r8 - 471e: 9f 92 push r9 - 4720: af 92 push r10 - 4722: bf 92 push r11 - 4724: cf 92 push r12 - 4726: df 92 push r13 - 4728: ef 92 push r14 - 472a: ff 92 push r15 - 472c: cf 93 push r28 - 472e: df 93 push r29 - 4730: ec 01 movw r28, r24 - 4732: 68 81 ld r22, Y - 4734: 79 81 ldd r23, Y+1 ; 0x01 - 4736: 8a 81 ldd r24, Y+2 ; 0x02 - 4738: 9b 81 ldd r25, Y+3 ; 0x03 - 473a: 61 15 cp r22, r1 - 473c: 71 05 cpc r23, r1 - 473e: 81 05 cpc r24, r1 - 4740: 91 05 cpc r25, r1 - 4742: 21 f4 brne .+8 ; 0x474c - 4744: 64 e2 ldi r22, 0x24 ; 36 - 4746: 79 ed ldi r23, 0xD9 ; 217 - 4748: 8b e5 ldi r24, 0x5B ; 91 - 474a: 97 e0 ldi r25, 0x07 ; 7 - 474c: 2d e1 ldi r18, 0x1D ; 29 - 474e: 33 ef ldi r19, 0xF3 ; 243 - 4750: 41 e0 ldi r20, 0x01 ; 1 - 4752: 50 e0 ldi r21, 0x00 ; 0 - 4754: 31 d3 rcall .+1634 ; 0x4db8 <__divmodsi4> - 4756: 49 01 movw r8, r18 - 4758: 5a 01 movw r10, r20 - 475a: 9b 01 movw r18, r22 - 475c: ac 01 movw r20, r24 - 475e: a7 ea ldi r26, 0xA7 ; 167 - 4760: b1 e4 ldi r27, 0x41 ; 65 - 4762: c3 df rcall .-122 ; 0x46ea <__muluhisi3> - 4764: 6b 01 movw r12, r22 - 4766: 7c 01 movw r14, r24 - 4768: ac ee ldi r26, 0xEC ; 236 - 476a: b4 ef ldi r27, 0xF4 ; 244 - 476c: a5 01 movw r20, r10 - 476e: 94 01 movw r18, r8 - 4770: b8 df rcall .-144 ; 0x46e2 <__mulohisi3> - 4772: c6 0e add r12, r22 - 4774: d7 1e adc r13, r23 - 4776: e8 1e adc r14, r24 - 4778: f9 1e adc r15, r25 - 477a: f7 fe sbrs r15, 7 - 477c: 06 c0 rjmp .+12 ; 0x478a - 477e: 81 e0 ldi r24, 0x01 ; 1 - 4780: c8 1a sub r12, r24 - 4782: d1 08 sbc r13, r1 - 4784: e1 08 sbc r14, r1 - 4786: 80 e8 ldi r24, 0x80 ; 128 - 4788: f8 0a sbc r15, r24 - 478a: c8 82 st Y, r12 - 478c: d9 82 std Y+1, r13 ; 0x01 - 478e: ea 82 std Y+2, r14 ; 0x02 - 4790: fb 82 std Y+3, r15 ; 0x03 - 4792: c6 01 movw r24, r12 - 4794: 9f 77 andi r25, 0x7F ; 127 - 4796: df 91 pop r29 - 4798: cf 91 pop r28 - 479a: ff 90 pop r15 - 479c: ef 90 pop r14 - 479e: df 90 pop r13 - 47a0: cf 90 pop r12 - 47a2: bf 90 pop r11 - 47a4: af 90 pop r10 - 47a6: 9f 90 pop r9 - 47a8: 8f 90 pop r8 - 47aa: 08 95 ret - -000047ac : - 47ac: b7 cf rjmp .-146 ; 0x471c - -000047ae : - 47ae: 8c e1 ldi r24, 0x1C ; 28 - 47b0: 90 e2 ldi r25, 0x20 ; 32 - 47b2: b4 cf rjmp .-152 ; 0x471c - -000047b4 : - 47b4: a0 e0 ldi r26, 0x00 ; 0 - 47b6: b0 e0 ldi r27, 0x00 ; 0 - 47b8: 80 93 1c 20 sts 0x201C, r24 - 47bc: 90 93 1d 20 sts 0x201D, r25 - 47c0: a0 93 1e 20 sts 0x201E, r26 - 47c4: b0 93 1f 20 sts 0x201F, r27 - 47c8: 08 95 ret - -000047ca : - 47ca: fb 01 movw r30, r22 - 47cc: dc 01 movw r26, r24 - 47ce: 02 c0 rjmp .+4 ; 0x47d4 - 47d0: 05 90 lpm r0, Z+ - 47d2: 0d 92 st X+, r0 - 47d4: 41 50 subi r20, 0x01 ; 1 - 47d6: 50 40 sbci r21, 0x00 ; 0 - 47d8: d8 f7 brcc .-10 ; 0x47d0 - 47da: 08 95 ret - -000047dc : - 47dc: fb 01 movw r30, r22 - 47de: dc 01 movw r26, r24 - 47e0: 8d 91 ld r24, X+ - 47e2: 05 90 lpm r0, Z+ - 47e4: 80 19 sub r24, r0 - 47e6: 01 10 cpse r0, r1 - 47e8: d9 f3 breq .-10 ; 0x47e0 - 47ea: 99 0b sbc r25, r25 - 47ec: 08 95 ret - -000047ee : - 47ee: fb 01 movw r30, r22 - 47f0: dc 01 movw r26, r24 - 47f2: 41 50 subi r20, 0x01 ; 1 - 47f4: 50 40 sbci r21, 0x00 ; 0 - 47f6: 48 f0 brcs .+18 ; 0x480a - 47f8: 05 90 lpm r0, Z+ - 47fa: 0d 92 st X+, r0 - 47fc: 00 20 and r0, r0 - 47fe: c9 f7 brne .-14 ; 0x47f2 - 4800: 01 c0 rjmp .+2 ; 0x4804 - 4802: 1d 92 st X+, r1 - 4804: 41 50 subi r20, 0x01 ; 1 - 4806: 50 40 sbci r21, 0x00 ; 0 - 4808: e0 f7 brcc .-8 ; 0x4802 - 480a: 08 95 ret - -0000480c : - 480c: fb 01 movw r30, r22 - 480e: dc 01 movw r26, r24 - 4810: 02 c0 rjmp .+4 ; 0x4816 - 4812: 01 90 ld r0, Z+ - 4814: 0d 92 st X+, r0 - 4816: 41 50 subi r20, 0x01 ; 1 - 4818: 50 40 sbci r21, 0x00 ; 0 - 481a: d8 f7 brcc .-10 ; 0x4812 - 481c: 08 95 ret - -0000481e : - 481e: ae e0 ldi r26, 0x0E ; 14 - 4820: b0 e0 ldi r27, 0x00 ; 0 - 4822: e4 e1 ldi r30, 0x14 ; 20 - 4824: f4 e2 ldi r31, 0x24 ; 36 - 4826: f2 c2 rjmp .+1508 ; 0x4e0c <__prologue_saves__+0x1c> - 4828: 0d 89 ldd r16, Y+21 ; 0x15 - 482a: 1e 89 ldd r17, Y+22 ; 0x16 - 482c: 8f 89 ldd r24, Y+23 ; 0x17 - 482e: 98 8d ldd r25, Y+24 ; 0x18 - 4830: 2e e0 ldi r18, 0x0E ; 14 - 4832: 2c 83 std Y+4, r18 ; 0x04 - 4834: 09 83 std Y+1, r16 ; 0x01 - 4836: 1a 83 std Y+2, r17 ; 0x02 - 4838: 97 ff sbrs r25, 7 - 483a: 02 c0 rjmp .+4 ; 0x4840 - 483c: 80 e0 ldi r24, 0x00 ; 0 - 483e: 90 e8 ldi r25, 0x80 ; 128 - 4840: 01 97 sbiw r24, 0x01 ; 1 - 4842: 8d 83 std Y+5, r24 ; 0x05 - 4844: 9e 83 std Y+6, r25 ; 0x06 - 4846: ae 01 movw r20, r28 - 4848: 45 5e subi r20, 0xE5 ; 229 - 484a: 5f 4f sbci r21, 0xFF ; 255 - 484c: 69 8d ldd r22, Y+25 ; 0x19 - 484e: 7a 8d ldd r23, Y+26 ; 0x1a - 4850: ce 01 movw r24, r28 - 4852: 01 96 adiw r24, 0x01 ; 1 - 4854: 11 d0 rcall .+34 ; 0x4878 - 4856: 4d 81 ldd r20, Y+5 ; 0x05 - 4858: 5e 81 ldd r21, Y+6 ; 0x06 - 485a: 57 fd sbrc r21, 7 - 485c: 0a c0 rjmp .+20 ; 0x4872 - 485e: 2f 81 ldd r18, Y+7 ; 0x07 - 4860: 38 85 ldd r19, Y+8 ; 0x08 - 4862: 42 17 cp r20, r18 - 4864: 53 07 cpc r21, r19 - 4866: 0c f4 brge .+2 ; 0x486a - 4868: 9a 01 movw r18, r20 - 486a: f8 01 movw r30, r16 - 486c: e2 0f add r30, r18 - 486e: f3 1f adc r31, r19 - 4870: 10 82 st Z, r1 - 4872: 2e 96 adiw r28, 0x0e ; 14 - 4874: e4 e0 ldi r30, 0x04 ; 4 - 4876: e3 c2 rjmp .+1478 ; 0x4e3e <__epilogue_restores__+0x1c> - -00004878 : - 4878: ac e0 ldi r26, 0x0C ; 12 - 487a: b0 e0 ldi r27, 0x00 ; 0 - 487c: e1 e4 ldi r30, 0x41 ; 65 - 487e: f4 e2 ldi r31, 0x24 ; 36 - 4880: b7 c2 rjmp .+1390 ; 0x4df0 <__prologue_saves__> - 4882: 7c 01 movw r14, r24 - 4884: 6b 01 movw r12, r22 - 4886: 8a 01 movw r16, r20 - 4888: fc 01 movw r30, r24 - 488a: 16 82 std Z+6, r1 ; 0x06 - 488c: 17 82 std Z+7, r1 ; 0x07 - 488e: 83 81 ldd r24, Z+3 ; 0x03 - 4890: 81 ff sbrs r24, 1 - 4892: b0 c1 rjmp .+864 ; 0x4bf4 - 4894: ce 01 movw r24, r28 - 4896: 01 96 adiw r24, 0x01 ; 1 - 4898: 4c 01 movw r8, r24 - 489a: f7 01 movw r30, r14 - 489c: 93 81 ldd r25, Z+3 ; 0x03 - 489e: f6 01 movw r30, r12 - 48a0: 93 fd sbrc r25, 3 - 48a2: 85 91 lpm r24, Z+ - 48a4: 93 ff sbrs r25, 3 - 48a6: 81 91 ld r24, Z+ - 48a8: 6f 01 movw r12, r30 - 48aa: 88 23 and r24, r24 - 48ac: 09 f4 brne .+2 ; 0x48b0 - 48ae: 9e c1 rjmp .+828 ; 0x4bec - 48b0: 85 32 cpi r24, 0x25 ; 37 - 48b2: 39 f4 brne .+14 ; 0x48c2 - 48b4: 93 fd sbrc r25, 3 - 48b6: 85 91 lpm r24, Z+ - 48b8: 93 ff sbrs r25, 3 - 48ba: 81 91 ld r24, Z+ - 48bc: 6f 01 movw r12, r30 - 48be: 85 32 cpi r24, 0x25 ; 37 - 48c0: 21 f4 brne .+8 ; 0x48ca - 48c2: b7 01 movw r22, r14 - 48c4: 90 e0 ldi r25, 0x00 ; 0 - 48c6: e8 d1 rcall .+976 ; 0x4c98 - 48c8: e8 cf rjmp .-48 ; 0x489a - 48ca: 51 2c mov r5, r1 - 48cc: 31 2c mov r3, r1 - 48ce: 20 e0 ldi r18, 0x00 ; 0 - 48d0: 20 32 cpi r18, 0x20 ; 32 - 48d2: a0 f4 brcc .+40 ; 0x48fc - 48d4: 8b 32 cpi r24, 0x2B ; 43 - 48d6: 69 f0 breq .+26 ; 0x48f2 - 48d8: 30 f4 brcc .+12 ; 0x48e6 - 48da: 80 32 cpi r24, 0x20 ; 32 - 48dc: 59 f0 breq .+22 ; 0x48f4 - 48de: 83 32 cpi r24, 0x23 ; 35 - 48e0: 69 f4 brne .+26 ; 0x48fc - 48e2: 20 61 ori r18, 0x10 ; 16 - 48e4: 2c c0 rjmp .+88 ; 0x493e - 48e6: 8d 32 cpi r24, 0x2D ; 45 - 48e8: 39 f0 breq .+14 ; 0x48f8 - 48ea: 80 33 cpi r24, 0x30 ; 48 - 48ec: 39 f4 brne .+14 ; 0x48fc - 48ee: 21 60 ori r18, 0x01 ; 1 - 48f0: 26 c0 rjmp .+76 ; 0x493e - 48f2: 22 60 ori r18, 0x02 ; 2 - 48f4: 24 60 ori r18, 0x04 ; 4 - 48f6: 23 c0 rjmp .+70 ; 0x493e - 48f8: 28 60 ori r18, 0x08 ; 8 - 48fa: 21 c0 rjmp .+66 ; 0x493e - 48fc: 27 fd sbrc r18, 7 - 48fe: 27 c0 rjmp .+78 ; 0x494e - 4900: 30 ed ldi r19, 0xD0 ; 208 - 4902: 38 0f add r19, r24 - 4904: 3a 30 cpi r19, 0x0A ; 10 - 4906: 78 f4 brcc .+30 ; 0x4926 - 4908: 26 ff sbrs r18, 6 - 490a: 06 c0 rjmp .+12 ; 0x4918 - 490c: fa e0 ldi r31, 0x0A ; 10 - 490e: 5f 9e mul r5, r31 - 4910: 30 0d add r19, r0 - 4912: 11 24 eor r1, r1 - 4914: 53 2e mov r5, r19 - 4916: 13 c0 rjmp .+38 ; 0x493e - 4918: 8a e0 ldi r24, 0x0A ; 10 - 491a: 38 9e mul r3, r24 - 491c: 30 0d add r19, r0 - 491e: 11 24 eor r1, r1 - 4920: 33 2e mov r3, r19 - 4922: 20 62 ori r18, 0x20 ; 32 - 4924: 0c c0 rjmp .+24 ; 0x493e - 4926: 8e 32 cpi r24, 0x2E ; 46 - 4928: 21 f4 brne .+8 ; 0x4932 - 492a: 26 fd sbrc r18, 6 - 492c: 5f c1 rjmp .+702 ; 0x4bec - 492e: 20 64 ori r18, 0x40 ; 64 - 4930: 06 c0 rjmp .+12 ; 0x493e - 4932: 8c 36 cpi r24, 0x6C ; 108 - 4934: 11 f4 brne .+4 ; 0x493a - 4936: 20 68 ori r18, 0x80 ; 128 - 4938: 02 c0 rjmp .+4 ; 0x493e - 493a: 88 36 cpi r24, 0x68 ; 104 - 493c: 41 f4 brne .+16 ; 0x494e - 493e: f6 01 movw r30, r12 - 4940: 93 fd sbrc r25, 3 - 4942: 85 91 lpm r24, Z+ - 4944: 93 ff sbrs r25, 3 - 4946: 81 91 ld r24, Z+ - 4948: 6f 01 movw r12, r30 - 494a: 81 11 cpse r24, r1 - 494c: c1 cf rjmp .-126 ; 0x48d0 - 494e: 98 2f mov r25, r24 - 4950: 9f 7d andi r25, 0xDF ; 223 - 4952: 95 54 subi r25, 0x45 ; 69 - 4954: 93 30 cpi r25, 0x03 ; 3 - 4956: 28 f4 brcc .+10 ; 0x4962 - 4958: 0c 5f subi r16, 0xFC ; 252 - 495a: 1f 4f sbci r17, 0xFF ; 255 - 495c: ff e3 ldi r31, 0x3F ; 63 - 495e: f9 83 std Y+1, r31 ; 0x01 - 4960: 0d c0 rjmp .+26 ; 0x497c - 4962: 83 36 cpi r24, 0x63 ; 99 - 4964: 31 f0 breq .+12 ; 0x4972 - 4966: 83 37 cpi r24, 0x73 ; 115 - 4968: 71 f0 breq .+28 ; 0x4986 - 496a: 83 35 cpi r24, 0x53 ; 83 - 496c: 09 f0 breq .+2 ; 0x4970 - 496e: 57 c0 rjmp .+174 ; 0x4a1e - 4970: 21 c0 rjmp .+66 ; 0x49b4 - 4972: f8 01 movw r30, r16 - 4974: 80 81 ld r24, Z - 4976: 89 83 std Y+1, r24 ; 0x01 - 4978: 0e 5f subi r16, 0xFE ; 254 - 497a: 1f 4f sbci r17, 0xFF ; 255 - 497c: 44 24 eor r4, r4 - 497e: 43 94 inc r4 - 4980: 51 2c mov r5, r1 - 4982: 54 01 movw r10, r8 - 4984: 14 c0 rjmp .+40 ; 0x49ae - 4986: 38 01 movw r6, r16 - 4988: f2 e0 ldi r31, 0x02 ; 2 - 498a: 6f 0e add r6, r31 - 498c: 71 1c adc r7, r1 - 498e: f8 01 movw r30, r16 - 4990: a0 80 ld r10, Z - 4992: b1 80 ldd r11, Z+1 ; 0x01 - 4994: 26 ff sbrs r18, 6 - 4996: 03 c0 rjmp .+6 ; 0x499e - 4998: 65 2d mov r22, r5 - 499a: 70 e0 ldi r23, 0x00 ; 0 - 499c: 02 c0 rjmp .+4 ; 0x49a2 - 499e: 6f ef ldi r22, 0xFF ; 255 - 49a0: 7f ef ldi r23, 0xFF ; 255 - 49a2: c5 01 movw r24, r10 - 49a4: 2c 87 std Y+12, r18 ; 0x0c - 49a6: 6d d1 rcall .+730 ; 0x4c82 - 49a8: 2c 01 movw r4, r24 - 49aa: 83 01 movw r16, r6 - 49ac: 2c 85 ldd r18, Y+12 ; 0x0c - 49ae: 2f 77 andi r18, 0x7F ; 127 - 49b0: 22 2e mov r2, r18 - 49b2: 16 c0 rjmp .+44 ; 0x49e0 - 49b4: 38 01 movw r6, r16 - 49b6: f2 e0 ldi r31, 0x02 ; 2 - 49b8: 6f 0e add r6, r31 - 49ba: 71 1c adc r7, r1 - 49bc: f8 01 movw r30, r16 - 49be: a0 80 ld r10, Z - 49c0: b1 80 ldd r11, Z+1 ; 0x01 - 49c2: 26 ff sbrs r18, 6 - 49c4: 03 c0 rjmp .+6 ; 0x49cc - 49c6: 65 2d mov r22, r5 - 49c8: 70 e0 ldi r23, 0x00 ; 0 - 49ca: 02 c0 rjmp .+4 ; 0x49d0 - 49cc: 6f ef ldi r22, 0xFF ; 255 - 49ce: 7f ef ldi r23, 0xFF ; 255 - 49d0: c5 01 movw r24, r10 - 49d2: 2c 87 std Y+12, r18 ; 0x0c - 49d4: 4b d1 rcall .+662 ; 0x4c6c - 49d6: 2c 01 movw r4, r24 - 49d8: 2c 85 ldd r18, Y+12 ; 0x0c - 49da: 20 68 ori r18, 0x80 ; 128 - 49dc: 22 2e mov r2, r18 - 49de: 83 01 movw r16, r6 - 49e0: 23 fc sbrc r2, 3 - 49e2: 19 c0 rjmp .+50 ; 0x4a16 - 49e4: 83 2d mov r24, r3 - 49e6: 90 e0 ldi r25, 0x00 ; 0 - 49e8: 48 16 cp r4, r24 - 49ea: 59 06 cpc r5, r25 - 49ec: a0 f4 brcc .+40 ; 0x4a16 - 49ee: b7 01 movw r22, r14 - 49f0: 80 e2 ldi r24, 0x20 ; 32 - 49f2: 90 e0 ldi r25, 0x00 ; 0 - 49f4: 51 d1 rcall .+674 ; 0x4c98 - 49f6: 3a 94 dec r3 - 49f8: f5 cf rjmp .-22 ; 0x49e4 - 49fa: f5 01 movw r30, r10 - 49fc: 27 fc sbrc r2, 7 - 49fe: 85 91 lpm r24, Z+ - 4a00: 27 fe sbrs r2, 7 - 4a02: 81 91 ld r24, Z+ - 4a04: 5f 01 movw r10, r30 - 4a06: b7 01 movw r22, r14 - 4a08: 90 e0 ldi r25, 0x00 ; 0 - 4a0a: 46 d1 rcall .+652 ; 0x4c98 - 4a0c: 31 10 cpse r3, r1 - 4a0e: 3a 94 dec r3 - 4a10: f1 e0 ldi r31, 0x01 ; 1 - 4a12: 4f 1a sub r4, r31 - 4a14: 51 08 sbc r5, r1 - 4a16: 41 14 cp r4, r1 - 4a18: 51 04 cpc r5, r1 - 4a1a: 79 f7 brne .-34 ; 0x49fa - 4a1c: de c0 rjmp .+444 ; 0x4bda - 4a1e: 84 36 cpi r24, 0x64 ; 100 - 4a20: 11 f0 breq .+4 ; 0x4a26 - 4a22: 89 36 cpi r24, 0x69 ; 105 - 4a24: 31 f5 brne .+76 ; 0x4a72 - 4a26: f8 01 movw r30, r16 - 4a28: 27 ff sbrs r18, 7 - 4a2a: 07 c0 rjmp .+14 ; 0x4a3a - 4a2c: 60 81 ld r22, Z - 4a2e: 71 81 ldd r23, Z+1 ; 0x01 - 4a30: 82 81 ldd r24, Z+2 ; 0x02 - 4a32: 93 81 ldd r25, Z+3 ; 0x03 - 4a34: 0c 5f subi r16, 0xFC ; 252 - 4a36: 1f 4f sbci r17, 0xFF ; 255 - 4a38: 08 c0 rjmp .+16 ; 0x4a4a - 4a3a: 60 81 ld r22, Z - 4a3c: 71 81 ldd r23, Z+1 ; 0x01 - 4a3e: 88 27 eor r24, r24 - 4a40: 77 fd sbrc r23, 7 - 4a42: 80 95 com r24 - 4a44: 98 2f mov r25, r24 - 4a46: 0e 5f subi r16, 0xFE ; 254 - 4a48: 1f 4f sbci r17, 0xFF ; 255 - 4a4a: 2f 76 andi r18, 0x6F ; 111 - 4a4c: b2 2e mov r11, r18 - 4a4e: 97 ff sbrs r25, 7 - 4a50: 09 c0 rjmp .+18 ; 0x4a64 - 4a52: 90 95 com r25 - 4a54: 80 95 com r24 - 4a56: 70 95 com r23 - 4a58: 61 95 neg r22 - 4a5a: 7f 4f sbci r23, 0xFF ; 255 - 4a5c: 8f 4f sbci r24, 0xFF ; 255 - 4a5e: 9f 4f sbci r25, 0xFF ; 255 - 4a60: 20 68 ori r18, 0x80 ; 128 - 4a62: b2 2e mov r11, r18 - 4a64: 2a e0 ldi r18, 0x0A ; 10 - 4a66: 30 e0 ldi r19, 0x00 ; 0 - 4a68: a4 01 movw r20, r8 - 4a6a: 48 d1 rcall .+656 ; 0x4cfc <__ultoa_invert> - 4a6c: a8 2e mov r10, r24 - 4a6e: a8 18 sub r10, r8 - 4a70: 43 c0 rjmp .+134 ; 0x4af8 - 4a72: 85 37 cpi r24, 0x75 ; 117 - 4a74: 29 f4 brne .+10 ; 0x4a80 - 4a76: 2f 7e andi r18, 0xEF ; 239 - 4a78: b2 2e mov r11, r18 - 4a7a: 2a e0 ldi r18, 0x0A ; 10 - 4a7c: 30 e0 ldi r19, 0x00 ; 0 - 4a7e: 25 c0 rjmp .+74 ; 0x4aca - 4a80: f2 2f mov r31, r18 - 4a82: f9 7f andi r31, 0xF9 ; 249 - 4a84: bf 2e mov r11, r31 - 4a86: 8f 36 cpi r24, 0x6F ; 111 - 4a88: c1 f0 breq .+48 ; 0x4aba - 4a8a: 18 f4 brcc .+6 ; 0x4a92 - 4a8c: 88 35 cpi r24, 0x58 ; 88 - 4a8e: 79 f0 breq .+30 ; 0x4aae - 4a90: ad c0 rjmp .+346 ; 0x4bec - 4a92: 80 37 cpi r24, 0x70 ; 112 - 4a94: 19 f0 breq .+6 ; 0x4a9c - 4a96: 88 37 cpi r24, 0x78 ; 120 - 4a98: 21 f0 breq .+8 ; 0x4aa2 - 4a9a: a8 c0 rjmp .+336 ; 0x4bec - 4a9c: 2f 2f mov r18, r31 - 4a9e: 20 61 ori r18, 0x10 ; 16 - 4aa0: b2 2e mov r11, r18 - 4aa2: b4 fe sbrs r11, 4 - 4aa4: 0d c0 rjmp .+26 ; 0x4ac0 - 4aa6: 8b 2d mov r24, r11 - 4aa8: 84 60 ori r24, 0x04 ; 4 - 4aaa: b8 2e mov r11, r24 - 4aac: 09 c0 rjmp .+18 ; 0x4ac0 - 4aae: 24 ff sbrs r18, 4 - 4ab0: 0a c0 rjmp .+20 ; 0x4ac6 - 4ab2: 9f 2f mov r25, r31 - 4ab4: 96 60 ori r25, 0x06 ; 6 - 4ab6: b9 2e mov r11, r25 - 4ab8: 06 c0 rjmp .+12 ; 0x4ac6 - 4aba: 28 e0 ldi r18, 0x08 ; 8 - 4abc: 30 e0 ldi r19, 0x00 ; 0 - 4abe: 05 c0 rjmp .+10 ; 0x4aca - 4ac0: 20 e1 ldi r18, 0x10 ; 16 - 4ac2: 30 e0 ldi r19, 0x00 ; 0 - 4ac4: 02 c0 rjmp .+4 ; 0x4aca - 4ac6: 20 e1 ldi r18, 0x10 ; 16 - 4ac8: 32 e0 ldi r19, 0x02 ; 2 - 4aca: f8 01 movw r30, r16 - 4acc: b7 fe sbrs r11, 7 - 4ace: 07 c0 rjmp .+14 ; 0x4ade - 4ad0: 60 81 ld r22, Z - 4ad2: 71 81 ldd r23, Z+1 ; 0x01 - 4ad4: 82 81 ldd r24, Z+2 ; 0x02 - 4ad6: 93 81 ldd r25, Z+3 ; 0x03 - 4ad8: 0c 5f subi r16, 0xFC ; 252 - 4ada: 1f 4f sbci r17, 0xFF ; 255 - 4adc: 06 c0 rjmp .+12 ; 0x4aea - 4ade: 60 81 ld r22, Z - 4ae0: 71 81 ldd r23, Z+1 ; 0x01 - 4ae2: 80 e0 ldi r24, 0x00 ; 0 - 4ae4: 90 e0 ldi r25, 0x00 ; 0 - 4ae6: 0e 5f subi r16, 0xFE ; 254 - 4ae8: 1f 4f sbci r17, 0xFF ; 255 - 4aea: a4 01 movw r20, r8 - 4aec: 07 d1 rcall .+526 ; 0x4cfc <__ultoa_invert> - 4aee: a8 2e mov r10, r24 - 4af0: a8 18 sub r10, r8 - 4af2: fb 2d mov r31, r11 - 4af4: ff 77 andi r31, 0x7F ; 127 - 4af6: bf 2e mov r11, r31 - 4af8: b6 fe sbrs r11, 6 - 4afa: 0b c0 rjmp .+22 ; 0x4b12 - 4afc: 2b 2d mov r18, r11 - 4afe: 2e 7f andi r18, 0xFE ; 254 - 4b00: a5 14 cp r10, r5 - 4b02: 50 f4 brcc .+20 ; 0x4b18 - 4b04: b4 fe sbrs r11, 4 - 4b06: 0a c0 rjmp .+20 ; 0x4b1c - 4b08: b2 fc sbrc r11, 2 - 4b0a: 08 c0 rjmp .+16 ; 0x4b1c - 4b0c: 2b 2d mov r18, r11 - 4b0e: 2e 7e andi r18, 0xEE ; 238 - 4b10: 05 c0 rjmp .+10 ; 0x4b1c - 4b12: 7a 2c mov r7, r10 - 4b14: 2b 2d mov r18, r11 - 4b16: 03 c0 rjmp .+6 ; 0x4b1e - 4b18: 7a 2c mov r7, r10 - 4b1a: 01 c0 rjmp .+2 ; 0x4b1e - 4b1c: 75 2c mov r7, r5 - 4b1e: 24 ff sbrs r18, 4 - 4b20: 0d c0 rjmp .+26 ; 0x4b3c - 4b22: fe 01 movw r30, r28 - 4b24: ea 0d add r30, r10 - 4b26: f1 1d adc r31, r1 - 4b28: 80 81 ld r24, Z - 4b2a: 80 33 cpi r24, 0x30 ; 48 - 4b2c: 11 f4 brne .+4 ; 0x4b32 - 4b2e: 29 7e andi r18, 0xE9 ; 233 - 4b30: 09 c0 rjmp .+18 ; 0x4b44 - 4b32: 22 ff sbrs r18, 2 - 4b34: 06 c0 rjmp .+12 ; 0x4b42 - 4b36: 73 94 inc r7 - 4b38: 73 94 inc r7 - 4b3a: 04 c0 rjmp .+8 ; 0x4b44 - 4b3c: 82 2f mov r24, r18 - 4b3e: 86 78 andi r24, 0x86 ; 134 - 4b40: 09 f0 breq .+2 ; 0x4b44 - 4b42: 73 94 inc r7 - 4b44: 23 fd sbrc r18, 3 - 4b46: 12 c0 rjmp .+36 ; 0x4b6c - 4b48: 20 ff sbrs r18, 0 - 4b4a: 06 c0 rjmp .+12 ; 0x4b58 - 4b4c: 5a 2c mov r5, r10 - 4b4e: 73 14 cp r7, r3 - 4b50: 18 f4 brcc .+6 ; 0x4b58 - 4b52: 53 0c add r5, r3 - 4b54: 57 18 sub r5, r7 - 4b56: 73 2c mov r7, r3 - 4b58: 73 14 cp r7, r3 - 4b5a: 60 f4 brcc .+24 ; 0x4b74 - 4b5c: b7 01 movw r22, r14 - 4b5e: 80 e2 ldi r24, 0x20 ; 32 - 4b60: 90 e0 ldi r25, 0x00 ; 0 - 4b62: 2c 87 std Y+12, r18 ; 0x0c - 4b64: 99 d0 rcall .+306 ; 0x4c98 - 4b66: 73 94 inc r7 - 4b68: 2c 85 ldd r18, Y+12 ; 0x0c - 4b6a: f6 cf rjmp .-20 ; 0x4b58 - 4b6c: 73 14 cp r7, r3 - 4b6e: 10 f4 brcc .+4 ; 0x4b74 - 4b70: 37 18 sub r3, r7 - 4b72: 01 c0 rjmp .+2 ; 0x4b76 - 4b74: 31 2c mov r3, r1 - 4b76: 24 ff sbrs r18, 4 - 4b78: 11 c0 rjmp .+34 ; 0x4b9c - 4b7a: b7 01 movw r22, r14 - 4b7c: 80 e3 ldi r24, 0x30 ; 48 - 4b7e: 90 e0 ldi r25, 0x00 ; 0 - 4b80: 2c 87 std Y+12, r18 ; 0x0c - 4b82: 8a d0 rcall .+276 ; 0x4c98 - 4b84: 2c 85 ldd r18, Y+12 ; 0x0c - 4b86: 22 ff sbrs r18, 2 - 4b88: 16 c0 rjmp .+44 ; 0x4bb6 - 4b8a: 21 ff sbrs r18, 1 - 4b8c: 03 c0 rjmp .+6 ; 0x4b94 - 4b8e: 88 e5 ldi r24, 0x58 ; 88 - 4b90: 90 e0 ldi r25, 0x00 ; 0 - 4b92: 02 c0 rjmp .+4 ; 0x4b98 - 4b94: 88 e7 ldi r24, 0x78 ; 120 - 4b96: 90 e0 ldi r25, 0x00 ; 0 - 4b98: b7 01 movw r22, r14 - 4b9a: 0c c0 rjmp .+24 ; 0x4bb4 - 4b9c: 82 2f mov r24, r18 - 4b9e: 86 78 andi r24, 0x86 ; 134 - 4ba0: 51 f0 breq .+20 ; 0x4bb6 - 4ba2: 21 fd sbrc r18, 1 - 4ba4: 02 c0 rjmp .+4 ; 0x4baa - 4ba6: 80 e2 ldi r24, 0x20 ; 32 - 4ba8: 01 c0 rjmp .+2 ; 0x4bac - 4baa: 8b e2 ldi r24, 0x2B ; 43 - 4bac: 27 fd sbrc r18, 7 - 4bae: 8d e2 ldi r24, 0x2D ; 45 - 4bb0: b7 01 movw r22, r14 - 4bb2: 90 e0 ldi r25, 0x00 ; 0 - 4bb4: 71 d0 rcall .+226 ; 0x4c98 - 4bb6: a5 14 cp r10, r5 - 4bb8: 30 f4 brcc .+12 ; 0x4bc6 - 4bba: b7 01 movw r22, r14 - 4bbc: 80 e3 ldi r24, 0x30 ; 48 - 4bbe: 90 e0 ldi r25, 0x00 ; 0 - 4bc0: 6b d0 rcall .+214 ; 0x4c98 - 4bc2: 5a 94 dec r5 - 4bc4: f8 cf rjmp .-16 ; 0x4bb6 - 4bc6: aa 94 dec r10 - 4bc8: f4 01 movw r30, r8 - 4bca: ea 0d add r30, r10 - 4bcc: f1 1d adc r31, r1 - 4bce: 80 81 ld r24, Z - 4bd0: b7 01 movw r22, r14 - 4bd2: 90 e0 ldi r25, 0x00 ; 0 - 4bd4: 61 d0 rcall .+194 ; 0x4c98 - 4bd6: a1 10 cpse r10, r1 - 4bd8: f6 cf rjmp .-20 ; 0x4bc6 - 4bda: 33 20 and r3, r3 - 4bdc: 09 f4 brne .+2 ; 0x4be0 - 4bde: 5d ce rjmp .-838 ; 0x489a - 4be0: b7 01 movw r22, r14 - 4be2: 80 e2 ldi r24, 0x20 ; 32 - 4be4: 90 e0 ldi r25, 0x00 ; 0 - 4be6: 58 d0 rcall .+176 ; 0x4c98 - 4be8: 3a 94 dec r3 - 4bea: f7 cf rjmp .-18 ; 0x4bda - 4bec: f7 01 movw r30, r14 - 4bee: 86 81 ldd r24, Z+6 ; 0x06 - 4bf0: 97 81 ldd r25, Z+7 ; 0x07 - 4bf2: 02 c0 rjmp .+4 ; 0x4bf8 - 4bf4: 8f ef ldi r24, 0xFF ; 255 - 4bf6: 9f ef ldi r25, 0xFF ; 255 - 4bf8: 2c 96 adiw r28, 0x0c ; 12 - 4bfa: e2 e1 ldi r30, 0x12 ; 18 - 4bfc: 12 c1 rjmp .+548 ; 0x4e22 <__epilogue_restores__> - -00004bfe <__eerd_block_x32a4u>: - 4bfe: e0 ec ldi r30, 0xC0 ; 192 - 4c00: f1 e0 ldi r31, 0x01 ; 1 - 4c02: a7 85 ldd r26, Z+15 ; 0x0f - 4c04: a7 fd sbrc r26, 7 - 4c06: fd cf rjmp .-6 ; 0x4c02 <__eerd_block_x32a4u+0x4> - 4c08: a4 85 ldd r26, Z+12 ; 0x0c - 4c0a: a8 60 ori r26, 0x08 ; 8 - 4c0c: a4 87 std Z+12, r26 ; 0x0c - 4c0e: 60 50 subi r22, 0x00 ; 0 - 4c10: 70 4f sbci r23, 0xF0 ; 240 - 4c12: fc cd rjmp .-1032 ; 0x480c - -00004c14 <__eewr_block_x32a4u>: - 4c14: dc 01 movw r26, r24 - 4c16: cb 01 movw r24, r22 - 4c18: 02 c0 rjmp .+4 ; 0x4c1e <__eewr_block_x32a4u+0xa> - 4c1a: 2d 91 ld r18, X+ - 4c1c: 05 d0 rcall .+10 ; 0x4c28 <__eewr_r18_x32a4u> - 4c1e: 41 50 subi r20, 0x01 ; 1 - 4c20: 50 40 sbci r21, 0x00 ; 0 - 4c22: d8 f7 brcc .-10 ; 0x4c1a <__eewr_block_x32a4u+0x6> - 4c24: 08 95 ret - -00004c26 <__eewr_byte_x32a4u>: - 4c26: 26 2f mov r18, r22 - -00004c28 <__eewr_r18_x32a4u>: - 4c28: e0 ec ldi r30, 0xC0 ; 192 - 4c2a: f1 e0 ldi r31, 0x01 ; 1 - 4c2c: 37 85 ldd r19, Z+15 ; 0x0f - 4c2e: 37 fd sbrc r19, 7 - 4c30: fd cf rjmp .-6 ; 0x4c2c <__eewr_r18_x32a4u+0x4> - 4c32: 34 85 ldd r19, Z+12 ; 0x0c - 4c34: 37 7f andi r19, 0xF7 ; 247 - 4c36: 34 87 std Z+12, r19 ; 0x0c - 4c38: 37 85 ldd r19, Z+15 ; 0x0f - 4c3a: 31 ff sbrs r19, 1 - 4c3c: 09 c0 rjmp .+18 ; 0x4c50 <__eewr_r18_x32a4u+0x28> - 4c3e: 36 e3 ldi r19, 0x36 ; 54 - 4c40: 32 87 std Z+10, r19 ; 0x0a - 4c42: 38 ed ldi r19, 0xD8 ; 216 - 4c44: 34 bf out 0x34, r19 ; 52 - 4c46: 31 e0 ldi r19, 0x01 ; 1 - 4c48: 33 87 std Z+11, r19 ; 0x0b - 4c4a: 37 85 ldd r19, Z+15 ; 0x0f - 4c4c: 37 fd sbrc r19, 7 - 4c4e: fd cf rjmp .-6 ; 0x4c4a <__eewr_r18_x32a4u+0x22> - 4c50: 33 e3 ldi r19, 0x33 ; 51 - 4c52: 32 87 std Z+10, r19 ; 0x0a - 4c54: 80 83 st Z, r24 - 4c56: 91 83 std Z+1, r25 ; 0x01 - 4c58: 12 82 std Z+2, r1 ; 0x02 - 4c5a: 24 83 std Z+4, r18 ; 0x04 - 4c5c: 25 e3 ldi r18, 0x35 ; 53 - 4c5e: 22 87 std Z+10, r18 ; 0x0a - 4c60: 28 ed ldi r18, 0xD8 ; 216 - 4c62: 31 e0 ldi r19, 0x01 ; 1 - 4c64: 24 bf out 0x34, r18 ; 52 - 4c66: 33 87 std Z+11, r19 ; 0x0b - 4c68: 01 96 adiw r24, 0x01 ; 1 - 4c6a: 08 95 ret - -00004c6c : - 4c6c: fc 01 movw r30, r24 - 4c6e: 05 90 lpm r0, Z+ - 4c70: 61 50 subi r22, 0x01 ; 1 - 4c72: 70 40 sbci r23, 0x00 ; 0 - 4c74: 01 10 cpse r0, r1 - 4c76: d8 f7 brcc .-10 ; 0x4c6e - 4c78: 80 95 com r24 - 4c7a: 90 95 com r25 - 4c7c: 8e 0f add r24, r30 - 4c7e: 9f 1f adc r25, r31 - 4c80: 08 95 ret - -00004c82 : - 4c82: fc 01 movw r30, r24 - 4c84: 61 50 subi r22, 0x01 ; 1 - 4c86: 70 40 sbci r23, 0x00 ; 0 - 4c88: 01 90 ld r0, Z+ - 4c8a: 01 10 cpse r0, r1 - 4c8c: d8 f7 brcc .-10 ; 0x4c84 - 4c8e: 80 95 com r24 - 4c90: 90 95 com r25 - 4c92: 8e 0f add r24, r30 - 4c94: 9f 1f adc r25, r31 - 4c96: 08 95 ret - -00004c98 : - 4c98: 0f 93 push r16 - 4c9a: 1f 93 push r17 - 4c9c: cf 93 push r28 - 4c9e: df 93 push r29 - 4ca0: 18 2f mov r17, r24 - 4ca2: 09 2f mov r16, r25 - 4ca4: eb 01 movw r28, r22 - 4ca6: 8b 81 ldd r24, Y+3 ; 0x03 - 4ca8: 81 fd sbrc r24, 1 - 4caa: 03 c0 rjmp .+6 ; 0x4cb2 - 4cac: 8f ef ldi r24, 0xFF ; 255 - 4cae: 9f ef ldi r25, 0xFF ; 255 - 4cb0: 20 c0 rjmp .+64 ; 0x4cf2 - 4cb2: 82 ff sbrs r24, 2 - 4cb4: 10 c0 rjmp .+32 ; 0x4cd6 - 4cb6: 4e 81 ldd r20, Y+6 ; 0x06 - 4cb8: 5f 81 ldd r21, Y+7 ; 0x07 - 4cba: 2c 81 ldd r18, Y+4 ; 0x04 - 4cbc: 3d 81 ldd r19, Y+5 ; 0x05 - 4cbe: 42 17 cp r20, r18 - 4cc0: 53 07 cpc r21, r19 - 4cc2: 7c f4 brge .+30 ; 0x4ce2 - 4cc4: e8 81 ld r30, Y - 4cc6: f9 81 ldd r31, Y+1 ; 0x01 - 4cc8: 9f 01 movw r18, r30 - 4cca: 2f 5f subi r18, 0xFF ; 255 - 4ccc: 3f 4f sbci r19, 0xFF ; 255 - 4cce: 28 83 st Y, r18 - 4cd0: 39 83 std Y+1, r19 ; 0x01 - 4cd2: 10 83 st Z, r17 - 4cd4: 06 c0 rjmp .+12 ; 0x4ce2 - 4cd6: e8 85 ldd r30, Y+8 ; 0x08 - 4cd8: f9 85 ldd r31, Y+9 ; 0x09 - 4cda: 81 2f mov r24, r17 - 4cdc: 09 95 icall - 4cde: 89 2b or r24, r25 - 4ce0: 29 f7 brne .-54 ; 0x4cac - 4ce2: 2e 81 ldd r18, Y+6 ; 0x06 - 4ce4: 3f 81 ldd r19, Y+7 ; 0x07 - 4ce6: 2f 5f subi r18, 0xFF ; 255 - 4ce8: 3f 4f sbci r19, 0xFF ; 255 - 4cea: 2e 83 std Y+6, r18 ; 0x06 - 4cec: 3f 83 std Y+7, r19 ; 0x07 - 4cee: 81 2f mov r24, r17 - 4cf0: 90 2f mov r25, r16 - 4cf2: df 91 pop r29 - 4cf4: cf 91 pop r28 - 4cf6: 1f 91 pop r17 - 4cf8: 0f 91 pop r16 - 4cfa: 08 95 ret - -00004cfc <__ultoa_invert>: - 4cfc: fa 01 movw r30, r20 - 4cfe: aa 27 eor r26, r26 - 4d00: 28 30 cpi r18, 0x08 ; 8 - 4d02: 51 f1 breq .+84 ; 0x4d58 <__ultoa_invert+0x5c> - 4d04: 20 31 cpi r18, 0x10 ; 16 - 4d06: 81 f1 breq .+96 ; 0x4d68 <__ultoa_invert+0x6c> - 4d08: e8 94 clt - 4d0a: 6f 93 push r22 - 4d0c: 6e 7f andi r22, 0xFE ; 254 - 4d0e: 6e 5f subi r22, 0xFE ; 254 - 4d10: 7f 4f sbci r23, 0xFF ; 255 - 4d12: 8f 4f sbci r24, 0xFF ; 255 - 4d14: 9f 4f sbci r25, 0xFF ; 255 - 4d16: af 4f sbci r26, 0xFF ; 255 - 4d18: b1 e0 ldi r27, 0x01 ; 1 - 4d1a: 3e d0 rcall .+124 ; 0x4d98 <__ultoa_invert+0x9c> - 4d1c: b4 e0 ldi r27, 0x04 ; 4 - 4d1e: 3c d0 rcall .+120 ; 0x4d98 <__ultoa_invert+0x9c> - 4d20: 67 0f add r22, r23 - 4d22: 78 1f adc r23, r24 - 4d24: 89 1f adc r24, r25 - 4d26: 9a 1f adc r25, r26 - 4d28: a1 1d adc r26, r1 - 4d2a: 68 0f add r22, r24 - 4d2c: 79 1f adc r23, r25 - 4d2e: 8a 1f adc r24, r26 - 4d30: 91 1d adc r25, r1 - 4d32: a1 1d adc r26, r1 - 4d34: 6a 0f add r22, r26 - 4d36: 71 1d adc r23, r1 - 4d38: 81 1d adc r24, r1 - 4d3a: 91 1d adc r25, r1 - 4d3c: a1 1d adc r26, r1 - 4d3e: 20 d0 rcall .+64 ; 0x4d80 <__ultoa_invert+0x84> - 4d40: 09 f4 brne .+2 ; 0x4d44 <__ultoa_invert+0x48> - 4d42: 68 94 set - 4d44: 3f 91 pop r19 - 4d46: 2a e0 ldi r18, 0x0A ; 10 - 4d48: 26 9f mul r18, r22 - 4d4a: 11 24 eor r1, r1 - 4d4c: 30 19 sub r19, r0 - 4d4e: 30 5d subi r19, 0xD0 ; 208 - 4d50: 31 93 st Z+, r19 - 4d52: de f6 brtc .-74 ; 0x4d0a <__ultoa_invert+0xe> - 4d54: cf 01 movw r24, r30 - 4d56: 08 95 ret - 4d58: 46 2f mov r20, r22 - 4d5a: 47 70 andi r20, 0x07 ; 7 - 4d5c: 40 5d subi r20, 0xD0 ; 208 - 4d5e: 41 93 st Z+, r20 - 4d60: b3 e0 ldi r27, 0x03 ; 3 - 4d62: 0f d0 rcall .+30 ; 0x4d82 <__ultoa_invert+0x86> - 4d64: c9 f7 brne .-14 ; 0x4d58 <__ultoa_invert+0x5c> - 4d66: f6 cf rjmp .-20 ; 0x4d54 <__ultoa_invert+0x58> - 4d68: 46 2f mov r20, r22 - 4d6a: 4f 70 andi r20, 0x0F ; 15 - 4d6c: 40 5d subi r20, 0xD0 ; 208 - 4d6e: 4a 33 cpi r20, 0x3A ; 58 - 4d70: 18 f0 brcs .+6 ; 0x4d78 <__ultoa_invert+0x7c> - 4d72: 49 5d subi r20, 0xD9 ; 217 - 4d74: 31 fd sbrc r19, 1 - 4d76: 40 52 subi r20, 0x20 ; 32 - 4d78: 41 93 st Z+, r20 - 4d7a: 02 d0 rcall .+4 ; 0x4d80 <__ultoa_invert+0x84> - 4d7c: a9 f7 brne .-22 ; 0x4d68 <__ultoa_invert+0x6c> - 4d7e: ea cf rjmp .-44 ; 0x4d54 <__ultoa_invert+0x58> - 4d80: b4 e0 ldi r27, 0x04 ; 4 - 4d82: a6 95 lsr r26 - 4d84: 97 95 ror r25 - 4d86: 87 95 ror r24 - 4d88: 77 95 ror r23 - 4d8a: 67 95 ror r22 - 4d8c: ba 95 dec r27 - 4d8e: c9 f7 brne .-14 ; 0x4d82 <__ultoa_invert+0x86> - 4d90: 00 97 sbiw r24, 0x00 ; 0 - 4d92: 61 05 cpc r22, r1 - 4d94: 71 05 cpc r23, r1 - 4d96: 08 95 ret - 4d98: 9b 01 movw r18, r22 - 4d9a: ac 01 movw r20, r24 - 4d9c: 0a 2e mov r0, r26 - 4d9e: 06 94 lsr r0 - 4da0: 57 95 ror r21 - 4da2: 47 95 ror r20 - 4da4: 37 95 ror r19 - 4da6: 27 95 ror r18 - 4da8: ba 95 dec r27 - 4daa: c9 f7 brne .-14 ; 0x4d9e <__ultoa_invert+0xa2> - 4dac: 62 0f add r22, r18 - 4dae: 73 1f adc r23, r19 - 4db0: 84 1f adc r24, r20 - 4db2: 95 1f adc r25, r21 - 4db4: a0 1d adc r26, r0 - 4db6: 08 95 ret - -00004db8 <__divmodsi4>: - 4db8: 05 2e mov r0, r21 - 4dba: 97 fb bst r25, 7 - 4dbc: 16 f4 brtc .+4 ; 0x4dc2 <__divmodsi4+0xa> - 4dbe: 00 94 com r0 - 4dc0: 0f d0 rcall .+30 ; 0x4de0 <__negsi2> - 4dc2: 57 fd sbrc r21, 7 - 4dc4: 05 d0 rcall .+10 ; 0x4dd0 <__divmodsi4_neg2> - 4dc6: 45 d0 rcall .+138 ; 0x4e52 <__udivmodsi4> - 4dc8: 07 fc sbrc r0, 7 - 4dca: 02 d0 rcall .+4 ; 0x4dd0 <__divmodsi4_neg2> - 4dcc: 46 f4 brtc .+16 ; 0x4dde <__divmodsi4_exit> - 4dce: 08 c0 rjmp .+16 ; 0x4de0 <__negsi2> - -00004dd0 <__divmodsi4_neg2>: - 4dd0: 50 95 com r21 - 4dd2: 40 95 com r20 - 4dd4: 30 95 com r19 - 4dd6: 21 95 neg r18 - 4dd8: 3f 4f sbci r19, 0xFF ; 255 - 4dda: 4f 4f sbci r20, 0xFF ; 255 - 4ddc: 5f 4f sbci r21, 0xFF ; 255 - -00004dde <__divmodsi4_exit>: - 4dde: 08 95 ret - -00004de0 <__negsi2>: - 4de0: 90 95 com r25 - 4de2: 80 95 com r24 - 4de4: 70 95 com r23 - 4de6: 61 95 neg r22 - 4de8: 7f 4f sbci r23, 0xFF ; 255 - 4dea: 8f 4f sbci r24, 0xFF ; 255 - 4dec: 9f 4f sbci r25, 0xFF ; 255 - 4dee: 08 95 ret - -00004df0 <__prologue_saves__>: - 4df0: 2f 92 push r2 - 4df2: 3f 92 push r3 - 4df4: 4f 92 push r4 - 4df6: 5f 92 push r5 - 4df8: 6f 92 push r6 - 4dfa: 7f 92 push r7 - 4dfc: 8f 92 push r8 - 4dfe: 9f 92 push r9 - 4e00: af 92 push r10 - 4e02: bf 92 push r11 - 4e04: cf 92 push r12 - 4e06: df 92 push r13 - 4e08: ef 92 push r14 - 4e0a: ff 92 push r15 - 4e0c: 0f 93 push r16 - 4e0e: 1f 93 push r17 - 4e10: cf 93 push r28 - 4e12: df 93 push r29 - 4e14: cd b7 in r28, 0x3d ; 61 - 4e16: de b7 in r29, 0x3e ; 62 - 4e18: ca 1b sub r28, r26 - 4e1a: db 0b sbc r29, r27 - 4e1c: cd bf out 0x3d, r28 ; 61 - 4e1e: de bf out 0x3e, r29 ; 62 - 4e20: 09 94 ijmp - -00004e22 <__epilogue_restores__>: - 4e22: 2a 88 ldd r2, Y+18 ; 0x12 - 4e24: 39 88 ldd r3, Y+17 ; 0x11 - 4e26: 48 88 ldd r4, Y+16 ; 0x10 - 4e28: 5f 84 ldd r5, Y+15 ; 0x0f - 4e2a: 6e 84 ldd r6, Y+14 ; 0x0e - 4e2c: 7d 84 ldd r7, Y+13 ; 0x0d - 4e2e: 8c 84 ldd r8, Y+12 ; 0x0c - 4e30: 9b 84 ldd r9, Y+11 ; 0x0b - 4e32: aa 84 ldd r10, Y+10 ; 0x0a - 4e34: b9 84 ldd r11, Y+9 ; 0x09 - 4e36: c8 84 ldd r12, Y+8 ; 0x08 - 4e38: df 80 ldd r13, Y+7 ; 0x07 - 4e3a: ee 80 ldd r14, Y+6 ; 0x06 - 4e3c: fd 80 ldd r15, Y+5 ; 0x05 - 4e3e: 0c 81 ldd r16, Y+4 ; 0x04 - 4e40: 1b 81 ldd r17, Y+3 ; 0x03 - 4e42: aa 81 ldd r26, Y+2 ; 0x02 - 4e44: b9 81 ldd r27, Y+1 ; 0x01 - 4e46: ce 0f add r28, r30 - 4e48: d1 1d adc r29, r1 - 4e4a: cd bf out 0x3d, r28 ; 61 - 4e4c: de bf out 0x3e, r29 ; 62 - 4e4e: ed 01 movw r28, r26 - 4e50: 08 95 ret - -00004e52 <__udivmodsi4>: - 4e52: a1 e2 ldi r26, 0x21 ; 33 - 4e54: 1a 2e mov r1, r26 - 4e56: aa 1b sub r26, r26 - 4e58: bb 1b sub r27, r27 - 4e5a: fd 01 movw r30, r26 - 4e5c: 0d c0 rjmp .+26 ; 0x4e78 <__udivmodsi4_ep> - -00004e5e <__udivmodsi4_loop>: - 4e5e: aa 1f adc r26, r26 - 4e60: bb 1f adc r27, r27 - 4e62: ee 1f adc r30, r30 - 4e64: ff 1f adc r31, r31 - 4e66: a2 17 cp r26, r18 - 4e68: b3 07 cpc r27, r19 - 4e6a: e4 07 cpc r30, r20 - 4e6c: f5 07 cpc r31, r21 - 4e6e: 20 f0 brcs .+8 ; 0x4e78 <__udivmodsi4_ep> - 4e70: a2 1b sub r26, r18 - 4e72: b3 0b sbc r27, r19 - 4e74: e4 0b sbc r30, r20 - 4e76: f5 0b sbc r31, r21 - -00004e78 <__udivmodsi4_ep>: - 4e78: 66 1f adc r22, r22 - 4e7a: 77 1f adc r23, r23 - 4e7c: 88 1f adc r24, r24 - 4e7e: 99 1f adc r25, r25 - 4e80: 1a 94 dec r1 - 4e82: 69 f7 brne .-38 ; 0x4e5e <__udivmodsi4_loop> - 4e84: 60 95 com r22 - 4e86: 70 95 com r23 - 4e88: 80 95 com r24 - 4e8a: 90 95 com r25 - 4e8c: 9b 01 movw r18, r22 - 4e8e: ac 01 movw r20, r24 - 4e90: bd 01 movw r22, r26 - 4e92: cf 01 movw r24, r30 - 4e94: 08 95 ret - -00004e96 <_exit>: - 4e96: f8 94 cli - -00004e98 <__stop_program>: - 4e98: ff cf rjmp .-2 ; 0x4e98 <__stop_program> + +Chameleon-Mini.elf: file format elf32-avr + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 0000628e 00000000 00000000 000000b4 2**1 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .data 00000092 00802000 0000628e 00006342 2**0 + CONTENTS, ALLOC, LOAD, DATA + 2 .bss 00000e37 00802092 00802092 000063d4 2**0 + ALLOC + 3 .eeprom 00000033 00810000 00810000 000063d4 2**0 + CONTENTS, ALLOC, LOAD, DATA + 4 .stab 000015a8 00000000 00000000 00006408 2**2 + CONTENTS, READONLY, DEBUGGING + 5 .stabstr 00000788 00000000 00000000 000079b0 2**0 + CONTENTS, READONLY, DEBUGGING + 6 .comment 0000002f 00000000 00000000 00008138 2**0 + CONTENTS, READONLY + 7 .debug_aranges 00000d80 00000000 00000000 00008167 2**0 + CONTENTS, READONLY, DEBUGGING + 8 .debug_info 0001c598 00000000 00000000 00008ee7 2**0 + CONTENTS, READONLY, DEBUGGING + 9 .debug_abbrev 00006309 00000000 00000000 0002547f 2**0 + CONTENTS, READONLY, DEBUGGING + 10 .debug_line 0000d67b 00000000 00000000 0002b788 2**0 + CONTENTS, READONLY, DEBUGGING + 11 .debug_frame 00002304 00000000 00000000 00038e04 2**2 + CONTENTS, READONLY, DEBUGGING + 12 .debug_str 00007fb5 00000000 00000000 0003b108 2**0 + CONTENTS, READONLY, DEBUGGING + 13 .debug_loc 0000eb2a 00000000 00000000 000430bd 2**0 + CONTENTS, READONLY, DEBUGGING + 14 .debug_ranges 00001de0 00000000 00000000 00051be7 2**0 + CONTENTS, READONLY, DEBUGGING + +Disassembly of section .text: + +00000000 <__vectors>: + 0: 6d c4 rjmp .+2266 ; 0x8dc <__ctors_end> + 2: 00 00 nop + 4: 87 c4 rjmp .+2318 ; 0x914 <__bad_interrupt> + 6: 00 00 nop + 8: 85 c4 rjmp .+2314 ; 0x914 <__bad_interrupt> + a: 00 00 nop + c: 83 c4 rjmp .+2310 ; 0x914 <__bad_interrupt> + e: 00 00 nop + 10: 81 c4 rjmp .+2306 ; 0x914 <__bad_interrupt> + 12: 00 00 nop + 14: 7f c4 rjmp .+2302 ; 0x914 <__bad_interrupt> + 16: 00 00 nop + 18: 7d c4 rjmp .+2298 ; 0x914 <__bad_interrupt> + 1a: 00 00 nop + 1c: 7b c4 rjmp .+2294 ; 0x914 <__bad_interrupt> + 1e: 00 00 nop + 20: 79 c4 rjmp .+2290 ; 0x914 <__bad_interrupt> + 22: 00 00 nop + 24: 77 c4 rjmp .+2286 ; 0x914 <__bad_interrupt> + 26: 00 00 nop + 28: 03 c5 rjmp .+2566 ; 0xa30 <__vector_10> + 2a: 00 00 nop + 2c: 73 c4 rjmp .+2278 ; 0x914 <__bad_interrupt> + 2e: 00 00 nop + 30: 71 c4 rjmp .+2274 ; 0x914 <__bad_interrupt> + 32: 00 00 nop + 34: 6f c4 rjmp .+2270 ; 0x914 <__bad_interrupt> + 36: 00 00 nop + 38: 6d c4 rjmp .+2266 ; 0x914 <__bad_interrupt> + 3a: 00 00 nop + 3c: 6b c4 rjmp .+2262 ; 0x914 <__bad_interrupt> + 3e: 00 00 nop + 40: 69 c4 rjmp .+2258 ; 0x914 <__bad_interrupt> + 42: 00 00 nop + 44: 67 c4 rjmp .+2254 ; 0x914 <__bad_interrupt> + 46: 00 00 nop + 48: 65 c4 rjmp .+2250 ; 0x914 <__bad_interrupt> + 4a: 00 00 nop + 4c: 63 c4 rjmp .+2246 ; 0x914 <__bad_interrupt> + 4e: 00 00 nop + 50: 61 c4 rjmp .+2242 ; 0x914 <__bad_interrupt> + 52: 00 00 nop + 54: 5f c4 rjmp .+2238 ; 0x914 <__bad_interrupt> + 56: 00 00 nop + 58: 0c 94 0c 17 jmp 0x2e18 ; 0x2e18 <__vector_22> + 5c: 5b c4 rjmp .+2230 ; 0x914 <__bad_interrupt> + 5e: 00 00 nop + 60: 59 c4 rjmp .+2226 ; 0x914 <__bad_interrupt> + 62: 00 00 nop + 64: 57 c4 rjmp .+2222 ; 0x914 <__bad_interrupt> + 66: 00 00 nop + 68: 55 c4 rjmp .+2218 ; 0x914 <__bad_interrupt> + 6a: 00 00 nop + 6c: 53 c4 rjmp .+2214 ; 0x914 <__bad_interrupt> + 6e: 00 00 nop + 70: 51 c4 rjmp .+2210 ; 0x914 <__bad_interrupt> + 72: 00 00 nop + 74: 4f c4 rjmp .+2206 ; 0x914 <__bad_interrupt> + 76: 00 00 nop + 78: 4d c4 rjmp .+2202 ; 0x914 <__bad_interrupt> + 7a: 00 00 nop + 7c: 4b c4 rjmp .+2198 ; 0x914 <__bad_interrupt> + 7e: 00 00 nop + 80: 49 c4 rjmp .+2194 ; 0x914 <__bad_interrupt> + 82: 00 00 nop + 84: 47 c4 rjmp .+2190 ; 0x914 <__bad_interrupt> + 86: 00 00 nop + 88: 0c 94 db 16 jmp 0x2db6 ; 0x2db6 <__vector_34> + 8c: 43 c4 rjmp .+2182 ; 0x914 <__bad_interrupt> + 8e: 00 00 nop + 90: 41 c4 rjmp .+2178 ; 0x914 <__bad_interrupt> + 92: 00 00 nop + 94: 3f c4 rjmp .+2174 ; 0x914 <__bad_interrupt> + 96: 00 00 nop + 98: 3d c4 rjmp .+2170 ; 0x914 <__bad_interrupt> + 9a: 00 00 nop + 9c: 3b c4 rjmp .+2166 ; 0x914 <__bad_interrupt> + 9e: 00 00 nop + a0: 39 c4 rjmp .+2162 ; 0x914 <__bad_interrupt> + a2: 00 00 nop + a4: 37 c4 rjmp .+2158 ; 0x914 <__bad_interrupt> + a6: 00 00 nop + a8: 35 c4 rjmp .+2154 ; 0x914 <__bad_interrupt> + aa: 00 00 nop + ac: 33 c4 rjmp .+2150 ; 0x914 <__bad_interrupt> + ae: 00 00 nop + b0: 31 c4 rjmp .+2146 ; 0x914 <__bad_interrupt> + b2: 00 00 nop + b4: 2f c4 rjmp .+2142 ; 0x914 <__bad_interrupt> + b6: 00 00 nop + b8: 2d c4 rjmp .+2138 ; 0x914 <__bad_interrupt> + ba: 00 00 nop + bc: 2b c4 rjmp .+2134 ; 0x914 <__bad_interrupt> + be: 00 00 nop + c0: 29 c4 rjmp .+2130 ; 0x914 <__bad_interrupt> + c2: 00 00 nop + c4: 27 c4 rjmp .+2126 ; 0x914 <__bad_interrupt> + c6: 00 00 nop + c8: 25 c4 rjmp .+2122 ; 0x914 <__bad_interrupt> + ca: 00 00 nop + cc: 23 c4 rjmp .+2118 ; 0x914 <__bad_interrupt> + ce: 00 00 nop + d0: 21 c4 rjmp .+2114 ; 0x914 <__bad_interrupt> + d2: 00 00 nop + d4: 1f c4 rjmp .+2110 ; 0x914 <__bad_interrupt> + d6: 00 00 nop + d8: 1d c4 rjmp .+2106 ; 0x914 <__bad_interrupt> + da: 00 00 nop + dc: 1b c4 rjmp .+2102 ; 0x914 <__bad_interrupt> + de: 00 00 nop + e0: 19 c4 rjmp .+2098 ; 0x914 <__bad_interrupt> + e2: 00 00 nop + e4: 17 c4 rjmp .+2094 ; 0x914 <__bad_interrupt> + e6: 00 00 nop + e8: 15 c4 rjmp .+2090 ; 0x914 <__bad_interrupt> + ea: 00 00 nop + ec: 13 c4 rjmp .+2086 ; 0x914 <__bad_interrupt> + ee: 00 00 nop + f0: 11 c4 rjmp .+2082 ; 0x914 <__bad_interrupt> + f2: 00 00 nop + f4: 0f c4 rjmp .+2078 ; 0x914 <__bad_interrupt> + f6: 00 00 nop + f8: 0d c4 rjmp .+2074 ; 0x914 <__bad_interrupt> + fa: 00 00 nop + fc: 0b c4 rjmp .+2070 ; 0x914 <__bad_interrupt> + fe: 00 00 nop + 100: 09 c4 rjmp .+2066 ; 0x914 <__bad_interrupt> + 102: 00 00 nop + 104: 07 c4 rjmp .+2062 ; 0x914 <__bad_interrupt> + 106: 00 00 nop + 108: 05 c4 rjmp .+2058 ; 0x914 <__bad_interrupt> + 10a: 00 00 nop + 10c: 03 c4 rjmp .+2054 ; 0x914 <__bad_interrupt> + 10e: 00 00 nop + 110: 01 c4 rjmp .+2050 ; 0x914 <__bad_interrupt> + 112: 00 00 nop + 114: ff c3 rjmp .+2046 ; 0x914 <__bad_interrupt> + 116: 00 00 nop + 118: fd c3 rjmp .+2042 ; 0x914 <__bad_interrupt> + 11a: 00 00 nop + 11c: fb c3 rjmp .+2038 ; 0x914 <__bad_interrupt> + 11e: 00 00 nop + 120: f9 c3 rjmp .+2034 ; 0x914 <__bad_interrupt> + 122: 00 00 nop + 124: f7 c3 rjmp .+2030 ; 0x914 <__bad_interrupt> + 126: 00 00 nop + 128: f5 c3 rjmp .+2026 ; 0x914 <__bad_interrupt> + 12a: 00 00 nop + 12c: f3 c3 rjmp .+2022 ; 0x914 <__bad_interrupt> + 12e: 00 00 nop + 130: f1 c3 rjmp .+2018 ; 0x914 <__bad_interrupt> + 132: 00 00 nop + 134: ef c3 rjmp .+2014 ; 0x914 <__bad_interrupt> + 136: 00 00 nop + 138: ed c3 rjmp .+2010 ; 0x914 <__bad_interrupt> + 13a: 00 00 nop + 13c: eb c3 rjmp .+2006 ; 0x914 <__bad_interrupt> + 13e: 00 00 nop + 140: e9 c3 rjmp .+2002 ; 0x914 <__bad_interrupt> + 142: 00 00 nop + 144: e7 c3 rjmp .+1998 ; 0x914 <__bad_interrupt> + 146: 00 00 nop + 148: e5 c3 rjmp .+1994 ; 0x914 <__bad_interrupt> + 14a: 00 00 nop + 14c: 0c 94 b0 17 jmp 0x2f60 ; 0x2f60 <__vector_83> + 150: e1 c3 rjmp .+1986 ; 0x914 <__bad_interrupt> + 152: 00 00 nop + 154: df c3 rjmp .+1982 ; 0x914 <__bad_interrupt> + 156: 00 00 nop + 158: dd c3 rjmp .+1978 ; 0x914 <__bad_interrupt> + 15a: 00 00 nop + 15c: db c3 rjmp .+1974 ; 0x914 <__bad_interrupt> + 15e: 00 00 nop + 160: d9 c3 rjmp .+1970 ; 0x914 <__bad_interrupt> + 162: 00 00 nop + 164: d7 c3 rjmp .+1966 ; 0x914 <__bad_interrupt> + 166: 00 00 nop + 168: d5 c3 rjmp .+1962 ; 0x914 <__bad_interrupt> + 16a: 00 00 nop + 16c: d3 c3 rjmp .+1958 ; 0x914 <__bad_interrupt> + 16e: 00 00 nop + 170: d1 c3 rjmp .+1954 ; 0x914 <__bad_interrupt> + 172: 00 00 nop + 174: cf c3 rjmp .+1950 ; 0x914 <__bad_interrupt> + 176: 00 00 nop + 178: cd c3 rjmp .+1946 ; 0x914 <__bad_interrupt> + 17a: 00 00 nop + 17c: cb c3 rjmp .+1942 ; 0x914 <__bad_interrupt> + 17e: 00 00 nop + 180: c9 c3 rjmp .+1938 ; 0x914 <__bad_interrupt> + 182: 00 00 nop + 184: c7 c3 rjmp .+1934 ; 0x914 <__bad_interrupt> + 186: 00 00 nop + 188: c5 c3 rjmp .+1930 ; 0x914 <__bad_interrupt> + 18a: 00 00 nop + 18c: c3 c3 rjmp .+1926 ; 0x914 <__bad_interrupt> + 18e: 00 00 nop + 190: c1 c3 rjmp .+1922 ; 0x914 <__bad_interrupt> + 192: 00 00 nop + 194: bf c3 rjmp .+1918 ; 0x914 <__bad_interrupt> + 196: 00 00 nop + 198: bd c3 rjmp .+1914 ; 0x914 <__bad_interrupt> + 19a: 00 00 nop + 19c: bb c3 rjmp .+1910 ; 0x914 <__bad_interrupt> + 19e: 00 00 nop + 1a0: b9 c3 rjmp .+1906 ; 0x914 <__bad_interrupt> + 1a2: 00 00 nop + 1a4: b7 c3 rjmp .+1902 ; 0x914 <__bad_interrupt> + 1a6: 00 00 nop + 1a8: b5 c3 rjmp .+1898 ; 0x914 <__bad_interrupt> + 1aa: 00 00 nop + 1ac: b3 c3 rjmp .+1894 ; 0x914 <__bad_interrupt> + 1ae: 00 00 nop + 1b0: b1 c3 rjmp .+1890 ; 0x914 <__bad_interrupt> + 1b2: 00 00 nop + 1b4: af c3 rjmp .+1886 ; 0x914 <__bad_interrupt> + 1b6: 00 00 nop + 1b8: ad c3 rjmp .+1882 ; 0x914 <__bad_interrupt> + 1ba: 00 00 nop + 1bc: ab c3 rjmp .+1878 ; 0x914 <__bad_interrupt> + 1be: 00 00 nop + 1c0: a9 c3 rjmp .+1874 ; 0x914 <__bad_interrupt> + 1c2: 00 00 nop + 1c4: a7 c3 rjmp .+1870 ; 0x914 <__bad_interrupt> + 1c6: 00 00 nop + 1c8: a5 c3 rjmp .+1866 ; 0x914 <__bad_interrupt> + 1ca: 00 00 nop + 1cc: a3 c3 rjmp .+1862 ; 0x914 <__bad_interrupt> + 1ce: 00 00 nop + 1d0: a1 c3 rjmp .+1858 ; 0x914 <__bad_interrupt> + 1d2: 00 00 nop + 1d4: 9f c3 rjmp .+1854 ; 0x914 <__bad_interrupt> + 1d6: 00 00 nop + 1d8: 9d c3 rjmp .+1850 ; 0x914 <__bad_interrupt> + 1da: 00 00 nop + 1dc: 9b c3 rjmp .+1846 ; 0x914 <__bad_interrupt> + 1de: 00 00 nop + 1e0: 99 c3 rjmp .+1842 ; 0x914 <__bad_interrupt> + 1e2: 00 00 nop + 1e4: 97 c3 rjmp .+1838 ; 0x914 <__bad_interrupt> + 1e6: 00 00 nop + 1e8: 95 c3 rjmp .+1834 ; 0x914 <__bad_interrupt> + 1ea: 00 00 nop + 1ec: 93 c3 rjmp .+1830 ; 0x914 <__bad_interrupt> + 1ee: 00 00 nop + 1f0: 91 c3 rjmp .+1826 ; 0x914 <__bad_interrupt> + 1f2: 00 00 nop + 1f4: 0c 94 da 2a jmp 0x55b4 ; 0x55b4 <__vector_125> + 1f8: 8d c3 rjmp .+1818 ; 0x914 <__bad_interrupt> + 1fa: 00 00 nop + +000001fc : + 1fc: 1c 03 4c 00 55 00 46 00 41 00 20 00 43 00 44 00 ..L.U.F.A. .C.D. + 20c: 43 00 20 00 44 00 65 00 6d 00 6f 00 00 00 C. .D.e.m.o... + +0000021a : + 21a: 18 03 44 00 65 00 61 00 6e 00 20 00 43 00 61 00 ..D.e.a.n. .C.a. + 22a: 6d 00 65 00 72 00 61 00 00 00 m.e.r.a... + +00000234 : + 234: 04 03 09 04 .... + +00000238 : + 238: 09 02 3e 00 02 01 00 c0 32 09 04 00 00 01 02 02 ..>.....2....... + 248: 01 00 05 24 00 10 01 04 24 02 06 05 24 06 00 01 ...$....$...$... + 258: 07 05 82 03 08 00 ff 09 04 01 00 02 0a 00 00 00 ................ + 268: 07 05 04 02 10 00 05 07 05 83 02 10 00 05 .............. + +00000276 : + 276: 12 01 10 01 02 00 00 08 eb 03 44 20 01 00 01 02 ..........D .... + 286: dc 01 .. + +00000288 : + 288: 00 4e 4f 4e 45 00 00 00 00 00 00 00 00 00 00 00 .NONE........... + 298: 00 a0 05 a1 05 a2 05 a3 05 a4 05 a5 05 a8 05 a9 ................ + 2a8: 05 00 00 00 01 01 4d 46 5f 55 4c 54 52 41 4c 49 ......MF_ULTRALI + 2b8: 47 48 54 00 00 00 a1 18 d8 18 89 19 8d 19 91 19 GHT............. + 2c8: 92 19 e4 1a f7 1a 40 00 07 00 02 4d 46 5f 43 4c ......@....MF_CL + 2d8: 41 53 53 49 43 5f 31 4b 00 00 00 a1 18 d8 18 36 ASSIC_1K.......6 + 2e8: 1b 69 1b 6d 1b 6e 1b 32 21 53 21 00 04 04 00 03 .i.m.n.2!S!..... + 2f8: 4d 46 5f 50 4c 55 53 31 4b 5f 37 42 00 00 00 00 MF_PLUS1K_7B.... + 308: a1 18 d8 18 45 1b 69 1b 6d 1b 6e 1b 32 21 53 21 ....E.i.m.n.2!S! + 318: 00 04 07 00 04 4d 46 5f 43 4c 41 53 53 49 43 5f .....MF_CLASSIC_ + 328: 34 4b 00 00 00 a1 18 d8 18 5a 1b 69 1b 6d 1b 6e 4K.......Z.i.m.n + 338: 1b 32 21 53 21 00 10 04 00 05 49 53 4f 31 34 34 .2!S!.....ISO144 + 348: 34 33 41 5f 53 4e 49 46 46 00 a1 18 d8 18 a2 05 43A_SNIFF....... + 358: a3 05 a4 05 a5 05 a8 05 a9 05 00 00 00 01 .............. + +00000366 : + 366: 4e 4f 4e 45 00 00 00 00 00 00 00 00 00 00 00 00 NONE............ + 376: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 386: 55 49 44 5f 52 41 4e 44 4f 4d 00 00 00 00 00 00 UID_RANDOM...... + 396: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 3a6: 55 49 44 5f 4c 45 46 54 5f 49 4e 43 52 45 4d 45 UID_LEFT_INCREME + 3b6: 4e 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 NT.............. + 3c6: 55 49 44 5f 52 49 47 48 54 5f 49 4e 43 52 45 4d UID_RIGHT_INCREM + 3d6: 45 4e 54 00 00 00 00 00 00 00 00 00 00 00 00 00 ENT............. + 3e6: 55 49 44 5f 4c 45 46 54 5f 44 45 43 52 45 4d 45 UID_LEFT_DECREME + 3f6: 4e 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 NT.............. + 406: 55 49 44 5f 52 49 47 48 54 5f 44 45 43 52 45 4d UID_RIGHT_DECREM + 416: 45 4e 54 00 00 00 00 00 00 00 00 00 00 00 00 00 ENT............. + 426: 43 59 43 4c 45 5f 53 45 54 54 49 4e 47 53 00 00 CYCLE_SETTINGS.. + 436: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 446: 53 54 4f 52 45 5f 4d 45 4d 00 00 00 00 00 00 00 STORE_MEM....... + 456: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 466: 52 45 43 41 4c 4c 5f 4d 45 4d 00 00 00 00 00 00 RECALL_MEM...... + 476: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + +00000486 : + 486: 4f 46 46 00 00 00 00 00 00 00 00 00 00 00 00 00 OFF............. + 496: 4d 45 4d 4f 52 59 00 00 00 00 00 00 00 00 00 00 MEMORY.......... + 4a6: 54 45 52 4d 49 4e 41 4c 00 00 00 00 00 00 00 00 TERMINAL........ + +000004b6 <__c.6349>: + 4b6: 2c 00 ,. + +000004b8 : + 4b8: 4e 4f 4e 45 00 00 00 00 00 00 00 00 00 00 00 00 NONE............ + 4c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 4d8: 54 45 52 4d 49 4e 41 4c 5f 43 4f 4e 4e 00 00 00 TERMINAL_CONN... + 4e8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 4f8: 54 45 52 4d 49 4e 41 4c 5f 52 58 54 58 00 00 00 TERMINAL_RXTX... + 508: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 518: 53 45 54 54 49 4e 47 5f 43 48 41 4e 47 45 00 00 SETTING_CHANGE.. + 528: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 538: 4d 45 4d 4f 52 59 5f 53 54 4f 52 45 44 00 00 00 MEMORY_STORED... + 548: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 558: 4d 45 4d 4f 52 59 5f 43 48 41 4e 47 45 44 00 00 MEMORY_CHANGED.. + 568: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 578: 43 4f 44 45 43 5f 52 58 00 00 00 00 00 00 00 00 CODEC_RX........ + 588: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 598: 43 4f 44 45 43 5f 54 58 00 00 00 00 00 00 00 00 CODEC_TX........ + 5a8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + +000005b8 <__c.6462>: + 5b8: 43 68 61 6d 65 6c 65 6f 6e 2d 4d 69 6e 69 20 25 Chameleon-Mini % + 5c8: 53 20 75 73 69 6e 67 20 4c 55 46 41 20 25 53 20 S using LUFA %S + 5d8: 63 6f 6d 70 69 6c 65 64 20 77 69 74 68 20 41 56 compiled with AV + 5e8: 52 2d 47 43 43 20 25 53 00 R-GCC %S. + +000005f1 <__c.6464>: + 5f1: 31 35 30 32 32 33 00 150223. + +000005f8 <__c.6466>: + 5f8: 31 33 30 39 30 31 00 130901. + +000005ff <__c.6468>: + 5ff: 34 2e 37 2e 32 00 4.7.2. + +00000605 <__c.6473>: + 605: 25 73 00 %s. + +00000608 <__c.6491>: + 608: 52 41 4e 44 4f 4d 00 RANDOM. + +0000060f <__c.6518>: + 60f: 25 75 00 %u. + +00000612 <__c.6523>: + 612: 25 75 00 %u. + +00000615 <__c.6573>: + 615: 25 53 2c 25 53 00 %S,%S. + +0000061b <__c.6575>: + 61b: 4c 4f 41 44 42 49 4e 00 LOADBIN. + +00000623 <__c.6577>: + 623: 43 4c 45 41 52 00 CLEAR. + +00000629 <__c.6582>: + 629: 25 75 00 %u. + +0000062c <__c.6587>: + 62c: 4c 4f 41 44 42 49 4e 00 LOADBIN. + +00000634 <__c.6589>: + 634: 43 4c 45 41 52 00 CLEAR. + +0000063a <__c.6619>: + 63a: 25 35 75 20 6d 56 00 %5u mV. + +00000641 : + 641: 56 45 52 53 49 4f 4e 00 00 00 00 00 00 00 00 00 VERSION......... + 651: 00 00 00 00 4f 11 43 4f 4e 46 49 47 00 00 00 00 ....O.CONFIG.... + 661: 00 00 00 00 00 00 8c 11 83 11 6d 11 55 49 44 00 ..........m.UID. + 671: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b9 11 ................ + 681: 92 11 52 45 41 44 4f 4e 4c 59 00 00 00 00 00 00 ..READONLY...... + 691: 00 00 00 00 24 12 12 12 55 50 4c 4f 41 44 00 00 ....$...UPLOAD.. + 6a1: 00 00 00 00 00 00 00 00 38 12 00 00 00 00 44 4f ........8.....DO + 6b1: 57 4e 4c 4f 41 44 00 00 00 00 00 00 00 00 3d 12 WNLOAD........=. + 6c1: 00 00 00 00 52 45 53 45 54 00 00 00 00 00 00 00 ....RESET....... + 6d1: 00 00 00 00 42 12 00 00 00 00 55 50 47 52 41 44 ....B.....UPGRAD + 6e1: 45 00 00 00 00 00 00 00 00 00 4d 12 00 00 00 00 E.........M..... + 6f1: 4d 45 4d 53 49 5a 45 00 00 00 00 00 00 00 00 00 MEMSIZE......... + 701: 00 00 00 00 58 12 55 49 44 53 49 5a 45 00 00 00 ....X.UIDSIZE... + 711: 00 00 00 00 00 00 00 00 00 00 70 12 42 55 54 54 ..........p.BUTT + 721: 4f 4e 00 00 00 00 00 00 00 00 00 00 86 12 92 12 ON.............. + 731: 8b 12 42 55 54 54 4f 4e 5f 4c 4f 4e 47 00 00 00 ..BUTTON_LONG... + 741: 00 00 9c 12 a8 12 a1 12 4c 45 44 47 52 45 45 4e ........LEDGREEN + 751: 00 00 00 00 00 00 00 00 b2 12 be 12 b7 12 4c 45 ..............LE + 761: 44 52 45 44 00 00 00 00 00 00 00 00 00 00 c8 12 DRED............ + 771: d4 12 cd 12 4c 4f 47 4d 4f 44 45 00 00 00 00 00 ....LOGMODE..... + 781: 00 00 00 00 de 12 e8 12 e3 12 4c 4f 47 4d 45 4d ..........LOGMEM + 791: 00 00 00 00 00 00 00 00 00 00 f0 12 24 13 0a 13 ............$... + 7a1: 53 45 54 54 49 4e 47 00 00 00 00 00 00 00 00 00 SETTING......... + 7b1: 00 00 49 13 44 13 43 4c 45 41 52 00 00 00 00 00 ..I.D.CLEAR..... + 7c1: 00 00 00 00 00 00 51 13 00 00 00 00 48 45 4c 50 ......Q.....HELP + 7d1: 00 00 00 00 00 00 00 00 00 00 00 00 55 13 00 00 ............U... + 7e1: 00 00 52 53 53 49 00 00 00 00 00 00 00 00 00 00 ..RSSI.......... + 7f1: 00 00 00 00 00 00 a1 13 00 00 00 00 00 00 00 00 ................ + 801: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .............. + +0000080f <__c.6126>: + 80f: 0d 0a 00 ... + +00000812 <__c.6128>: + 812: 0d 0a 00 ... + +00000815 : + 815: 64 31 30 30 3a 4f 4b 00 00 00 00 00 00 00 00 00 d100:OK......... + 825: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 835: 00 65 31 30 31 3a 4f 4b 20 57 49 54 48 20 54 45 .e101:OK WITH TE + 845: 58 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 XT.............. + 855: 00 00 6e 31 31 30 3a 57 41 49 54 49 4e 47 20 46 ..n110:WAITING F + 865: 4f 52 20 58 4d 4f 44 45 4d 00 00 00 00 00 00 00 OR XMODEM....... + 875: 00 00 00 c8 32 30 30 3a 55 4e 4b 4e 4f 57 4e 20 ....200:UNKNOWN + 885: 43 4f 4d 4d 41 4e 44 00 00 00 00 00 00 00 00 00 COMMAND......... + 895: 00 00 00 00 c9 32 30 31 3a 49 4e 56 41 4c 49 44 .....201:INVALID + 8a5: 20 43 4f 4d 4d 41 4e 44 20 55 53 41 47 45 00 00 COMMAND USAGE.. + 8b5: 00 00 00 00 00 ca 32 30 32 3a 49 4e 56 41 4c 49 ......202:INVALI + 8c5: 44 20 50 41 52 41 4d 45 54 45 52 00 00 00 00 00 D PARAMETER..... + 8d5: 00 00 00 00 00 00 00 ....... + +000008dc <__ctors_end>: + 8dc: 11 24 eor r1, r1 + 8de: 1f be out 0x3f, r1 ; 63 + 8e0: cf ef ldi r28, 0xFF ; 255 + 8e2: df e2 ldi r29, 0x2F ; 47 + 8e4: de bf out 0x3e, r29 ; 62 + 8e6: cd bf out 0x3d, r28 ; 61 + +000008e8 <__do_copy_data>: + 8e8: 10 e2 ldi r17, 0x20 ; 32 + 8ea: a0 e0 ldi r26, 0x00 ; 0 + 8ec: b0 e2 ldi r27, 0x20 ; 32 + 8ee: ee e8 ldi r30, 0x8E ; 142 + 8f0: f2 e6 ldi r31, 0x62 ; 98 + 8f2: 02 c0 rjmp .+4 ; 0x8f8 <__do_copy_data+0x10> + 8f4: 05 90 lpm r0, Z+ + 8f6: 0d 92 st X+, r0 + 8f8: a2 39 cpi r26, 0x92 ; 146 + 8fa: b1 07 cpc r27, r17 + 8fc: d9 f7 brne .-10 ; 0x8f4 <__do_copy_data+0xc> + +000008fe <__do_clear_bss>: + 8fe: 2e e2 ldi r18, 0x2E ; 46 + 900: a2 e9 ldi r26, 0x92 ; 146 + 902: b0 e2 ldi r27, 0x20 ; 32 + 904: 01 c0 rjmp .+2 ; 0x908 <.do_clear_bss_start> + +00000906 <.do_clear_bss_loop>: + 906: 1d 92 st X+, r1 + +00000908 <.do_clear_bss_start>: + 908: a9 3c cpi r26, 0xC9 ; 201 + 90a: b2 07 cpc r27, r18 + 90c: e1 f7 brne .-8 ; 0x906 <.do_clear_bss_loop> + 90e: 03 d0 rcall .+6 ; 0x916
+ 910: 0c 94 45 31 jmp 0x628a ; 0x628a <_exit> + +00000914 <__bad_interrupt>: + 914: 87 c0 rjmp .+270 ; 0xa24 <__vector_default> + +00000916
: +#include "Chameleon-Mini.h" + +int main(void) +{ + SystemInit(); + 916: 8d d0 rcall .+282 ; 0xa32 + SettingsLoad(); + 918: 0e 94 34 0e call 0x1c68 ; 0x1c68 + LogInit(); + 91c: 0e 94 d2 0d call 0x1ba4 ; 0x1ba4 + LEDInit(); + 920: 0e 94 1d 0f call 0x1e3a ; 0x1e3a + MemoryInit(); + 924: fd d2 rcall .+1530 ; 0xf20 + ConfigurationInit(); + 926: 31 d1 rcall .+610 ; 0xb8a + TerminalInit(); + 928: 0e 94 db 10 call 0x21b6 ; 0x21b6 + RandomInit(); + 92c: a4 d1 rcall .+840 ; 0xc76 + ButtonInit(); + 92e: 95 d7 rcall .+3882 ; 0x185a +#define ANTENNA_LEVEL_DENOMINATOR (ANTENNA_LEVEL_SCALE) + +static inline +void AntennaLevelInit(void) +{ + ADCA.CTRLA = ADC_ENABLE_bm; + 930: 81 e0 ldi r24, 0x01 ; 1 + 932: 80 93 00 02 sts 0x0200, r24 + ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc; + 936: 10 92 01 02 sts 0x0201, r1 + ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm; + 93a: 92 e0 ldi r25, 0x02 ; 2 + 93c: 90 93 02 02 sts 0x0202, r25 + ADCA.PRESCALER = ADC_PRESCALER_DIV32_gc; + 940: 93 e0 ldi r25, 0x03 ; 3 + 942: 90 93 04 02 sts 0x0204, r25 + ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; + 946: 80 93 20 02 sts 0x0220, r24 + ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN7_gc; + 94a: 88 e3 ldi r24, 0x38 ; 56 + 94c: 80 93 21 02 sts 0x0221, r24 + AntennaLevelInit(); + + SystemInterruptInit(); + 950: f1 d0 rcall .+482 ; 0xb34 + asm volatile("sleep"); +} + +INLINE void SystemSleepEnable(void) +{ + SLEEP.CTRL |= SLEEP_SEN_bm; + 952: 80 91 48 00 lds r24, 0x0048 + 956: 81 60 ori r24, 0x01 ; 1 + 958: 80 93 48 00 sts 0x0048, r24 +{ + if (RTC.INTFLAGS & RTC_COMPIF_bm) { + while(RTC.STATUS & RTC_SYNCBUSY_bm) + ; + + RTC.INTFLAGS = RTC_COMPIF_bm; + 95c: c2 e0 ldi r28, 0x02 ; 2 + 95e: 0e c0 rjmp .+28 ; 0x97c + ButtonTick(); + LogTick(); + LEDTick(); + } + + TerminalTask(); + 960: 0e 94 e0 10 call 0x21c0 ; 0x21c0 +INLINE void ApplicationInit(void) { + ActiveConfiguration.ApplicationInitFunc(); +} + +INLINE void ApplicationTask(void) { + ActiveConfiguration.ApplicationTaskFunc(); + 964: e0 91 fb 28 lds r30, 0x28FB + 968: f0 91 fc 28 lds r31, 0x28FC + 96c: 09 95 icall + ApplicationTask(); + LogTask(); + 96e: 0e 94 48 0d call 0x1a90 ; 0x1a90 +INLINE void CodecInit(void) { + ActiveConfiguration.CodecInitFunc(); +} + +INLINE void CodecTask(void) { + ActiveConfiguration.CodecTaskFunc(); + 972: e0 91 f5 28 lds r30, 0x28F5 + 976: f0 91 f6 28 lds r31, 0x28F6 + 97a: 09 95 icall +INLINE void SystemSleepDisable(void); +INLINE void SystemSleepSetMode(uint8_t SleepMode); + +INLINE bool SystemTick100ms(void) +{ + if (RTC.INTFLAGS & RTC_COMPIF_bm) { + 97c: 80 91 03 04 lds r24, 0x0403 + 980: 81 ff sbrs r24, 1 + 982: ee cf rjmp .-36 ; 0x960 + while(RTC.STATUS & RTC_SYNCBUSY_bm) + 984: 80 91 01 04 lds r24, 0x0401 + 988: 80 fd sbrc r24, 0 + 98a: fc cf rjmp .-8 ; 0x984 + ; + + RTC.INTFLAGS = RTC_COMPIF_bm; + 98c: c0 93 03 04 sts 0x0403, r28 + SystemInterruptInit(); + SystemSleepEnable(); + + while(1) { + if (SystemTick100ms()) { + RandomTick(); + 990: 85 d1 rcall .+778 ; 0xc9c + TerminalTick(); + 992: 0e 94 01 11 call 0x2202 ; 0x2202 + ButtonTick(); + 996: 68 d7 rcall .+3792 ; 0x1868 + LogTick(); + 998: 0e 94 47 0d call 0x1a8e ; 0x1a8e + LEDTick(); + 99c: 0e 94 22 0f call 0x1e44 ; 0x1e44 + 9a0: df cf rjmp .-66 ; 0x960 + +000009a2 : + break; + } + + *DescriptorAddress = Address; + return Size; +} + 9a2: 29 2f mov r18, r25 + 9a4: 33 27 eor r19, r19 + const uint8_t DescriptorNumber = (wValue & 0xFF); + + const void* Address = NULL; + uint16_t Size = NO_DESCRIPTOR; + + switch (DescriptorType) + 9a6: 22 30 cpi r18, 0x02 ; 2 + 9a8: 31 05 cpc r19, r1 + 9aa: 39 f1 breq .+78 ; 0x9fa + 9ac: 23 30 cpi r18, 0x03 ; 3 + 9ae: 31 05 cpc r19, r1 + 9b0: a9 f0 breq .+42 ; 0x9dc + 9b2: 21 30 cpi r18, 0x01 ; 1 + 9b4: 31 05 cpc r19, r1 + 9b6: 49 f0 breq .+18 ; 0x9ca +{ + const uint8_t DescriptorType = (wValue >> 8); + const uint8_t DescriptorNumber = (wValue & 0xFF); + + const void* Address = NULL; + uint16_t Size = NO_DESCRIPTOR; + 9b8: 20 e0 ldi r18, 0x00 ; 0 + 9ba: 30 e0 ldi r19, 0x00 ; 0 + const void** const DescriptorAddress) +{ + const uint8_t DescriptorType = (wValue >> 8); + const uint8_t DescriptorNumber = (wValue & 0xFF); + + const void* Address = NULL; + 9bc: 80 e0 ldi r24, 0x00 ; 0 + 9be: 90 e0 ldi r25, 0x00 ; 0 + } + + break; + } + + *DescriptorAddress = Address; + 9c0: fa 01 movw r30, r20 + 9c2: 80 83 st Z, r24 + 9c4: 91 83 std Z+1, r25 ; 0x01 + return Size; +} + 9c6: c9 01 movw r24, r18 + 9c8: 08 95 ret + + switch (DescriptorType) + { + case DTYPE_Device: + Address = &DeviceDescriptor; + Size = sizeof(USB_Descriptor_Device_t); + 9ca: 22 e1 ldi r18, 0x12 ; 18 + 9cc: 30 e0 ldi r19, 0x00 ; 0 + uint16_t Size = NO_DESCRIPTOR; + + switch (DescriptorType) + { + case DTYPE_Device: + Address = &DeviceDescriptor; + 9ce: 86 e7 ldi r24, 0x76 ; 118 + 9d0: 92 e0 ldi r25, 0x02 ; 2 + } + + break; + } + + *DescriptorAddress = Address; + 9d2: fa 01 movw r30, r20 + 9d4: 80 83 st Z, r24 + 9d6: 91 83 std Z+1, r25 ; 0x01 + return Size; +} + 9d8: c9 01 movw r24, r18 + 9da: 08 95 ret + 9dc: 99 27 eor r25, r25 + case DTYPE_Configuration: + Address = &ConfigurationDescriptor; + Size = sizeof(USB_Descriptor_Configuration_t); + break; + case DTYPE_String: + switch (DescriptorNumber) + 9de: 81 30 cpi r24, 0x01 ; 1 + 9e0: 91 05 cpc r25, r1 + 9e2: a1 f0 breq .+40 ; 0xa0c + 9e4: 82 30 cpi r24, 0x02 ; 2 + 9e6: 91 05 cpc r25, r1 + 9e8: b9 f0 breq .+46 ; 0xa18 + 9ea: 89 2b or r24, r25 + 9ec: 29 f7 brne .-54 ; 0x9b8 + { + case 0x00: + Address = &LanguageString; + Size = pgm_read_byte(&LanguageString.Header.Size); + 9ee: e4 e3 ldi r30, 0x34 ; 52 + 9f0: f2 e0 ldi r31, 0x02 ; 2 + 9f2: 24 91 lpm r18, Z + 9f4: 30 e0 ldi r19, 0x00 ; 0 + break; + case DTYPE_String: + switch (DescriptorNumber) + { + case 0x00: + Address = &LanguageString; + 9f6: cf 01 movw r24, r30 + Size = pgm_read_byte(&LanguageString.Header.Size); + break; + 9f8: e3 cf rjmp .-58 ; 0x9c0 + Address = &DeviceDescriptor; + Size = sizeof(USB_Descriptor_Device_t); + break; + case DTYPE_Configuration: + Address = &ConfigurationDescriptor; + Size = sizeof(USB_Descriptor_Configuration_t); + 9fa: 2e e3 ldi r18, 0x3E ; 62 + 9fc: 30 e0 ldi r19, 0x00 ; 0 + case DTYPE_Device: + Address = &DeviceDescriptor; + Size = sizeof(USB_Descriptor_Device_t); + break; + case DTYPE_Configuration: + Address = &ConfigurationDescriptor; + 9fe: 88 e3 ldi r24, 0x38 ; 56 + a00: 92 e0 ldi r25, 0x02 ; 2 + } + + break; + } + + *DescriptorAddress = Address; + a02: fa 01 movw r30, r20 + a04: 80 83 st Z, r24 + a06: 91 83 std Z+1, r25 ; 0x01 + return Size; +} + a08: c9 01 movw r24, r18 + a0a: 08 95 ret + Address = &LanguageString; + Size = pgm_read_byte(&LanguageString.Header.Size); + break; + case 0x01: + Address = &ManufacturerString; + Size = pgm_read_byte(&ManufacturerString.Header.Size); + a0c: ea e1 ldi r30, 0x1A ; 26 + a0e: f2 e0 ldi r31, 0x02 ; 2 + a10: 24 91 lpm r18, Z + a12: 30 e0 ldi r19, 0x00 ; 0 + case 0x00: + Address = &LanguageString; + Size = pgm_read_byte(&LanguageString.Header.Size); + break; + case 0x01: + Address = &ManufacturerString; + a14: cf 01 movw r24, r30 + Size = pgm_read_byte(&ManufacturerString.Header.Size); + break; + a16: d4 cf rjmp .-88 ; 0x9c0 + case 0x02: + Address = &ProductString; + Size = pgm_read_byte(&ProductString.Header.Size); + a18: ec ef ldi r30, 0xFC ; 252 + a1a: f1 e0 ldi r31, 0x01 ; 1 + a1c: 24 91 lpm r18, Z + a1e: 30 e0 ldi r19, 0x00 ; 0 + case 0x01: + Address = &ManufacturerString; + Size = pgm_read_byte(&ManufacturerString.Header.Size); + break; + case 0x02: + Address = &ProductString; + a20: cf 01 movw r24, r30 + Size = pgm_read_byte(&ProductString.Header.Size); + break; + a22: ce cf rjmp .-100 ; 0x9c0 + +00000a24 <__vector_default>: +#include "System.h" +#include "LED.h" +#include + +ISR(BADISR_vect) +{ + a24: 1f 92 push r1 + a26: 0f 92 push r0 + a28: 0f b6 in r0, 0x3f ; 63 + a2a: 0f 92 push r0 + a2c: 11 24 eor r1, r1 + a2e: ff cf rjmp .-2 ; 0xa2e <__vector_default+0xa> + +00000a30 <__vector_10>: + while(1); +} + +EMPTY_INTERRUPT(RTC_OVF_vect); + a30: 18 95 reti + +00000a32 : + +void SystemInit(void) +{ + if (RST.STATUS & RST_WDRF_bm) { + a32: 80 91 78 00 lds r24, 0x0078 + a36: 83 ff sbrs r24, 3 + a38: 0a c0 rjmp .+20 ; 0xa4e + /* On Watchdog reset clear WDRF bit, disable watchdog + * and jump into bootloader */ + RST.STATUS = RST_WDRF_bm; + a3a: 88 e0 ldi r24, 0x08 ; 8 + a3c: 80 93 78 00 sts 0x0078, r24 + + CCP = CCP_IOREG_gc; + a40: 88 ed ldi r24, 0xD8 ; 216 + a42: 84 bf out 0x34, r24 ; 52 + WDT.CTRL = WDT_CEN_bm; + a44: 81 e0 ldi r24, 0x01 ; 1 + a46: 80 93 80 00 sts 0x0080, r24 + + asm volatile ("jmp %0"::"i" (BOOT_SECTION_START + 0x1FC)); + a4a: fd 95 fe c0 jmp 0x7f81fc ; 0x7f81fc <__data_load_end+0x7f1edc> + } + + /* 32MHz system clock using internal RC and 32K DFLL*/ + OSC.CTRL |= OSC_RC32MEN_bm | OSC_RC32KEN_bm; + a4e: 80 91 50 00 lds r24, 0x0050 + a52: 86 60 ori r24, 0x06 ; 6 + a54: 80 93 50 00 sts 0x0050, r24 + while(!(OSC.STATUS & OSC_RC32MRDY_bm)) + a58: 80 91 51 00 lds r24, 0x0051 + a5c: 81 ff sbrs r24, 1 + a5e: fc cf rjmp .-8 ; 0xa58 + ; + while(!(OSC.STATUS & OSC_RC32KRDY_bm)) + a60: 80 91 51 00 lds r24, 0x0051 + a64: 82 ff sbrs r24, 2 + a66: fc cf rjmp .-8 ; 0xa60 + ; + + OSC.DFLLCTRL = OSC_RC32MCREF_RC32K_gc; + a68: 10 92 56 00 sts 0x0056, r1 + DFLLRC32M.CTRL = DFLL_ENABLE_bm; + a6c: 21 e0 ldi r18, 0x01 ; 1 + a6e: 20 93 60 00 sts 0x0060, r18 + + CCP = CCP_IOREG_gc; + a72: 88 ed ldi r24, 0xD8 ; 216 + a74: 84 bf out 0x34, r24 ; 52 + CLK.CTRL = CLK_SCLKSEL_RC32M_gc; + a76: 20 93 40 00 sts 0x0040, r18 + + /* Use TCE0 as system tick */ + TCE0.PER = F_CPU / 256 / SYSTEM_TICK_FREQ - 1; + a7a: 83 ed ldi r24, 0xD3 ; 211 + a7c: 90 e3 ldi r25, 0x30 ; 48 + a7e: 80 93 26 0a sts 0x0A26, r24 + a82: 90 93 27 0a sts 0x0A27, r25 + TCE0.CTRLA = TC_CLKSEL_DIV256_gc; + a86: 86 e0 ldi r24, 0x06 ; 6 + a88: 80 93 00 0a sts 0x0A00, r24 + + /* Enable RTC with roughly 1kHz clock for system tick + * and to wake up while sleeping. */ + CLK.RTCCTRL = CLK_RTCSRC_ULP_gc | CLK_RTCEN_bm; + a8c: 20 93 43 00 sts 0x0043, r18 + RTC.PER = 1000 / SYSTEM_TICK_FREQ - 1; + a90: 83 e6 ldi r24, 0x63 ; 99 + a92: 90 e0 ldi r25, 0x00 ; 0 + a94: 80 93 0a 04 sts 0x040A, r24 + a98: 90 93 0b 04 sts 0x040B, r25 + RTC.COMP = 1000 / SYSTEM_TICK_FREQ - 1; + a9c: 80 93 0c 04 sts 0x040C, r24 + aa0: 90 93 0d 04 sts 0x040D, r25 + RTC.CTRL = RTC_PRESCALER_DIV1_gc; + aa4: 20 93 00 04 sts 0x0400, r18 + RTC.INTCTRL = RTC_OVFINTLVL_LO_gc; + aa8: 20 93 02 04 sts 0x0402, r18 + + + /* Enable EEPROM data memory mapping */ + NVM.CTRLB |= NVM_EEMAPEN_bm; + aac: 80 91 cc 01 lds r24, 0x01CC + ab0: 88 60 ori r24, 0x08 ; 8 + ab2: 80 93 cc 01 sts 0x01CC, r24 + ab6: 08 95 ret + +00000ab8 : +} + +void SystemReset(void) +{ + CCP = CCP_IOREG_gc; + ab8: 88 ed ldi r24, 0xD8 ; 216 + aba: 84 bf out 0x34, r24 ; 52 + RST.CTRL = RST_SWRST_bm; + abc: 81 e0 ldi r24, 0x01 ; 1 + abe: e8 e7 ldi r30, 0x78 ; 120 + ac0: f0 e0 ldi r31, 0x00 ; 0 + ac2: 81 83 std Z+1, r24 ; 0x01 + ac4: 08 95 ret + +00000ac6 : +} + +void SystemEnterBootloader(void) +{ + /* Use Watchdog timer to reset into bootloader. */ + CCP = CCP_IOREG_gc; + ac6: 88 ed ldi r24, 0xD8 ; 216 + ac8: 84 bf out 0x34, r24 ; 52 + WDT.CTRL = WDT_PER_500CLK_gc | WDT_ENABLE_bm | WDT_CEN_bm; + aca: 8b e1 ldi r24, 0x1B ; 27 + acc: 80 93 80 00 sts 0x0080, r24 + ad0: 08 95 ret + +00000ad2 : + SLEEP.CTRL |= SLEEP_SEN_bm; +} + +INLINE void SystemSleepDisable(void) +{ + SLEEP.CTRL &= ~SLEEP_SEN_bm; + ad2: 80 91 48 00 lds r24, 0x0048 + ad6: 8e 7f andi r24, 0xFE ; 254 + ad8: 80 93 48 00 sts 0x0048, r24 +void SystemStartUSBClock(void) +{ + SystemSleepDisable(); + + /* 48MHz USB Clock using 12MHz XTAL */ + OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc; + adc: 8b ec ldi r24, 0xCB ; 203 + ade: 80 93 52 00 sts 0x0052, r24 + OSC.CTRL |= OSC_XOSCEN_bm; + ae2: 80 91 50 00 lds r24, 0x0050 + ae6: 88 60 ori r24, 0x08 ; 8 + ae8: 80 93 50 00 sts 0x0050, r24 + while(!(OSC.STATUS & OSC_XOSCRDY_bm)) + aec: 80 91 51 00 lds r24, 0x0051 + af0: 83 ff sbrs r24, 3 + af2: fc cf rjmp .-8 ; 0xaec + ; + + OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | (4 << OSC_PLLFAC_gp); + af4: 84 ec ldi r24, 0xC4 ; 196 + af6: 80 93 55 00 sts 0x0055, r24 + + OSC.CTRL |= OSC_PLLEN_bm; + afa: 80 91 50 00 lds r24, 0x0050 + afe: 80 61 ori r24, 0x10 ; 16 + b00: 80 93 50 00 sts 0x0050, r24 + while(!(OSC.STATUS & OSC_PLLRDY_bm)) + b04: 80 91 51 00 lds r24, 0x0051 + b08: 84 ff sbrs r24, 4 + b0a: fc cf rjmp .-8 ; 0xb04 + ; +} + b0c: 08 95 ret + +00000b0e : + asm volatile("sleep"); +} + +INLINE void SystemSleepEnable(void) +{ + SLEEP.CTRL |= SLEEP_SEN_bm; + b0e: e8 e4 ldi r30, 0x48 ; 72 + b10: f0 e0 ldi r31, 0x00 ; 0 + b12: 80 81 ld r24, Z + b14: 81 60 ori r24, 0x01 ; 1 + b16: 80 83 st Z, r24 +void SystemStopUSBClock(void) +{ + SystemSleepEnable(); + + /* Disable USB Clock to minimize power consumption */ + CLK.USBCTRL &= ~CLK_USBSEN_bm; + b18: e0 e4 ldi r30, 0x40 ; 64 + b1a: f0 e0 ldi r31, 0x00 ; 0 + b1c: 84 81 ldd r24, Z+4 ; 0x04 + b1e: 8e 7f andi r24, 0xFE ; 254 + b20: 84 83 std Z+4, r24 ; 0x04 + OSC.CTRL &= ~OSC_PLLEN_bm; + b22: e0 e5 ldi r30, 0x50 ; 80 + b24: f0 e0 ldi r31, 0x00 ; 0 + b26: 80 81 ld r24, Z + b28: 8f 7e andi r24, 0xEF ; 239 + b2a: 80 83 st Z, r24 + OSC.CTRL &= ~OSC_XOSCEN_bm; + b2c: 80 81 ld r24, Z + b2e: 87 7f andi r24, 0xF7 ; 247 + b30: 80 83 st Z, r24 + b32: 08 95 ret + +00000b34 : +} + +void SystemInterruptInit(void) +{ + /* Enable all interrupt levels */ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; + b34: 87 e0 ldi r24, 0x07 ; 7 + b36: e0 ea ldi r30, 0xA0 ; 160 + b38: f0 e0 ldi r31, 0x00 ; 0 + b3a: 82 83 std Z+2, r24 ; 0x02 + sei(); + b3c: 78 94 sei + b3e: 08 95 ret + +00000b40 : + +/* Include all Codecs and Applications */ +#include "Codec/Codec.h" +#include "Application/Application.h" + +static void CodecInitDummy(void) { } + b40: 08 95 ret + +00000b42 : +static void CodecTaskDummy(void) { } + b42: 08 95 ret + +00000b44 : +static void ApplicationInitDummy(void) {} + b44: 08 95 ret + +00000b46 : +static void ApplicationResetDummy(void) {} + b46: 08 95 ret + +00000b48 : +static void ApplicationTaskDummy(void) {} + b48: 08 95 ret + +00000b4a : +static uint16_t ApplicationProcessDummy(uint8_t* ByteBuffer, uint16_t ByteCount) { return 0; } + b4a: 80 e0 ldi r24, 0x00 ; 0 + b4c: 90 e0 ldi r25, 0x00 ; 0 + b4e: 08 95 ret + +00000b50 : +static void ApplicationGetUidDummy(ConfigurationUidType Uid) { } + b50: 08 95 ret + +00000b52 : +static void ApplicationSetUidDummy(ConfigurationUidType Uid) { } + b52: 08 95 ret + +00000b54 : + ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration); +} + +void ConfigurationSetById( ConfigurationEnum Configuration ) +{ + GlobalSettings.ActiveSettingPtr->Configuration = Configuration; + b54: e0 91 0a 29 lds r30, 0x290A + b58: f0 91 0b 29 lds r31, 0x290B + b5c: 83 83 std Z+3, r24 ; 0x03 + + /* Copy struct from PROGMEM to RAM */ + memcpy_P(&ActiveConfiguration, + &ConfigurationTable[Configuration], sizeof(ConfigurationType)); + b5e: 95 e2 ldi r25, 0x25 ; 37 + b60: 89 9f mul r24, r25 + b62: b0 01 movw r22, r0 + b64: 11 24 eor r1, r1 + b66: 68 57 subi r22, 0x78 ; 120 + b68: 7d 4f sbci r23, 0xFD ; 253 +void ConfigurationSetById( ConfigurationEnum Configuration ) +{ + GlobalSettings.ActiveSettingPtr->Configuration = Configuration; + + /* Copy struct from PROGMEM to RAM */ + memcpy_P(&ActiveConfiguration, + b6a: 45 e2 ldi r20, 0x25 ; 37 + b6c: 50 e0 ldi r21, 0x00 ; 0 + b6e: 82 ee ldi r24, 0xE2 ; 226 + b70: 98 e2 ldi r25, 0x28 ; 40 + b72: 0e 94 cc 2d call 0x5b98 ; 0x5b98 +#include "MifareClassic.h" + + +/* Function wrappers */ +INLINE void ApplicationInit(void) { + ActiveConfiguration.ApplicationInitFunc(); + b76: e0 91 f7 28 lds r30, 0x28F7 + b7a: f0 91 f8 28 lds r31, 0x28F8 + b7e: 09 95 icall +#define CODEC_CARRIER_FREQ 13560000 + +extern uint8_t CodecBuffer[CODEC_BUFFER_SIZE]; + +INLINE void CodecInit(void) { + ActiveConfiguration.CodecInitFunc(); + b80: e0 91 f3 28 lds r30, 0x28F3 + b84: f0 91 f4 28 lds r31, 0x28F4 + b88: 09 94 ijmp + +00000b8a : + +ConfigurationType ActiveConfiguration; + +void ConfigurationInit(void) +{ + ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration); + b8a: e0 91 0a 29 lds r30, 0x290A + b8e: f0 91 0b 29 lds r31, 0x290B + b92: 83 81 ldd r24, Z+3 ; 0x03 + b94: df cf rjmp .-66 ; 0xb54 + +00000b96 : + ApplicationInit(); + CodecInit(); +} + +bool ConfigurationSetByName(const char* ConfigurationName) +{ + b96: 0f 93 push r16 + b98: 1f 93 push r17 + b9a: cf 93 push r28 + b9c: df 93 push r29 + b9e: 20 e0 ldi r18, 0x00 ; 0 + ba0: 30 e0 ldi r19, 0x00 ; 0 + uint8_t i; + + /* Loop through table trying to find the configuration */ + for (i=0; i<(sizeof(ConfigurationTable) / sizeof(*ConfigurationTable)); i++) { + const char* pTableConfigName = ConfigurationTable[i].ConfigurationName; + ba2: 15 e2 ldi r17, 0x25 ; 37 + + ApplicationInit(); + CodecInit(); +} + +bool ConfigurationSetByName(const char* ConfigurationName) + ba4: ac 01 movw r20, r24 + ba6: 4f 5f subi r20, 0xFF ; 255 + ba8: 5f 4f sbci r21, 0xFF ; 255 + baa: 02 2f mov r16, r18 +{ + uint8_t i; + + /* Loop through table trying to find the configuration */ + for (i=0; i<(sizeof(ConfigurationTable) / sizeof(*ConfigurationTable)); i++) { + const char* pTableConfigName = ConfigurationTable[i].ConfigurationName; + bac: 12 9f mul r17, r18 + bae: f0 01 movw r30, r0 + bb0: 13 9f mul r17, r19 + bb2: f0 0d add r31, r0 + bb4: 11 24 eor r1, r1 + bb6: e7 57 subi r30, 0x77 ; 119 + bb8: fd 4f sbci r31, 0xFD ; 253 + const char* pRequestedConfigName = ConfigurationName; + bool StringMismatch = false; + char c = pgm_read_byte(pTableConfigName); + bba: 64 91 lpm r22, Z + + /* Try to keep running until both strings end at the same point */ + while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { + bbc: 61 11 cpse r22, r1 + bbe: 0f c0 rjmp .+30 ; 0xbde + uint8_t i; + + /* Loop through table trying to find the configuration */ + for (i=0; i<(sizeof(ConfigurationTable) / sizeof(*ConfigurationTable)); i++) { + const char* pTableConfigName = ConfigurationTable[i].ConfigurationName; + const char* pRequestedConfigName = ConfigurationName; + bc0: ec 01 movw r28, r24 + bool StringMismatch = false; + char c = pgm_read_byte(pTableConfigName); + + /* Try to keep running until both strings end at the same point */ + while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { + bc2: 68 81 ld r22, Y + bc4: 66 23 and r22, r22 + bc6: 01 f1 breq .+64 ; 0xc08 + bc8: 2f 5f subi r18, 0xFF ; 255 + bca: 3f 4f sbci r19, 0xFF ; 255 +bool ConfigurationSetByName(const char* ConfigurationName) +{ + uint8_t i; + + /* Loop through table trying to find the configuration */ + for (i=0; i<(sizeof(ConfigurationTable) / sizeof(*ConfigurationTable)); i++) { + bcc: 26 30 cpi r18, 0x06 ; 6 + bce: 31 05 cpc r19, r1 + bd0: 61 f7 brne .-40 ; 0xbaa + ConfigurationSetById(i); + return true; + } + } + + return false; + bd2: 80 e0 ldi r24, 0x00 ; 0 +} + bd4: df 91 pop r29 + bd6: cf 91 pop r28 + bd8: 1f 91 pop r17 + bda: 0f 91 pop r16 + bdc: 08 95 ret + bool StringMismatch = false; + char c = pgm_read_byte(pTableConfigName); + + /* Try to keep running until both strings end at the same point */ + while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { + if ( (c == '\0') || (*pRequestedConfigName == '\0') ) { + bde: dc 01 movw r26, r24 + be0: 7c 91 ld r23, X + be2: 77 23 and r23, r23 + be4: 89 f3 breq .-30 ; 0xbc8 + /* One String ended before the other did -> unequal length */ + StringMismatch = true; + break; + } + + if (c != *pRequestedConfigName) { + be6: 67 13 cpse r22, r23 + be8: ef cf rjmp .-34 ; 0xbc8 + + ApplicationInit(); + CodecInit(); +} + +bool ConfigurationSetByName(const char* ConfigurationName) + bea: da 01 movw r26, r20 + bec: 05 c0 rjmp .+10 ; 0xbf8 + bool StringMismatch = false; + char c = pgm_read_byte(pTableConfigName); + + /* Try to keep running until both strings end at the same point */ + while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { + if ( (c == '\0') || (*pRequestedConfigName == '\0') ) { + bee: 7d 91 ld r23, X+ + bf0: 77 23 and r23, r23 + bf2: 51 f3 breq .-44 ; 0xbc8 + /* One String ended before the other did -> unequal length */ + StringMismatch = true; + break; + } + + if (c != *pRequestedConfigName) { + bf4: 76 13 cpse r23, r22 + bf6: e8 cf rjmp .-48 ; 0xbc8 + StringMismatch = true; + break; + } + + /* Proceed to next character */ + pTableConfigName++; + bf8: 31 96 adiw r30, 0x01 ; 1 + pRequestedConfigName++; + bfa: ed 01 movw r28, r26 + + c = pgm_read_byte(pTableConfigName); + bfc: 64 91 lpm r22, Z + const char* pRequestedConfigName = ConfigurationName; + bool StringMismatch = false; + char c = pgm_read_byte(pTableConfigName); + + /* Try to keep running until both strings end at the same point */ + while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { + bfe: 61 11 cpse r22, r1 + c00: f6 cf rjmp .-20 ; 0xbee + c02: 68 81 ld r22, Y + c04: 61 11 cpse r22, r1 + c06: e0 cf rjmp .-64 ; 0xbc8 + c = pgm_read_byte(pTableConfigName); + } + + if (!StringMismatch) { + /* Configuration found */ + ConfigurationSetById(i); + c08: 80 2f mov r24, r16 + c0a: a4 df rcall .-184 ; 0xb54 + return true; + c0c: 81 e0 ldi r24, 0x01 ; 1 + } + } + + return false; +} + c0e: df 91 pop r29 + c10: cf 91 pop r28 + c12: 1f 91 pop r17 + c14: 0f 91 pop r16 + c16: 08 95 ret + +00000c18 : + +void ConfigurationGetList(char* ConfigListOut, uint16_t ByteCount) +{ + c18: cf 93 push r28 + c1a: df 93 push r29 + c1c: ec 01 movw r28, r24 + uint8_t i; + + /* Account for '\0' */ + ByteCount--; + c1e: 61 50 subi r22, 0x01 ; 1 + c20: 71 09 sbc r23, r1 + c22: 80 e0 ldi r24, 0x00 ; 0 + c24: 90 e0 ldi r25, 0x00 ; 0 + + for (i=0; i CONFIGURATION_NAME_LENGTH_MAX) { + c38: 24 91 lpm r18, Z + c3a: 22 23 and r18, r18 + c3c: 81 f0 breq .+32 ; 0xc5e + c3e: 61 31 cpi r22, 0x11 ; 17 + c40: 71 05 cpc r23, r1 + c42: 68 f0 brcs .+26 ; 0xc5e + c44: de 01 movw r26, r28 + c46: 03 c0 rjmp .+6 ; 0xc4e + c48: 60 31 cpi r22, 0x10 ; 16 + c4a: 71 05 cpc r23, r1 + c4c: 41 f0 breq .+16 ; 0xc5e + /* While not end-of-string and enough buffer to + * put a complete configuration name */ + *ConfigListOut++ = c; + c4e: 2d 93 st X+, r18 + c50: ed 01 movw r28, r26 + ConfigName++; + c52: 31 96 adiw r30, 0x01 ; 1 + ByteCount--; + c54: 61 50 subi r22, 0x01 ; 1 + c56: 71 09 sbc r23, r1 + + for (i=0; i CONFIGURATION_NAME_LENGTH_MAX) { + c58: 24 91 lpm r18, Z + c5a: 21 11 cpse r18, r1 + c5c: f5 cf rjmp .-22 ; 0xc48 + *ConfigListOut++ = c; + ConfigName++; + ByteCount--; + } + + if ( i < (CONFIG_COUNT - 1) ) { + c5e: 85 30 cpi r24, 0x05 ; 5 + c60: 91 05 cpc r25, r1 + c62: 21 f4 brne .+8 ; 0xc6c + *ConfigListOut++ = ','; + ByteCount--; + } + } + + *ConfigListOut = '\0'; + c64: 18 82 st Y, r1 +} + c66: df 91 pop r29 + c68: cf 91 pop r28 + c6a: 08 95 ret + ByteCount--; + } + + if ( i < (CONFIG_COUNT - 1) ) { + /* No comma on last configuration */ + *ConfigListOut++ = ','; + c6c: 49 93 st Y+, r20 + ByteCount--; + c6e: 61 50 subi r22, 0x01 ; 1 + c70: 71 09 sbc r23, r1 + c72: 01 96 adiw r24, 0x01 ; 1 + c74: da cf rjmp .-76 ; 0xc2a + +00000c76 : +#include "Random.h" + +#include + +void RandomInit(void) +{ + c76: 08 95 ret + +00000c78 : + +} + +uint8_t RandomGetByte(void) +{ + return rand() & 0xFF; + c78: 0c 94 be 2d jmp 0x5b7c ; 0x5b7c +} + c7c: 08 95 ret + +00000c7e : + +void RandomGetBuffer(void* Buffer, uint8_t ByteCount) +{ + c7e: 1f 93 push r17 + c80: cf 93 push r28 + c82: df 93 push r29 + c84: 16 2f mov r17, r22 + uint8_t* BufferPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + c86: 66 23 and r22, r22 + c88: 29 f0 breq .+10 ; 0xc94 + c8a: ec 01 movw r28, r24 + *BufferPtr++ = RandomGetByte(); + c8c: f5 df rcall .-22 ; 0xc78 + c8e: 89 93 st Y+, r24 + c90: 11 50 subi r17, 0x01 ; 1 + +void RandomGetBuffer(void* Buffer, uint8_t ByteCount) +{ + uint8_t* BufferPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + c92: e1 f7 brne .-8 ; 0xc8c + *BufferPtr++ = RandomGetByte(); + } +} + c94: df 91 pop r29 + c96: cf 91 pop r28 + c98: 1f 91 pop r17 + c9a: 08 95 ret + +00000c9c : + +void RandomTick(void) +{ + rand(); + c9c: 0e 94 be 2d call 0x5b7c ; 0x5b7c + rand(); + ca0: 0e 94 be 2d call 0x5b7c ; 0x5b7c + rand(); + ca4: 0e 94 be 2d call 0x5b7c ; 0x5b7c + rand(); + ca8: 0c 94 be 2d jmp 0x5b7c ; 0x5b7c + +00000cac : +#include "Common.h" + +uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount) +{ + cac: cf 93 push r28 + cae: df 93 push r29 + cb0: dc 01 movw r26, r24 + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t CharCount = 0; + + /* Account for '\0' at the end */ + MaxChars--; + cb2: 61 50 subi r22, 0x01 ; 1 + cb4: 71 09 sbc r23, r1 + + while( (ByteCount > 0) && (MaxChars >= 2) ) { + cb6: 21 15 cp r18, r1 + cb8: 31 05 cpc r19, r1 + cba: 99 f1 breq .+102 ; 0xd22 + cbc: 62 30 cpi r22, 0x02 ; 2 + cbe: 71 05 cpc r23, r1 + cc0: 80 f1 brcs .+96 ; 0xd22 + cc2: fa 01 movw r30, r20 +#include "Common.h" + +uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount) + cc4: 24 0f add r18, r20 + cc6: 35 1f adc r19, r21 + cc8: 21 50 subi r18, 0x01 ; 1 + cca: 31 09 sbc r19, r1 +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t CharCount = 0; + ccc: 40 e0 ldi r20, 0x00 ; 0 + cce: 50 e0 ldi r21, 0x00 ; 0 + cd0: 17 c0 rjmp .+46 ; 0xd00 + MaxChars--; + + while( (ByteCount > 0) && (MaxChars >= 2) ) { + uint8_t Byte = *ByteBuffer; + + HexOut[0] = NIBBLE_TO_HEXCHAR( (Byte >> 4) & 0x0F ); + cd2: d0 5d subi r29, 0xD0 ; 208 + cd4: dc 93 st X, r29 + HexOut[1] = NIBBLE_TO_HEXCHAR( (Byte >> 0) & 0x0F ); + cd6: cf 70 andi r28, 0x0F ; 15 + cd8: 8c 2f mov r24, r28 + cda: 90 e0 ldi r25, 0x00 ; 0 + cdc: 0a 97 sbiw r24, 0x0a ; 10 + cde: fc f4 brge .+62 ; 0xd1e + ce0: c0 5d subi r28, 0xD0 ; 208 + ce2: 11 96 adiw r26, 0x01 ; 1 + ce4: cc 93 st X, r28 + ce6: 11 97 sbiw r26, 0x01 ; 1 + + HexOut += 2; + ce8: 12 96 adiw r26, 0x02 ; 2 + MaxChars -= 2; + cea: 62 50 subi r22, 0x02 ; 2 + cec: 71 09 sbc r23, r1 + CharCount += 2; + cee: 4e 5f subi r20, 0xFE ; 254 + cf0: 5f 4f sbci r21, 0xFF ; 255 + uint16_t CharCount = 0; + + /* Account for '\0' at the end */ + MaxChars--; + + while( (ByteCount > 0) && (MaxChars >= 2) ) { + cf2: e2 17 cp r30, r18 + cf4: f3 07 cpc r31, r19 + cf6: b9 f0 breq .+46 ; 0xd26 + cf8: 31 96 adiw r30, 0x01 ; 1 + cfa: 62 30 cpi r22, 0x02 ; 2 + cfc: 71 05 cpc r23, r1 + cfe: 98 f0 brcs .+38 ; 0xd26 + uint8_t Byte = *ByteBuffer; + d00: c0 81 ld r28, Z + + HexOut[0] = NIBBLE_TO_HEXCHAR( (Byte >> 4) & 0x0F ); + d02: dc 2f mov r29, r28 + d04: d2 95 swap r29 + d06: df 70 andi r29, 0x0F ; 15 + d08: 8d 2f mov r24, r29 + d0a: 90 e0 ldi r25, 0x00 ; 0 + d0c: 0a 97 sbiw r24, 0x0a ; 10 + d0e: 0c f3 brlt .-62 ; 0xcd2 + d10: d9 5c subi r29, 0xC9 ; 201 + d12: dc 93 st X, r29 + HexOut[1] = NIBBLE_TO_HEXCHAR( (Byte >> 0) & 0x0F ); + d14: cf 70 andi r28, 0x0F ; 15 + d16: 8c 2f mov r24, r28 + d18: 90 e0 ldi r25, 0x00 ; 0 + d1a: 0a 97 sbiw r24, 0x0a ; 10 + d1c: 0c f3 brlt .-62 ; 0xce0 + d1e: c9 5c subi r28, 0xC9 ; 201 + d20: e0 cf rjmp .-64 ; 0xce2 +#include "Common.h" + +uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t CharCount = 0; + d22: 40 e0 ldi r20, 0x00 ; 0 + d24: 50 e0 ldi r21, 0x00 ; 0 + CharCount += 2; + ByteBuffer++; + ByteCount -= 1; + } + + *HexOut = '\0'; + d26: 1c 92 st X, r1 + + return CharCount; +} + d28: ca 01 movw r24, r20 + d2a: df 91 pop r29 + d2c: cf 91 pop r28 + d2e: 08 95 ret + +00000d30 : + +uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) +{ + d30: fa 01 movw r30, r20 + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t ByteCount = 0; + + while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) { + d32: 40 81 ld r20, Z + d34: 44 23 and r20, r20 + d36: f1 f1 breq .+124 ; 0xdb4 + d38: 51 81 ldd r21, Z+1 ; 0x01 + d3a: 55 23 and r21, r21 + d3c: d9 f1 breq .+118 ; 0xdb4 + d3e: 61 15 cp r22, r1 + d40: 71 05 cpc r23, r1 + d42: c1 f1 breq .+112 ; 0xdb4 + d44: dc 01 movw r26, r24 + d46: 20 e0 ldi r18, 0x00 ; 0 + d48: 30 e0 ldi r19, 0x00 ; 0 + d4a: 13 c0 rjmp .+38 ; 0xd72 + if (VALID_HEXCHAR(HexIn[0]) && VALID_HEXCHAR(HexIn[1])) { + uint8_t Byte = 0; + + Byte |= HEXCHAR_TO_NIBBLE(HexIn[0]) << 4; + d4c: 42 95 swap r20 + d4e: 40 7f andi r20, 0xF0 ; 240 + Byte |= HEXCHAR_TO_NIBBLE(HexIn[1]) << 0; + d50: 51 34 cpi r21, 0x41 ; 65 + d52: 28 f5 brcc .+74 ; 0xd9e + d54: 58 2f mov r21, r24 + d56: 45 2b or r20, r21 + + *ByteBuffer = Byte; + d58: 4d 93 st X+, r20 + + ByteBuffer++; + MaxBytes--; + ByteCount++; + d5a: 2f 5f subi r18, 0xFF ; 255 + d5c: 3f 4f sbci r19, 0xFF ; 255 + HexIn += 2; + d5e: 32 96 adiw r30, 0x02 ; 2 +uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t ByteCount = 0; + + while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) { + d60: 40 81 ld r20, Z + d62: 44 23 and r20, r20 + d64: 29 f1 breq .+74 ; 0xdb0 + d66: 51 81 ldd r21, Z+1 ; 0x01 + d68: 55 23 and r21, r21 + d6a: 21 f1 breq .+72 ; 0xdb4 + d6c: 62 17 cp r22, r18 + d6e: 73 07 cpc r23, r19 + d70: f9 f0 breq .+62 ; 0xdb0 + if (VALID_HEXCHAR(HexIn[0]) && VALID_HEXCHAR(HexIn[1])) { + d72: 84 2f mov r24, r20 + d74: 80 53 subi r24, 0x30 ; 48 + d76: 8a 30 cpi r24, 0x0A ; 10 + d78: 18 f0 brcs .+6 ; 0xd80 + d7a: 81 51 subi r24, 0x11 ; 17 + d7c: 86 30 cpi r24, 0x06 ; 6 + d7e: d0 f4 brcc .+52 ; 0xdb4 + d80: 85 2f mov r24, r21 + d82: 80 53 subi r24, 0x30 ; 48 + d84: 8a 30 cpi r24, 0x0A ; 10 + d86: 20 f0 brcs .+8 ; 0xd90 + d88: 95 2f mov r25, r21 + d8a: 91 54 subi r25, 0x41 ; 65 + d8c: 96 30 cpi r25, 0x06 ; 6 + d8e: 90 f4 brcc .+36 ; 0xdb4 + uint8_t Byte = 0; + + Byte |= HEXCHAR_TO_NIBBLE(HexIn[0]) << 4; + d90: 41 34 cpi r20, 0x41 ; 65 + d92: e0 f2 brcs .-72 ; 0xd4c + d94: 42 95 swap r20 + d96: 40 7f andi r20, 0xF0 ; 240 + d98: 40 57 subi r20, 0x70 ; 112 + Byte |= HEXCHAR_TO_NIBBLE(HexIn[1]) << 0; + d9a: 51 34 cpi r21, 0x41 ; 65 + d9c: d8 f2 brcs .-74 ; 0xd54 + d9e: 57 53 subi r21, 0x37 ; 55 + da0: 45 2b or r20, r21 + + *ByteBuffer = Byte; + da2: 4d 93 st X+, r20 + + ByteBuffer++; + MaxBytes--; + ByteCount++; + da4: 2f 5f subi r18, 0xFF ; 255 + da6: 3f 4f sbci r19, 0xFF ; 255 + HexIn += 2; + da8: 32 96 adiw r30, 0x02 ; 2 +uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t ByteCount = 0; + + while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) { + daa: 40 81 ld r20, Z + dac: 41 11 cpse r20, r1 + dae: db cf rjmp .-74 ; 0xd66 + /* Odd number of characters */ + return 0; + } + + return ByteCount; +} + db0: c9 01 movw r24, r18 + db2: 08 95 ret + } + } + + if ( (HexIn[0] != '\0') && (HexIn[1] == '\0') ) { + /* Odd number of characters */ + return 0; + db4: 20 e0 ldi r18, 0x00 ; 0 + db6: 30 e0 ldi r19, 0x00 ; 0 + } + + return ByteCount; +} + db8: c9 01 movw r24, r18 + dba: 08 95 ret + +00000dbc : + MemoryRecall(); +} + +void MemoryReadBlock(void* Buffer, uint16_t Address, uint16_t ByteCount) +{ + uint8_t* SrcPtr = &Memory[Address]; + dbc: fb 01 movw r30, r22 + dbe: ee 56 subi r30, 0x6E ; 110 + dc0: ff 4d sbci r31, 0xDF ; 223 + uint8_t* DstPtr = (uint8_t*) Buffer; + + /* Prevent Buf Ovfs */ + ByteCount = MIN(ByteCount, MEMORY_SIZE_PER_SETTING - Address); + dc2: a0 e0 ldi r26, 0x00 ; 0 + dc4: b4 e0 ldi r27, 0x04 ; 4 + dc6: a6 1b sub r26, r22 + dc8: b7 0b sbc r27, r23 + dca: 9a 01 movw r18, r20 + dcc: a4 17 cp r26, r20 + dce: b5 07 cpc r27, r21 + dd0: 08 f4 brcc .+2 ; 0xdd4 + dd2: 9d 01 movw r18, r26 + + while(ByteCount--) { + dd4: 21 15 cp r18, r1 + dd6: 31 05 cpc r19, r1 + dd8: 41 f0 breq .+16 ; 0xdea + + /* Load permanent flash contents to memory at startup */ + MemoryRecall(); +} + +void MemoryReadBlock(void* Buffer, uint16_t Address, uint16_t ByteCount) + dda: 2e 0f add r18, r30 + ddc: 3f 1f adc r19, r31 +{ + uint8_t* SrcPtr = &Memory[Address]; + uint8_t* DstPtr = (uint8_t*) Buffer; + dde: dc 01 movw r26, r24 + + /* Prevent Buf Ovfs */ + ByteCount = MIN(ByteCount, MEMORY_SIZE_PER_SETTING - Address); + + while(ByteCount--) { + *DstPtr++ = *SrcPtr++; + de0: 81 91 ld r24, Z+ + de2: 8d 93 st X+, r24 + uint8_t* DstPtr = (uint8_t*) Buffer; + + /* Prevent Buf Ovfs */ + ByteCount = MIN(ByteCount, MEMORY_SIZE_PER_SETTING - Address); + + while(ByteCount--) { + de4: e2 17 cp r30, r18 + de6: f3 07 cpc r31, r19 + de8: d9 f7 brne .-10 ; 0xde0 + dea: 08 95 ret + +00000dec : +} + +void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount) +{ + uint8_t* SrcPtr = (uint8_t*) Buffer; + uint8_t* DstPtr = &Memory[Address]; + dec: db 01 movw r26, r22 + dee: ae 56 subi r26, 0x6E ; 110 + df0: bf 4d sbci r27, 0xDF ; 223 + + /* Prevent Buf Ovfs */ + ByteCount = MIN(ByteCount, MEMORY_SIZE_PER_SETTING - Address); + df2: e0 e0 ldi r30, 0x00 ; 0 + df4: f4 e0 ldi r31, 0x04 ; 4 + df6: e6 1b sub r30, r22 + df8: f7 0b sbc r31, r23 + dfa: 9a 01 movw r18, r20 + dfc: e4 17 cp r30, r20 + dfe: f5 07 cpc r31, r21 + e00: 08 f4 brcc .+2 ; 0xe04 + e02: 9f 01 movw r18, r30 + + while(ByteCount--) { + e04: 21 15 cp r18, r1 + e06: 31 05 cpc r19, r1 + e08: 49 f0 breq .+18 ; 0xe1c + e0a: fc 01 movw r30, r24 + while(ByteCount--) { + *DstPtr++ = *SrcPtr++; + } +} + +void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount) + e0c: c9 01 movw r24, r18 + e0e: 8e 0f add r24, r30 + e10: 9f 1f adc r25, r31 + + /* Prevent Buf Ovfs */ + ByteCount = MIN(ByteCount, MEMORY_SIZE_PER_SETTING - Address); + + while(ByteCount--) { + *DstPtr++ = *SrcPtr++; + e12: 21 91 ld r18, Z+ + e14: 2d 93 st X+, r18 + uint8_t* DstPtr = &Memory[Address]; + + /* Prevent Buf Ovfs */ + ByteCount = MIN(ByteCount, MEMORY_SIZE_PER_SETTING - Address); + + while(ByteCount--) { + e16: e8 17 cp r30, r24 + e18: f9 07 cpc r31, r25 + e1a: d9 f7 brne .-10 ; 0xe12 + *DstPtr++ = *SrcPtr++; + } + + LEDTrigger(LED_MEMORY_CHANGED, LED_ON); + e1c: 61 e1 ldi r22, 0x11 ; 17 + e1e: 85 e0 ldi r24, 0x05 ; 5 + e20: 0c 94 af 0f jmp 0x1f5e ; 0x1f5e + +00000e24 : +} + +void MemoryClear(void) +{ + e24: e2 e9 ldi r30, 0x92 ; 146 + e26: f0 e2 ldi r31, 0x20 ; 32 + for (uint16_t i=0; i + Memory[i] = 0; + } +} + e32: 08 95 ret + +00000e34 : + +void MemoryRecall(void) +{ + /* Recall memory from permanent flash */ + FlashRead(Memory, (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); + e34: 80 91 09 29 lds r24, 0x2909 + e38: 90 e0 ldi r25, 0x00 ; 0 + e3a: a0 e0 ldi r26, 0x00 ; 0 + e3c: b0 e0 ldi r27, 0x00 ; 0 + e3e: 4a e0 ldi r20, 0x0A ; 10 + e40: 88 0f add r24, r24 + e42: 99 1f adc r25, r25 + e44: aa 1f adc r26, r26 + e46: bb 1f adc r27, r27 + e48: 4a 95 dec r20 + e4a: d1 f7 brne .-12 ; 0xe40 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + e4c: 40 e1 ldi r20, 0x10 ; 16 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + e4e: 57 ed ldi r21, 0xD7 ; 215 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + e50: 30 e4 ldi r19, 0x40 ; 64 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + e52: 40 93 66 06 sts 0x0666, r20 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + e56: 50 93 a0 09 sts 0x09A0, r21 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + e5a: 20 91 a1 09 lds r18, 0x09A1 + e5e: 26 ff sbrs r18, 6 + e60: fc cf rjmp .-8 ; 0xe5a + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + e62: 30 93 a1 09 sts 0x09A1, r19 + + return MEMORY_FLASH_USART.DATA; + e66: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + e6a: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + e6e: 20 91 a1 09 lds r18, 0x09A1 + e72: 26 ff sbrs r18, 6 + e74: fc cf rjmp .-8 ; 0xe6e + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + e76: 30 93 a1 09 sts 0x09A1, r19 + + return MEMORY_FLASH_USART.DATA; + e7a: 20 91 a0 09 lds r18, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + e7e: 40 93 65 06 sts 0x0665, r20 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashRead(void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(FlashIsBusy()); + e82: 27 ff sbrs r18, 7 + e84: e6 cf rjmp .-52 ; 0xe52 + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + e86: 20 e1 ldi r18, 0x10 ; 16 + e88: 20 93 66 06 sts 0x0666, r18 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + e8c: 23 e0 ldi r18, 0x03 ; 3 + e8e: 20 93 a0 09 sts 0x09A0, r18 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + e92: 20 91 a1 09 lds r18, 0x09A1 + e96: 26 ff sbrs r18, 6 + e98: fc cf rjmp .-8 ; 0xe92 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + e9a: 20 e4 ldi r18, 0x40 ; 64 + e9c: 20 93 a1 09 sts 0x09A1, r18 + + return MEMORY_FLASH_USART.DATA; + ea0: 20 91 a0 09 lds r18, 0x09A0 +{ + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(0x03); + SPITransferByte( (Address >> 16) & 0xFF ); + ea4: ad 01 movw r20, r26 + ea6: 66 27 eor r22, r22 + ea8: 77 27 eor r23, r23 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + eaa: 40 93 a0 09 sts 0x09A0, r20 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + eae: 20 91 a1 09 lds r18, 0x09A1 + eb2: 26 ff sbrs r18, 6 + eb4: fc cf rjmp .-8 ; 0xeae + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + eb6: 20 e4 ldi r18, 0x40 ; 64 + eb8: 20 93 a1 09 sts 0x09A1, r18 + + return MEMORY_FLASH_USART.DATA; + ebc: 20 91 a0 09 lds r18, 0x09A0 + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(0x03); + SPITransferByte( (Address >> 16) & 0xFF ); + SPITransferByte( (Address >> 8) & 0xFF ); + ec0: 89 2f mov r24, r25 + ec2: 9a 2f mov r25, r26 + ec4: ab 2f mov r26, r27 + ec6: bb 27 eor r27, r27 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + ec8: 80 93 a0 09 sts 0x09A0, r24 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + ecc: 80 91 a1 09 lds r24, 0x09A1 + ed0: 86 ff sbrs r24, 6 + ed2: fc cf rjmp .-8 ; 0xecc + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + ed4: 80 e4 ldi r24, 0x40 ; 64 + ed6: 80 93 a1 09 sts 0x09A1, r24 + + return MEMORY_FLASH_USART.DATA; + eda: 80 91 a0 09 lds r24, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + ede: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + ee2: 80 91 a1 09 lds r24, 0x09A1 + ee6: 86 ff sbrs r24, 6 + ee8: fc cf rjmp .-8 ; 0xee2 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + eea: 80 e4 ldi r24, 0x40 ; 64 + eec: 80 93 a1 09 sts 0x09A1, r24 + + return MEMORY_FLASH_USART.DATA; + ef0: 80 91 a0 09 lds r24, 0x09A0 +} + +INLINE void SPIReadBlock(void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + ef4: e2 e9 ldi r30, 0x92 ; 146 + ef6: f0 e2 ldi r31, 0x20 ; 32 + + while(ByteCount-- > 0) { + MEMORY_FLASH_USART.DATA = 0; + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + ef8: 90 e4 ldi r25, 0x40 ; 64 +INLINE void SPIReadBlock(void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + MEMORY_FLASH_USART.DATA = 0; + efa: 10 92 a0 09 sts 0x09A0, r1 + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + efe: 80 91 a1 09 lds r24, 0x09A1 + f02: 86 ff sbrs r24, 6 + f04: fc cf rjmp .-8 ; 0xefe + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + f06: 90 93 a1 09 sts 0x09A1, r25 + *ByteBuffer++ = MEMORY_FLASH_USART.DATA; + f0a: 80 91 a0 09 lds r24, 0x09A0 + f0e: 81 93 st Z+, r24 + +INLINE void SPIReadBlock(void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + f10: 84 e2 ldi r24, 0x24 ; 36 + f12: e2 39 cpi r30, 0x92 ; 146 + f14: f8 07 cpc r31, r24 + f16: 89 f7 brne .-30 ; 0xefa + SPITransferByte(0x03); + SPITransferByte( (Address >> 16) & 0xFF ); + SPITransferByte( (Address >> 8) & 0xFF ); + SPITransferByte( (Address >> 0) & 0xFF ); + SPIReadBlock(Buffer, ByteCount); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + f18: 80 e1 ldi r24, 0x10 ; 16 + f1a: 80 93 65 06 sts 0x0665, r24 + f1e: 08 95 ret + +00000f20 : + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +void MemoryInit(void) +{ + f20: cf 93 push r28 + f22: df 93 push r29 + f24: 00 d0 rcall .+0 ; 0xf26 + f26: 00 d0 rcall .+0 ; 0xf28 + f28: cd b7 in r28, 0x3d ; 61 + f2a: de b7 in r29, 0x3e ; 62 + /* Configure MEMORY_FLASH_USART for SPI master mode 0 with maximum clock frequency */ + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + f2c: 80 e1 ldi r24, 0x10 ; 16 + f2e: 80 93 65 06 sts 0x0665, r24 + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_SCK; + f32: 92 e0 ldi r25, 0x02 ; 2 + f34: 90 93 66 06 sts 0x0666, r25 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_MOSI; + f38: 98 e0 ldi r25, 0x08 ; 8 + f3a: 90 93 65 06 sts 0x0665, r25 + + MEMORY_FLASH_PORT.DIRSET = MEMORY_FLASH_SCK | MEMORY_FLASH_MOSI | MEMORY_FLASH_CS; + f3e: 9a e1 ldi r25, 0x1A ; 26 + f40: 90 93 61 06 sts 0x0661, r25 + + MEMORY_FLASH_USART.BAUDCTRLA = 15;//0; + f44: 9f e0 ldi r25, 0x0F ; 15 + f46: 90 93 a6 09 sts 0x09A6, r25 + MEMORY_FLASH_USART.BAUDCTRLB = 0; + f4a: 10 92 a7 09 sts 0x09A7, r1 + MEMORY_FLASH_USART.CTRLC = USART_CMODE_MSPI_gc; // | USART_CHSIZE_8BIT_gc; + f4e: 90 ec ldi r25, 0xC0 ; 192 + f50: 90 93 a5 09 sts 0x09A5, r25 + MEMORY_FLASH_USART.CTRLB = USART_RXEN_bm | USART_TXEN_bm; + f54: 98 e1 ldi r25, 0x18 ; 24 + f56: 90 93 a4 09 sts 0x09A4, r25 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + f5a: 80 93 66 06 sts 0x0666, r24 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + f5e: 87 ed ldi r24, 0xD7 ; 215 + f60: 80 93 a0 09 sts 0x09A0, r24 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + f64: 80 91 a1 09 lds r24, 0x09A1 + f68: 86 ff sbrs r24, 6 + f6a: fc cf rjmp .-8 ; 0xf64 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + f6c: 80 e4 ldi r24, 0x40 ; 64 + f6e: 80 93 a1 09 sts 0x09A1, r24 + + return MEMORY_FLASH_USART.DATA; + f72: 80 91 a0 09 lds r24, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + f76: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + f7a: 80 91 a1 09 lds r24, 0x09A1 + f7e: 86 ff sbrs r24, 6 + f80: fc cf rjmp .-8 ; 0xf7a + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + f82: 80 e4 ldi r24, 0x40 ; 64 + f84: 80 93 a1 09 sts 0x09A1, r24 + + return MEMORY_FLASH_USART.DATA; + f88: 80 91 a0 09 lds r24, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + f8c: 90 e1 ldi r25, 0x10 ; 16 + f8e: 90 93 65 06 sts 0x0665, r25 + MEMORY_FLASH_USART.BAUDCTRLB = 0; + MEMORY_FLASH_USART.CTRLC = USART_CMODE_MSPI_gc; // | USART_CHSIZE_8BIT_gc; + MEMORY_FLASH_USART.CTRLB = USART_RXEN_bm | USART_TXEN_bm; + + + if ( !(FlashReadStatusRegister() & FLASH_STATUS_REG_PAGESIZE_BIT) ) { + f92: 80 fd sbrc r24, 0 + f94: 3e c0 rjmp .+124 ; 0x1012 + return !(FlashReadStatusRegister() & FLASH_STATUS_REG_READY_BIT); +} + +INLINE void FlashConfigurePageSize(void) +{ + uint8_t Sequence[] = {0x3D, 0x2A, 0x80, 0xA6}; + f96: 8d e3 ldi r24, 0x3D ; 61 + f98: 89 83 std Y+1, r24 ; 0x01 + f9a: 8a e2 ldi r24, 0x2A ; 42 + f9c: 8a 83 std Y+2, r24 ; 0x02 + f9e: 80 e8 ldi r24, 0x80 ; 128 + fa0: 8b 83 std Y+3, r24 ; 0x03 + fa2: 86 ea ldi r24, 0xA6 ; 166 + fa4: 8c 83 std Y+4, r24 ; 0x04 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + fa6: 20 e1 ldi r18, 0x10 ; 16 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + fa8: 37 ed ldi r19, 0xD7 ; 215 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + faa: 90 e4 ldi r25, 0x40 ; 64 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + fac: 20 93 66 06 sts 0x0666, r18 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + fb0: 30 93 a0 09 sts 0x09A0, r19 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + fb4: 80 91 a1 09 lds r24, 0x09A1 + fb8: 86 ff sbrs r24, 6 + fba: fc cf rjmp .-8 ; 0xfb4 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + fbc: 90 93 a1 09 sts 0x09A1, r25 + + return MEMORY_FLASH_USART.DATA; + fc0: 80 91 a0 09 lds r24, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + fc4: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + fc8: 80 91 a1 09 lds r24, 0x09A1 + fcc: 86 ff sbrs r24, 6 + fce: fc cf rjmp .-8 ; 0xfc8 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + fd0: 90 93 a1 09 sts 0x09A1, r25 + + return MEMORY_FLASH_USART.DATA; + fd4: 80 91 a0 09 lds r24, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + fd8: 20 93 65 06 sts 0x0665, r18 + +INLINE void FlashConfigurePageSize(void) +{ + uint8_t Sequence[] = {0x3D, 0x2A, 0x80, 0xA6}; + + while(FlashIsBusy()); + fdc: 87 ff sbrs r24, 7 + fde: e6 cf rjmp .-52 ; 0xfac + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + fe0: 80 e1 ldi r24, 0x10 ; 16 + fe2: 80 93 66 06 sts 0x0666, r24 + } +} + +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + fe6: fe 01 movw r30, r28 + fe8: 31 96 adiw r30, 0x01 ; 1 + fea: ce 01 movw r24, r28 + fec: 05 96 adiw r24, 0x05 ; 5 + + while(ByteCount-- > 0) { + MEMORY_FLASH_USART.DATA = *ByteBuffer++; + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + fee: 30 e4 ldi r19, 0x40 ; 64 +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + MEMORY_FLASH_USART.DATA = *ByteBuffer++; + ff0: 21 91 ld r18, Z+ + ff2: 20 93 a0 09 sts 0x09A0, r18 + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + ff6: 20 91 a1 09 lds r18, 0x09A1 + ffa: 26 ff sbrs r18, 6 + ffc: fc cf rjmp .-8 ; 0xff6 + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + ffe: 30 93 a1 09 sts 0x09A1, r19 + MEMORY_FLASH_USART.DATA; /* Flush Buffer */ + 1002: 20 91 a0 09 lds r18, 0x09A0 + +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + 1006: e8 17 cp r30, r24 + 1008: f9 07 cpc r31, r25 + 100a: 91 f7 brne .-28 ; 0xff0 + + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPIWriteBlock(Sequence, sizeof(Sequence)); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 100c: 80 e1 ldi r24, 0x10 ; 16 + 100e: 80 93 65 06 sts 0x0665, r24 + FlashConfigurePageSize(); + } + + /* Load permanent flash contents to memory at startup */ + MemoryRecall(); +} + 1012: 24 96 adiw r28, 0x04 ; 4 + 1014: cd bf out 0x3d, r28 ; 61 + 1016: de bf out 0x3e, r29 ; 62 + 1018: df 91 pop r29 + 101a: cf 91 pop r28 + /* Configure for 256 byte Dataflash if not already done. */ + FlashConfigurePageSize(); + } + + /* Load permanent flash contents to memory at startup */ + MemoryRecall(); + 101c: 0b cf rjmp .-490 ; 0xe34 + +0000101e : + /* Recall memory from permanent flash */ + FlashRead(Memory, (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); +} + +void MemoryStore(void) +{ + 101e: 4f 92 push r4 + 1020: 5f 92 push r5 + 1022: 6f 92 push r6 + 1024: 7f 92 push r7 + 1026: 8f 92 push r8 + 1028: 9f 92 push r9 + 102a: af 92 push r10 + 102c: bf 92 push r11 + 102e: cf 92 push r12 + 1030: df 92 push r13 + 1032: ef 92 push r14 + 1034: ff 92 push r15 + 1036: 0f 93 push r16 + 1038: 1f 93 push r17 + 103a: cf 93 push r28 + 103c: df 93 push r29 + /* Store current memory into permanent flash */ + FlashWrite(Memory, (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); + 103e: 80 91 09 29 lds r24, 0x2909 + 1042: 90 e0 ldi r25, 0x00 ; 0 + 1044: a0 e0 ldi r26, 0x00 ; 0 + 1046: b0 e0 ldi r27, 0x00 ; 0 + 1048: 6a e0 ldi r22, 0x0A ; 10 + 104a: 88 0f add r24, r24 + 104c: 99 1f adc r25, r25 + 104e: aa 1f adc r26, r26 + 1050: bb 1f adc r27, r27 + 1052: 6a 95 dec r22 + 1054: d1 f7 brne .-12 ; 0x104a + 1056: e2 e9 ldi r30, 0x92 ; 146 + 1058: f0 e2 ldi r31, 0x20 ; 32 + 105a: 00 e0 ldi r16, 0x00 ; 0 + 105c: 14 e0 ldi r17, 0x04 ; 4 +INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(ByteCount > 0) { + uint16_t PageAddress = Address / FLASH_PAGE_SIZE; + uint8_t ByteAddress = Address % FLASH_PAGE_SIZE; + uint16_t PageBytes = MIN(FLASH_PAGE_SIZE - ByteAddress, ByteCount); + 105e: e1 2c mov r14, r1 + 1060: ff 24 eor r15, r15 + 1062: f3 94 inc r15 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 1064: c0 e1 ldi r28, 0x10 ; 16 + 1066: cc 2e mov r12, r28 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1068: d7 ed ldi r29, 0xD7 ; 215 + 106a: bd 2e mov r11, r29 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 106c: 20 e4 ldi r18, 0x40 ; 64 + 106e: d2 2e mov r13, r18 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 1070: 30 e1 ldi r19, 0x10 ; 16 + 1072: a3 2e mov r10, r19 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1074: 47 ed ldi r20, 0xD7 ; 215 + 1076: 94 2e mov r9, r20 + 1078: 53 e5 ldi r21, 0x53 ; 83 + 107a: 45 2e mov r4, r21 + 107c: 64 e8 ldi r22, 0x84 ; 132 + 107e: 56 2e mov r5, r22 + 1080: 73 e8 ldi r23, 0x83 ; 131 + 1082: 67 2e mov r6, r23 +} + +INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(ByteCount > 0) { + uint16_t PageAddress = Address / FLASH_PAGE_SIZE; + 1084: 49 2f mov r20, r25 + 1086: 5a 2f mov r21, r26 + 1088: 6b 2f mov r22, r27 + 108a: 77 27 eor r23, r23 + 108c: 85 2e mov r8, r21 + uint8_t ByteAddress = Address % FLASH_PAGE_SIZE; + 108e: 38 2f mov r19, r24 + uint16_t PageBytes = MIN(FLASH_PAGE_SIZE - ByteAddress, ByteCount); + 1090: e7 01 movw r28, r14 + 1092: c8 1b sub r28, r24 + 1094: d1 09 sbc r29, r1 + 1096: 0c 17 cp r16, r28 + 1098: 1d 07 cpc r17, r29 + 109a: 08 f4 brcc .+2 ; 0x109e + 109c: e8 01 movw r28, r16 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 109e: a0 92 66 06 sts 0x0666, r10 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 10a2: 90 92 a0 09 sts 0x09A0, r9 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 10a6: 20 91 a1 09 lds r18, 0x09A1 + 10aa: 26 ff sbrs r18, 6 + 10ac: fc cf rjmp .-8 ; 0x10a6 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 10ae: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 10b2: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 10b6: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 10ba: 20 91 a1 09 lds r18, 0x09A1 + 10be: 26 ff sbrs r18, 6 + 10c0: fc cf rjmp .-8 ; 0x10ba + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 10c2: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 10c6: 20 91 a0 09 lds r18, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 10ca: c0 92 65 06 sts 0x0665, r12 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashMemoryToBuffer(uint16_t PageAddress) +{ + while(FlashIsBusy()); + 10ce: 27 ff sbrs r18, 7 + 10d0: e6 cf rjmp .-52 ; 0x109e + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 10d2: a0 92 66 06 sts 0x0666, r10 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 10d6: 40 92 a0 09 sts 0x09A0, r4 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 10da: 20 91 a1 09 lds r18, 0x09A1 + 10de: 26 ff sbrs r18, 6 + 10e0: fc cf rjmp .-8 ; 0x10da + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 10e2: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 10e6: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 10ea: 80 92 a0 09 sts 0x09A0, r8 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 10ee: 20 91 a1 09 lds r18, 0x09A1 + 10f2: 26 ff sbrs r18, 6 + 10f4: fc cf rjmp .-8 ; 0x10ee + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 10f6: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 10fa: 20 91 a0 09 lds r18, 0x09A0 + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_MEM_TO_BUF1); + SPITransferByte( (PageAddress >> 8) & 0xFF ); + SPITransferByte( (PageAddress >> 0) & 0xFF ); + 10fe: 74 2e mov r7, r20 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1100: 40 93 a0 09 sts 0x09A0, r20 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1104: 20 91 a1 09 lds r18, 0x09A1 + 1108: 26 ff sbrs r18, 6 + 110a: fc cf rjmp .-8 ; 0x1104 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 110c: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1110: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1114: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1118: 20 91 a1 09 lds r18, 0x09A1 + 111c: 26 ff sbrs r18, 6 + 111e: fc cf rjmp .-8 ; 0x1118 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1120: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1124: 20 91 a0 09 lds r18, 0x09A0 + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_MEM_TO_BUF1); + SPITransferByte( (PageAddress >> 8) & 0xFF ); + SPITransferByte( (PageAddress >> 0) & 0xFF ); + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 1128: c0 92 65 06 sts 0x0665, r12 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 112c: c0 92 66 06 sts 0x0666, r12 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1130: b0 92 a0 09 sts 0x09A0, r11 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1134: 20 91 a1 09 lds r18, 0x09A1 + 1138: 26 ff sbrs r18, 6 + 113a: fc cf rjmp .-8 ; 0x1134 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 113c: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1140: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1144: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1148: 20 91 a1 09 lds r18, 0x09A1 + 114c: 26 ff sbrs r18, 6 + 114e: fc cf rjmp .-8 ; 0x1148 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1150: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1154: 20 91 a0 09 lds r18, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 1158: c0 92 65 06 sts 0x0665, r12 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashWriteBuffer(const void* Buffer, uint8_t Address, uint16_t ByteCount) +{ + while(FlashIsBusy()); + 115c: 27 ff sbrs r18, 7 + 115e: e6 cf rjmp .-52 ; 0x112c + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 1160: a0 92 66 06 sts 0x0666, r10 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1164: 50 92 a0 09 sts 0x09A0, r5 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1168: 20 91 a1 09 lds r18, 0x09A1 + 116c: 26 ff sbrs r18, 6 + 116e: fc cf rjmp .-8 ; 0x1168 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1170: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1174: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1178: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 117c: 20 91 a1 09 lds r18, 0x09A1 + 1180: 26 ff sbrs r18, 6 + 1182: fc cf rjmp .-8 ; 0x117c + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1184: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1188: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 118c: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1190: 20 91 a1 09 lds r18, 0x09A1 + 1194: 26 ff sbrs r18, 6 + 1196: fc cf rjmp .-8 ; 0x1190 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1198: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 119c: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 11a0: 30 93 a0 09 sts 0x09A0, r19 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 11a4: 20 91 a1 09 lds r18, 0x09A1 + 11a8: 26 ff sbrs r18, 6 + 11aa: fc cf rjmp .-8 ; 0x11a4 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 11ac: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 11b0: 20 91 a0 09 lds r18, 0x09A0 +{ + /* Recall memory from permanent flash */ + FlashRead(Memory, (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); +} + +void MemoryStore(void) + 11b4: 9f 01 movw r18, r30 + +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + 11b6: 20 97 sbiw r28, 0x00 ; 0 + 11b8: 81 f0 breq .+32 ; 0x11da +{ + /* Recall memory from permanent flash */ + FlashRead(Memory, (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); +} + +void MemoryStore(void) + 11ba: 2c 0f add r18, r28 + 11bc: 3d 1f adc r19, r29 +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + MEMORY_FLASH_USART.DATA = *ByteBuffer++; + 11be: 41 91 ld r20, Z+ + 11c0: 40 93 a0 09 sts 0x09A0, r20 + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 11c4: 40 91 a1 09 lds r20, 0x09A1 + 11c8: 46 ff sbrs r20, 6 + 11ca: fc cf rjmp .-8 ; 0x11c4 + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 11cc: d0 92 a1 09 sts 0x09A1, r13 + MEMORY_FLASH_USART.DATA; /* Flush Buffer */ + 11d0: 40 91 a0 09 lds r20, 0x09A0 + +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + 11d4: e2 17 cp r30, r18 + 11d6: f3 07 cpc r31, r19 + 11d8: 91 f7 brne .-28 ; 0x11be + SPITransferByte(FLASH_CMD_BUF1_WRITE); + SPITransferByte( 0 ); + SPITransferByte( 0 ); + SPITransferByte( Address ); + SPIWriteBlock(Buffer, ByteCount); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 11da: c0 92 65 06 sts 0x0665, r12 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 11de: c0 92 66 06 sts 0x0666, r12 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 11e2: b0 92 a0 09 sts 0x09A0, r11 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 11e6: 40 91 a1 09 lds r20, 0x09A1 + 11ea: 46 ff sbrs r20, 6 + 11ec: fc cf rjmp .-8 ; 0x11e6 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 11ee: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 11f2: 40 91 a0 09 lds r20, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 11f6: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 11fa: 40 91 a1 09 lds r20, 0x09A1 + 11fe: 46 ff sbrs r20, 6 + 1200: fc cf rjmp .-8 ; 0x11fa + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1202: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1206: 40 91 a0 09 lds r20, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 120a: c0 92 65 06 sts 0x0665, r12 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashBufferToMemory(uint16_t PageAddress) +{ + while(FlashIsBusy()); + 120e: 47 ff sbrs r20, 7 + 1210: e6 cf rjmp .-52 ; 0x11de + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 1212: a0 92 66 06 sts 0x0666, r10 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1216: 60 92 a0 09 sts 0x09A0, r6 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 121a: 40 91 a1 09 lds r20, 0x09A1 + 121e: 46 ff sbrs r20, 6 + 1220: fc cf rjmp .-8 ; 0x121a + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1222: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1226: 40 91 a0 09 lds r20, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 122a: 80 92 a0 09 sts 0x09A0, r8 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 122e: 40 91 a1 09 lds r20, 0x09A1 + 1232: 46 ff sbrs r20, 6 + 1234: fc cf rjmp .-8 ; 0x122e + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1236: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 123a: 40 91 a0 09 lds r20, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 123e: 70 92 a0 09 sts 0x09A0, r7 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1242: 40 91 a1 09 lds r20, 0x09A1 + 1246: 46 ff sbrs r20, 6 + 1248: fc cf rjmp .-8 ; 0x1242 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 124a: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 124e: 40 91 a0 09 lds r20, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1252: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1256: 40 91 a1 09 lds r20, 0x09A1 + 125a: 46 ff sbrs r20, 6 + 125c: fc cf rjmp .-8 ; 0x1256 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 125e: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1262: 40 91 a0 09 lds r20, 0x09A0 + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_BUF1_TO_MEM_ERASE); + SPITransferByte( (PageAddress >> 8) & 0xFF ); + SPITransferByte( (PageAddress >> 0) & 0xFF ); + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 1266: c0 92 65 06 sts 0x0665, r12 + + FlashMemoryToBuffer(PageAddress); + FlashWriteBuffer(Buffer, ByteAddress, PageBytes); + FlashBufferToMemory(PageAddress); + + ByteCount -= PageBytes; + 126a: 0c 1b sub r16, r28 + 126c: 1d 0b sbc r17, r29 + Address += PageBytes; + 126e: 8c 0f add r24, r28 + 1270: 9d 1f adc r25, r29 + 1272: a1 1d adc r26, r1 + 1274: b1 1d adc r27, r1 + Buffer += PageBytes; + 1276: f9 01 movw r30, r18 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(ByteCount > 0) { + 1278: 01 15 cp r16, r1 + 127a: 11 05 cpc r17, r1 + 127c: 09 f0 breq .+2 ; 0x1280 + 127e: 02 cf rjmp .-508 ; 0x1084 +void MemoryStore(void) +{ + /* Store current memory into permanent flash */ + FlashWrite(Memory, (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); + + LEDTrigger(LED_MEMORY_CHANGED, LED_OFF); + 1280: 60 e1 ldi r22, 0x10 ; 16 + 1282: 85 e0 ldi r24, 0x05 ; 5 + 1284: 6c d6 rcall .+3288 ; 0x1f5e + LEDTrigger(LED_MEMORY_STORED, LED_PULSE); + 1286: 63 e1 ldi r22, 0x13 ; 19 + 1288: 84 e0 ldi r24, 0x04 ; 4 +} + 128a: df 91 pop r29 + 128c: cf 91 pop r28 + 128e: 1f 91 pop r17 + 1290: 0f 91 pop r16 + 1292: ff 90 pop r15 + 1294: ef 90 pop r14 + 1296: df 90 pop r13 + 1298: cf 90 pop r12 + 129a: bf 90 pop r11 + 129c: af 90 pop r10 + 129e: 9f 90 pop r9 + 12a0: 8f 90 pop r8 + 12a2: 7f 90 pop r7 + 12a4: 6f 90 pop r6 + 12a6: 5f 90 pop r5 + 12a8: 4f 90 pop r4 +{ + /* Store current memory into permanent flash */ + FlashWrite(Memory, (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); + + LEDTrigger(LED_MEMORY_CHANGED, LED_OFF); + LEDTrigger(LED_MEMORY_STORED, LED_PULSE); + 12aa: 59 c6 rjmp .+3250 ; 0x1f5e + +000012ac : +} + +bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) +{ + 12ac: 2f 92 push r2 + 12ae: 3f 92 push r3 + 12b0: 4f 92 push r4 + 12b2: 5f 92 push r5 + 12b4: 6f 92 push r6 + 12b6: 7f 92 push r7 + 12b8: 8f 92 push r8 + 12ba: 9f 92 push r9 + 12bc: af 92 push r10 + 12be: bf 92 push r11 + 12c0: cf 92 push r12 + 12c2: df 92 push r13 + 12c4: ef 92 push r14 + 12c6: ff 92 push r15 + 12c8: 0f 93 push r16 + 12ca: 1f 93 push r17 + 12cc: cf 93 push r28 + 12ce: df 93 push r29 + 12d0: cd b7 in r28, 0x3d ; 61 + 12d2: de b7 in r29, 0x3e ; 62 + 12d4: 2b 97 sbiw r28, 0x0b ; 11 + 12d6: cd bf out 0x3d, r28 ; 61 + 12d8: de bf out 0x3e, r29 ; 62 + 12da: 8d 83 std Y+5, r24 ; 0x05 + 12dc: 29 2e mov r2, r25 + 12de: 59 01 movw r10, r18 + if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { + 12e0: 41 15 cp r20, r1 + 12e2: 84 e0 ldi r24, 0x04 ; 4 + 12e4: 58 07 cpc r21, r24 + 12e6: 61 05 cpc r22, r1 + 12e8: 71 05 cpc r23, r1 + 12ea: 08 f0 brcs .+2 ; 0x12ee + 12ec: 85 c1 rjmp .+778 ; 0x15f8 + /* Prevent writing out of bounds by silently ignoring it */ + return true; + } else { + /* Calculate bytes left in memory and start writing */ + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING; + 12ee: 80 91 09 29 lds r24, 0x2909 + 12f2: 90 e0 ldi r25, 0x00 ; 0 + 12f4: a0 e0 ldi r26, 0x00 ; 0 + 12f6: b0 e0 ldi r27, 0x00 ; 0 + 12f8: fa e0 ldi r31, 0x0A ; 10 + 12fa: 88 0f add r24, r24 + 12fc: 99 1f adc r25, r25 + 12fe: aa 1f adc r26, r26 + 1300: bb 1f adc r27, r27 + 1302: fa 95 dec r31 + 1304: d1 f7 brne .-12 ; 0x12fa + 1306: 84 0f add r24, r20 + 1308: 95 1f adc r25, r21 + 130a: a6 1f adc r26, r22 + 130c: b7 1f adc r27, r23 + if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { + /* Prevent writing out of bounds by silently ignoring it */ + return true; + } else { + /* Calculate bytes left in memory and start writing */ + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + 130e: 00 e0 ldi r16, 0x00 ; 0 + 1310: 14 e0 ldi r17, 0x04 ; 4 + 1312: 20 e0 ldi r18, 0x00 ; 0 + 1314: 30 e0 ldi r19, 0x00 ; 0 + 1316: 04 1b sub r16, r20 + 1318: 15 0b sbc r17, r21 + 131a: 26 0b sbc r18, r22 + 131c: 37 0b sbc r19, r23 + uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING; + ByteCount = MIN(ByteCount, BytesLeft); + 131e: 65 01 movw r12, r10 + 1320: e1 2c mov r14, r1 + 1322: f1 2c mov r15, r1 + 1324: c9 82 std Y+1, r12 ; 0x01 + 1326: da 82 std Y+2, r13 ; 0x02 + 1328: eb 82 std Y+3, r14 ; 0x03 + 132a: fc 82 std Y+4, r15 ; 0x04 + 132c: 0c 15 cp r16, r12 + 132e: 1d 05 cpc r17, r13 + 1330: 2e 05 cpc r18, r14 + 1332: 3f 05 cpc r19, r15 + 1334: 08 f4 brcc .+2 ; 0x1338 + 1336: 7a c1 rjmp .+756 ; 0x162c + 1338: 09 81 ldd r16, Y+1 ; 0x01 + 133a: 1a 81 ldd r17, Y+2 ; 0x02 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(ByteCount > 0) { + 133c: 01 15 cp r16, r1 + 133e: 11 05 cpc r17, r1 + 1340: 09 f4 brne .+2 ; 0x1344 + 1342: 5a c1 rjmp .+692 ; 0x15f8 + 1344: 2d 81 ldd r18, Y+5 ; 0x05 + 1346: 32 2d mov r19, r2 + uint16_t PageAddress = Address / FLASH_PAGE_SIZE; + uint8_t ByteAddress = Address % FLASH_PAGE_SIZE; + uint16_t PageBytes = MIN(FLASH_PAGE_SIZE - ByteAddress, ByteCount); + 1348: e1 2c mov r14, r1 + 134a: ff 24 eor r15, r15 + 134c: f3 94 inc r15 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 134e: e0 e1 ldi r30, 0x10 ; 16 + 1350: ce 2e mov r12, r30 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1352: f7 ed ldi r31, 0xD7 ; 215 + 1354: bf 2e mov r11, r31 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1356: e0 e4 ldi r30, 0x40 ; 64 + 1358: de 2e mov r13, r30 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 135a: f0 e1 ldi r31, 0x10 ; 16 + 135c: af 2e mov r10, r31 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 135e: e7 ed ldi r30, 0xD7 ; 215 + 1360: 9e 2e mov r9, r30 + 1362: f3 e5 ldi r31, 0x53 ; 83 + 1364: 6f 2e mov r6, r31 + 1366: e4 e8 ldi r30, 0x84 ; 132 + 1368: 8e 2e mov r8, r30 + 136a: 2a 87 std Y+10, r18 ; 0x0a + 136c: 3b 87 std Y+11, r19 ; 0x0b + 136e: 4e 83 std Y+6, r20 ; 0x06 + 1370: 5f 83 std Y+7, r21 ; 0x07 + 1372: 68 87 std Y+8, r22 ; 0x08 + 1374: 79 87 std Y+9, r23 ; 0x09 + 1376: 36 2c mov r3, r6 +} + +INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(ByteCount > 0) { + uint16_t PageAddress = Address / FLASH_PAGE_SIZE; + 1378: 49 2e mov r4, r25 + 137a: 5a 2e mov r5, r26 + 137c: 6b 2e mov r6, r27 + 137e: 77 24 eor r7, r7 + 1380: 45 2d mov r20, r5 + uint8_t ByteAddress = Address % FLASH_PAGE_SIZE; + 1382: 38 2f mov r19, r24 + uint16_t PageBytes = MIN(FLASH_PAGE_SIZE - ByteAddress, ByteCount); + 1384: b7 01 movw r22, r14 + 1386: 68 1b sub r22, r24 + 1388: 71 09 sbc r23, r1 + 138a: 06 17 cp r16, r22 + 138c: 17 07 cpc r17, r23 + 138e: 08 f0 brcs .+2 ; 0x1392 + 1390: 4a c1 rjmp .+660 ; 0x1626 + 1392: b8 01 movw r22, r16 + 1394: ea 85 ldd r30, Y+10 ; 0x0a + 1396: fb 85 ldd r31, Y+11 ; 0x0b + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 1398: a0 92 66 06 sts 0x0666, r10 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 139c: 90 92 a0 09 sts 0x09A0, r9 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 13a0: 20 91 a1 09 lds r18, 0x09A1 + 13a4: 26 ff sbrs r18, 6 + 13a6: fc cf rjmp .-8 ; 0x13a0 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 13a8: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 13ac: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 13b0: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 13b4: 20 91 a1 09 lds r18, 0x09A1 + 13b8: 26 ff sbrs r18, 6 + 13ba: fc cf rjmp .-8 ; 0x13b4 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 13bc: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 13c0: 20 91 a0 09 lds r18, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 13c4: c0 92 65 06 sts 0x0665, r12 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashMemoryToBuffer(uint16_t PageAddress) +{ + while(FlashIsBusy()); + 13c8: 27 ff sbrs r18, 7 + 13ca: e6 cf rjmp .-52 ; 0x1398 + 13cc: ea 87 std Y+10, r30 ; 0x0a + 13ce: fb 87 std Y+11, r31 ; 0x0b + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 13d0: a0 92 66 06 sts 0x0666, r10 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 13d4: 30 92 a0 09 sts 0x09A0, r3 + 13d8: ea 85 ldd r30, Y+10 ; 0x0a + 13da: fb 85 ldd r31, Y+11 ; 0x0b + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 13dc: 20 91 a1 09 lds r18, 0x09A1 + 13e0: 26 ff sbrs r18, 6 + 13e2: fc cf rjmp .-8 ; 0x13dc + 13e4: ea 87 std Y+10, r30 ; 0x0a + 13e6: fb 87 std Y+11, r31 ; 0x0b + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 13e8: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 13ec: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 13f0: 40 93 a0 09 sts 0x09A0, r20 + 13f4: ea 85 ldd r30, Y+10 ; 0x0a + 13f6: fb 85 ldd r31, Y+11 ; 0x0b + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 13f8: 20 91 a1 09 lds r18, 0x09A1 + 13fc: 26 ff sbrs r18, 6 + 13fe: fc cf rjmp .-8 ; 0x13f8 + 1400: ea 87 std Y+10, r30 ; 0x0a + 1402: fb 87 std Y+11, r31 ; 0x0b + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1404: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1408: 20 91 a0 09 lds r18, 0x09A0 + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_MEM_TO_BUF1); + SPITransferByte( (PageAddress >> 8) & 0xFF ); + SPITransferByte( (PageAddress >> 0) & 0xFF ); + 140c: 54 2d mov r21, r4 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 140e: 40 92 a0 09 sts 0x09A0, r4 + 1412: ea 85 ldd r30, Y+10 ; 0x0a + 1414: fb 85 ldd r31, Y+11 ; 0x0b + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1416: 20 91 a1 09 lds r18, 0x09A1 + 141a: 26 ff sbrs r18, 6 + 141c: fc cf rjmp .-8 ; 0x1416 + 141e: ea 87 std Y+10, r30 ; 0x0a + 1420: fb 87 std Y+11, r31 ; 0x0b + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1422: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1426: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 142a: 10 92 a0 09 sts 0x09A0, r1 + 142e: ea 85 ldd r30, Y+10 ; 0x0a + 1430: fb 85 ldd r31, Y+11 ; 0x0b + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1432: 20 91 a1 09 lds r18, 0x09A1 + 1436: 26 ff sbrs r18, 6 + 1438: fc cf rjmp .-8 ; 0x1432 + 143a: ea 87 std Y+10, r30 ; 0x0a + 143c: fb 87 std Y+11, r31 ; 0x0b + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 143e: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1442: 20 91 a0 09 lds r18, 0x09A0 + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_MEM_TO_BUF1); + SPITransferByte( (PageAddress >> 8) & 0xFF ); + SPITransferByte( (PageAddress >> 0) & 0xFF ); + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 1446: c0 92 65 06 sts 0x0665, r12 + 144a: ea 85 ldd r30, Y+10 ; 0x0a + 144c: fb 85 ldd r31, Y+11 ; 0x0b + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 144e: c0 92 66 06 sts 0x0666, r12 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1452: b0 92 a0 09 sts 0x09A0, r11 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1456: 20 91 a1 09 lds r18, 0x09A1 + 145a: 26 ff sbrs r18, 6 + 145c: fc cf rjmp .-8 ; 0x1456 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 145e: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1462: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1466: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 146a: 20 91 a1 09 lds r18, 0x09A1 + 146e: 26 ff sbrs r18, 6 + 1470: fc cf rjmp .-8 ; 0x146a + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1472: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1476: 20 91 a0 09 lds r18, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 147a: c0 92 65 06 sts 0x0665, r12 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashWriteBuffer(const void* Buffer, uint8_t Address, uint16_t ByteCount) +{ + while(FlashIsBusy()); + 147e: 27 ff sbrs r18, 7 + 1480: e6 cf rjmp .-52 ; 0x144e + 1482: ea 87 std Y+10, r30 ; 0x0a + 1484: fb 87 std Y+11, r31 ; 0x0b + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 1486: a0 92 66 06 sts 0x0666, r10 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 148a: 80 92 a0 09 sts 0x09A0, r8 + 148e: ea 85 ldd r30, Y+10 ; 0x0a + 1490: fb 85 ldd r31, Y+11 ; 0x0b + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1492: 20 91 a1 09 lds r18, 0x09A1 + 1496: 26 ff sbrs r18, 6 + 1498: fc cf rjmp .-8 ; 0x1492 + 149a: ea 87 std Y+10, r30 ; 0x0a + 149c: fb 87 std Y+11, r31 ; 0x0b + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 149e: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 14a2: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 14a6: 10 92 a0 09 sts 0x09A0, r1 + 14aa: ea 85 ldd r30, Y+10 ; 0x0a + 14ac: fb 85 ldd r31, Y+11 ; 0x0b + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 14ae: 20 91 a1 09 lds r18, 0x09A1 + 14b2: 26 ff sbrs r18, 6 + 14b4: fc cf rjmp .-8 ; 0x14ae + 14b6: ea 87 std Y+10, r30 ; 0x0a + 14b8: fb 87 std Y+11, r31 ; 0x0b + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 14ba: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 14be: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 14c2: 10 92 a0 09 sts 0x09A0, r1 + 14c6: ea 85 ldd r30, Y+10 ; 0x0a + 14c8: fb 85 ldd r31, Y+11 ; 0x0b + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 14ca: 20 91 a1 09 lds r18, 0x09A1 + 14ce: 26 ff sbrs r18, 6 + 14d0: fc cf rjmp .-8 ; 0x14ca + 14d2: ea 87 std Y+10, r30 ; 0x0a + 14d4: fb 87 std Y+11, r31 ; 0x0b + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 14d6: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 14da: 20 91 a0 09 lds r18, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 14de: 30 93 a0 09 sts 0x09A0, r19 + 14e2: ea 85 ldd r30, Y+10 ; 0x0a + 14e4: fb 85 ldd r31, Y+11 ; 0x0b + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 14e6: 20 91 a1 09 lds r18, 0x09A1 + 14ea: 26 ff sbrs r18, 6 + 14ec: fc cf rjmp .-8 ; 0x14e6 + 14ee: ea 87 std Y+10, r30 ; 0x0a + 14f0: fb 87 std Y+11, r31 ; 0x0b + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 14f2: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 14f6: 20 91 a0 09 lds r18, 0x09A0 + + LEDTrigger(LED_MEMORY_CHANGED, LED_OFF); + LEDTrigger(LED_MEMORY_STORED, LED_PULSE); +} + +bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) + 14fa: 2a 85 ldd r18, Y+10 ; 0x0a + 14fc: 3b 85 ldd r19, Y+11 ; 0x0b + +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + 14fe: 61 15 cp r22, r1 + 1500: 71 05 cpc r23, r1 + 1502: 91 f0 breq .+36 ; 0x1528 + + LEDTrigger(LED_MEMORY_CHANGED, LED_OFF); + LEDTrigger(LED_MEMORY_STORED, LED_PULSE); +} + +bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) + 1504: 26 0f add r18, r22 + 1506: 37 1f adc r19, r23 + 1508: ea 85 ldd r30, Y+10 ; 0x0a + 150a: fb 85 ldd r31, Y+11 ; 0x0b +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + MEMORY_FLASH_USART.DATA = *ByteBuffer++; + 150c: 71 90 ld r7, Z+ + 150e: 70 92 a0 09 sts 0x09A0, r7 + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1512: 70 90 a1 09 lds r7, 0x09A1 + 1516: 76 fe sbrs r7, 6 + 1518: fc cf rjmp .-8 ; 0x1512 + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 151a: d0 92 a1 09 sts 0x09A1, r13 + MEMORY_FLASH_USART.DATA; /* Flush Buffer */ + 151e: 70 90 a0 09 lds r7, 0x09A0 + +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + 1522: e2 17 cp r30, r18 + 1524: f3 07 cpc r31, r19 + 1526: 91 f7 brne .-28 ; 0x150c + SPITransferByte(FLASH_CMD_BUF1_WRITE); + SPITransferByte( 0 ); + SPITransferByte( 0 ); + SPITransferByte( Address ); + SPIWriteBlock(Buffer, ByteCount); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 1528: c0 92 65 06 sts 0x0665, r12 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 152c: c0 92 66 06 sts 0x0666, r12 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1530: b0 92 a0 09 sts 0x09A0, r11 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1534: e0 91 a1 09 lds r30, 0x09A1 + 1538: e6 ff sbrs r30, 6 + 153a: fc cf rjmp .-8 ; 0x1534 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 153c: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1540: e0 91 a0 09 lds r30, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1544: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1548: e0 91 a1 09 lds r30, 0x09A1 + 154c: e6 ff sbrs r30, 6 + 154e: fc cf rjmp .-8 ; 0x1548 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1550: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1554: e0 91 a0 09 lds r30, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 1558: c0 92 65 06 sts 0x0665, r12 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashBufferToMemory(uint16_t PageAddress) +{ + while(FlashIsBusy()); + 155c: e7 ff sbrs r30, 7 + 155e: e6 cf rjmp .-52 ; 0x152c + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 1560: a0 92 66 06 sts 0x0666, r10 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1564: e3 e8 ldi r30, 0x83 ; 131 + 1566: e0 93 a0 09 sts 0x09A0, r30 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 156a: e0 91 a1 09 lds r30, 0x09A1 + 156e: e6 ff sbrs r30, 6 + 1570: fc cf rjmp .-8 ; 0x156a + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1572: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 1576: e0 91 a0 09 lds r30, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 157a: 40 93 a0 09 sts 0x09A0, r20 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 157e: 40 91 a1 09 lds r20, 0x09A1 + 1582: 46 ff sbrs r20, 6 + 1584: fc cf rjmp .-8 ; 0x157e + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1586: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 158a: 40 91 a0 09 lds r20, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 158e: 50 93 a0 09 sts 0x09A0, r21 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1592: 40 91 a1 09 lds r20, 0x09A1 + 1596: 46 ff sbrs r20, 6 + 1598: fc cf rjmp .-8 ; 0x1592 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 159a: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 159e: 40 91 a0 09 lds r20, 0x09A0 + +static uint8_t Memory[MEMORY_SIZE_PER_SETTING]; + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 15a2: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 15a6: 40 91 a1 09 lds r20, 0x09A1 + 15aa: 46 ff sbrs r20, 6 + 15ac: fc cf rjmp .-8 ; 0x15a6 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 15ae: d0 92 a1 09 sts 0x09A1, r13 + + return MEMORY_FLASH_USART.DATA; + 15b2: 40 91 a0 09 lds r20, 0x09A0 + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_BUF1_TO_MEM_ERASE); + SPITransferByte( (PageAddress >> 8) & 0xFF ); + SPITransferByte( (PageAddress >> 0) & 0xFF ); + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 15b6: c0 92 65 06 sts 0x0665, r12 + + FlashMemoryToBuffer(PageAddress); + FlashWriteBuffer(Buffer, ByteAddress, PageBytes); + FlashBufferToMemory(PageAddress); + + ByteCount -= PageBytes; + 15ba: 06 1b sub r16, r22 + 15bc: 17 0b sbc r17, r23 + Address += PageBytes; + 15be: 86 0f add r24, r22 + 15c0: 97 1f adc r25, r23 + 15c2: a1 1d adc r26, r1 + 15c4: b1 1d adc r27, r1 + Buffer += PageBytes; + 15c6: 2a 87 std Y+10, r18 ; 0x0a + 15c8: 3b 87 std Y+11, r19 ; 0x0b + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(ByteCount > 0) { + 15ca: 01 15 cp r16, r1 + 15cc: 11 05 cpc r17, r1 + 15ce: 09 f0 breq .+2 ; 0x15d2 + 15d0: d3 ce rjmp .-602 ; 0x1378 + 15d2: 4e 81 ldd r20, Y+6 ; 0x06 + 15d4: 5f 81 ldd r21, Y+7 ; 0x07 + 15d6: 68 85 ldd r22, Y+8 ; 0x08 + 15d8: 79 85 ldd r23, Y+9 ; 0x09 + + /* Store into flash */ + FlashWrite(Buffer, FlashAddress, ByteCount); + + /* Store to local memory */ + uint8_t* DstPtr = &Memory[BlockAddress]; + 15da: da 01 movw r26, r20 + 15dc: ae 56 subi r26, 0x6E ; 110 + 15de: bf 4d sbci r27, 0xDF ; 223 + 15e0: 2d 81 ldd r18, Y+5 ; 0x05 + 15e2: 32 2d mov r19, r2 + + LEDTrigger(LED_MEMORY_CHANGED, LED_OFF); + LEDTrigger(LED_MEMORY_STORED, LED_PULSE); +} + +bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) + 15e4: 89 81 ldd r24, Y+1 ; 0x01 + 15e6: 9a 81 ldd r25, Y+2 ; 0x02 + 15e8: 8a 0f add r24, r26 + 15ea: 9b 1f adc r25, r27 + 15ec: f9 01 movw r30, r18 + /* Store to local memory */ + uint8_t* DstPtr = &Memory[BlockAddress]; + uint8_t* SrcPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + *DstPtr++ = *SrcPtr++; + 15ee: 21 91 ld r18, Z+ + 15f0: 2d 93 st X+, r18 + + /* Store to local memory */ + uint8_t* DstPtr = &Memory[BlockAddress]; + uint8_t* SrcPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 15f2: a8 17 cp r26, r24 + 15f4: b9 07 cpc r27, r25 + 15f6: d9 f7 brne .-10 ; 0x15ee + } + + return true; + } + +} + 15f8: 81 e0 ldi r24, 0x01 ; 1 + 15fa: 2b 96 adiw r28, 0x0b ; 11 + 15fc: cd bf out 0x3d, r28 ; 61 + 15fe: de bf out 0x3e, r29 ; 62 + 1600: df 91 pop r29 + 1602: cf 91 pop r28 + 1604: 1f 91 pop r17 + 1606: 0f 91 pop r16 + 1608: ff 90 pop r15 + 160a: ef 90 pop r14 + 160c: df 90 pop r13 + 160e: cf 90 pop r12 + 1610: bf 90 pop r11 + 1612: af 90 pop r10 + 1614: 9f 90 pop r9 + 1616: 8f 90 pop r8 + 1618: 7f 90 pop r7 + 161a: 6f 90 pop r6 + 161c: 5f 90 pop r5 + 161e: 4f 90 pop r4 + 1620: 3f 90 pop r3 + 1622: 2f 90 pop r2 + 1624: 08 95 ret + 1626: ea 85 ldd r30, Y+10 ; 0x0a + 1628: fb 85 ldd r31, Y+11 ; 0x0b + 162a: b6 ce rjmp .-660 ; 0x1398 + return true; + } else { + /* Calculate bytes left in memory and start writing */ + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING; + ByteCount = MIN(ByteCount, BytesLeft); + 162c: 09 83 std Y+1, r16 ; 0x01 + 162e: 1a 83 std Y+2, r17 ; 0x02 + 1630: 2b 83 std Y+3, r18 ; 0x03 + 1632: 3c 83 std Y+4, r19 ; 0x04 + 1634: 81 ce rjmp .-766 ; 0x1338 + +00001636 : + } + +} + +bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) +{ + 1636: cf 92 push r12 + 1638: df 92 push r13 + 163a: ef 92 push r14 + 163c: ff 92 push r15 + 163e: 0f 93 push r16 + 1640: 1f 93 push r17 + 1642: 69 01 movw r12, r18 + if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { + 1644: 41 15 cp r20, r1 + 1646: 24 e0 ldi r18, 0x04 ; 4 + 1648: 52 07 cpc r21, r18 + 164a: 61 05 cpc r22, r1 + 164c: 71 05 cpc r23, r1 + 164e: 40 f5 brcc .+80 ; 0x16a0 + /* There are bytes out of bounds to be read. Notify that we are done. */ + return false; + } else { + /* Calculate bytes left in memory and issue reading */ + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + 1650: 00 e0 ldi r16, 0x00 ; 0 + 1652: 14 e0 ldi r17, 0x04 ; 4 + 1654: 20 e0 ldi r18, 0x00 ; 0 + 1656: 30 e0 ldi r19, 0x00 ; 0 + 1658: 04 1b sub r16, r20 + 165a: 15 0b sbc r17, r21 + 165c: 26 0b sbc r18, r22 + 165e: 37 0b sbc r19, r23 + //uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; + ByteCount = MIN(ByteCount, BytesLeft); + 1660: e1 2c mov r14, r1 + 1662: f1 2c mov r15, r1 + 1664: 0c 15 cp r16, r12 + 1666: 1d 05 cpc r17, r13 + 1668: 2e 05 cpc r18, r14 + 166a: 3f 05 cpc r19, r15 + 166c: b0 f0 brcs .+44 ; 0x169a + + /* Output local memory contents */ + uint8_t* DstPtr = (uint8_t*) Buffer; + uint8_t* SrcPtr = &Memory[BlockAddress]; + 166e: 4e 56 subi r20, 0x6E ; 110 + 1670: 5f 4d sbci r21, 0xDF ; 223 + + while(ByteCount--) { + 1672: c1 14 cp r12, r1 + 1674: d1 04 cpc r13, r1 + 1676: 49 f0 breq .+18 ; 0x168a + 1678: da 01 movw r26, r20 + return true; + } + +} + +bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) + 167a: c8 0e add r12, r24 + 167c: d9 1e adc r13, r25 + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + //uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; + ByteCount = MIN(ByteCount, BytesLeft); + + /* Output local memory contents */ + uint8_t* DstPtr = (uint8_t*) Buffer; + 167e: fc 01 movw r30, r24 + uint8_t* SrcPtr = &Memory[BlockAddress]; + + while(ByteCount--) { + *DstPtr++ = *SrcPtr++; + 1680: 8d 91 ld r24, X+ + 1682: 81 93 st Z+, r24 + + /* Output local memory contents */ + uint8_t* DstPtr = (uint8_t*) Buffer; + uint8_t* SrcPtr = &Memory[BlockAddress]; + + while(ByteCount--) { + 1684: ec 15 cp r30, r12 + 1686: fd 05 cpc r31, r13 + 1688: d9 f7 brne .-10 ; 0x1680 + *DstPtr++ = *SrcPtr++; + } + + return true; + 168a: 81 e0 ldi r24, 0x01 ; 1 + } +} + 168c: 1f 91 pop r17 + 168e: 0f 91 pop r16 + 1690: ff 90 pop r15 + 1692: ef 90 pop r14 + 1694: df 90 pop r13 + 1696: cf 90 pop r12 + 1698: 08 95 ret + return false; + } else { + /* Calculate bytes left in memory and issue reading */ + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + //uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; + ByteCount = MIN(ByteCount, BytesLeft); + 169a: 68 01 movw r12, r16 + 169c: 79 01 movw r14, r18 + 169e: e7 cf rjmp .-50 ; 0x166e + +bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) +{ + if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { + /* There are bytes out of bounds to be read. Notify that we are done. */ + return false; + 16a0: 80 e0 ldi r24, 0x00 ; 0 + *DstPtr++ = *SrcPtr++; + } + + return true; + } +} + 16a2: 1f 91 pop r17 + 16a4: 0f 91 pop r16 + 16a6: ff 90 pop r15 + 16a8: ef 90 pop r14 + 16aa: df 90 pop r13 + 16ac: cf 90 pop r12 + 16ae: 08 95 ret + +000016b0 : + [BUTTON_ACTION_STORE_MEM] = "STORE_MEM", + [BUTTON_ACTION_RECALL_MEM] = "RECALL_MEM", +}; + +static void ExecuteButtonAction(ButtonActionEnum ButtonAction) +{ + 16b0: ff 92 push r15 + 16b2: 0f 93 push r16 + 16b4: 1f 93 push r17 + 16b6: cf 93 push r28 + 16b8: df 93 push r29 + 16ba: cd b7 in r28, 0x3d ; 61 + 16bc: de b7 in r29, 0x3e ; 62 + 16be: a0 97 sbiw r28, 0x20 ; 32 + 16c0: cd bf out 0x3d, r28 ; 61 + 16c2: de bf out 0x3e, r29 ; 62 + uint8_t UidBuffer[32]; + + if (ButtonAction == BUTTON_ACTION_UID_RANDOM) { + 16c4: 81 30 cpi r24, 0x01 ; 1 + 16c6: e9 f0 breq .+58 ; 0x1702 + for (uint8_t i=0; i + 16cc: 55 c0 rjmp .+170 ; 0x1778 + UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF; + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_INCREMENT) { + 16ce: 83 30 cpi r24, 0x03 ; 3 + 16d0: 09 f4 brne .+2 ; 0x16d4 + 16d2: 74 c0 rjmp .+232 ; 0x17bc + UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF; + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_DECREMENT) { + 16d4: 84 30 cpi r24, 0x04 ; 4 + 16d6: 79 f1 breq .+94 ; 0x1736 + UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF; + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_DECREMENT) { + 16d8: 85 30 cpi r24, 0x05 ; 5 + 16da: 09 f4 brne .+2 ; 0x16de + 16dc: 94 c0 rjmp .+296 ; 0x1806 + UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF; + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_CYCLE_SETTINGS) { + 16de: 86 30 cpi r24, 0x06 ; 6 + 16e0: 09 f4 brne .+2 ; 0x16e4 + 16e2: b3 c0 rjmp .+358 ; 0x184a + SettingsCycle(); + } else if (ButtonAction == BUTTON_ACTION_STORE_MEM) { + 16e4: 87 30 cpi r24, 0x07 ; 7 + 16e6: 09 f4 brne .+2 ; 0x16ea + 16e8: b2 c0 rjmp .+356 ; 0x184e + MemoryStore(); + } else if (ButtonAction == BUTTON_ACTION_RECALL_MEM) { + 16ea: 88 30 cpi r24, 0x08 ; 8 + 16ec: 09 f4 brne .+2 ; 0x16f0 + 16ee: 89 c0 rjmp .+274 ; 0x1802 + MemoryRecall(); + } +} + 16f0: a0 96 adiw r28, 0x20 ; 32 + 16f2: cd bf out 0x3d, r28 ; 61 + 16f4: de bf out 0x3e, r29 ; 62 + 16f6: df 91 pop r29 + 16f8: cf 91 pop r28 + 16fa: 1f 91 pop r17 + 16fc: 0f 91 pop r16 + 16fe: ff 90 pop r15 + 1700: 08 95 ret +static void ExecuteButtonAction(ButtonActionEnum ButtonAction) +{ + uint8_t UidBuffer[32]; + + if (ButtonAction == BUTTON_ACTION_UID_RANDOM) { + for (uint8_t i=0; i + 170a: a3 c0 rjmp .+326 ; 0x1852 + 170c: f1 2c mov r15, r1 + 170e: 8e 01 movw r16, r28 + 1710: 0f 5f subi r16, 0xFF ; 255 + 1712: 1f 4f sbci r17, 0xFF ; 255 + UidBuffer[i] = RandomGetByte(); + 1714: b1 da rcall .-2718 ; 0xc78 + 1716: f8 01 movw r30, r16 + 1718: ef 0d add r30, r15 + 171a: f1 1d adc r31, r1 + 171c: 80 83 st Z, r24 +static void ExecuteButtonAction(ButtonActionEnum ButtonAction) +{ + uint8_t UidBuffer[32]; + + if (ButtonAction == BUTTON_ACTION_UID_RANDOM) { + for (uint8_t i=0; i +INLINE void ApplicationGetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationGetUidFunc(Uid); +} + +INLINE void ApplicationSetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationSetUidFunc(Uid); + 1728: e0 91 01 29 lds r30, 0x2901 + 172c: f0 91 02 29 lds r31, 0x2902 + 1730: c8 01 movw r24, r16 + 1732: 09 95 icall + 1734: dd cf rjmp .-70 ; 0x16f0 + ActiveConfiguration.ApplicationResetFunc(); + //LogEntry(LOG_INFO_APP_RESET, NULL, 0); +} + +INLINE void ApplicationGetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationGetUidFunc(Uid); + 1736: e0 91 ff 28 lds r30, 0x28FF + 173a: f0 91 00 29 lds r31, 0x2900 + 173e: 8e 01 movw r16, r28 + 1740: 0f 5f subi r16, 0xFF ; 255 + 1742: 1f 4f sbci r17, 0xFF ; 255 + 1744: c8 01 movw r24, r16 + 1746: 09 95 icall + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i; + + for (i=0; i + 1750: f8 01 movw r30, r16 + [BUTTON_ACTION_CYCLE_SETTINGS] = "CYCLE_SETTINGS", + [BUTTON_ACTION_STORE_MEM] = "STORE_MEM", + [BUTTON_ACTION_RECALL_MEM] = "RECALL_MEM", +}; + +static void ExecuteButtonAction(ButtonActionEnum ButtonAction) + 1752: ce 01 movw r24, r28 + 1754: 02 96 adiw r24, 0x02 ; 2 + 1756: 21 50 subi r18, 0x01 ; 1 + 1758: 82 0f add r24, r18 + 175a: 91 1d adc r25, r1 + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + 175c: 21 e0 ldi r18, 0x01 ; 1 + uint8_t i; + + for (i=0; i + if (UidBuffer[i] == 0x00) { + 1762: 30 81 ld r19, Z + 1764: 21 e0 ldi r18, 0x01 ; 1 + 1766: 31 11 cpse r19, r1 + 1768: 20 e0 ldi r18, 0x00 ; 0 + Carry = 1; + } else { + Carry = 0; + } + + UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF; + 176a: 31 50 subi r19, 0x01 ; 1 + 176c: 30 83 st Z, r19 + 176e: 31 96 adiw r30, 0x01 ; 1 + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i; + + for (i=0; i + 1776: d8 cf rjmp .-80 ; 0x1728 + 1778: e0 91 ff 28 lds r30, 0x28FF + 177c: f0 91 00 29 lds r31, 0x2900 + 1780: 8e 01 movw r16, r28 + 1782: 0f 5f subi r16, 0xFF ; 255 + 1784: 1f 4f sbci r17, 0xFF ; 255 + 1786: c8 01 movw r24, r16 + 1788: 09 95 icall + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_INCREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i; + + for (i=0; i + 1792: f8 01 movw r30, r16 + [BUTTON_ACTION_CYCLE_SETTINGS] = "CYCLE_SETTINGS", + [BUTTON_ACTION_STORE_MEM] = "STORE_MEM", + [BUTTON_ACTION_RECALL_MEM] = "RECALL_MEM", +}; + +static void ExecuteButtonAction(ButtonActionEnum ButtonAction) + 1794: ce 01 movw r24, r28 + 1796: 02 96 adiw r24, 0x02 ; 2 + 1798: 21 50 subi r18, 0x01 ; 1 + 179a: 82 0f add r24, r18 + 179c: 91 1d adc r25, r1 + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_INCREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + 179e: 21 e0 ldi r18, 0x01 ; 1 + uint8_t i; + + for (i=0; i + if (UidBuffer[i] == 0xFF) { + 17a4: 30 81 ld r19, Z + 17a6: 21 e0 ldi r18, 0x01 ; 1 + 17a8: 3f 3f cpi r19, 0xFF ; 255 + 17aa: 09 f0 breq .+2 ; 0x17ae + 17ac: 20 e0 ldi r18, 0x00 ; 0 + Carry = 1; + } else { + Carry = 0; + } + + UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF; + 17ae: 3f 5f subi r19, 0xFF ; 255 + 17b0: 30 83 st Z, r19 + 17b2: 31 96 adiw r30, 0x01 ; 1 + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_INCREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i; + + for (i=0; i + 17ba: b6 cf rjmp .-148 ; 0x1728 + 17bc: e0 91 ff 28 lds r30, 0x28FF + 17c0: f0 91 00 29 lds r31, 0x2900 + 17c4: 8e 01 movw r16, r28 + 17c6: 0f 5f subi r16, 0xFF ; 255 + 17c8: 1f 4f sbci r17, 0xFF ; 255 + 17ca: c8 01 movw r24, r16 + 17cc: 09 95 icall + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_INCREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i = ActiveConfiguration.UidSize; + 17ce: 20 91 05 29 lds r18, 0x2905 + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_INCREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + 17d2: 31 e0 ldi r19, 0x01 ; 1 + uint8_t i = ActiveConfiguration.UidSize; + + while(i-- > 0) { + 17d4: 21 50 subi r18, 0x01 ; 1 + 17d6: 08 f4 brcc .+2 ; 0x17da + 17d8: a7 cf rjmp .-178 ; 0x1728 + if (Carry) { + 17da: 33 23 and r19, r19 + 17dc: d9 f3 breq .-10 ; 0x17d4 + if (UidBuffer[i] == 0xFF) { + 17de: 82 2f mov r24, r18 + 17e0: 90 e0 ldi r25, 0x00 ; 0 + 17e2: f8 01 movw r30, r16 + 17e4: e8 0f add r30, r24 + 17e6: f9 1f adc r31, r25 + 17e8: 40 81 ld r20, Z + 17ea: 31 e0 ldi r19, 0x01 ; 1 + 17ec: 4f 3f cpi r20, 0xFF ; 255 + 17ee: 09 f0 breq .+2 ; 0x17f2 + 17f0: 30 e0 ldi r19, 0x00 ; 0 + Carry = 1; + } else { + Carry = 0; + } + + UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF; + 17f2: f8 01 movw r30, r16 + 17f4: e8 0f add r30, r24 + 17f6: f9 1f adc r31, r25 + 17f8: 4f 5f subi r20, 0xFF ; 255 + 17fa: 40 83 st Z, r20 + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_INCREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i = ActiveConfiguration.UidSize; + + while(i-- > 0) { + 17fc: 21 50 subi r18, 0x01 ; 1 + 17fe: 68 f7 brcc .-38 ; 0x17da + 1800: 93 cf rjmp .-218 ; 0x1728 + } else if (ButtonAction == BUTTON_ACTION_CYCLE_SETTINGS) { + SettingsCycle(); + } else if (ButtonAction == BUTTON_ACTION_STORE_MEM) { + MemoryStore(); + } else if (ButtonAction == BUTTON_ACTION_RECALL_MEM) { + MemoryRecall(); + 1802: 18 db rcall .-2512 ; 0xe34 + 1804: 75 cf rjmp .-278 ; 0x16f0 + 1806: e0 91 ff 28 lds r30, 0x28FF + 180a: f0 91 00 29 lds r31, 0x2900 + 180e: 8e 01 movw r16, r28 + 1810: 0f 5f subi r16, 0xFF ; 255 + 1812: 1f 4f sbci r17, 0xFF ; 255 + 1814: c8 01 movw r24, r16 + 1816: 09 95 icall + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i = ActiveConfiguration.UidSize; + 1818: 20 91 05 29 lds r18, 0x2905 + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + 181c: 31 e0 ldi r19, 0x01 ; 1 + uint8_t i = ActiveConfiguration.UidSize; + + while(i-- > 0) { + 181e: 21 50 subi r18, 0x01 ; 1 + 1820: 08 f4 brcc .+2 ; 0x1824 + 1822: 82 cf rjmp .-252 ; 0x1728 + if (Carry) { + 1824: 33 23 and r19, r19 + 1826: d9 f3 breq .-10 ; 0x181e + if (UidBuffer[i] == 0x00) { + 1828: 82 2f mov r24, r18 + 182a: 90 e0 ldi r25, 0x00 ; 0 + 182c: f8 01 movw r30, r16 + 182e: e8 0f add r30, r24 + 1830: f9 1f adc r31, r25 + 1832: 40 81 ld r20, Z + 1834: 31 e0 ldi r19, 0x01 ; 1 + 1836: 41 11 cpse r20, r1 + 1838: 30 e0 ldi r19, 0x00 ; 0 + Carry = 1; + } else { + Carry = 0; + } + + UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF; + 183a: f8 01 movw r30, r16 + 183c: e8 0f add r30, r24 + 183e: f9 1f adc r31, r25 + 1840: 41 50 subi r20, 0x01 ; 1 + 1842: 40 83 st Z, r20 + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i = ActiveConfiguration.UidSize; + + while(i-- > 0) { + 1844: 21 50 subi r18, 0x01 ; 1 + 1846: 70 f7 brcc .-36 ; 0x1824 + 1848: 6f cf rjmp .-290 ; 0x1728 + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_CYCLE_SETTINGS) { + SettingsCycle(); + 184a: 50 d2 rcall .+1184 ; 0x1cec + 184c: 51 cf rjmp .-350 ; 0x16f0 + } else if (ButtonAction == BUTTON_ACTION_STORE_MEM) { + MemoryStore(); + 184e: e7 db rcall .-2098 ; 0x101e + 1850: 4f cf rjmp .-354 ; 0x16f0 + 1852: 8e 01 movw r16, r28 + 1854: 0f 5f subi r16, 0xFF ; 255 + 1856: 1f 4f sbci r17, 0xFF ; 255 + 1858: 67 cf rjmp .-306 ; 0x1728 + +0000185a : + } +} + +void ButtonInit(void) +{ + BUTTON_PORT.DIRCLR = BUTTON_MASK; + 185a: e0 e0 ldi r30, 0x00 ; 0 + 185c: f6 e0 ldi r31, 0x06 ; 6 + 185e: 80 e4 ldi r24, 0x40 ; 64 + 1860: 82 83 std Z+2, r24 ; 0x02 + BUTTON_PORT.BUTTON_PINCTRL = PORT_OPC_PULLUP_gc; + 1862: 88 e1 ldi r24, 0x18 ; 24 + 1864: 86 8b std Z+22, r24 ; 0x16 + 1866: 08 95 ret + +00001868 : +} + +void ButtonTick(void) +{ + static uint8_t PressTickCounter = 0; + uint8_t ThisButtonState = ~BUTTON_PORT.IN; + 1868: 80 91 08 06 lds r24, 0x0608 + + if (ThisButtonState & BUTTON_MASK) { + 186c: 86 ff sbrs r24, 6 + 186e: 08 c0 rjmp .+16 ; 0x1880 + /* Button is still pressed, ignore */ + } + } else if (!(ThisButtonState & BUTTON_MASK)) { + /* Button is currently not being pressed. Check if PressTickCounter contains + * a recent short button press. */ + if ( (PressTickCounter > 0) && (PressTickCounter <= LONG_PRESS_TICK_COUNT) ) { + 1870: 80 91 92 24 lds r24, 0x2492 + 1874: 81 50 subi r24, 0x01 ; 1 + 1876: 8a 30 cpi r24, 0x0A ; 10 + 1878: a8 f0 brcs .+42 ; 0x18a4 + /* We have a short button press */ + ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonAction); + } + + PressTickCounter = 0; + 187a: 10 92 92 24 sts 0x2492, r1 + 187e: 08 95 ret + static uint8_t PressTickCounter = 0; + uint8_t ThisButtonState = ~BUTTON_PORT.IN; + + if (ThisButtonState & BUTTON_MASK) { + /* Button is currently pressed */ + if (PressTickCounter < LONG_PRESS_TICK_COUNT) { + 1880: 80 91 92 24 lds r24, 0x2492 + 1884: 8a 30 cpi r24, 0x0A ; 10 + 1886: 50 f0 brcs .+20 ; 0x189c + /* Count ticks while button is being pressed */ + PressTickCounter++; + } else if (PressTickCounter == LONG_PRESS_TICK_COUNT) { + 1888: 8a 30 cpi r24, 0x0A ; 10 + 188a: c9 f7 brne .-14 ; 0x187e + /* Long button press detected execute button action and advance PressTickCounter + * to an invalid state. */ + ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonLongAction); + 188c: e0 91 0a 29 lds r30, 0x290A + 1890: f0 91 0b 29 lds r31, 0x290B + 1894: 81 81 ldd r24, Z+1 ; 0x01 + 1896: 0c df rcall .-488 ; 0x16b0 + PressTickCounter++; + 1898: 80 91 92 24 lds r24, 0x2492 + 189c: 8f 5f subi r24, 0xFF ; 255 + 189e: 80 93 92 24 sts 0x2492, r24 + 18a2: 08 95 ret + } else if (!(ThisButtonState & BUTTON_MASK)) { + /* Button is currently not being pressed. Check if PressTickCounter contains + * a recent short button press. */ + if ( (PressTickCounter > 0) && (PressTickCounter <= LONG_PRESS_TICK_COUNT) ) { + /* We have a short button press */ + ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonAction); + 18a4: e0 91 0a 29 lds r30, 0x290A + 18a8: f0 91 0b 29 lds r31, 0x290B + 18ac: 80 81 ld r24, Z + 18ae: 00 df rcall .-512 ; 0x16b0 + 18b0: e4 cf rjmp .-56 ; 0x187a + +000018b2 : + PressTickCounter = 0; + } +} + +void ButtonGetActionList(char* ListOut, uint16_t BufferSize) +{ + 18b2: cf 93 push r28 + 18b4: df 93 push r29 + 18b6: ec 01 movw r28, r24 + uint8_t i; + + /* Account for '\0' */ + BufferSize--; + 18b8: 61 50 subi r22, 0x01 ; 1 + 18ba: 71 09 sbc r23, r1 + 18bc: 80 e0 ldi r24, 0x00 ; 0 + 18be: 90 e0 ldi r25, 0x00 ; 0 + BufferSize--; + } + + if ( i < (BUTTON_ACTION_COUNT - 1) ) { + /* No comma on last configuration */ + *ListOut++ = ','; + 18c0: 3c e2 ldi r19, 0x2C ; 44 + + /* Account for '\0' */ + BufferSize--; + + for (i=0; i sizeof(ButtonActionTable[i]) ) { + 18d8: 24 91 lpm r18, Z + 18da: 22 23 and r18, r18 + 18dc: 81 f0 breq .+32 ; 0x18fe + 18de: 61 32 cpi r22, 0x21 ; 33 + 18e0: 71 05 cpc r23, r1 + 18e2: 68 f0 brcs .+26 ; 0x18fe + 18e4: de 01 movw r26, r28 + 18e6: 03 c0 rjmp .+6 ; 0x18ee + 18e8: 60 32 cpi r22, 0x20 ; 32 + 18ea: 71 05 cpc r23, r1 + 18ec: 41 f0 breq .+16 ; 0x18fe + /* While not end-of-string and enough buffer to + * put a complete configuration name */ + *ListOut++ = c; + 18ee: 2d 93 st X+, r18 + 18f0: ed 01 movw r28, r26 + ActionName++; + 18f2: 31 96 adiw r30, 0x01 ; 1 + BufferSize--; + 18f4: 61 50 subi r22, 0x01 ; 1 + 18f6: 71 09 sbc r23, r1 + + for (i=0; i sizeof(ButtonActionTable[i]) ) { + 18f8: 24 91 lpm r18, Z + 18fa: 21 11 cpse r18, r1 + 18fc: f5 cf rjmp .-22 ; 0x18e8 + *ListOut++ = c; + ActionName++; + BufferSize--; + } + + if ( i < (BUTTON_ACTION_COUNT - 1) ) { + 18fe: 88 30 cpi r24, 0x08 ; 8 + 1900: 91 05 cpc r25, r1 + 1902: 21 f4 brne .+8 ; 0x190c + *ListOut++ = ','; + BufferSize--; + } + } + + *ListOut = '\0'; + 1904: 18 82 st Y, r1 +} + 1906: df 91 pop r29 + 1908: cf 91 pop r28 + 190a: 08 95 ret + BufferSize--; + } + + if ( i < (BUTTON_ACTION_COUNT - 1) ) { + /* No comma on last configuration */ + *ListOut++ = ','; + 190c: 39 93 st Y+, r19 + BufferSize--; + 190e: 61 50 subi r22, 0x01 ; 1 + 1910: 71 09 sbc r23, r1 + 1912: 01 96 adiw r24, 0x01 ; 1 + 1914: d6 cf rjmp .-84 ; 0x18c2 + +00001916 : + + *ListOut = '\0'; +} + +void ButtonSetActionById(ButtonTypeEnum Type, ButtonActionEnum Action) +{ + 1916: 88 23 and r24, r24 + 1918: 19 f0 breq .+6 ; 0x1920 + 191a: 81 30 cpi r24, 0x01 ; 1 + 191c: 91 f0 breq .+36 ; 0x1942 + 191e: 08 95 ret + } +#else + /* Write button action to all settings when using global settings */ + for (uint8_t i=0; i: + } +#endif +} + +void ButtonGetActionByName(ButtonTypeEnum Type, char* ActionOut, uint16_t BufferSize) +{ + 1964: fb 01 movw r30, r22 + if (Type == BUTTON_PRESS_SHORT) { + 1966: 88 23 and r24, r24 + 1968: 21 f0 breq .+8 ; 0x1972 + strncpy_P(ActionOut, ButtonActionTable[GlobalSettings.ActiveSettingPtr->ButtonAction], BufferSize); + } else if (Type == BUTTON_PRESS_LONG) { + 196a: 81 30 cpi r24, 0x01 ; 1 + 196c: 81 f0 breq .+32 ; 0x198e + strncpy_P(ActionOut, ButtonActionTable[GlobalSettings.ActiveSettingPtr->ButtonLongAction], BufferSize); + } else { + /* Should not happen (TM) */ + *ActionOut = '\0'; + 196e: 10 82 st Z, r1 + 1970: 08 95 ret +} + +void ButtonGetActionByName(ButtonTypeEnum Type, char* ActionOut, uint16_t BufferSize) +{ + if (Type == BUTTON_PRESS_SHORT) { + strncpy_P(ActionOut, ButtonActionTable[GlobalSettings.ActiveSettingPtr->ButtonAction], BufferSize); + 1972: a0 91 0a 29 lds r26, 0x290A + 1976: b0 91 0b 29 lds r27, 0x290B + 197a: 6c 91 ld r22, X + } else if (Type == BUTTON_PRESS_LONG) { + strncpy_P(ActionOut, ButtonActionTable[GlobalSettings.ActiveSettingPtr->ButtonLongAction], BufferSize); + 197c: 80 e2 ldi r24, 0x20 ; 32 + 197e: 68 9f mul r22, r24 + 1980: b0 01 movw r22, r0 + 1982: 11 24 eor r1, r1 + 1984: 6a 59 subi r22, 0x9A ; 154 + 1986: 7c 4f sbci r23, 0xFC ; 252 + 1988: cf 01 movw r24, r30 + 198a: 0c 94 ee 2d jmp 0x5bdc ; 0x5bdc + 198e: a0 91 0a 29 lds r26, 0x290A + 1992: b0 91 0b 29 lds r27, 0x290B + 1996: 11 96 adiw r26, 0x01 ; 1 + 1998: 6c 91 ld r22, X + 199a: f0 cf rjmp .-32 ; 0x197c + +0000199c : + *ActionOut = '\0'; + } +} + +bool ButtonSetActionByName(ButtonTypeEnum Type, const char* Action) +{ + 199c: 1f 93 push r17 + 199e: cf 93 push r28 + 19a0: df 93 push r29 + 19a2: 18 2f mov r17, r24 + 19a4: eb 01 movw r28, r22 + uint8_t i; + + for (i=0; i + 19b0: 89 2b or r24, r25 + 19b2: f1 f1 breq .+124 ; 0x1a30 + 19b4: 66 e8 ldi r22, 0x86 ; 134 + 19b6: 73 e0 ldi r23, 0x03 ; 3 + 19b8: ce 01 movw r24, r28 + 19ba: 0e 94 d5 2d call 0x5baa ; 0x5baa + 19be: 89 2b or r24, r25 + 19c0: 09 f4 brne .+2 ; 0x19c4 + 19c2: 3e c0 rjmp .+124 ; 0x1a40 + 19c4: 66 ea ldi r22, 0xA6 ; 166 + 19c6: 73 e0 ldi r23, 0x03 ; 3 + 19c8: ce 01 movw r24, r28 + 19ca: 0e 94 d5 2d call 0x5baa ; 0x5baa + 19ce: 89 2b or r24, r25 + 19d0: c9 f1 breq .+114 ; 0x1a44 + 19d2: 66 ec ldi r22, 0xC6 ; 198 + 19d4: 73 e0 ldi r23, 0x03 ; 3 + 19d6: ce 01 movw r24, r28 + 19d8: 0e 94 d5 2d call 0x5baa ; 0x5baa + 19dc: 89 2b or r24, r25 + 19de: a1 f1 breq .+104 ; 0x1a48 + 19e0: 66 ee ldi r22, 0xE6 ; 230 + 19e2: 73 e0 ldi r23, 0x03 ; 3 + 19e4: ce 01 movw r24, r28 + 19e6: 0e 94 d5 2d call 0x5baa ; 0x5baa + 19ea: 89 2b or r24, r25 + 19ec: 79 f1 breq .+94 ; 0x1a4c + 19ee: 66 e0 ldi r22, 0x06 ; 6 + 19f0: 74 e0 ldi r23, 0x04 ; 4 + 19f2: ce 01 movw r24, r28 + 19f4: 0e 94 d5 2d call 0x5baa ; 0x5baa + 19f8: 89 2b or r24, r25 + 19fa: 51 f1 breq .+84 ; 0x1a50 + 19fc: 66 e2 ldi r22, 0x26 ; 38 + 19fe: 74 e0 ldi r23, 0x04 ; 4 + 1a00: ce 01 movw r24, r28 + 1a02: 0e 94 d5 2d call 0x5baa ; 0x5baa + 1a06: 89 2b or r24, r25 + 1a08: 29 f1 breq .+74 ; 0x1a54 + 1a0a: 66 e4 ldi r22, 0x46 ; 70 + 1a0c: 74 e0 ldi r23, 0x04 ; 4 + 1a0e: ce 01 movw r24, r28 + 1a10: 0e 94 d5 2d call 0x5baa ; 0x5baa + 1a14: 89 2b or r24, r25 + 1a16: 01 f1 breq .+64 ; 0x1a58 + 1a18: 66 e6 ldi r22, 0x66 ; 102 + 1a1a: 74 e0 ldi r23, 0x04 ; 4 + 1a1c: ce 01 movw r24, r28 + 1a1e: 0e 94 d5 2d call 0x5baa ; 0x5baa + 1a22: 89 2b or r24, r25 + 1a24: d9 f0 breq .+54 ; 0x1a5c + return true; + } + } + + /* Button action not found */ + return false; + 1a26: 80 e0 ldi r24, 0x00 ; 0 +} + 1a28: df 91 pop r29 + 1a2a: cf 91 pop r28 + 1a2c: 1f 91 pop r17 + 1a2e: 08 95 ret + +bool ButtonSetActionByName(ButtonTypeEnum Type, const char* Action) +{ + uint8_t i; + + for (i=0; i + return true; + 1a36: 81 e0 ldi r24, 0x01 ; 1 + } + } + + /* Button action not found */ + return false; +} + 1a38: df 91 pop r29 + 1a3a: cf 91 pop r28 + 1a3c: 1f 91 pop r17 + 1a3e: 08 95 ret + +bool ButtonSetActionByName(ButtonTypeEnum Type, const char* Action) +{ + uint8_t i; + + for (i=0; i + 1a44: 62 e0 ldi r22, 0x02 ; 2 + 1a46: f5 cf rjmp .-22 ; 0x1a32 + 1a48: 63 e0 ldi r22, 0x03 ; 3 + 1a4a: f3 cf rjmp .-26 ; 0x1a32 + 1a4c: 64 e0 ldi r22, 0x04 ; 4 + 1a4e: f1 cf rjmp .-30 ; 0x1a32 + 1a50: 65 e0 ldi r22, 0x05 ; 5 + 1a52: ef cf rjmp .-34 ; 0x1a32 + 1a54: 66 e0 ldi r22, 0x06 ; 6 + 1a56: ed cf rjmp .-38 ; 0x1a32 + 1a58: 67 e0 ldi r22, 0x07 ; 7 + 1a5a: eb cf rjmp .-42 ; 0x1a32 + if (strcmp_P(Action, ButtonActionTable[i]) == 0) { + 1a5c: 68 e0 ldi r22, 0x08 ; 8 + 1a5e: e9 cf rjmp .-46 ; 0x1a32 + +00001a60 : + [LOG_MODE_MEMORY] = "MEMORY", + [LOG_MODE_TERMINAL] = "TERMINAL" +}; + +static void LogFuncOff(LogEntryEnum Entry, void* Data, uint8_t Length) +{ + 1a60: 08 95 ret + +00001a62 : + LogSetModeById(LOG_MODE_OFF); + } +} + +static void LogFuncTerminal(LogEntryEnum Entry, void* Data, uint8_t Length) +{ + 1a62: 1f 93 push r17 + 1a64: cf 93 push r28 + 1a66: df 93 push r29 + 1a68: eb 01 movw r28, r22 + 1a6a: 14 2f mov r17, r20 +void EVENT_USB_Device_Disconnect(void); +void EVENT_USB_Device_ConfigurationChanged(void); +void EVENT_USB_Device_ControlRequest(void); + +INLINE void TerminalSendChar(char c) { CDC_Device_SendByte(&TerminalHandle, c); } +INLINE void TerminalSendByte(uint8_t Byte) { CDC_Device_SendByte(&TerminalHandle, Byte); } + 1a6c: 68 2f mov r22, r24 + 1a6e: 80 e0 ldi r24, 0x00 ; 0 + 1a70: 90 e2 ldi r25, 0x20 ; 32 + 1a72: 0e 94 bf 2b call 0x577e ; 0x577e + 1a76: 61 2f mov r22, r17 + 1a78: 80 e0 ldi r24, 0x00 ; 0 + 1a7a: 90 e2 ldi r25, 0x20 ; 32 + 1a7c: 0e 94 bf 2b call 0x577e ; 0x577e + TerminalSendByte((uint8_t) Entry); + TerminalSendByte((uint8_t) Length); + TerminalSendBlock(Data, Length); + 1a80: 61 2f mov r22, r17 + 1a82: 70 e0 ldi r23, 0x00 ; 0 + 1a84: ce 01 movw r24, r28 +} + 1a86: df 91 pop r29 + 1a88: cf 91 pop r28 + 1a8a: 1f 91 pop r17 + +static void LogFuncTerminal(LogEntryEnum Entry, void* Data, uint8_t Length) +{ + TerminalSendByte((uint8_t) Entry); + TerminalSendByte((uint8_t) Length); + TerminalSendBlock(Data, Length); + 1a8c: 8e c3 rjmp .+1820 ; 0x21aa + +00001a8e : + LogMemClear(); + LogSetModeById(GlobalSettings.ActiveSettingPtr->LogMode); +} + +void LogTick(void) +{ + 1a8e: 08 95 ret + +00001a90 : + +} + +void LogTask(void) +{ + 1a90: 08 95 ret + +00001a92 : + +} + +bool LogMemLoadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) +{ + if (BlockAddress < sizeof(LogMem)) { + 1a92: 41 15 cp r20, r1 + 1a94: e4 e0 ldi r30, 0x04 ; 4 + 1a96: 5e 07 cpc r21, r30 + 1a98: 61 05 cpc r22, r1 + 1a9a: 71 05 cpc r23, r1 + 1a9c: 80 f4 brcc .+32 ; 0x1abe + uint8_t* DataPtr = (uint8_t*) Buffer; + uint8_t* MemPtr = &LogMem[BlockAddress]; + 1a9e: 4d 56 subi r20, 0x6D ; 109 + 1aa0: 5b 4d sbci r21, 0xDB ; 219 + + while(ByteCount-- > 0) { + 1aa2: 21 15 cp r18, r1 + 1aa4: 31 05 cpc r19, r1 + 1aa6: 49 f0 breq .+18 ; 0x1aba + 1aa8: da 01 movw r26, r20 +void LogTask(void) +{ + +} + +bool LogMemLoadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) + 1aaa: 28 0f add r18, r24 + 1aac: 39 1f adc r19, r25 +{ + if (BlockAddress < sizeof(LogMem)) { + uint8_t* DataPtr = (uint8_t*) Buffer; + 1aae: fc 01 movw r30, r24 + uint8_t* MemPtr = &LogMem[BlockAddress]; + + while(ByteCount-- > 0) { + *DataPtr++ = *MemPtr++; + 1ab0: 8d 91 ld r24, X+ + 1ab2: 81 93 st Z+, r24 +{ + if (BlockAddress < sizeof(LogMem)) { + uint8_t* DataPtr = (uint8_t*) Buffer; + uint8_t* MemPtr = &LogMem[BlockAddress]; + + while(ByteCount-- > 0) { + 1ab4: e2 17 cp r30, r18 + 1ab6: f3 07 cpc r31, r19 + 1ab8: d9 f7 brne .-10 ; 0x1ab0 + *DataPtr++ = *MemPtr++; + } + + return true; + 1aba: 81 e0 ldi r24, 0x01 ; 1 + 1abc: 08 95 ret + } else { + return false; + 1abe: 80 e0 ldi r24, 0x00 ; 0 + } +} + 1ac0: 08 95 ret + +00001ac2 : + +void LogMemClear(void) +{ + 1ac2: e3 e9 ldi r30, 0x93 ; 147 + 1ac4: f4 e2 ldi r31, 0x24 ; 36 + uint16_t i; + + for (i=0; i + LogMem[i] = (uint8_t) LOG_EMPTY; + } + + LogMemPtr = LogMem; + 1ad2: 83 e9 ldi r24, 0x93 ; 147 + 1ad4: 94 e2 ldi r25, 0x24 ; 36 + 1ad6: 80 93 93 28 sts 0x2893, r24 + 1ada: 90 93 94 28 sts 0x2894, r25 + LogMemLeft = sizeof(LogMem); + 1ade: 80 e0 ldi r24, 0x00 ; 0 + 1ae0: 94 e0 ldi r25, 0x04 ; 4 + 1ae2: 80 93 95 28 sts 0x2895, r24 + 1ae6: 90 93 96 28 sts 0x2896, r25 + 1aea: 08 95 ret + +00001aec : +} + +uint16_t LogMemFree(void) +{ + return LogMemLeft; +} + 1aec: 80 91 95 28 lds r24, 0x2895 + 1af0: 90 91 96 28 lds r25, 0x2896 + 1af4: 08 95 ret + +00001af6 : + +void LogSetModeById(LogModeEnum Mode) +{ + GlobalSettings.ActiveSettingPtr->LogMode = Mode; + 1af6: e0 91 0a 29 lds r30, 0x290A + 1afa: f0 91 0b 29 lds r31, 0x290B + 1afe: 82 83 std Z+2, r24 ; 0x02 + + switch(Mode) { + 1b00: 81 30 cpi r24, 0x01 ; 1 + 1b02: 91 f0 breq .+36 ; 0x1b28 + 1b04: 38 f4 brcc .+14 ; 0x1b14 + case LOG_MODE_OFF: + LogFunc = LogFuncOff; + 1b06: 80 e3 ldi r24, 0x30 ; 48 + 1b08: 9d e0 ldi r25, 0x0D ; 13 + 1b0a: 80 93 07 29 sts 0x2907, r24 + 1b0e: 90 93 08 29 sts 0x2908, r25 + break; + 1b12: 08 95 ret + +void LogSetModeById(LogModeEnum Mode) +{ + GlobalSettings.ActiveSettingPtr->LogMode = Mode; + + switch(Mode) { + 1b14: 82 30 cpi r24, 0x02 ; 2 + 1b16: 09 f0 breq .+2 ; 0x1b1a + 1b18: 08 95 ret + case LOG_MODE_MEMORY: + LogFunc = LogFuncMemory; + break; + + case LOG_MODE_TERMINAL: + LogFunc = LogFuncTerminal; + 1b1a: 81 e3 ldi r24, 0x31 ; 49 + 1b1c: 9d e0 ldi r25, 0x0D ; 13 + 1b1e: 80 93 07 29 sts 0x2907, r24 + 1b22: 90 93 08 29 sts 0x2908, r25 + 1b26: 08 95 ret + case LOG_MODE_OFF: + LogFunc = LogFuncOff; + break; + + case LOG_MODE_MEMORY: + LogFunc = LogFuncMemory; + 1b28: 8b e9 ldi r24, 0x9B ; 155 + 1b2a: 9d e0 ldi r25, 0x0D ; 13 + 1b2c: 80 93 07 29 sts 0x2907, r24 + 1b30: 90 93 08 29 sts 0x2908, r25 + break; + 1b34: 08 95 ret + +00001b36 : + /* Do nothing */ +} + +static void LogFuncMemory(LogEntryEnum Entry, void* Data, uint8_t Length) +{ + if (LogMemLeft >= (Length + 2)) { + 1b36: 20 91 95 28 lds r18, 0x2895 + 1b3a: 30 91 96 28 lds r19, 0x2896 + 1b3e: e4 2f mov r30, r20 + 1b40: f0 e0 ldi r31, 0x00 ; 0 + 1b42: df 01 movw r26, r30 + 1b44: 12 96 adiw r26, 0x02 ; 2 + 1b46: 2a 17 cp r18, r26 + 1b48: 3b 07 cpc r19, r27 + 1b4a: 50 f1 brcs .+84 ; 0x1ba0 + LogMemLeft -= Length + 2; + 1b4c: 22 50 subi r18, 0x02 ; 2 + 1b4e: 31 09 sbc r19, r1 + 1b50: 2e 1b sub r18, r30 + 1b52: 3f 0b sbc r19, r31 + 1b54: 20 93 95 28 sts 0x2895, r18 + 1b58: 30 93 96 28 sts 0x2896, r19 + + uint8_t* DataPtr = (uint8_t*) Data; + + *LogMemPtr++ = (uint8_t) Entry; + 1b5c: e0 91 93 28 lds r30, 0x2893 + 1b60: f0 91 94 28 lds r31, 0x2894 + 1b64: 80 83 st Z, r24 + *LogMemPtr++ = (uint8_t) Length; + 1b66: 41 83 std Z+1, r20 ; 0x01 + 1b68: 9f 01 movw r18, r30 + 1b6a: 2e 5f subi r18, 0xFE ; 254 + 1b6c: 3f 4f sbci r19, 0xFF ; 255 + 1b6e: 20 93 93 28 sts 0x2893, r18 + 1b72: 30 93 94 28 sts 0x2894, r19 + + while(Length--) { + 1b76: 84 2f mov r24, r20 + 1b78: 81 50 subi r24, 0x01 ; 1 + 1b7a: 44 23 and r20, r20 + 1b7c: 81 f0 breq .+32 ; 0x1b9e + 1b7e: fb 01 movw r30, r22 + 1b80: d9 01 movw r26, r18 + 1b82: 98 2f mov r25, r24 + *LogMemPtr++ = *DataPtr++; + 1b84: 41 91 ld r20, Z+ + 1b86: 4d 93 st X+, r20 + uint8_t* DataPtr = (uint8_t*) Data; + + *LogMemPtr++ = (uint8_t) Entry; + *LogMemPtr++ = (uint8_t) Length; + + while(Length--) { + 1b88: 91 50 subi r25, 0x01 ; 1 + 1b8a: e0 f7 brcc .-8 ; 0x1b84 +static void LogFuncOff(LogEntryEnum Entry, void* Data, uint8_t Length) +{ + /* Do nothing */ +} + +static void LogFuncMemory(LogEntryEnum Entry, void* Data, uint8_t Length) + 1b8c: 90 e0 ldi r25, 0x00 ; 0 + 1b8e: 01 96 adiw r24, 0x01 ; 1 + 1b90: 82 0f add r24, r18 + 1b92: 93 1f adc r25, r19 + 1b94: 80 93 93 28 sts 0x2893, r24 + 1b98: 90 93 94 28 sts 0x2894, r25 + 1b9c: 08 95 ret + 1b9e: 08 95 ret + while(Length--) { + *LogMemPtr++ = *DataPtr++; + } + } else { + /* If memory full. Deactivate logmode */ + LogSetModeById(LOG_MODE_OFF); + 1ba0: 80 e0 ldi r24, 0x00 ; 0 + 1ba2: a9 cf rjmp .-174 ; 0x1af6 + +00001ba4 : + TerminalSendBlock(Data, Length); +} + +void LogInit(void) +{ + LogMemClear(); + 1ba4: 8e df rcall .-228 ; 0x1ac2 + LogSetModeById(GlobalSettings.ActiveSettingPtr->LogMode); + 1ba6: e0 91 0a 29 lds r30, 0x290A + 1baa: f0 91 0b 29 lds r31, 0x290B + 1bae: 82 81 ldd r24, Z+2 ; 0x02 + 1bb0: a2 cf rjmp .-188 ; 0x1af6 + +00001bb2 : + } + +} + +bool LogSetModeByName(const char* Name) +{ + 1bb2: cf 93 push r28 + 1bb4: df 93 push r29 + 1bb6: ec 01 movw r28, r24 + uint8_t i; + + for (i=0; i<(sizeof(LogModeTable) / sizeof(*LogModeTable)); i++) { + if (strcmp_P(Name, LogModeTable[i]) == 0) { + 1bb8: 66 e8 ldi r22, 0x86 ; 134 + 1bba: 74 e0 ldi r23, 0x04 ; 4 + 1bbc: 0e 94 d5 2d call 0x5baa ; 0x5baa + 1bc0: 89 2b or r24, r25 + 1bc2: 91 f0 breq .+36 ; 0x1be8 + 1bc4: 66 e9 ldi r22, 0x96 ; 150 + 1bc6: 74 e0 ldi r23, 0x04 ; 4 + 1bc8: ce 01 movw r24, r28 + 1bca: 0e 94 d5 2d call 0x5baa ; 0x5baa + 1bce: 89 2b or r24, r25 + 1bd0: 89 f0 breq .+34 ; 0x1bf4 + 1bd2: 66 ea ldi r22, 0xA6 ; 166 + 1bd4: 74 e0 ldi r23, 0x04 ; 4 + 1bd6: ce 01 movw r24, r28 + 1bd8: 0e 94 d5 2d call 0x5baa ; 0x5baa + 1bdc: 89 2b or r24, r25 + 1bde: 61 f0 breq .+24 ; 0x1bf8 + LogSetModeById(i); + return true; + } + } + + return false; + 1be0: 80 e0 ldi r24, 0x00 ; 0 +} + 1be2: df 91 pop r29 + 1be4: cf 91 pop r28 + 1be6: 08 95 ret + +bool LogSetModeByName(const char* Name) +{ + uint8_t i; + + for (i=0; i<(sizeof(LogModeTable) / sizeof(*LogModeTable)); i++) { + 1be8: 80 e0 ldi r24, 0x00 ; 0 + if (strcmp_P(Name, LogModeTable[i]) == 0) { + LogSetModeById(i); + 1bea: 85 df rcall .-246 ; 0x1af6 + return true; + 1bec: 81 e0 ldi r24, 0x01 ; 1 + } + } + + return false; +} + 1bee: df 91 pop r29 + 1bf0: cf 91 pop r28 + 1bf2: 08 95 ret + +bool LogSetModeByName(const char* Name) +{ + uint8_t i; + + for (i=0; i<(sizeof(LogModeTable) / sizeof(*LogModeTable)); i++) { + 1bf4: 81 e0 ldi r24, 0x01 ; 1 + 1bf6: f9 cf rjmp .-14 ; 0x1bea + if (strcmp_P(Name, LogModeTable[i]) == 0) { + 1bf8: 82 e0 ldi r24, 0x02 ; 2 + 1bfa: f7 cf rjmp .-18 ; 0x1bea + +00001bfc : + + return false; +} + +void LogGetModeByName(char* Name, uint16_t BufferSize) +{ + 1bfc: ab 01 movw r20, r22 + strncpy_P(Name, LogModeTable[GlobalSettings.ActiveSettingPtr->LogMode], BufferSize); + 1bfe: e0 91 0a 29 lds r30, 0x290A + 1c02: f0 91 0b 29 lds r31, 0x290B + 1c06: 62 81 ldd r22, Z+2 ; 0x02 + 1c08: 20 e1 ldi r18, 0x10 ; 16 + 1c0a: 62 9f mul r22, r18 + 1c0c: b0 01 movw r22, r0 + 1c0e: 11 24 eor r1, r1 + 1c10: 6a 57 subi r22, 0x7A ; 122 + 1c12: 7b 4f sbci r23, 0xFB ; 251 + 1c14: 0c 94 ee 2d jmp 0x5bdc ; 0x5bdc + +00001c18 : +} + +void LogGetModeList(char* List, uint16_t BufferSize) +{ + 1c18: 0f 93 push r16 + 1c1a: 1f 93 push r17 + 1c1c: cf 93 push r28 + 1c1e: df 93 push r29 + 1c20: ec 01 movw r28, r24 + 1c22: 8b 01 movw r16, r22 + uint8_t i; + + *List = '\0'; + 1c24: 18 82 st Y, r1 + + for (i=0; i<(sizeof(LogModeTable) / sizeof(*LogModeTable)); i++) { + strncat_P(List, LogModeTable[i], BufferSize); + 1c26: ab 01 movw r20, r22 + 1c28: 66 e8 ldi r22, 0x86 ; 134 + 1c2a: 74 e0 ldi r23, 0x04 ; 4 + 1c2c: 0e 94 de 2d call 0x5bbc ; 0x5bbc + + if (i < (sizeof(LogModeTable) / sizeof(*LogModeTable) - 1)) { + strncat_P(List, PSTR(","), BufferSize); + 1c30: a8 01 movw r20, r16 + 1c32: 66 eb ldi r22, 0xB6 ; 182 + 1c34: 74 e0 ldi r23, 0x04 ; 4 + 1c36: ce 01 movw r24, r28 + 1c38: 0e 94 de 2d call 0x5bbc ; 0x5bbc + uint8_t i; + + *List = '\0'; + + for (i=0; i<(sizeof(LogModeTable) / sizeof(*LogModeTable)); i++) { + strncat_P(List, LogModeTable[i], BufferSize); + 1c3c: a8 01 movw r20, r16 + 1c3e: 66 e9 ldi r22, 0x96 ; 150 + 1c40: 74 e0 ldi r23, 0x04 ; 4 + 1c42: ce 01 movw r24, r28 + 1c44: 0e 94 de 2d call 0x5bbc ; 0x5bbc + + if (i < (sizeof(LogModeTable) / sizeof(*LogModeTable) - 1)) { + strncat_P(List, PSTR(","), BufferSize); + 1c48: a8 01 movw r20, r16 + 1c4a: 66 eb ldi r22, 0xB6 ; 182 + 1c4c: 74 e0 ldi r23, 0x04 ; 4 + 1c4e: ce 01 movw r24, r28 + 1c50: 0e 94 de 2d call 0x5bbc ; 0x5bbc + uint8_t i; + + *List = '\0'; + + for (i=0; i<(sizeof(LogModeTable) / sizeof(*LogModeTable)); i++) { + strncat_P(List, LogModeTable[i], BufferSize); + 1c54: a8 01 movw r20, r16 + 1c56: 66 ea ldi r22, 0xA6 ; 166 + 1c58: 74 e0 ldi r23, 0x04 ; 4 + 1c5a: ce 01 movw r24, r28 + + if (i < (sizeof(LogModeTable) / sizeof(*LogModeTable) - 1)) { + strncat_P(List, PSTR(","), BufferSize); + } + } +} + 1c5c: df 91 pop r29 + 1c5e: cf 91 pop r28 + 1c60: 1f 91 pop r17 + 1c62: 0f 91 pop r16 + uint8_t i; + + *List = '\0'; + + for (i=0; i<(sizeof(LogModeTable) / sizeof(*LogModeTable)); i++) { + strncat_P(List, LogModeTable[i], BufferSize); + 1c64: 0c 94 de 2d jmp 0x5bbc ; 0x5bbc + +00001c68 : + .LEDGreenFunction = DEFAULT_GREEN_LED_ACTION + } } +}; + +void SettingsLoad(void) { + eeprom_read_block(&GlobalSettings, &StoredSettings, sizeof(SettingsType)); + 1c68: 43 e3 ldi r20, 0x33 ; 51 + 1c6a: 50 e0 ldi r21, 0x00 ; 0 + 1c6c: 60 e0 ldi r22, 0x00 ; 0 + 1c6e: 70 e0 ldi r23, 0x00 ; 0 + 1c70: 89 e0 ldi r24, 0x09 ; 9 + 1c72: 99 e2 ldi r25, 0x29 ; 41 + 1c74: 0c 94 00 30 jmp 0x6000 ; 0x6000 <__eerd_block_x32a4u> + +00001c78 : +} + +void SettingsSave(void) { +#if ENABLE_EEPROM_SETTINGS + eeprom_write_block(&GlobalSettings, &StoredSettings, sizeof(SettingsType)); + 1c78: 43 e3 ldi r20, 0x33 ; 51 + 1c7a: 50 e0 ldi r21, 0x00 ; 0 + 1c7c: 60 e0 ldi r22, 0x00 ; 0 + 1c7e: 70 e0 ldi r23, 0x00 ; 0 + 1c80: 89 e0 ldi r24, 0x09 ; 9 + 1c82: 99 e2 ldi r25, 0x29 ; 41 + 1c84: 0c 94 0b 30 jmp 0x6016 ; 0x6016 <__eewr_block_x32a4u> + +00001c88 : + break; + } + } +} + +bool SettingsSetActiveById(uint8_t Setting) { + 1c88: 1f 93 push r17 + 1c8a: cf 93 push r28 + 1c8c: df 93 push r29 + 1c8e: 1f 92 push r1 + 1c90: cd b7 in r28, 0x3d ; 61 + 1c92: de b7 in r29, 0x3e ; 62 + if ( (Setting >= SETTINGS_FIRST) && (Setting <= SETTINGS_LAST) ) { + 1c94: 18 2f mov r17, r24 + 1c96: 11 50 subi r17, 0x01 ; 1 + 1c98: 18 30 cpi r17, 0x08 ; 8 + 1c9a: 30 f0 brcs .+12 ; 0x1ca8 + /* Notify LED. blink according to current setting */ + LEDTrigger(LED_SETTING_CHANGE, LED_BLINK + SettingIdx); + + return true; + } else { + return false; + 1c9c: 80 e0 ldi r24, 0x00 ; 0 + } +} + 1c9e: 0f 90 pop r0 + 1ca0: df 91 pop r29 + 1ca2: cf 91 pop r28 + 1ca4: 1f 91 pop r17 + 1ca6: 08 95 ret + +bool SettingsSetActiveById(uint8_t Setting) { + if ( (Setting >= SETTINGS_FIRST) && (Setting <= SETTINGS_LAST) ) { + uint8_t SettingIdx = SETTING_TO_INDEX(Setting); + /* Store current memory contents permanently */ + MemoryStore(); + 1ca8: 89 83 std Y+1, r24 ; 0x01 + 1caa: b9 d9 rcall .-3214 ; 0x101e + + GlobalSettings.ActiveSettingIdx = SettingIdx; + 1cac: 10 93 09 29 sts 0x2909, r17 + GlobalSettings.ActiveSettingPtr = + &GlobalSettings.Settings[SettingIdx]; + 1cb0: 41 2f mov r20, r17 + 1cb2: 50 e0 ldi r21, 0x00 ; 0 + 1cb4: 9a 01 movw r18, r20 + 1cb6: 22 0f add r18, r18 + 1cb8: 33 1f adc r19, r19 + 1cba: 24 0f add r18, r20 + 1cbc: 35 1f adc r19, r21 + 1cbe: 22 0f add r18, r18 + 1cc0: 33 1f adc r19, r19 + 1cc2: 24 5f subi r18, 0xF4 ; 244 + 1cc4: 36 4d sbci r19, 0xD6 ; 214 + uint8_t SettingIdx = SETTING_TO_INDEX(Setting); + /* Store current memory contents permanently */ + MemoryStore(); + + GlobalSettings.ActiveSettingIdx = SettingIdx; + GlobalSettings.ActiveSettingPtr = + 1cc6: 20 93 0a 29 sts 0x290A, r18 + 1cca: 30 93 0b 29 sts 0x290B, r19 + &GlobalSettings.Settings[SettingIdx]; + + /* Settings have changed. Progress changes through system */ + ConfigurationInit(); + 1cce: 0e 94 c5 05 call 0xb8a ; 0xb8a + LogInit(); + 1cd2: 68 df rcall .-304 ; 0x1ba4 + + /* Recall new memory contents */ + MemoryRecall(); + 1cd4: af d8 rcall .-3746 ; 0xe34 + + /* Notify LED. blink according to current setting */ + LEDTrigger(LED_SETTING_CHANGE, LED_BLINK + SettingIdx); + 1cd6: 89 81 ldd r24, Y+1 ; 0x01 + 1cd8: 68 2f mov r22, r24 + 1cda: 61 5e subi r22, 0xE1 ; 225 + 1cdc: 83 e0 ldi r24, 0x03 ; 3 + 1cde: 3f d1 rcall .+638 ; 0x1f5e + + return true; + 1ce0: 81 e0 ldi r24, 0x01 ; 1 + } else { + return false; + } +} + 1ce2: 0f 90 pop r0 + 1ce4: df 91 pop r29 + 1ce6: cf 91 pop r28 + 1ce8: 1f 91 pop r17 + 1cea: 08 95 ret + +00001cec : + uint8_t SettingIdx = GlobalSettings.ActiveSettingIdx; + + while (i-- > 0) { + /* Try to set one of the SETTINGS_COUNT following settings. + * But only set if it is not CONFIG_NONE. */ + SettingIdx = (SettingIdx + 1) % SETTINGS_COUNT; + 1cec: 20 91 09 29 lds r18, 0x2909 + 1cf0: 30 e0 ldi r19, 0x00 ; 0 + 1cf2: 2f 5f subi r18, 0xFF ; 255 + 1cf4: 3f 4f sbci r19, 0xFF ; 255 + 1cf6: 27 70 andi r18, 0x07 ; 7 + 1cf8: 33 27 eor r19, r19 + 1cfa: 82 2f mov r24, r18 + + if (GlobalSettings.Settings[SettingIdx].Configuration != CONFIG_NONE) { + 1cfc: 2f 5f subi r18, 0xFF ; 255 + 1cfe: 3f 4f sbci r19, 0xFF ; 255 + 1d00: f9 01 movw r30, r18 + 1d02: ee 0f add r30, r30 + 1d04: ff 1f adc r31, r31 + 1d06: e2 0f add r30, r18 + 1d08: f3 1f adc r31, r19 + 1d0a: ee 0f add r30, r30 + 1d0c: ff 1f adc r31, r31 + 1d0e: e7 5f subi r30, 0xF7 ; 247 + 1d10: f6 4d sbci r31, 0xD6 ; 214 + 1d12: 90 81 ld r25, Z + 1d14: 91 11 cpse r25, r1 + 1d16: 78 c0 rjmp .+240 ; 0x1e08 + uint8_t SettingIdx = GlobalSettings.ActiveSettingIdx; + + while (i-- > 0) { + /* Try to set one of the SETTINGS_COUNT following settings. + * But only set if it is not CONFIG_NONE. */ + SettingIdx = (SettingIdx + 1) % SETTINGS_COUNT; + 1d18: 27 70 andi r18, 0x07 ; 7 + 1d1a: 33 27 eor r19, r19 + 1d1c: 82 2f mov r24, r18 + + if (GlobalSettings.Settings[SettingIdx].Configuration != CONFIG_NONE) { + 1d1e: 2f 5f subi r18, 0xFF ; 255 + 1d20: 3f 4f sbci r19, 0xFF ; 255 + 1d22: f9 01 movw r30, r18 + 1d24: ee 0f add r30, r30 + 1d26: ff 1f adc r31, r31 + 1d28: e2 0f add r30, r18 + 1d2a: f3 1f adc r31, r19 + 1d2c: ee 0f add r30, r30 + 1d2e: ff 1f adc r31, r31 + 1d30: e7 5f subi r30, 0xF7 ; 247 + 1d32: f6 4d sbci r31, 0xD6 ; 214 + 1d34: 90 81 ld r25, Z + 1d36: 91 11 cpse r25, r1 + 1d38: 67 c0 rjmp .+206 ; 0x1e08 + uint8_t SettingIdx = GlobalSettings.ActiveSettingIdx; + + while (i-- > 0) { + /* Try to set one of the SETTINGS_COUNT following settings. + * But only set if it is not CONFIG_NONE. */ + SettingIdx = (SettingIdx + 1) % SETTINGS_COUNT; + 1d3a: 27 70 andi r18, 0x07 ; 7 + 1d3c: 33 27 eor r19, r19 + 1d3e: 82 2f mov r24, r18 + + if (GlobalSettings.Settings[SettingIdx].Configuration != CONFIG_NONE) { + 1d40: 2f 5f subi r18, 0xFF ; 255 + 1d42: 3f 4f sbci r19, 0xFF ; 255 + 1d44: f9 01 movw r30, r18 + 1d46: ee 0f add r30, r30 + 1d48: ff 1f adc r31, r31 + 1d4a: e2 0f add r30, r18 + 1d4c: f3 1f adc r31, r19 + 1d4e: ee 0f add r30, r30 + 1d50: ff 1f adc r31, r31 + 1d52: e7 5f subi r30, 0xF7 ; 247 + 1d54: f6 4d sbci r31, 0xD6 ; 214 + 1d56: 90 81 ld r25, Z + 1d58: 91 11 cpse r25, r1 + 1d5a: 56 c0 rjmp .+172 ; 0x1e08 + uint8_t SettingIdx = GlobalSettings.ActiveSettingIdx; + + while (i-- > 0) { + /* Try to set one of the SETTINGS_COUNT following settings. + * But only set if it is not CONFIG_NONE. */ + SettingIdx = (SettingIdx + 1) % SETTINGS_COUNT; + 1d5c: 27 70 andi r18, 0x07 ; 7 + 1d5e: 33 27 eor r19, r19 + 1d60: 82 2f mov r24, r18 + + if (GlobalSettings.Settings[SettingIdx].Configuration != CONFIG_NONE) { + 1d62: 2f 5f subi r18, 0xFF ; 255 + 1d64: 3f 4f sbci r19, 0xFF ; 255 + 1d66: f9 01 movw r30, r18 + 1d68: ee 0f add r30, r30 + 1d6a: ff 1f adc r31, r31 + 1d6c: e2 0f add r30, r18 + 1d6e: f3 1f adc r31, r19 + 1d70: ee 0f add r30, r30 + 1d72: ff 1f adc r31, r31 + 1d74: e7 5f subi r30, 0xF7 ; 247 + 1d76: f6 4d sbci r31, 0xD6 ; 214 + 1d78: 90 81 ld r25, Z + 1d7a: 91 11 cpse r25, r1 + 1d7c: 45 c0 rjmp .+138 ; 0x1e08 + uint8_t SettingIdx = GlobalSettings.ActiveSettingIdx; + + while (i-- > 0) { + /* Try to set one of the SETTINGS_COUNT following settings. + * But only set if it is not CONFIG_NONE. */ + SettingIdx = (SettingIdx + 1) % SETTINGS_COUNT; + 1d7e: 27 70 andi r18, 0x07 ; 7 + 1d80: 33 27 eor r19, r19 + 1d82: 82 2f mov r24, r18 + + if (GlobalSettings.Settings[SettingIdx].Configuration != CONFIG_NONE) { + 1d84: 2f 5f subi r18, 0xFF ; 255 + 1d86: 3f 4f sbci r19, 0xFF ; 255 + 1d88: f9 01 movw r30, r18 + 1d8a: ee 0f add r30, r30 + 1d8c: ff 1f adc r31, r31 + 1d8e: e2 0f add r30, r18 + 1d90: f3 1f adc r31, r19 + 1d92: ee 0f add r30, r30 + 1d94: ff 1f adc r31, r31 + 1d96: e7 5f subi r30, 0xF7 ; 247 + 1d98: f6 4d sbci r31, 0xD6 ; 214 + 1d9a: 90 81 ld r25, Z + 1d9c: 91 11 cpse r25, r1 + 1d9e: 34 c0 rjmp .+104 ; 0x1e08 + uint8_t SettingIdx = GlobalSettings.ActiveSettingIdx; + + while (i-- > 0) { + /* Try to set one of the SETTINGS_COUNT following settings. + * But only set if it is not CONFIG_NONE. */ + SettingIdx = (SettingIdx + 1) % SETTINGS_COUNT; + 1da0: 27 70 andi r18, 0x07 ; 7 + 1da2: 33 27 eor r19, r19 + 1da4: 82 2f mov r24, r18 + + if (GlobalSettings.Settings[SettingIdx].Configuration != CONFIG_NONE) { + 1da6: 2f 5f subi r18, 0xFF ; 255 + 1da8: 3f 4f sbci r19, 0xFF ; 255 + 1daa: f9 01 movw r30, r18 + 1dac: ee 0f add r30, r30 + 1dae: ff 1f adc r31, r31 + 1db0: e2 0f add r30, r18 + 1db2: f3 1f adc r31, r19 + 1db4: ee 0f add r30, r30 + 1db6: ff 1f adc r31, r31 + 1db8: e7 5f subi r30, 0xF7 ; 247 + 1dba: f6 4d sbci r31, 0xD6 ; 214 + 1dbc: 90 81 ld r25, Z + 1dbe: 91 11 cpse r25, r1 + 1dc0: 23 c0 rjmp .+70 ; 0x1e08 + uint8_t SettingIdx = GlobalSettings.ActiveSettingIdx; + + while (i-- > 0) { + /* Try to set one of the SETTINGS_COUNT following settings. + * But only set if it is not CONFIG_NONE. */ + SettingIdx = (SettingIdx + 1) % SETTINGS_COUNT; + 1dc2: 27 70 andi r18, 0x07 ; 7 + 1dc4: 33 27 eor r19, r19 + 1dc6: 82 2f mov r24, r18 + + if (GlobalSettings.Settings[SettingIdx].Configuration != CONFIG_NONE) { + 1dc8: 2f 5f subi r18, 0xFF ; 255 + 1dca: 3f 4f sbci r19, 0xFF ; 255 + 1dcc: f9 01 movw r30, r18 + 1dce: ee 0f add r30, r30 + 1dd0: ff 1f adc r31, r31 + 1dd2: e2 0f add r30, r18 + 1dd4: f3 1f adc r31, r19 + 1dd6: ee 0f add r30, r30 + 1dd8: ff 1f adc r31, r31 + 1dda: e7 5f subi r30, 0xF7 ; 247 + 1ddc: f6 4d sbci r31, 0xD6 ; 214 + 1dde: 90 81 ld r25, Z + 1de0: 91 11 cpse r25, r1 + 1de2: 12 c0 rjmp .+36 ; 0x1e08 + uint8_t SettingIdx = GlobalSettings.ActiveSettingIdx; + + while (i-- > 0) { + /* Try to set one of the SETTINGS_COUNT following settings. + * But only set if it is not CONFIG_NONE. */ + SettingIdx = (SettingIdx + 1) % SETTINGS_COUNT; + 1de4: 27 70 andi r18, 0x07 ; 7 + 1de6: 33 27 eor r19, r19 + 1de8: 82 2f mov r24, r18 + + if (GlobalSettings.Settings[SettingIdx].Configuration != CONFIG_NONE) { + 1dea: 2f 5f subi r18, 0xFF ; 255 + 1dec: 3f 4f sbci r19, 0xFF ; 255 + 1dee: f9 01 movw r30, r18 + 1df0: ee 0f add r30, r30 + 1df2: ff 1f adc r31, r31 + 1df4: e2 0f add r30, r18 + 1df6: f3 1f adc r31, r19 + 1df8: ee 0f add r30, r30 + 1dfa: ff 1f adc r31, r31 + 1dfc: e7 5f subi r30, 0xF7 ; 247 + 1dfe: f6 4d sbci r31, 0xD6 ; 214 + 1e00: 90 81 ld r25, Z + 1e02: 91 11 cpse r25, r1 + 1e04: 01 c0 rjmp .+2 ; 0x1e08 + 1e06: 08 95 ret + SettingsSetActiveById(INDEX_TO_SETTING(SettingIdx)); + 1e08: 8f 5f subi r24, 0xFF ; 255 + 1e0a: 3e cf rjmp .-388 ; 0x1c88 + +00001e0c : + return false; + } +} + +uint8_t SettingsGetActiveById(void) { + return INDEX_TO_SETTING(GlobalSettings.ActiveSettingIdx); + 1e0c: 80 91 09 29 lds r24, 0x2909 +} + 1e10: 8f 5f subi r24, 0xFF ; 255 + 1e12: 08 95 ret + +00001e14 : + +void SettingsGetActiveByName(char* SettingOut, uint16_t BufferSize) { + 1e14: cf 93 push r28 + 1e16: df 93 push r29 + 1e18: ec 01 movw r28, r24 + SettingOut[0] = SettingsGetActiveById() + '0'; + 1e1a: f8 df rcall .-16 ; 0x1e0c + 1e1c: 80 5d subi r24, 0xD0 ; 208 + 1e1e: 88 83 st Y, r24 + SettingOut[1] = '\0'; + 1e20: 19 82 std Y+1, r1 ; 0x01 +} + 1e22: df 91 pop r29 + 1e24: cf 91 pop r28 + 1e26: 08 95 ret + +00001e28 : + +bool SettingsSetActiveByName(const char* Setting) { + 1e28: fc 01 movw r30, r24 + uint8_t SettingNr = Setting[0] - '0'; + 1e2a: 80 81 ld r24, Z + + if (Setting[1] == '\0') { + 1e2c: 91 81 ldd r25, Z+1 ; 0x01 + 1e2e: 99 23 and r25, r25 + 1e30: 11 f0 breq .+4 ; 0x1e36 + return SettingsSetActiveById(SettingNr); + } else { + return false; + } +} + 1e32: 80 e0 ldi r24, 0x00 ; 0 + 1e34: 08 95 ret + +bool SettingsSetActiveByName(const char* Setting) { + uint8_t SettingNr = Setting[0] - '0'; + + if (Setting[1] == '\0') { + return SettingsSetActiveById(SettingNr); + 1e36: 80 53 subi r24, 0x30 ; 48 + 1e38: 27 cf rjmp .-434 ; 0x1c88 + +00001e3a : + } +} + +void LEDInit(void) +{ + LED_PORT.DIRSET = LED_MASK; + 1e3a: 80 e3 ldi r24, 0x30 ; 48 + 1e3c: e0 e0 ldi r30, 0x00 ; 0 + 1e3e: f6 e0 ldi r31, 0x06 ; 6 + 1e40: 81 83 std Z+1, r24 ; 0x01 + 1e42: 08 95 ret + +00001e44 : + +INLINE void Tick(uint8_t Mask, LEDActionEnum* Action) +{ + static uint8_t BlinkPrescaler = 0; + + switch (*Action) + 1e44: 80 91 97 28 lds r24, 0x2897 + 1e48: 82 31 cpi r24, 0x12 ; 18 + 1e4a: 09 f4 brne .+2 ; 0x1e4e + 1e4c: 60 c0 rjmp .+192 ; 0x1f0e + 1e4e: c8 f0 brcs .+50 ; 0x1e82 + 1e50: 83 31 cpi r24, 0x13 ; 19 + 1e52: 01 f1 breq .+64 ; 0x1e94 + 1e54: 98 2f mov r25, r24 + 1e56: 90 52 subi r25, 0x20 ; 32 + 1e58: 98 30 cpi r25, 0x08 ; 8 + 1e5a: 08 f0 brcs .+2 ; 0x1e5e + 1e5c: 4d c0 rjmp .+154 ; 0x1ef8 + *Action = LED_NO_ACTION; + } + break; + + case LED_BLINK_1X ... LED_BLINK_8X: + if (++BlinkPrescaler == BLINK_PRESCALER) { + 1e5e: 90 91 99 28 lds r25, 0x2899 + 1e62: 9f 5f subi r25, 0xFF ; 255 + 1e64: 91 30 cpi r25, 0x01 ; 1 + 1e66: 09 f4 brne .+2 ; 0x1e6a + 1e68: 6b c0 rjmp .+214 ; 0x1f40 + 1e6a: 90 93 99 28 sts 0x2899, r25 + +INLINE void Tick(uint8_t Mask, LEDActionEnum* Action) +{ + static uint8_t BlinkPrescaler = 0; + + switch (*Action) + 1e6e: 80 91 98 28 lds r24, 0x2898 + 1e72: 82 31 cpi r24, 0x12 ; 18 + 1e74: e1 f4 brne .+56 ; 0x1eae + LED_PORT.OUTSET = Mask; + *Action = LED_NO_ACTION; + break; + + case LED_TOGGLE: + LED_PORT.OUTTGL = Mask; + 1e76: 80 e2 ldi r24, 0x20 ; 32 + 1e78: 80 93 07 06 sts 0x0607, r24 + *Action = LED_NO_ACTION; + 1e7c: 10 92 98 28 sts 0x2898, r1 + 1e80: 08 95 ret + +INLINE void Tick(uint8_t Mask, LEDActionEnum* Action) +{ + static uint8_t BlinkPrescaler = 0; + + switch (*Action) + 1e82: 80 31 cpi r24, 0x10 ; 16 + 1e84: 61 f0 breq .+24 ; 0x1e9e + 1e86: b0 f1 brcs .+108 ; 0x1ef4 + LED_PORT.OUTCLR = Mask; + *Action = LED_NO_ACTION; + break; + + case LED_ON: + LED_PORT.OUTSET = Mask; + 1e88: 80 e1 ldi r24, 0x10 ; 16 + 1e8a: 80 93 05 06 sts 0x0605, r24 + *Action = LED_NO_ACTION; + 1e8e: 10 92 97 28 sts 0x2897, r1 + 1e92: 09 c0 rjmp .+18 ; 0x1ea6 + LED_PORT.OUTTGL = Mask; + *Action = LED_NO_ACTION; + break; + + case LED_PULSE: + if (!(LED_PORT.OUT & Mask)) { + 1e94: 80 91 04 06 lds r24, 0x0604 + 1e98: 84 ff sbrs r24, 4 + 1e9a: 3f c0 rjmp .+126 ; 0x1f1a + LED_PORT.OUTSET = Mask; + } else { + LED_PORT.OUTCLR = Mask; + 1e9c: 80 e1 ldi r24, 0x10 ; 16 + 1e9e: 80 93 06 06 sts 0x0606, r24 + *Action = LED_NO_ACTION; + 1ea2: 10 92 97 28 sts 0x2897, r1 + +INLINE void Tick(uint8_t Mask, LEDActionEnum* Action) +{ + static uint8_t BlinkPrescaler = 0; + + switch (*Action) + 1ea6: 80 91 98 28 lds r24, 0x2898 + 1eaa: 82 31 cpi r24, 0x12 ; 18 + 1eac: 21 f3 breq .-56 ; 0x1e76 + 1eae: 83 31 cpi r24, 0x13 ; 19 + 1eb0: 48 f4 brcc .+18 ; 0x1ec4 + 1eb2: 80 31 cpi r24, 0x10 ; 16 + 1eb4: a9 f0 breq .+42 ; 0x1ee0 + 1eb6: d0 f0 brcs .+52 ; 0x1eec + LED_PORT.OUTCLR = Mask; + *Action = LED_NO_ACTION; + break; + + case LED_ON: + LED_PORT.OUTSET = Mask; + 1eb8: 80 e2 ldi r24, 0x20 ; 32 + 1eba: 80 93 05 06 sts 0x0605, r24 + *Action = LED_NO_ACTION; + 1ebe: 10 92 98 28 sts 0x2898, r1 + 1ec2: 08 95 ret + +INLINE void Tick(uint8_t Mask, LEDActionEnum* Action) +{ + static uint8_t BlinkPrescaler = 0; + + switch (*Action) + 1ec4: 83 31 cpi r24, 0x13 ; 19 + 1ec6: d9 f0 breq .+54 ; 0x1efe + 1ec8: 98 2f mov r25, r24 + 1eca: 90 52 subi r25, 0x20 ; 32 + 1ecc: 98 30 cpi r25, 0x08 ; 8 + 1ece: 78 f4 brcc .+30 ; 0x1eee + *Action = LED_NO_ACTION; + } + break; + + case LED_BLINK_1X ... LED_BLINK_8X: + if (++BlinkPrescaler == BLINK_PRESCALER) { + 1ed0: 90 91 99 28 lds r25, 0x2899 + 1ed4: 9f 5f subi r25, 0xFF ; 255 + 1ed6: 91 30 cpi r25, 0x01 ; 1 + 1ed8: 21 f1 breq .+72 ; 0x1f22 + 1eda: 90 93 99 28 sts 0x2899, r25 + 1ede: 08 95 ret + + case LED_PULSE: + if (!(LED_PORT.OUT & Mask)) { + LED_PORT.OUTSET = Mask; + } else { + LED_PORT.OUTCLR = Mask; + 1ee0: 80 e2 ldi r24, 0x20 ; 32 + 1ee2: 80 93 06 06 sts 0x0606, r24 + *Action = LED_NO_ACTION; + 1ee6: 10 92 98 28 sts 0x2898, r1 + 1eea: 08 95 ret + +INLINE void Tick(uint8_t Mask, LEDActionEnum* Action) +{ + static uint8_t BlinkPrescaler = 0; + + switch (*Action) + 1eec: 81 11 cpse r24, r1 + } + break; + + default: + /* Should not happen (TM) */ + *Action = LED_NO_ACTION; + 1eee: 10 92 98 28 sts 0x2898, r1 + 1ef2: 08 95 ret + +INLINE void Tick(uint8_t Mask, LEDActionEnum* Action) +{ + static uint8_t BlinkPrescaler = 0; + + switch (*Action) + 1ef4: 88 23 and r24, r24 + 1ef6: b9 f2 breq .-82 ; 0x1ea6 + } + break; + + default: + /* Should not happen (TM) */ + *Action = LED_NO_ACTION; + 1ef8: 10 92 97 28 sts 0x2897, r1 + 1efc: d4 cf rjmp .-88 ; 0x1ea6 + LED_PORT.OUTTGL = Mask; + *Action = LED_NO_ACTION; + break; + + case LED_PULSE: + if (!(LED_PORT.OUT & Mask)) { + 1efe: 80 91 04 06 lds r24, 0x0604 + 1f02: 85 fd sbrc r24, 5 + 1f04: ed cf rjmp .-38 ; 0x1ee0 + BlinkPrescaler = 0; + /* Blink functionality occurs at slower speed than Tick-frequency */ + + if (!(LED_PORT.OUT & Mask)) { + /* LED is off, turn it on */ + LED_PORT.OUTSET = Mask; + 1f06: 80 e2 ldi r24, 0x20 ; 32 + 1f08: 80 93 05 06 sts 0x0605, r24 + 1f0c: 08 95 ret + LED_PORT.OUTSET = Mask; + *Action = LED_NO_ACTION; + break; + + case LED_TOGGLE: + LED_PORT.OUTTGL = Mask; + 1f0e: 80 e1 ldi r24, 0x10 ; 16 + 1f10: 80 93 07 06 sts 0x0607, r24 + *Action = LED_NO_ACTION; + 1f14: 10 92 97 28 sts 0x2897, r1 + 1f18: c6 cf rjmp .-116 ; 0x1ea6 + BlinkPrescaler = 0; + /* Blink functionality occurs at slower speed than Tick-frequency */ + + if (!(LED_PORT.OUT & Mask)) { + /* LED is off, turn it on */ + LED_PORT.OUTSET = Mask; + 1f1a: 80 e1 ldi r24, 0x10 ; 16 + 1f1c: 80 93 05 06 sts 0x0605, r24 + 1f20: c2 cf rjmp .-124 ; 0x1ea6 + } + break; + + case LED_BLINK_1X ... LED_BLINK_8X: + if (++BlinkPrescaler == BLINK_PRESCALER) { + BlinkPrescaler = 0; + 1f22: 10 92 99 28 sts 0x2899, r1 + /* Blink functionality occurs at slower speed than Tick-frequency */ + + if (!(LED_PORT.OUT & Mask)) { + 1f26: 90 91 04 06 lds r25, 0x0604 + 1f2a: 95 ff sbrs r25, 5 + 1f2c: ec cf rjmp .-40 ; 0x1f06 + /* LED is off, turn it on */ + LED_PORT.OUTSET = Mask; + } else { + /* LED is on, turn it off and change state */ + LED_PORT.OUTCLR = Mask; + 1f2e: 90 e2 ldi r25, 0x20 ; 32 + 1f30: 90 93 06 06 sts 0x0606, r25 + + if (*Action == LED_BLINK_1X) { + 1f34: 80 32 cpi r24, 0x20 ; 32 + 1f36: d9 f2 breq .-74 ; 0x1eee + *Action = LED_NO_ACTION; + } else { + /* Still some blinks to do. Use the fact that LED_BLINK_XY are ordered sequentially */ + *Action = *Action - 1; + 1f38: 81 50 subi r24, 0x01 ; 1 + 1f3a: 80 93 98 28 sts 0x2898, r24 + 1f3e: 08 95 ret + } + break; + + case LED_BLINK_1X ... LED_BLINK_8X: + if (++BlinkPrescaler == BLINK_PRESCALER) { + BlinkPrescaler = 0; + 1f40: 10 92 99 28 sts 0x2899, r1 + /* Blink functionality occurs at slower speed than Tick-frequency */ + + if (!(LED_PORT.OUT & Mask)) { + 1f44: 90 91 04 06 lds r25, 0x0604 + 1f48: 94 ff sbrs r25, 4 + 1f4a: e7 cf rjmp .-50 ; 0x1f1a + /* LED is off, turn it on */ + LED_PORT.OUTSET = Mask; + } else { + /* LED is on, turn it off and change state */ + LED_PORT.OUTCLR = Mask; + 1f4c: 90 e1 ldi r25, 0x10 ; 16 + 1f4e: 90 93 06 06 sts 0x0606, r25 + + if (*Action == LED_BLINK_1X) { + 1f52: 80 32 cpi r24, 0x20 ; 32 + 1f54: 89 f2 breq .-94 ; 0x1ef8 + *Action = LED_NO_ACTION; + } else { + /* Still some blinks to do. Use the fact that LED_BLINK_XY are ordered sequentially */ + *Action = *Action - 1; + 1f56: 81 50 subi r24, 0x01 ; 1 + 1f58: 80 93 97 28 sts 0x2897, r24 + 1f5c: a4 cf rjmp .-184 ; 0x1ea6 + +00001f5e : + Tick(LED_GREEN, &LEDGreenAction); +} + +/* TODO: This would be nicer as INLINE */ +void LEDTrigger(LEDFunctionEnum Func, LEDActionEnum Action) { + if (GlobalSettings.ActiveSettingPtr->LEDGreenFunction == Func) { + 1f5e: e0 91 0a 29 lds r30, 0x290A + 1f62: f0 91 0b 29 lds r31, 0x290B + 1f66: 95 81 ldd r25, Z+5 ; 0x05 + 1f68: 98 17 cp r25, r24 + 1f6a: 31 f0 breq .+12 ; 0x1f78 + LEDGreenAction = Action; + } + + if (GlobalSettings.ActiveSettingPtr->LEDRedFunction == Func) { + 1f6c: 94 81 ldd r25, Z+4 ; 0x04 + 1f6e: 98 13 cpse r25, r24 + 1f70: 08 95 ret + LEDRedAction = Action; + 1f72: 60 93 97 28 sts 0x2897, r22 + 1f76: 08 95 ret +} + +/* TODO: This would be nicer as INLINE */ +void LEDTrigger(LEDFunctionEnum Func, LEDActionEnum Action) { + if (GlobalSettings.ActiveSettingPtr->LEDGreenFunction == Func) { + LEDGreenAction = Action; + 1f78: 60 93 98 28 sts 0x2898, r22 + 1f7c: f7 cf rjmp .-18 ; 0x1f6c + +00001f7e : + LEDRedAction = Action; + } +} + +void LEDGetFuncList(char* ListOut, uint16_t BufferSize) +{ + 1f7e: cf 93 push r28 + 1f80: df 93 push r29 + 1f82: ec 01 movw r28, r24 + uint8_t i; + + /* Account for '\0' */ + BufferSize--; + 1f84: 61 50 subi r22, 0x01 ; 1 + 1f86: 71 09 sbc r23, r1 + 1f88: 80 e0 ldi r24, 0x00 ; 0 + 1f8a: 90 e0 ldi r25, 0x00 ; 0 + BufferSize--; + } + + if ( i < (LED_FUNC_COUNT - 1) ) { + /* No comma on last configuration */ + *ListOut++ = ','; + 1f8c: 3c e2 ldi r19, 0x2C ; 44 + + /* Account for '\0' */ + BufferSize--; + + for (i=0; i sizeof(LEDFuncTable[i]) ) { + 1fa4: 24 91 lpm r18, Z + 1fa6: 22 23 and r18, r18 + 1fa8: 81 f0 breq .+32 ; 0x1fca + 1faa: 61 32 cpi r22, 0x21 ; 33 + 1fac: 71 05 cpc r23, r1 + 1fae: 68 f0 brcs .+26 ; 0x1fca + 1fb0: de 01 movw r26, r28 + 1fb2: 03 c0 rjmp .+6 ; 0x1fba + 1fb4: 60 32 cpi r22, 0x20 ; 32 + 1fb6: 71 05 cpc r23, r1 + 1fb8: 41 f0 breq .+16 ; 0x1fca + /* While not end-of-string and enough buffer to + * put a complete configuration name */ + *ListOut++ = c; + 1fba: 2d 93 st X+, r18 + 1fbc: ed 01 movw r28, r26 + FuncName++; + 1fbe: 31 96 adiw r30, 0x01 ; 1 + BufferSize--; + 1fc0: 61 50 subi r22, 0x01 ; 1 + 1fc2: 71 09 sbc r23, r1 + + for (i=0; i sizeof(LEDFuncTable[i]) ) { + 1fc4: 24 91 lpm r18, Z + 1fc6: 21 11 cpse r18, r1 + 1fc8: f5 cf rjmp .-22 ; 0x1fb4 + *ListOut++ = c; + FuncName++; + BufferSize--; + } + + if ( i < (LED_FUNC_COUNT - 1) ) { + 1fca: 87 30 cpi r24, 0x07 ; 7 + 1fcc: 91 05 cpc r25, r1 + 1fce: 21 f4 brne .+8 ; 0x1fd8 + *ListOut++ = ','; + BufferSize--; + } + } + + *ListOut = '\0'; + 1fd0: 18 82 st Y, r1 +} + 1fd2: df 91 pop r29 + 1fd4: cf 91 pop r28 + 1fd6: 08 95 ret + BufferSize--; + } + + if ( i < (LED_FUNC_COUNT - 1) ) { + /* No comma on last configuration */ + *ListOut++ = ','; + 1fd8: 39 93 st Y+, r19 + BufferSize--; + 1fda: 61 50 subi r22, 0x01 ; 1 + 1fdc: 71 09 sbc r23, r1 + 1fde: 01 96 adiw r24, 0x01 ; 1 + 1fe0: d6 cf rjmp .-84 ; 0x1f8e + +00001fe2 : + + *ListOut = '\0'; +} + +void LEDSetFuncById(uint8_t Mask, LEDFunctionEnum Func) +{ + 1fe2: 98 2f mov r25, r24 + 1fe4: 90 71 andi r25, 0x10 ; 16 + 1fe6: 85 fd sbrc r24, 5 + 1fe8: 03 c0 rjmp .+6 ; 0x1ff0 + 1fea: 91 11 cpse r25, r1 + 1fec: 3f c0 rjmp .+126 ; 0x206c + 1fee: 08 95 ret + } +#else + /* Write LED func to all settings when using global settings */ + for (uint8_t i=0; i + } + + if (Mask & LED_RED) { + GlobalSettings.Settings[i].LEDRedFunction = Func; + 1ff8: 60 93 10 29 sts 0x2910, r22 + } +#else + /* Write LED func to all settings when using global settings */ + for (uint8_t i=0; i + LED_PORT.OUTCLR = LED_RED; + 2042: 80 e1 ldi r24, 0x10 ; 16 + 2044: 80 93 06 06 sts 0x0606, r24 + LEDRedAction = LED_NO_ACTION; + 2048: 10 92 97 28 sts 0x2897, r1 + 204c: 08 95 ret + } +#else + /* Write LED func to all settings when using global settings */ + for (uint8_t i=0; i + } + + if (Mask & LED_RED) { + GlobalSettings.Settings[i].LEDRedFunction = Func; + 206c: 60 93 10 29 sts 0x2910, r22 + 2070: 60 93 16 29 sts 0x2916, r22 + 2074: 60 93 1c 29 sts 0x291C, r22 + 2078: 60 93 22 29 sts 0x2922, r22 + 207c: 60 93 28 29 sts 0x2928, r22 + 2080: 60 93 2e 29 sts 0x292E, r22 + 2084: 60 93 34 29 sts 0x2934, r22 + 2088: 60 93 3a 29 sts 0x293A, r22 + 208c: d8 cf rjmp .-80 ; 0x203e + +0000208e : + } + +} + +void LEDGetFuncByName(uint8_t Mask, char* FuncOut, uint16_t BufferSize) +{ + 208e: fb 01 movw r30, r22 + if (Mask == LED_GREEN) { + 2090: 80 32 cpi r24, 0x20 ; 32 + 2092: 21 f0 breq .+8 ; 0x209c + strncpy_P(FuncOut, LEDFuncTable[GlobalSettings.ActiveSettingPtr->LEDGreenFunction], BufferSize); + } else if (Mask == LED_RED) { + 2094: 80 31 cpi r24, 0x10 ; 16 + 2096: 89 f0 breq .+34 ; 0x20ba + strncpy_P(FuncOut, LEDFuncTable[GlobalSettings.ActiveSettingPtr->LEDRedFunction], BufferSize); + } else { + *FuncOut = '\0'; + 2098: 10 82 st Z, r1 + 209a: 08 95 ret +} + +void LEDGetFuncByName(uint8_t Mask, char* FuncOut, uint16_t BufferSize) +{ + if (Mask == LED_GREEN) { + strncpy_P(FuncOut, LEDFuncTable[GlobalSettings.ActiveSettingPtr->LEDGreenFunction], BufferSize); + 209c: a0 91 0a 29 lds r26, 0x290A + 20a0: b0 91 0b 29 lds r27, 0x290B + 20a4: 15 96 adiw r26, 0x05 ; 5 + 20a6: 6c 91 ld r22, X + } else if (Mask == LED_RED) { + strncpy_P(FuncOut, LEDFuncTable[GlobalSettings.ActiveSettingPtr->LEDRedFunction], BufferSize); + 20a8: 80 e2 ldi r24, 0x20 ; 32 + 20aa: 68 9f mul r22, r24 + 20ac: b0 01 movw r22, r0 + 20ae: 11 24 eor r1, r1 + 20b0: 68 54 subi r22, 0x48 ; 72 + 20b2: 7b 4f sbci r23, 0xFB ; 251 + 20b4: cf 01 movw r24, r30 + 20b6: 0c 94 ee 2d jmp 0x5bdc ; 0x5bdc + 20ba: a0 91 0a 29 lds r26, 0x290A + 20be: b0 91 0b 29 lds r27, 0x290B + 20c2: 14 96 adiw r26, 0x04 ; 4 + 20c4: 6c 91 ld r22, X + 20c6: f0 cf rjmp .-32 ; 0x20a8 + +000020c8 : + *FuncOut = '\0'; + } +} + +bool LEDSetFuncByName(uint8_t Mask, const char* FuncName) +{ + 20c8: 1f 93 push r17 + 20ca: cf 93 push r28 + 20cc: df 93 push r29 + 20ce: 18 2f mov r17, r24 + 20d0: eb 01 movw r28, r22 + uint8_t i; + + for (i=0; i + 20dc: 89 2b or r24, r25 + 20de: b1 f1 breq .+108 ; 0x214c + 20e0: 68 ed ldi r22, 0xD8 ; 216 + 20e2: 74 e0 ldi r23, 0x04 ; 4 + 20e4: ce 01 movw r24, r28 + 20e6: 0e 94 d5 2d call 0x5baa ; 0x5baa + 20ea: 89 2b or r24, r25 + 20ec: b9 f1 breq .+110 ; 0x215c + 20ee: 68 ef ldi r22, 0xF8 ; 248 + 20f0: 74 e0 ldi r23, 0x04 ; 4 + 20f2: ce 01 movw r24, r28 + 20f4: 0e 94 d5 2d call 0x5baa ; 0x5baa + 20f8: 89 2b or r24, r25 + 20fa: 91 f1 breq .+100 ; 0x2160 + 20fc: 68 e1 ldi r22, 0x18 ; 24 + 20fe: 75 e0 ldi r23, 0x05 ; 5 + 2100: ce 01 movw r24, r28 + 2102: 0e 94 d5 2d call 0x5baa ; 0x5baa + 2106: 89 2b or r24, r25 + 2108: 69 f1 breq .+90 ; 0x2164 + 210a: 68 e3 ldi r22, 0x38 ; 56 + 210c: 75 e0 ldi r23, 0x05 ; 5 + 210e: ce 01 movw r24, r28 + 2110: 0e 94 d5 2d call 0x5baa ; 0x5baa + 2114: 89 2b or r24, r25 + 2116: 41 f1 breq .+80 ; 0x2168 + 2118: 68 e5 ldi r22, 0x58 ; 88 + 211a: 75 e0 ldi r23, 0x05 ; 5 + 211c: ce 01 movw r24, r28 + 211e: 0e 94 d5 2d call 0x5baa ; 0x5baa + 2122: 89 2b or r24, r25 + 2124: 19 f1 breq .+70 ; 0x216c + 2126: 68 e7 ldi r22, 0x78 ; 120 + 2128: 75 e0 ldi r23, 0x05 ; 5 + 212a: ce 01 movw r24, r28 + 212c: 0e 94 d5 2d call 0x5baa ; 0x5baa + 2130: 89 2b or r24, r25 + 2132: f1 f0 breq .+60 ; 0x2170 + 2134: 68 e9 ldi r22, 0x98 ; 152 + 2136: 75 e0 ldi r23, 0x05 ; 5 + 2138: ce 01 movw r24, r28 + 213a: 0e 94 d5 2d call 0x5baa ; 0x5baa + 213e: 89 2b or r24, r25 + 2140: c9 f0 breq .+50 ; 0x2174 + return true; + } + } + + /* LED Func not found */ + return false; + 2142: 80 e0 ldi r24, 0x00 ; 0 +} + 2144: df 91 pop r29 + 2146: cf 91 pop r28 + 2148: 1f 91 pop r17 + 214a: 08 95 ret + +bool LEDSetFuncByName(uint8_t Mask, const char* FuncName) +{ + uint8_t i; + + for (i=0; i + return true; + 2152: 81 e0 ldi r24, 0x01 ; 1 + } + } + + /* LED Func not found */ + return false; +} + 2154: df 91 pop r29 + 2156: cf 91 pop r28 + 2158: 1f 91 pop r17 + 215a: 08 95 ret + +bool LEDSetFuncByName(uint8_t Mask, const char* FuncName) +{ + uint8_t i; + + for (i=0; i + 2160: 62 e0 ldi r22, 0x02 ; 2 + 2162: f5 cf rjmp .-22 ; 0x214e + 2164: 63 e0 ldi r22, 0x03 ; 3 + 2166: f3 cf rjmp .-26 ; 0x214e + 2168: 64 e0 ldi r22, 0x04 ; 4 + 216a: f1 cf rjmp .-30 ; 0x214e + 216c: 65 e0 ldi r22, 0x05 ; 5 + 216e: ef cf rjmp .-34 ; 0x214e + 2170: 66 e0 ldi r22, 0x06 ; 6 + 2172: ed cf rjmp .-38 ; 0x214e + if (strcmp_P(FuncName, LEDFuncTable[i]) == 0) { + 2174: 67 e0 ldi r22, 0x07 ; 7 + 2176: eb cf rjmp .-42 ; 0x214e + +00002178 : +uint8_t TerminalBuffer[TERMINAL_BUFFER_SIZE]; +TerminalStateEnum TerminalState = TERMINAL_UNINITIALIZED; +static uint8_t TerminalInitDelay = INIT_DELAY; + +void TerminalSendString(const char* s) { + CDC_Device_SendString(&TerminalHandle, s); + 2178: bc 01 movw r22, r24 + 217a: 80 e0 ldi r24, 0x00 ; 0 + 217c: 90 e2 ldi r25, 0x20 ; 32 + 217e: 0c 94 6c 2b jmp 0x56d8 ; 0x56d8 + +00002182 : +} + +void TerminalSendStringP(const char* s) { + 2182: cf 93 push r28 + 2184: df 93 push r29 + char c; + + while( (c = pgm_read_byte(s++)) != '\0' ) { + 2186: ec 01 movw r28, r24 + 2188: 21 96 adiw r28, 0x01 ; 1 + 218a: fc 01 movw r30, r24 + 218c: 64 91 lpm r22, Z + 218e: 66 23 and r22, r22 + 2190: 49 f0 breq .+18 ; 0x21a4 +void EVENT_USB_Device_Connect(void); +void EVENT_USB_Device_Disconnect(void); +void EVENT_USB_Device_ConfigurationChanged(void); +void EVENT_USB_Device_ControlRequest(void); + +INLINE void TerminalSendChar(char c) { CDC_Device_SendByte(&TerminalHandle, c); } + 2192: 80 e0 ldi r24, 0x00 ; 0 + 2194: 90 e2 ldi r25, 0x20 ; 32 + 2196: 0e 94 bf 2b call 0x577e ; 0x577e + 219a: fe 01 movw r30, r28 + 219c: 21 96 adiw r28, 0x01 ; 1 + 219e: 64 91 lpm r22, Z + 21a0: 61 11 cpse r22, r1 + 21a2: f7 cf rjmp .-18 ; 0x2192 + TerminalSendChar(c); + } +} + 21a4: df 91 pop r29 + 21a6: cf 91 pop r28 + 21a8: 08 95 ret + +000021aa : +#endif + + + +void TerminalSendBlock(void* Buffer, uint16_t ByteCount) +{ + 21aa: ab 01 movw r20, r22 + CDC_Device_SendData(&TerminalHandle, Buffer, ByteCount); + 21ac: bc 01 movw r22, r24 + 21ae: 80 e0 ldi r24, 0x00 ; 0 + 21b0: 90 e2 ldi r25, 0x20 ; 32 + 21b2: 0c 94 95 2b jmp 0x572a ; 0x572a + +000021b6 : + } +} + +void TerminalInit(void) +{ + TERMINAL_VBUS_PORT.DIRCLR = TERMINAL_VBUS_MASK; + 21b6: 80 e2 ldi r24, 0x20 ; 32 + 21b8: e0 e6 ldi r30, 0x60 ; 96 + 21ba: f6 e0 ldi r31, 0x06 ; 6 + 21bc: 82 83 std Z+2, r24 ; 0x02 + 21be: 08 95 ret + +000021c0 : +} + +void TerminalTask(void) +{ + 21c0: cf 93 push r28 + 21c2: df 93 push r29 + if (TerminalState == TERMINAL_INITIALIZED) { + 21c4: 80 91 9a 28 lds r24, 0x289A + 21c8: 82 30 cpi r24, 0x02 ; 2 + 21ca: 19 f0 breq .+6 ; 0x21d2 + CDC_Device_USBTask(&TerminalHandle); + USB_USBTask(); + + ProcessByte(); + } +} + 21cc: df 91 pop r29 + 21ce: cf 91 pop r28 + 21d0: 08 95 ret +} + +void TerminalTask(void) +{ + if (TerminalState == TERMINAL_INITIALIZED) { + CDC_Device_USBTask(&TerminalHandle); + 21d2: 80 e0 ldi r24, 0x00 ; 0 + 21d4: 90 e2 ldi r25, 0x20 ; 32 + 21d6: 0e 94 3e 2c call 0x587c ; 0x587c + USB_USBTask(); + 21da: 0e 94 3f 26 call 0x4c7e ; 0x4c7e + CDC_Device_SendData(&TerminalHandle, Buffer, ByteCount); +} + + +static void ProcessByte(void) { + int16_t Byte = CDC_Device_ReceiveByte(&TerminalHandle); + 21de: 80 e0 ldi r24, 0x00 ; 0 + 21e0: 90 e2 ldi r25, 0x20 ; 32 + 21e2: 0e 94 59 2c call 0x58b2 ; 0x58b2 + 21e6: ec 01 movw r28, r24 + + if (Byte >= 0) { + 21e8: 97 fd sbrc r25, 7 + 21ea: f0 cf rjmp .-32 ; 0x21cc + /* Byte received */ + LEDTrigger(LED_TERMINAL_RXTX, LED_PULSE); + 21ec: 63 e1 ldi r22, 0x13 ; 19 + 21ee: 82 e0 ldi r24, 0x02 ; 2 + 21f0: b6 de rcall .-660 ; 0x1f5e + + if (XModemProcessByte(Byte)) { + 21f2: 8c 2f mov r24, r28 + 21f4: 15 d3 rcall .+1578 ; 0x2820 + 21f6: 81 11 cpse r24, r1 + 21f8: e9 cf rjmp .-46 ; 0x21cc + /* XModem handled the byte */ + } else if (CommandLineProcessByte(Byte)) { + 21fa: 8c 2f mov r24, r28 + CDC_Device_USBTask(&TerminalHandle); + USB_USBTask(); + + ProcessByte(); + } +} + 21fc: df 91 pop r29 + 21fe: cf 91 pop r28 + /* Byte received */ + LEDTrigger(LED_TERMINAL_RXTX, LED_PULSE); + + if (XModemProcessByte(Byte)) { + /* XModem handled the byte */ + } else if (CommandLineProcessByte(Byte)) { + 2200: 95 c4 rjmp .+2346 ; 0x2b2c + +00002202 : + } +} + +static void SenseVBus(void) +{ + switch(TerminalState) { + 2202: 80 91 9a 28 lds r24, 0x289A + 2206: 81 30 cpi r24, 0x01 ; 1 + 2208: 09 f1 breq .+66 ; 0x224c + 220a: 38 f0 brcs .+14 ; 0x221a + 220c: 82 30 cpi r24, 0x02 ; 2 + 220e: 71 f1 breq .+92 ; 0x226c + 2210: 83 30 cpi r24, 0x03 ; 3 + 2212: 71 f0 breq .+28 ; 0x2230 + +void TerminalTick(void) +{ + SenseVBus(); + + if (TerminalState == TERMINAL_INITIALIZED) { + 2214: 82 30 cpi r24, 0x02 ; 2 + 2216: 41 f1 breq .+80 ; 0x2268 + 2218: 08 95 ret + +static void SenseVBus(void) +{ + switch(TerminalState) { + case TERMINAL_UNINITIALIZED: + if (TERMINAL_VBUS_PORT.IN & TERMINAL_VBUS_MASK) { + 221a: 80 91 68 06 lds r24, 0x0668 + 221e: 85 ff sbrs r24, 5 + 2220: fb cf rjmp .-10 ; 0x2218 + /* Not initialized and VBUS sense high */ + TerminalInitDelay = INIT_DELAY; + 2222: 84 e1 ldi r24, 0x14 ; 20 + 2224: 80 93 1b 20 sts 0x201B, r24 + TerminalState = TERMINAL_INITIALIZING; + 2228: 81 e0 ldi r24, 0x01 ; 1 + 222a: 80 93 9a 28 sts 0x289A, r24 + 222e: 08 95 ret + TerminalState = TERMINAL_UNITIALIZING; + } + break; + + case TERMINAL_UNITIALIZING: + if (--TerminalInitDelay == 0) { + 2230: 80 91 1b 20 lds r24, 0x201B + 2234: 81 50 subi r24, 0x01 ; 1 + 2236: 80 93 1b 20 sts 0x201B, r24 + 223a: 81 11 cpse r24, r1 + 223c: ed cf rjmp .-38 ; 0x2218 + USB_Disable(); + 223e: 0e 94 69 2a call 0x54d2 ; 0x54d2 + SystemStopUSBClock(); + 2242: 0e 94 87 05 call 0xb0e ; 0xb0e + TerminalState = TERMINAL_UNINITIALIZED; + 2246: 10 92 9a 28 sts 0x289A, r1 + 224a: 08 95 ret + TerminalState = TERMINAL_INITIALIZING; + } + break; + + case TERMINAL_INITIALIZING: + if (--TerminalInitDelay == 0) { + 224c: 80 91 1b 20 lds r24, 0x201B + 2250: 81 50 subi r24, 0x01 ; 1 + 2252: 80 93 1b 20 sts 0x201B, r24 + 2256: 81 11 cpse r24, r1 + 2258: df cf rjmp .-66 ; 0x2218 + SystemStartUSBClock(); + 225a: 0e 94 69 05 call 0xad2 ; 0xad2 + USB_Init(); + 225e: 0e 94 a4 2a call 0x5548 ; 0x5548 + TerminalState = TERMINAL_INITIALIZED; + 2262: 82 e0 ldi r24, 0x02 ; 2 + 2264: 80 93 9a 28 sts 0x289A, r24 +void TerminalTick(void) +{ + SenseVBus(); + + if (TerminalState == TERMINAL_INITIALIZED) { + XModemTick(); + 2268: 26 d4 rcall .+2124 ; 0x2ab6 + CommandLineTick(); + 226a: 67 c5 rjmp .+2766 ; 0x2d3a + TerminalState = TERMINAL_INITIALIZED; + } + break; + + case TERMINAL_INITIALIZED: + if (!(TERMINAL_VBUS_PORT.IN & TERMINAL_VBUS_MASK)) { + 226c: 80 91 68 06 lds r24, 0x0668 + 2270: 85 fd sbrc r24, 5 + 2272: fa cf rjmp .-12 ; 0x2268 + /* Initialized and VBUS sense low */ + TerminalInitDelay = INIT_DELAY; + 2274: 84 e1 ldi r24, 0x14 ; 20 + 2276: 80 93 1b 20 sts 0x201B, r24 + TerminalState = TERMINAL_UNITIALIZING; + 227a: 83 e0 ldi r24, 0x03 ; 3 + 227c: 80 93 9a 28 sts 0x289A, r24 + 2280: 08 95 ret + +00002282 : +} + +/** Event handler for the library USB Connection event. */ +void EVENT_USB_Device_Connect(void) +{ + LEDTrigger(LED_TERMINAL_CONN, LED_ON); + 2282: 61 e1 ldi r22, 0x11 ; 17 + 2284: 81 e0 ldi r24, 0x01 ; 1 + 2286: 6b ce rjmp .-810 ; 0x1f5e + +00002288 : +} + +/** Event handler for the library USB Disconnection event. */ +void EVENT_USB_Device_Disconnect(void) +{ + LEDTrigger(LED_TERMINAL_CONN, LED_OFF); + 2288: 60 e1 ldi r22, 0x10 ; 16 + 228a: 81 e0 ldi r24, 0x01 ; 1 + 228c: 68 ce rjmp .-816 ; 0x1f5e + +0000228e : + + +/** Event handler for the library USB Configuration Changed event. */ +void EVENT_USB_Device_ConfigurationChanged(void) +{ + CDC_Device_ConfigureEndpoints(&TerminalHandle); + 228e: 80 e0 ldi r24, 0x00 ; 0 + 2290: 90 e2 ldi r25, 0x20 ; 32 + 2292: 0c 94 47 2b jmp 0x568e ; 0x568e + +00002296 : +} + +/** Event handler for the library USB Control Request reception event. */ +void EVENT_USB_Device_ControlRequest(void) +{ + CDC_Device_ProcessControlRequest(&TerminalHandle); + 2296: 80 e0 ldi r24, 0x00 ; 0 + 2298: 90 e2 ldi r25, 0x20 ; 32 + 229a: 0c 94 b9 2c jmp 0x5972 ; 0x5972 + +0000229e : + +extern const PROGMEM CommandEntryType CommandTable[]; + +CommandStatusIdType CommandGetVersion(char* OutParam) +{ + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR( + 229e: 2f ef ldi r18, 0xFF ; 255 + 22a0: 35 e0 ldi r19, 0x05 ; 5 + 22a2: 3f 93 push r19 + 22a4: 2f 93 push r18 + 22a6: 28 ef ldi r18, 0xF8 ; 248 + 22a8: 35 e0 ldi r19, 0x05 ; 5 + 22aa: 3f 93 push r19 + 22ac: 2f 93 push r18 + 22ae: 21 ef ldi r18, 0xF1 ; 241 + 22b0: 35 e0 ldi r19, 0x05 ; 5 + 22b2: 3f 93 push r19 + 22b4: 2f 93 push r18 + 22b6: 28 eb ldi r18, 0xB8 ; 184 + 22b8: 35 e0 ldi r19, 0x05 ; 5 + 22ba: 3f 93 push r19 + 22bc: 2f 93 push r18 + 22be: 21 e0 ldi r18, 0x01 ; 1 + 22c0: 2f 93 push r18 + 22c2: 1f 92 push r1 + 22c4: 9f 93 push r25 + 22c6: 8f 93 push r24 + 22c8: 0e 94 06 2e call 0x5c0c ; 0x5c0c + "Chameleon-Mini %S using LUFA %S compiled with AVR-GCC %S" + ), PSTR(CHAMELEON_MINI_VERSION_STRING), PSTR(LUFA_VERSION_STRING), PSTR(__VERSION__) + ); + + return COMMAND_INFO_OK_WITH_TEXT_ID; + 22cc: 8d b7 in r24, 0x3d ; 61 + 22ce: 9e b7 in r25, 0x3e ; 62 + 22d0: 0c 96 adiw r24, 0x0c ; 12 + 22d2: 8d bf out 0x3d, r24 ; 61 + 22d4: 9e bf out 0x3e, r25 ; 62 +} + 22d6: 85 e6 ldi r24, 0x65 ; 101 + 22d8: 08 95 ret + +000022da : + +CommandStatusIdType CommandGetConfig(char* OutParam) +{ + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, + 22da: 23 ee ldi r18, 0xE3 ; 227 + 22dc: 38 e2 ldi r19, 0x28 ; 40 + 22de: 3f 93 push r19 + 22e0: 2f 93 push r18 + 22e2: 25 e0 ldi r18, 0x05 ; 5 + 22e4: 36 e0 ldi r19, 0x06 ; 6 + 22e6: 3f 93 push r19 + 22e8: 2f 93 push r18 + 22ea: 21 e0 ldi r18, 0x01 ; 1 + 22ec: 2f 93 push r18 + 22ee: 1f 92 push r1 + 22f0: 9f 93 push r25 + 22f2: 8f 93 push r24 + 22f4: 0e 94 06 2e call 0x5c0c ; 0x5c0c + PSTR("%s"), ActiveConfiguration.ConfigurationName); + + return COMMAND_INFO_OK_WITH_TEXT_ID; + 22f8: 8d b7 in r24, 0x3d ; 61 + 22fa: 9e b7 in r25, 0x3e ; 62 + 22fc: 08 96 adiw r24, 0x08 ; 8 + 22fe: 8d bf out 0x3d, r24 ; 61 + 2300: 9e bf out 0x3e, r25 ; 62 + +} + 2302: 85 e6 ldi r24, 0x65 ; 101 + 2304: 08 95 ret + +00002306 : + +CommandStatusIdType CommandSetConfig(const char* InParam) +{ + if (ConfigurationSetByName(InParam)) { + 2306: 0e 94 cb 05 call 0xb96 ; 0xb96 + 230a: 81 11 cpse r24, r1 + 230c: 02 c0 rjmp .+4 ; 0x2312 + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + 230e: 8a ec ldi r24, 0xCA ; 202 + } +} + 2310: 08 95 ret +} + +CommandStatusIdType CommandSetConfig(const char* InParam) +{ + if (ConfigurationSetByName(InParam)) { + SettingsSave(); + 2312: b2 dc rcall .-1692 ; 0x1c78 + return COMMAND_INFO_OK_ID; + 2314: 84 e6 ldi r24, 0x64 ; 100 + 2316: 08 95 ret + +00002318 : + } +} + +CommandStatusIdType CommandExecConfig(char* OutMessage) +{ + ConfigurationGetList(OutMessage, TERMINAL_BUFFER_SIZE); + 2318: 60 e0 ldi r22, 0x00 ; 0 + 231a: 71 e0 ldi r23, 0x01 ; 1 + 231c: 0e 94 0c 06 call 0xc18 ; 0xc18 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 2320: 85 e6 ldi r24, 0x65 ; 101 + 2322: 08 95 ret + +00002324 : + +CommandStatusIdType CommandGetUid(char* OutParam) +{ + 2324: 0f 93 push r16 + 2326: 1f 93 push r17 + 2328: cf 93 push r28 + 232a: df 93 push r29 + 232c: cd b7 in r28, 0x3d ; 61 + 232e: de b7 in r29, 0x3e ; 62 + 2330: a1 97 sbiw r28, 0x21 ; 33 + 2332: cd bf out 0x3d, r28 ; 61 + 2334: de bf out 0x3e, r29 ; 62 + 2336: 8c 01 movw r16, r24 + uint8_t UidBuffer[COMMAND_UID_BUFSIZE]; + uint16_t UidSize = ActiveConfiguration.UidSize; + 2338: 20 91 05 29 lds r18, 0x2905 + ActiveConfiguration.ApplicationResetFunc(); + //LogEntry(LOG_INFO_APP_RESET, NULL, 0); +} + +INLINE void ApplicationGetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationGetUidFunc(Uid); + 233c: e0 91 ff 28 lds r30, 0x28FF + 2340: f0 91 00 29 lds r31, 0x2900 + 2344: ce 01 movw r24, r28 + 2346: 01 96 adiw r24, 0x01 ; 1 + 2348: 29 a3 std Y+33, r18 ; 0x21 + 234a: 09 95 icall + + ApplicationGetUid(UidBuffer); + + BufferToHexString(OutParam, TERMINAL_BUFFER_SIZE, + 234c: 29 a1 ldd r18, Y+33 ; 0x21 + 234e: 30 e0 ldi r19, 0x00 ; 0 + 2350: ae 01 movw r20, r28 + 2352: 4f 5f subi r20, 0xFF ; 255 + 2354: 5f 4f sbci r21, 0xFF ; 255 + 2356: 60 e0 ldi r22, 0x00 ; 0 + 2358: 71 e0 ldi r23, 0x01 ; 1 + 235a: c8 01 movw r24, r16 + 235c: 0e 94 56 06 call 0xcac ; 0xcac + UidBuffer, UidSize); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 2360: 85 e6 ldi r24, 0x65 ; 101 + 2362: a1 96 adiw r28, 0x21 ; 33 + 2364: cd bf out 0x3d, r28 ; 61 + 2366: de bf out 0x3e, r29 ; 62 + 2368: df 91 pop r29 + 236a: cf 91 pop r28 + 236c: 1f 91 pop r17 + 236e: 0f 91 pop r16 + 2370: 08 95 ret + +00002372 : + +CommandStatusIdType CommandSetUid(const char* InParam) +{ + 2372: bf 92 push r11 + 2374: cf 92 push r12 + 2376: df 92 push r13 + 2378: ef 92 push r14 + 237a: ff 92 push r15 + 237c: 0f 93 push r16 + 237e: 1f 93 push r17 + 2380: cf 93 push r28 + 2382: df 93 push r29 + 2384: cd b7 in r28, 0x3d ; 61 + 2386: de b7 in r29, 0x3e ; 62 + 2388: a0 97 sbiw r28, 0x20 ; 32 + 238a: cd bf out 0x3d, r28 ; 61 + 238c: de bf out 0x3e, r29 ; 62 + 238e: 8c 01 movw r16, r24 + uint8_t UidBuffer[COMMAND_UID_BUFSIZE]; + uint16_t UidSize = ActiveConfiguration.UidSize; + 2390: c0 90 05 29 lds r12, 0x2905 + 2394: d1 2c mov r13, r1 + + if (strcmp_P(InParam, PSTR(COMMAND_UID_RANDOM)) == 0) { + 2396: 68 e0 ldi r22, 0x08 ; 8 + 2398: 76 e0 ldi r23, 0x06 ; 6 + 239a: 0e 94 d5 2d call 0x5baa ; 0x5baa + 239e: 89 2b or r24, r25 + 23a0: 59 f5 brne .+86 ; 0x23f8 + /* Load with random bytes */ + for (uint8_t i=0; i + 23a8: b1 2c mov r11, r1 + 23aa: ee 24 eor r14, r14 + 23ac: e3 94 inc r14 + 23ae: f1 2c mov r15, r1 + 23b0: ec 0e add r14, r28 + 23b2: fd 1e adc r15, r29 + 23b4: 00 e0 ldi r16, 0x00 ; 0 + 23b6: 10 e0 ldi r17, 0x00 ; 0 + UidBuffer[i] = RandomGetByte(); + 23b8: 0e 94 3c 06 call 0xc78 ; 0xc78 + 23bc: f7 01 movw r30, r14 + 23be: e0 0f add r30, r16 + 23c0: f1 1f adc r31, r17 + 23c2: 80 83 st Z, r24 + uint8_t UidBuffer[COMMAND_UID_BUFSIZE]; + uint16_t UidSize = ActiveConfiguration.UidSize; + + if (strcmp_P(InParam, PSTR(COMMAND_UID_RANDOM)) == 0) { + /* Load with random bytes */ + for (uint8_t i=0; i +} + +INLINE void ApplicationSetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationSetUidFunc(Uid); + 23d0: e0 91 01 29 lds r30, 0x2901 + 23d4: f0 91 02 29 lds r31, 0x2902 + 23d8: c7 01 movw r24, r14 + 23da: 09 95 icall + } + } + + ApplicationSetUid(UidBuffer); + + return COMMAND_INFO_OK_ID; + 23dc: 84 e6 ldi r24, 0x64 ; 100 +} + 23de: a0 96 adiw r28, 0x20 ; 32 + 23e0: cd bf out 0x3d, r28 ; 61 + 23e2: de bf out 0x3e, r29 ; 62 + 23e4: df 91 pop r29 + 23e6: cf 91 pop r28 + 23e8: 1f 91 pop r17 + 23ea: 0f 91 pop r16 + 23ec: ff 90 pop r15 + 23ee: ef 90 pop r14 + 23f0: df 90 pop r13 + 23f2: cf 90 pop r12 + 23f4: bf 90 pop r11 + 23f6: 08 95 ret + for (uint8_t i=0; i + 240e: 8c 15 cp r24, r12 + 2410: 9d 05 cpc r25, r13 + 2412: f1 f2 breq .-68 ; 0x23d0 + /* Malformed input. Abort */ + return COMMAND_ERR_INVALID_PARAM_ID; + 2414: 8a ec ldi r24, 0xCA ; 202 + 2416: e3 cf rjmp .-58 ; 0x23de + 2418: ee 24 eor r14, r14 + 241a: e3 94 inc r14 + 241c: f1 2c mov r15, r1 + 241e: ec 0e add r14, r28 + 2420: fd 1e adc r15, r29 + 2422: d6 cf rjmp .-84 ; 0x23d0 + +00002424 : + return COMMAND_INFO_OK_ID; +} + +CommandStatusIdType CommandGetReadOnly(char* OutParam) +{ + if (ActiveConfiguration.ReadOnly) { + 2424: 20 91 06 29 lds r18, 0x2906 + 2428: 21 11 cpse r18, r1 + 242a: 07 c0 rjmp .+14 ; 0x243a + OutParam[0] = COMMAND_CHAR_TRUE; + } else { + OutParam[0] = COMMAND_CHAR_FALSE; + 242c: 20 e3 ldi r18, 0x30 ; 48 + 242e: fc 01 movw r30, r24 + 2430: 20 83 st Z, r18 + } + + OutParam[1] = '\0'; + 2432: fc 01 movw r30, r24 + 2434: 11 82 std Z+1, r1 ; 0x01 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 2436: 85 e6 ldi r24, 0x65 ; 101 + 2438: 08 95 ret +} + +CommandStatusIdType CommandGetReadOnly(char* OutParam) +{ + if (ActiveConfiguration.ReadOnly) { + OutParam[0] = COMMAND_CHAR_TRUE; + 243a: 21 e3 ldi r18, 0x31 ; 49 + 243c: fc 01 movw r30, r24 + 243e: 20 83 st Z, r18 + } else { + OutParam[0] = COMMAND_CHAR_FALSE; + } + + OutParam[1] = '\0'; + 2440: fc 01 movw r30, r24 + 2442: 11 82 std Z+1, r1 ; 0x01 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 2444: 85 e6 ldi r24, 0x65 ; 101 + 2446: 08 95 ret + +00002448 : + +CommandStatusIdType CommandSetReadOnly(const char* InParam) +{ + if (InParam[1] == '\0') { + 2448: fc 01 movw r30, r24 + 244a: 21 81 ldd r18, Z+1 ; 0x01 + 244c: 21 11 cpse r18, r1 + 244e: 05 c0 rjmp .+10 ; 0x245a + if (InParam[0] == COMMAND_CHAR_TRUE) { + 2450: 80 81 ld r24, Z + 2452: 81 33 cpi r24, 0x31 ; 49 + 2454: 41 f0 breq .+16 ; 0x2466 + ActiveConfiguration.ReadOnly = true; + return COMMAND_INFO_OK_ID; + } else if (InParam[0] == COMMAND_CHAR_FALSE) { + 2456: 80 33 cpi r24, 0x30 ; 48 + 2458: 11 f0 breq .+4 ; 0x245e + ActiveConfiguration.ReadOnly = false; + return COMMAND_INFO_OK_ID; + } + } + + return COMMAND_ERR_INVALID_PARAM_ID; + 245a: 8a ec ldi r24, 0xCA ; 202 +} + 245c: 08 95 ret + if (InParam[1] == '\0') { + if (InParam[0] == COMMAND_CHAR_TRUE) { + ActiveConfiguration.ReadOnly = true; + return COMMAND_INFO_OK_ID; + } else if (InParam[0] == COMMAND_CHAR_FALSE) { + ActiveConfiguration.ReadOnly = false; + 245e: 10 92 06 29 sts 0x2906, r1 + return COMMAND_INFO_OK_ID; + 2462: 84 e6 ldi r24, 0x64 ; 100 + 2464: 08 95 ret + +CommandStatusIdType CommandSetReadOnly(const char* InParam) +{ + if (InParam[1] == '\0') { + if (InParam[0] == COMMAND_CHAR_TRUE) { + ActiveConfiguration.ReadOnly = true; + 2466: 81 e0 ldi r24, 0x01 ; 1 + 2468: 80 93 06 29 sts 0x2906, r24 + return COMMAND_INFO_OK_ID; + 246c: 84 e6 ldi r24, 0x64 ; 100 + 246e: 08 95 ret + +00002470 : + return COMMAND_ERR_INVALID_PARAM_ID; +} + +CommandStatusIdType CommandExecUpload(char* OutMessage) +{ + XModemReceive(MemoryUploadBlock); + 2470: 86 e5 ldi r24, 0x56 ; 86 + 2472: 99 e0 ldi r25, 0x09 ; 9 + 2474: a4 d1 rcall .+840 ; 0x27be + return COMMAND_INFO_XMODEM_WAIT_ID; +} + 2476: 8e e6 ldi r24, 0x6E ; 110 + 2478: 08 95 ret + +0000247a : + +CommandStatusIdType CommandExecDownload(char* OutMessage) +{ + XModemSend(MemoryDownloadBlock); + 247a: 8b e1 ldi r24, 0x1B ; 27 + 247c: 9b e0 ldi r25, 0x0B ; 11 + 247e: ba d1 rcall .+884 ; 0x27f4 + return COMMAND_INFO_XMODEM_WAIT_ID; +} + 2480: 8e e6 ldi r24, 0x6E ; 110 + 2482: 08 95 ret + +00002484 : + * enumerating the device once attached until \ref USB_Attach() is called. + */ + static inline void USB_Detach(void) ATTR_ALWAYS_INLINE; + static inline void USB_Detach(void) + { + USB.CTRLB &= ~USB_ATTACH_bm; + 2484: e0 ec ldi r30, 0xC0 ; 192 + 2486: f4 e0 ldi r31, 0x04 ; 4 + 2488: 81 81 ldd r24, Z+1 ; 0x01 + 248a: 8e 7f andi r24, 0xFE ; 254 + 248c: 81 83 std Z+1, r24 ; 0x01 + +CommandStatusIdType CommandExecReset(char* OutMessage) +{ + USB_Detach(); + USB_Disable(); + 248e: 0e 94 69 2a call 0x54d2 ; 0x54d2 + + SystemReset(); + 2492: 0e 94 5c 05 call 0xab8 ; 0xab8 + + return COMMAND_INFO_OK_ID; +} + 2496: 84 e6 ldi r24, 0x64 ; 100 + 2498: 08 95 ret + +0000249a : + 249a: e0 ec ldi r30, 0xC0 ; 192 + 249c: f4 e0 ldi r31, 0x04 ; 4 + 249e: 81 81 ldd r24, Z+1 ; 0x01 + 24a0: 8e 7f andi r24, 0xFE ; 254 + 24a2: 81 83 std Z+1, r24 ; 0x01 + +#ifdef SUPPORT_FIRMWARE_UPGRADE +CommandStatusIdType CommandExecUpgrade(char* OutMessage) +{ + USB_Detach(); + USB_Disable(); + 24a4: 0e 94 69 2a call 0x54d2 ; 0x54d2 + + SystemEnterBootloader(); + 24a8: 0e 94 63 05 call 0xac6 ; 0xac6 + + return COMMAND_INFO_OK_ID; +} + 24ac: 84 e6 ldi r24, 0x64 ; 100 + 24ae: 08 95 ret + +000024b0 : +#endif + +CommandStatusIdType CommandGetMemSize(char* OutParam) +{ + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%u"), ActiveConfiguration.MemorySize); + 24b0: e3 e0 ldi r30, 0x03 ; 3 + 24b2: f9 e2 ldi r31, 0x29 ; 41 + 24b4: 21 81 ldd r18, Z+1 ; 0x01 + 24b6: 2f 93 push r18 + 24b8: 20 81 ld r18, Z + 24ba: 2f 93 push r18 + 24bc: 2f e0 ldi r18, 0x0F ; 15 + 24be: 36 e0 ldi r19, 0x06 ; 6 + 24c0: 3f 93 push r19 + 24c2: 2f 93 push r18 + 24c4: 21 e0 ldi r18, 0x01 ; 1 + 24c6: 2f 93 push r18 + 24c8: 1f 92 push r1 + 24ca: 9f 93 push r25 + 24cc: 8f 93 push r24 + 24ce: 0e 94 06 2e call 0x5c0c ; 0x5c0c + + return COMMAND_INFO_OK_WITH_TEXT_ID; + 24d2: 8d b7 in r24, 0x3d ; 61 + 24d4: 9e b7 in r25, 0x3e ; 62 + 24d6: 08 96 adiw r24, 0x08 ; 8 + 24d8: 8d bf out 0x3d, r24 ; 61 + 24da: 9e bf out 0x3e, r25 ; 62 +} + 24dc: 85 e6 ldi r24, 0x65 ; 101 + 24de: 08 95 ret + +000024e0 : + +CommandStatusIdType CommandGetUidSize(char* OutParam) +{ + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%u"), ActiveConfiguration.UidSize); + 24e0: 20 91 05 29 lds r18, 0x2905 + 24e4: 1f 92 push r1 + 24e6: 2f 93 push r18 + 24e8: 22 e1 ldi r18, 0x12 ; 18 + 24ea: 36 e0 ldi r19, 0x06 ; 6 + 24ec: 3f 93 push r19 + 24ee: 2f 93 push r18 + 24f0: 21 e0 ldi r18, 0x01 ; 1 + 24f2: 2f 93 push r18 + 24f4: 1f 92 push r1 + 24f6: 9f 93 push r25 + 24f8: 8f 93 push r24 + 24fa: 0e 94 06 2e call 0x5c0c ; 0x5c0c + + return COMMAND_INFO_OK_WITH_TEXT_ID; + 24fe: 8d b7 in r24, 0x3d ; 61 + 2500: 9e b7 in r25, 0x3e ; 62 + 2502: 08 96 adiw r24, 0x08 ; 8 + 2504: 8d bf out 0x3d, r24 ; 61 + 2506: 9e bf out 0x3e, r25 ; 62 +} + 2508: 85 e6 ldi r24, 0x65 ; 101 + 250a: 08 95 ret + +0000250c : + +CommandStatusIdType CommandExecButton(char* OutMessage) +{ + ButtonGetActionList(OutMessage, TERMINAL_BUFFER_SIZE); + 250c: 60 e0 ldi r22, 0x00 ; 0 + 250e: 71 e0 ldi r23, 0x01 ; 1 + 2510: d0 d9 rcall .-3168 ; 0x18b2 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 2512: 85 e6 ldi r24, 0x65 ; 101 + 2514: 08 95 ret + +00002516 : + +CommandStatusIdType CommandGetButton(char* OutParam) +{ + ButtonGetActionByName(BUTTON_PRESS_SHORT, OutParam, TERMINAL_BUFFER_SIZE); + 2516: 40 e0 ldi r20, 0x00 ; 0 + 2518: 51 e0 ldi r21, 0x01 ; 1 + 251a: bc 01 movw r22, r24 + 251c: 80 e0 ldi r24, 0x00 ; 0 + 251e: 22 da rcall .-3004 ; 0x1964 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 2520: 85 e6 ldi r24, 0x65 ; 101 + 2522: 08 95 ret + +00002524 : + +CommandStatusIdType CommandSetButton(const char* InParam) +{ + if (ButtonSetActionByName(BUTTON_PRESS_SHORT, InParam)) { + 2524: bc 01 movw r22, r24 + 2526: 80 e0 ldi r24, 0x00 ; 0 + 2528: 39 da rcall .-2958 ; 0x199c + 252a: 81 11 cpse r24, r1 + 252c: 02 c0 rjmp .+4 ; 0x2532 + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + 252e: 8a ec ldi r24, 0xCA ; 202 + } +} + 2530: 08 95 ret +} + +CommandStatusIdType CommandSetButton(const char* InParam) +{ + if (ButtonSetActionByName(BUTTON_PRESS_SHORT, InParam)) { + SettingsSave(); + 2532: a2 db rcall .-2236 ; 0x1c78 + return COMMAND_INFO_OK_ID; + 2534: 84 e6 ldi r24, 0x64 ; 100 + 2536: 08 95 ret + +00002538 : + } +} + +CommandStatusIdType CommandExecButtonLong(char* OutMessage) +{ + ButtonGetActionList(OutMessage, TERMINAL_BUFFER_SIZE); + 2538: 60 e0 ldi r22, 0x00 ; 0 + 253a: 71 e0 ldi r23, 0x01 ; 1 + 253c: ba d9 rcall .-3212 ; 0x18b2 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 253e: 85 e6 ldi r24, 0x65 ; 101 + 2540: 08 95 ret + +00002542 : + +CommandStatusIdType CommandGetButtonLong(char* OutParam) +{ + ButtonGetActionByName(BUTTON_PRESS_LONG, OutParam, TERMINAL_BUFFER_SIZE); + 2542: 40 e0 ldi r20, 0x00 ; 0 + 2544: 51 e0 ldi r21, 0x01 ; 1 + 2546: bc 01 movw r22, r24 + 2548: 81 e0 ldi r24, 0x01 ; 1 + 254a: 0c da rcall .-3048 ; 0x1964 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 254c: 85 e6 ldi r24, 0x65 ; 101 + 254e: 08 95 ret + +00002550 : + +CommandStatusIdType CommandSetButtonLong(const char* InParam) +{ + if (ButtonSetActionByName(BUTTON_PRESS_LONG, InParam)) { + 2550: bc 01 movw r22, r24 + 2552: 81 e0 ldi r24, 0x01 ; 1 + 2554: 23 da rcall .-3002 ; 0x199c + 2556: 81 11 cpse r24, r1 + 2558: 02 c0 rjmp .+4 ; 0x255e + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + 255a: 8a ec ldi r24, 0xCA ; 202 + } +} + 255c: 08 95 ret +} + +CommandStatusIdType CommandSetButtonLong(const char* InParam) +{ + if (ButtonSetActionByName(BUTTON_PRESS_LONG, InParam)) { + SettingsSave(); + 255e: 8c db rcall .-2280 ; 0x1c78 + return COMMAND_INFO_OK_ID; + 2560: 84 e6 ldi r24, 0x64 ; 100 + 2562: 08 95 ret + +00002564 : + } +} + +CommandStatusIdType CommandExecLedGreen(char* OutMessage) +{ + LEDGetFuncList(OutMessage, TERMINAL_BUFFER_SIZE); + 2564: 60 e0 ldi r22, 0x00 ; 0 + 2566: 71 e0 ldi r23, 0x01 ; 1 + 2568: 0a dd rcall .-1516 ; 0x1f7e + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 256a: 85 e6 ldi r24, 0x65 ; 101 + 256c: 08 95 ret + +0000256e : + +CommandStatusIdType CommandGetLedGreen(char* OutParam) +{ + LEDGetFuncByName(LED_GREEN, OutParam, TERMINAL_BUFFER_SIZE); + 256e: 40 e0 ldi r20, 0x00 ; 0 + 2570: 51 e0 ldi r21, 0x01 ; 1 + 2572: bc 01 movw r22, r24 + 2574: 80 e2 ldi r24, 0x20 ; 32 + 2576: 8b dd rcall .-1258 ; 0x208e + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 2578: 85 e6 ldi r24, 0x65 ; 101 + 257a: 08 95 ret + +0000257c : + +CommandStatusIdType CommandSetLedGreen(const char* InParam) +{ + if (LEDSetFuncByName(LED_GREEN, InParam)) { + 257c: bc 01 movw r22, r24 + 257e: 80 e2 ldi r24, 0x20 ; 32 + 2580: a3 dd rcall .-1210 ; 0x20c8 + 2582: 81 11 cpse r24, r1 + 2584: 02 c0 rjmp .+4 ; 0x258a + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + 2586: 8a ec ldi r24, 0xCA ; 202 + } +} + 2588: 08 95 ret +} + +CommandStatusIdType CommandSetLedGreen(const char* InParam) +{ + if (LEDSetFuncByName(LED_GREEN, InParam)) { + SettingsSave(); + 258a: 76 db rcall .-2324 ; 0x1c78 + return COMMAND_INFO_OK_ID; + 258c: 84 e6 ldi r24, 0x64 ; 100 + 258e: 08 95 ret + +00002590 : + } +} + +CommandStatusIdType CommandExecLedRed(char* OutMessage) +{ + LEDGetFuncList(OutMessage, TERMINAL_BUFFER_SIZE); + 2590: 60 e0 ldi r22, 0x00 ; 0 + 2592: 71 e0 ldi r23, 0x01 ; 1 + 2594: f4 dc rcall .-1560 ; 0x1f7e + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 2596: 85 e6 ldi r24, 0x65 ; 101 + 2598: 08 95 ret + +0000259a : + +CommandStatusIdType CommandGetLedRed(char* OutParam) +{ + LEDGetFuncByName(LED_RED, OutParam, TERMINAL_BUFFER_SIZE); + 259a: 40 e0 ldi r20, 0x00 ; 0 + 259c: 51 e0 ldi r21, 0x01 ; 1 + 259e: bc 01 movw r22, r24 + 25a0: 80 e1 ldi r24, 0x10 ; 16 + 25a2: 75 dd rcall .-1302 ; 0x208e + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 25a4: 85 e6 ldi r24, 0x65 ; 101 + 25a6: 08 95 ret + +000025a8 : + +CommandStatusIdType CommandSetLedRed(const char* InParam) +{ + if (LEDSetFuncByName(LED_RED, InParam)) { + 25a8: bc 01 movw r22, r24 + 25aa: 80 e1 ldi r24, 0x10 ; 16 + 25ac: 8d dd rcall .-1254 ; 0x20c8 + 25ae: 81 11 cpse r24, r1 + 25b0: 02 c0 rjmp .+4 ; 0x25b6 + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + 25b2: 8a ec ldi r24, 0xCA ; 202 + } +} + 25b4: 08 95 ret +} + +CommandStatusIdType CommandSetLedRed(const char* InParam) +{ + if (LEDSetFuncByName(LED_RED, InParam)) { + SettingsSave(); + 25b6: 60 db rcall .-2368 ; 0x1c78 + return COMMAND_INFO_OK_ID; + 25b8: 84 e6 ldi r24, 0x64 ; 100 + 25ba: 08 95 ret + +000025bc : +} + +CommandStatusIdType CommandExecLogMode(char* OutMessage) +{ + /* Get list of log modes */ + LogGetModeList(OutMessage, TERMINAL_BUFFER_SIZE); + 25bc: 60 e0 ldi r22, 0x00 ; 0 + 25be: 71 e0 ldi r23, 0x01 ; 1 + 25c0: 2b db rcall .-2474 ; 0x1c18 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 25c2: 85 e6 ldi r24, 0x65 ; 101 + 25c4: 08 95 ret + +000025c6 : + +CommandStatusIdType CommandGetLogMode(char* OutParam) +{ + /* Get Logmode */ + LogGetModeByName(OutParam, TERMINAL_BUFFER_SIZE); + 25c6: 60 e0 ldi r22, 0x00 ; 0 + 25c8: 71 e0 ldi r23, 0x01 ; 1 + 25ca: 18 db rcall .-2512 ; 0x1bfc + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 25cc: 85 e6 ldi r24, 0x65 ; 101 + 25ce: 08 95 ret + +000025d0 : + +CommandStatusIdType CommandSetLogMode(const char* InParam) +{ + if (LogSetModeByName(InParam)) { + 25d0: f0 da rcall .-2592 ; 0x1bb2 + 25d2: 81 11 cpse r24, r1 + 25d4: 02 c0 rjmp .+4 ; 0x25da + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + 25d6: 8a ec ldi r24, 0xCA ; 202 + } +} + 25d8: 08 95 ret +} + +CommandStatusIdType CommandSetLogMode(const char* InParam) +{ + if (LogSetModeByName(InParam)) { + SettingsSave(); + 25da: 4e db rcall .-2404 ; 0x1c78 + return COMMAND_INFO_OK_ID; + 25dc: 84 e6 ldi r24, 0x64 ; 100 + 25de: 08 95 ret + +000025e0 : + } +} + +CommandStatusIdType CommandExecLogMem(char* OutMessage) +{ + snprintf_P(OutMessage, TERMINAL_BUFFER_SIZE, + 25e0: 23 e2 ldi r18, 0x23 ; 35 + 25e2: 36 e0 ldi r19, 0x06 ; 6 + 25e4: 3f 93 push r19 + 25e6: 2f 93 push r18 + 25e8: 2b e1 ldi r18, 0x1B ; 27 + 25ea: 36 e0 ldi r19, 0x06 ; 6 + 25ec: 3f 93 push r19 + 25ee: 2f 93 push r18 + 25f0: 25 e1 ldi r18, 0x15 ; 21 + 25f2: 36 e0 ldi r19, 0x06 ; 6 + 25f4: 3f 93 push r19 + 25f6: 2f 93 push r18 + 25f8: 21 e0 ldi r18, 0x01 ; 1 + 25fa: 2f 93 push r18 + 25fc: 1f 92 push r1 + 25fe: 9f 93 push r25 + 2600: 8f 93 push r24 + 2602: 0e 94 06 2e call 0x5c0c ; 0x5c0c + PSTR("%S,%S"), PSTR(COMMAND_LOGMEM_LOADBIN), PSTR(COMMAND_LOGMEM_CLEAR) ); + + return COMMAND_INFO_OK_WITH_TEXT_ID; + 2606: 8d b7 in r24, 0x3d ; 61 + 2608: 9e b7 in r25, 0x3e ; 62 + 260a: 0a 96 adiw r24, 0x0a ; 10 + 260c: 8d bf out 0x3d, r24 ; 61 + 260e: 9e bf out 0x3e, r25 ; 62 +} + 2610: 85 e6 ldi r24, 0x65 ; 101 + 2612: 08 95 ret + +00002614 : + +CommandStatusIdType CommandGetLogMem(char* OutParam) +{ + 2614: cf 93 push r28 + 2616: df 93 push r29 + 2618: ec 01 movw r28, r24 + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, + 261a: 68 da rcall .-2864 ; 0x1aec + 261c: 9f 93 push r25 + 261e: 8f 93 push r24 + 2620: 29 e2 ldi r18, 0x29 ; 41 + 2622: 36 e0 ldi r19, 0x06 ; 6 + 2624: 3f 93 push r19 + 2626: 2f 93 push r18 + 2628: 81 e0 ldi r24, 0x01 ; 1 + 262a: 8f 93 push r24 + 262c: 1f 92 push r1 + 262e: df 93 push r29 + 2630: cf 93 push r28 + 2632: 0e 94 06 2e call 0x5c0c ; 0x5c0c + PSTR("%u"), LogMemFree()); + + + return COMMAND_INFO_OK_WITH_TEXT_ID; + 2636: 8d b7 in r24, 0x3d ; 61 + 2638: 9e b7 in r25, 0x3e ; 62 + 263a: 08 96 adiw r24, 0x08 ; 8 + 263c: 8d bf out 0x3d, r24 ; 61 + 263e: 9e bf out 0x3e, r25 ; 62 +} + 2640: 85 e6 ldi r24, 0x65 ; 101 + 2642: df 91 pop r29 + 2644: cf 91 pop r28 + 2646: 08 95 ret + +00002648 : + +CommandStatusIdType CommandSetLogMem(const char* InParam) +{ + 2648: cf 93 push r28 + 264a: df 93 push r29 + 264c: ec 01 movw r28, r24 + if (strcmp_P(InParam, PSTR(COMMAND_LOGMEM_LOADBIN)) == 0) { + 264e: 6c e2 ldi r22, 0x2C ; 44 + 2650: 76 e0 ldi r23, 0x06 ; 6 + 2652: 0e 94 d5 2d call 0x5baa ; 0x5baa + 2656: 89 2b or r24, r25 + 2658: 81 f0 breq .+32 ; 0x267a + XModemSend(LogMemLoadBlock); + return COMMAND_INFO_XMODEM_WAIT_ID; + } else if (strcmp_P(InParam, PSTR(COMMAND_LOGMEM_CLEAR)) == 0) { + 265a: 64 e3 ldi r22, 0x34 ; 52 + 265c: 76 e0 ldi r23, 0x06 ; 6 + 265e: ce 01 movw r24, r28 + 2660: 0e 94 d5 2d call 0x5baa ; 0x5baa + 2664: 89 2b or r24, r25 + 2666: 21 f0 breq .+8 ; 0x2670 + LogMemClear(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + 2668: 8a ec ldi r24, 0xCA ; 202 + } +} + 266a: df 91 pop r29 + 266c: cf 91 pop r28 + 266e: 08 95 ret +{ + if (strcmp_P(InParam, PSTR(COMMAND_LOGMEM_LOADBIN)) == 0) { + XModemSend(LogMemLoadBlock); + return COMMAND_INFO_XMODEM_WAIT_ID; + } else if (strcmp_P(InParam, PSTR(COMMAND_LOGMEM_CLEAR)) == 0) { + LogMemClear(); + 2670: 28 da rcall .-2992 ; 0x1ac2 + return COMMAND_INFO_OK_ID; + 2672: 84 e6 ldi r24, 0x64 ; 100 + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + } +} + 2674: df 91 pop r29 + 2676: cf 91 pop r28 + 2678: 08 95 ret +} + +CommandStatusIdType CommandSetLogMem(const char* InParam) +{ + if (strcmp_P(InParam, PSTR(COMMAND_LOGMEM_LOADBIN)) == 0) { + XModemSend(LogMemLoadBlock); + 267a: 89 e4 ldi r24, 0x49 ; 73 + 267c: 9d e0 ldi r25, 0x0D ; 13 + 267e: ba d0 rcall .+372 ; 0x27f4 + return COMMAND_INFO_XMODEM_WAIT_ID; + 2680: 8e e6 ldi r24, 0x6E ; 110 + LogMemClear(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + } +} + 2682: df 91 pop r29 + 2684: cf 91 pop r28 + 2686: 08 95 ret + +00002688 : + +CommandStatusIdType CommandGetSetting(char* OutParam) +{ + SettingsGetActiveByName(OutParam, TERMINAL_BUFFER_SIZE); + 2688: 60 e0 ldi r22, 0x00 ; 0 + 268a: 71 e0 ldi r23, 0x01 ; 1 + 268c: c3 db rcall .-2170 ; 0x1e14 + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 268e: 85 e6 ldi r24, 0x65 ; 101 + 2690: 08 95 ret + +00002692 : + +CommandStatusIdType CommandSetSetting(const char* InParam) +{ + if (SettingsSetActiveByName(InParam)) { + 2692: ca db rcall .-2156 ; 0x1e28 + 2694: 81 11 cpse r24, r1 + 2696: 02 c0 rjmp .+4 ; 0x269c + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + 2698: 8a ec ldi r24, 0xCA ; 202 + } +} + 269a: 08 95 ret +} + +CommandStatusIdType CommandSetSetting(const char* InParam) +{ + if (SettingsSetActiveByName(InParam)) { + SettingsSave(); + 269c: ed da rcall .-2598 ; 0x1c78 + return COMMAND_INFO_OK_ID; + 269e: 84 e6 ldi r24, 0x64 ; 100 + 26a0: 08 95 ret + +000026a2 : + } +} + +CommandStatusIdType CommandExecClear(char* OutParam) +{ + MemoryClear(); + 26a2: 0e 94 12 07 call 0xe24 ; 0xe24 + return COMMAND_INFO_OK_ID; +} + 26a6: 84 e6 ldi r24, 0x64 ; 100 + 26a8: 08 95 ret + +000026aa : + +CommandStatusIdType CommandExecHelp(char* OutMessage) +{ + 26aa: bf 92 push r11 + 26ac: cf 92 push r12 + 26ae: df 92 push r13 + 26b0: ef 92 push r14 + 26b2: ff 92 push r15 + 26b4: 0f 93 push r16 + 26b6: 1f 93 push r17 + 26b8: cf 93 push r28 + 26ba: df 93 push r29 + 26bc: 7c 01 movw r14, r24 + const CommandEntryType* EntryPtr = CommandTable; + uint16_t ByteCount = TERMINAL_BUFFER_SIZE - 1; /* Account for '\0' */ + 26be: cf ef ldi r28, 0xFF ; 255 + 26c0: d0 e0 ldi r29, 0x00 ; 0 + return COMMAND_INFO_OK_ID; +} + +CommandStatusIdType CommandExecHelp(char* OutMessage) +{ + const CommandEntryType* EntryPtr = CommandTable; + 26c2: 31 e4 ldi r19, 0x41 ; 65 + 26c4: c3 2e mov r12, r19 + 26c6: 36 e0 ldi r19, 0x06 ; 6 + 26c8: d3 2e mov r13, r19 + *OutMessage++ = c; + CommandName++; + ByteCount--; + } + + *OutMessage++ = ','; + 26ca: 4c e2 ldi r20, 0x2C ; 44 + 26cc: b4 2e mov r11, r20 +CommandStatusIdType CommandExecHelp(char* OutMessage) +{ + const CommandEntryType* EntryPtr = CommandTable; + uint16_t ByteCount = TERMINAL_BUFFER_SIZE - 1; /* Account for '\0' */ + + while(strcmp_P(COMMAND_LIST_END, EntryPtr->Command) != 0) { + 26ce: 86 01 movw r16, r12 + 26d0: b6 01 movw r22, r12 + 26d2: 80 e9 ldi r24, 0x90 ; 144 + 26d4: 90 e2 ldi r25, 0x20 ; 32 + 26d6: 0e 94 d5 2d call 0x5baa ; 0x5baa + 26da: 89 2b or r24, r25 + 26dc: 21 f1 breq .+72 ; 0x2726 + const char* CommandName = EntryPtr->Command; + char c; + + while( (c = pgm_read_byte(CommandName)) != '\0' && ByteCount > 32) { + 26de: f6 01 movw r30, r12 + 26e0: 84 91 lpm r24, Z + 26e2: 88 23 and r24, r24 + 26e4: 89 f0 breq .+34 ; 0x2708 + 26e6: c1 32 cpi r28, 0x21 ; 33 + 26e8: d1 05 cpc r29, r1 + 26ea: 70 f0 brcs .+28 ; 0x2708 + 26ec: d7 01 movw r26, r14 + 26ee: 03 c0 rjmp .+6 ; 0x26f6 + 26f0: c0 32 cpi r28, 0x20 ; 32 + 26f2: d1 05 cpc r29, r1 + 26f4: 49 f0 breq .+18 ; 0x2708 + *OutMessage++ = c; + 26f6: 8d 93 st X+, r24 + 26f8: 7d 01 movw r14, r26 + CommandName++; + 26fa: 0f 5f subi r16, 0xFF ; 255 + 26fc: 1f 4f sbci r17, 0xFF ; 255 + ByteCount--; + 26fe: 21 97 sbiw r28, 0x01 ; 1 + + while(strcmp_P(COMMAND_LIST_END, EntryPtr->Command) != 0) { + const char* CommandName = EntryPtr->Command; + char c; + + while( (c = pgm_read_byte(CommandName)) != '\0' && ByteCount > 32) { + 2700: f8 01 movw r30, r16 + 2702: 84 91 lpm r24, Z + 2704: 81 11 cpse r24, r1 + 2706: f4 cf rjmp .-24 ; 0x26f0 + *OutMessage++ = c; + CommandName++; + ByteCount--; + } + + *OutMessage++ = ','; + 2708: f7 01 movw r30, r14 + 270a: b1 92 st Z+, r11 + 270c: 7f 01 movw r14, r30 + ByteCount--; + 270e: 21 97 sbiw r28, 0x01 ; 1 + + EntryPtr++; + 2710: f6 e1 ldi r31, 0x16 ; 22 + 2712: cf 0e add r12, r31 + 2714: d1 1c adc r13, r1 +CommandStatusIdType CommandExecHelp(char* OutMessage) +{ + const CommandEntryType* EntryPtr = CommandTable; + uint16_t ByteCount = TERMINAL_BUFFER_SIZE - 1; /* Account for '\0' */ + + while(strcmp_P(COMMAND_LIST_END, EntryPtr->Command) != 0) { + 2716: 86 01 movw r16, r12 + 2718: b6 01 movw r22, r12 + 271a: 80 e9 ldi r24, 0x90 ; 144 + 271c: 90 e2 ldi r25, 0x20 ; 32 + 271e: 0e 94 d5 2d call 0x5baa ; 0x5baa + 2722: 89 2b or r24, r25 + 2724: e1 f6 brne .-72 ; 0x26de + ByteCount--; + + EntryPtr++; + } + + *--OutMessage = '\0'; + 2726: f7 01 movw r30, r14 + 2728: 31 97 sbiw r30, 0x01 ; 1 + 272a: 10 82 st Z, r1 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 272c: 85 e6 ldi r24, 0x65 ; 101 + 272e: df 91 pop r29 + 2730: cf 91 pop r28 + 2732: 1f 91 pop r17 + 2734: 0f 91 pop r16 + 2736: ff 90 pop r15 + 2738: ef 90 pop r14 + 273a: df 90 pop r13 + 273c: cf 90 pop r12 + 273e: bf 90 pop r11 + 2740: 08 95 ret + +00002742 : + +CommandStatusIdType CommandGetRssi(char* OutParam) +{ + 2742: fc 01 movw r30, r24 +} + +static inline +uint16_t AntennaLevelGet(void) +{ + ADCA.CH0.CTRL |= ADC_CH_START_bm; + 2744: 20 91 20 02 lds r18, 0x0220 + 2748: 20 68 ori r18, 0x80 ; 128 + 274a: 20 93 20 02 sts 0x0220, r18 + while( !(ADCA.CH0.INTFLAGS & ADC_CH_CHIF_bm) ); + 274e: 20 91 23 02 lds r18, 0x0223 + 2752: 20 ff sbrs r18, 0 + 2754: fc cf rjmp .-8 ; 0x274e + + ADCA.CH0.INTFLAGS = ADC_CH_CHIF_bm; + 2756: 81 e0 ldi r24, 0x01 ; 1 + 2758: 80 93 23 02 sts 0x0223, r24 + + int16_t Result = ADCA.CH0RES - ANTENNA_LEVEL_OFFSET; + 275c: a0 91 10 02 lds r26, 0x0210 + 2760: b0 91 11 02 lds r27, 0x0211 + if (Result < 0) Result = 0; + + return (uint16_t) (((uint32_t) Result * ANTENNA_LEVEL_NUMERATOR) / ANTENNA_LEVEL_DENOMINATOR); + 2764: ae 5b subi r26, 0xBE ; 190 + 2766: b1 09 sbc r27, r1 + 2768: b7 fd sbrc r27, 7 + 276a: 1c c0 rjmp .+56 ; 0x27a4 + 276c: 29 e6 ldi r18, 0x69 ; 105 + 276e: 37 e5 ldi r19, 0x57 ; 87 + 2770: 4b e0 ldi r20, 0x0B ; 11 + 2772: 50 e0 ldi r21, 0x00 ; 0 + 2774: 0e 94 56 2d call 0x5aac ; 0x5aac <__mulshisi3> + 2778: aa 27 eor r26, r26 + 277a: bb 27 eor r27, r27 + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, + 277c: 9f 93 push r25 + 277e: 8f 93 push r24 + 2780: 2a e3 ldi r18, 0x3A ; 58 + 2782: 36 e0 ldi r19, 0x06 ; 6 + 2784: 3f 93 push r19 + 2786: 2f 93 push r18 + 2788: 81 e0 ldi r24, 0x01 ; 1 + 278a: 8f 93 push r24 + 278c: 1f 92 push r1 + 278e: ff 93 push r31 + 2790: ef 93 push r30 + 2792: 0e 94 06 2e call 0x5c0c ; 0x5c0c + PSTR("%5u mV"), AntennaLevelGet()); + + + return COMMAND_INFO_OK_WITH_TEXT_ID; + 2796: 8d b7 in r24, 0x3d ; 61 + 2798: 9e b7 in r25, 0x3e ; 62 + 279a: 08 96 adiw r24, 0x08 ; 8 + 279c: 8d bf out 0x3d, r24 ; 61 + 279e: 9e bf out 0x3e, r25 ; 62 +} + 27a0: 85 e6 ldi r24, 0x65 ; 101 + 27a2: 08 95 ret + 27a4: a0 e0 ldi r26, 0x00 ; 0 + 27a6: b0 e0 ldi r27, 0x00 ; 0 + 27a8: e1 cf rjmp .-62 ; 0x276c + +000027aa : +static uint32_t BlockAddress; + +static XModemCallbackType CallbackFunc; + +static uint8_t CalcChecksum(const void* Buffer, uint16_t ByteCount) { + uint8_t Checksum = CHECKSUM_INIT_VALUE; + 27aa: 80 e0 ldi r24, 0x00 ; 0 + uint8_t* DataPtr = (uint8_t*) Buffer; + 27ac: ec e3 ldi r30, 0x3C ; 60 + 27ae: f9 e2 ldi r31, 0x29 ; 41 + + while(ByteCount--) { + Checksum += *DataPtr++; + 27b0: 91 91 ld r25, Z+ + 27b2: 89 0f add r24, r25 + +static uint8_t CalcChecksum(const void* Buffer, uint16_t ByteCount) { + uint8_t Checksum = CHECKSUM_INIT_VALUE; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 27b4: 99 e2 ldi r25, 0x29 ; 41 + 27b6: ec 3b cpi r30, 0xBC ; 188 + 27b8: f9 07 cpc r31, r25 + 27ba: d1 f7 brne .-12 ; 0x27b0 + Checksum += *DataPtr++; + } + + return Checksum; +} + 27bc: 08 95 ret + +000027be : + +void XModemReceive(XModemCallbackType TheCallbackFunc) +{ + State = STATE_RECEIVE_INIT; + 27be: 21 e0 ldi r18, 0x01 ; 1 + 27c0: 20 93 9b 28 sts 0x289B, r18 + CurrentFrameNumber = FIRST_FRAME_NUMBER; + 27c4: 20 93 9c 28 sts 0x289C, r18 + RetryCount = RECV_INIT_COUNT; + 27c8: 2c e3 ldi r18, 0x3C ; 60 + 27ca: 20 93 9d 28 sts 0x289D, r18 + RetryTimeout = RECV_INIT_TIMEOUT; + 27ce: 25 e0 ldi r18, 0x05 ; 5 + 27d0: 30 e0 ldi r19, 0x00 ; 0 + 27d2: 20 93 9e 28 sts 0x289E, r18 + 27d6: 30 93 9f 28 sts 0x289F, r19 + BlockAddress = 0; + 27da: 10 92 a0 28 sts 0x28A0, r1 + 27de: 10 92 a1 28 sts 0x28A1, r1 + 27e2: 10 92 a2 28 sts 0x28A2, r1 + 27e6: 10 92 a3 28 sts 0x28A3, r1 + + CallbackFunc = TheCallbackFunc; + 27ea: 80 93 a4 28 sts 0x28A4, r24 + 27ee: 90 93 a5 28 sts 0x28A5, r25 + 27f2: 08 95 ret + +000027f4 : +} + +void XModemSend(XModemCallbackType TheCallbackFunc) +{ + State = STATE_SEND_INIT; + 27f4: 27 e0 ldi r18, 0x07 ; 7 + 27f6: 20 93 9b 28 sts 0x289B, r18 + RetryTimeout = SEND_INIT_TIMEOUT; + 27fa: 2c e2 ldi r18, 0x2C ; 44 + 27fc: 31 e0 ldi r19, 0x01 ; 1 + 27fe: 20 93 9e 28 sts 0x289E, r18 + 2802: 30 93 9f 28 sts 0x289F, r19 + BlockAddress = 0; + 2806: 10 92 a0 28 sts 0x28A0, r1 + 280a: 10 92 a1 28 sts 0x28A1, r1 + 280e: 10 92 a2 28 sts 0x28A2, r1 + 2812: 10 92 a3 28 sts 0x28A3, r1 + + CallbackFunc = TheCallbackFunc; + 2816: 80 93 a4 28 sts 0x28A4, r24 + 281a: 90 93 a5 28 sts 0x28A5, r25 + 281e: 08 95 ret + +00002820 : +} + +bool XModemProcessByte(uint8_t Byte) +{ + 2820: cf 93 push r28 + 2822: c8 2f mov r28, r24 + switch(State) { + 2824: 90 91 9b 28 lds r25, 0x289B + 2828: 95 30 cpi r25, 0x05 ; 5 + 282a: 09 f4 brne .+2 ; 0x282e + 282c: 84 c0 rjmp .+264 ; 0x2936 + 282e: e0 f0 brcs .+56 ; 0x2868 + 2830: 97 30 cpi r25, 0x07 ; 7 + 2832: 09 f4 brne .+2 ; 0x2836 + 2834: 4c c0 rjmp .+152 ; 0x28ce + 2836: 60 f5 brcc .+88 ; 0x2890 + } + + break; + + case STATE_RECEIVE_PROCESS: + if (ReceivedFrameNumber == CurrentFrameNumber) { + 2838: 20 91 a9 28 lds r18, 0x28A9 + 283c: 80 91 9c 28 lds r24, 0x289C + 2840: 28 17 cp r18, r24 + 2842: 09 f4 brne .+2 ; 0x2846 + 2844: ec c0 rjmp .+472 ; 0x2a1e + } else { + /* Data seems to be damaged */ + TerminalSendByte(BYTE_NAK); + State = STATE_RECEIVE_WAIT; + } + } else if (ReceivedFrameNumber == (CurrentFrameNumber - 1)) { + 2846: 30 e0 ldi r19, 0x00 ; 0 + 2848: 90 e0 ldi r25, 0x00 ; 0 + 284a: 01 97 sbiw r24, 0x01 ; 1 + 284c: 28 17 cp r18, r24 + 284e: 39 07 cpc r19, r25 + 2850: 09 f4 brne .+2 ; 0x2854 + 2852: 14 c1 rjmp .+552 ; 0x2a7c +INLINE void TerminalSendByte(uint8_t Byte) { CDC_Device_SendByte(&TerminalHandle, Byte); } + 2854: 68 e1 ldi r22, 0x18 ; 24 + 2856: 80 e0 ldi r24, 0x00 ; 0 + 2858: 90 e2 ldi r25, 0x20 ; 32 + 285a: 0e 94 bf 2b call 0x577e ; 0x577e + TerminalSendByte(BYTE_ACK); + State = STATE_RECEIVE_WAIT; + } else { + /* This frame is completely out of order. Just cancel */ + TerminalSendByte(BYTE_CAN); + State = STATE_OFF; + 285e: 10 92 9b 28 sts 0x289B, r1 + default: + return false; + break; + } + + return true; + 2862: 81 e0 ldi r24, 0x01 ; 1 +} + 2864: cf 91 pop r28 + 2866: 08 95 ret + CallbackFunc = TheCallbackFunc; +} + +bool XModemProcessByte(uint8_t Byte) +{ + switch(State) { + 2868: 93 30 cpi r25, 0x03 ; 3 + 286a: 09 f4 brne .+2 ; 0x286e + 286c: 5c c0 rjmp .+184 ; 0x2926 + 286e: b8 f0 brcs .+46 ; 0x289e + ReceivedFrameNumber = Byte; + State = STATE_RECEIVE_FRAMENUM2; + break; + + case STATE_RECEIVE_FRAMENUM2: + if (Byte == (255 - ReceivedFrameNumber)) { + 2870: 90 e0 ldi r25, 0x00 ; 0 + 2872: 40 91 a9 28 lds r20, 0x28A9 + 2876: 2f ef ldi r18, 0xFF ; 255 + 2878: 30 e0 ldi r19, 0x00 ; 0 + 287a: 24 1b sub r18, r20 + 287c: 31 09 sbc r19, r1 + 287e: 82 17 cp r24, r18 + 2880: 93 07 cpc r25, r19 + 2882: 09 f0 breq .+2 ; 0x2886 + 2884: 6f c0 rjmp .+222 ; 0x2964 + /* frame-number check passed. */ + State = STATE_RECEIVE_DATA; + 2886: 85 e0 ldi r24, 0x05 ; 5 + 2888: 80 93 9b 28 sts 0x289B, r24 + default: + return false; + break; + } + + return true; + 288c: 81 e0 ldi r24, 0x01 ; 1 + 288e: ea cf rjmp .-44 ; 0x2864 + CallbackFunc = TheCallbackFunc; +} + +bool XModemProcessByte(uint8_t Byte) +{ + switch(State) { + 2890: 98 30 cpi r25, 0x08 ; 8 + 2892: 19 f1 breq .+70 ; 0x28da + 2894: 99 30 cpi r25, 0x09 ; 9 + 2896: b1 f0 breq .+44 ; 0x28c4 + /* Receive Ack */ + State = STATE_OFF; + break; + + default: + return false; + 2898: 80 e0 ldi r24, 0x00 ; 0 + break; + } + + return true; +} + 289a: cf 91 pop r28 + 289c: 08 95 ret + CallbackFunc = TheCallbackFunc; +} + +bool XModemProcessByte(uint8_t Byte) +{ + switch(State) { + 289e: 91 30 cpi r25, 0x01 ; 1 + 28a0: d8 f3 brcs .-10 ; 0x2898 + case STATE_RECEIVE_INIT: + case STATE_RECEIVE_WAIT: + if (Byte == BYTE_SOH) { + 28a2: 81 30 cpi r24, 0x01 ; 1 + 28a4: 09 f4 brne .+2 ; 0x28a8 + 28a6: ec c0 rjmp .+472 ; 0x2a80 + /* Next frame incoming */ + BufferIdx = 0; + Checksum = CHECKSUM_INIT_VALUE; + State = STATE_RECEIVE_FRAMENUM1; + } else if (Byte == BYTE_EOT) { + 28a8: 84 30 cpi r24, 0x04 ; 4 + 28aa: 39 f0 breq .+14 ; 0x28ba + /* Transmission finished */ + TerminalSendByte(BYTE_ACK); + State = STATE_OFF; + } else if ( (Byte == BYTE_CAN) || (Byte == BYTE_ESC) ) { + 28ac: 88 31 cpi r24, 0x18 ; 24 + 28ae: 51 f0 breq .+20 ; 0x28c4 + 28b0: 8b 31 cpi r24, 0x1B ; 27 + 28b2: 41 f0 breq .+16 ; 0x28c4 + default: + return false; + break; + } + + return true; + 28b4: 81 e0 ldi r24, 0x01 ; 1 +} + 28b6: cf 91 pop r28 + 28b8: 08 95 ret + 28ba: 66 e0 ldi r22, 0x06 ; 6 + 28bc: 80 e0 ldi r24, 0x00 ; 0 + 28be: 90 e2 ldi r25, 0x20 ; 32 + 28c0: 0e 94 bf 2b call 0x577e ; 0x577e + + case STATE_SEND_WAIT: + if (Byte == BYTE_CAN) { + /* Cancel */ + TerminalSendByte(BYTE_ACK); + State = STATE_OFF; + 28c4: 10 92 9b 28 sts 0x289B, r1 + default: + return false; + break; + } + + return true; + 28c8: 81 e0 ldi r24, 0x01 ; 1 +} + 28ca: cf 91 pop r28 + 28cc: 08 95 ret + + break; + + case STATE_SEND_INIT: + /* Start sending on NAK */ + if (Byte == BYTE_NAK) { + 28ce: 85 31 cpi r24, 0x15 ; 21 + 28d0: 09 f4 brne .+2 ; 0x28d4 + 28d2: 57 c0 rjmp .+174 ; 0x2982 + CurrentFrameNumber = FIRST_FRAME_NUMBER - 1; + Byte = BYTE_ACK; + } else if (Byte == BYTE_ESC) { + 28d4: 8b 31 cpi r24, 0x1B ; 27 + 28d6: 09 f4 brne .+2 ; 0x28da + 28d8: 50 c0 rjmp .+160 ; 0x297a + } + + /* Fallthrough */ + + case STATE_SEND_WAIT: + if (Byte == BYTE_CAN) { + 28da: c8 31 cpi r28, 0x18 ; 24 + 28dc: 71 f3 breq .-36 ; 0x28ba + /* Cancel */ + TerminalSendByte(BYTE_ACK); + State = STATE_OFF; + } else if (Byte == BYTE_ACK) { + 28de: c6 30 cpi r28, 0x06 ; 6 + 28e0: 09 f4 brne .+2 ; 0x28e4 + 28e2: 51 c0 rjmp .+162 ; 0x2986 + BlockAddress += XMODEM_BLOCK_SIZE; + } else { + TerminalSendByte(BYTE_EOT); + State = STATE_SEND_EOT; + } + } else if (Byte == BYTE_NAK){ + 28e4: c5 31 cpi r28, 0x15 ; 21 + 28e6: 31 f7 brne .-52 ; 0x28b4 + 28e8: 61 e0 ldi r22, 0x01 ; 1 + 28ea: 80 e0 ldi r24, 0x00 ; 0 + 28ec: 90 e2 ldi r25, 0x20 ; 32 + 28ee: 0e 94 bf 2b call 0x577e ; 0x577e + 28f2: 60 91 9c 28 lds r22, 0x289C + 28f6: 80 e0 ldi r24, 0x00 ; 0 + 28f8: 90 e2 ldi r25, 0x20 ; 32 + 28fa: 0e 94 bf 2b call 0x577e ; 0x577e + /* Resend frame */ + TerminalSendByte(BYTE_SOH); + TerminalSendByte(CurrentFrameNumber); + TerminalSendByte(255 - CurrentFrameNumber); + 28fe: 60 91 9c 28 lds r22, 0x289C + 2902: 60 95 com r22 + 2904: 80 e0 ldi r24, 0x00 ; 0 + 2906: 90 e2 ldi r25, 0x20 ; 32 + 2908: 0e 94 bf 2b call 0x577e ; 0x577e + TerminalSendBlock(TerminalBuffer, XMODEM_BLOCK_SIZE); + 290c: 60 e8 ldi r22, 0x80 ; 128 + 290e: 70 e0 ldi r23, 0x00 ; 0 + 2910: 8c e3 ldi r24, 0x3C ; 60 + 2912: 99 e2 ldi r25, 0x29 ; 41 + 2914: 4a dc rcall .-1900 ; 0x21aa + TerminalSendByte(CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE)); + 2916: 49 df rcall .-366 ; 0x27aa + 2918: 68 2f mov r22, r24 + 291a: 80 e0 ldi r24, 0x00 ; 0 + 291c: 90 e2 ldi r25, 0x20 ; 32 + 291e: 0e 94 bf 2b call 0x577e ; 0x577e + default: + return false; + break; + } + + return true; + 2922: 81 e0 ldi r24, 0x01 ; 1 + 2924: 9f cf rjmp .-194 ; 0x2864 + + break; + + case STATE_RECEIVE_FRAMENUM1: + /* Store frame number */ + ReceivedFrameNumber = Byte; + 2926: 80 93 a9 28 sts 0x28A9, r24 + State = STATE_RECEIVE_FRAMENUM2; + 292a: 84 e0 ldi r24, 0x04 ; 4 + 292c: 80 93 9b 28 sts 0x289B, r24 + default: + return false; + break; + } + + return true; + 2930: 81 e0 ldi r24, 0x01 ; 1 +} + 2932: cf 91 pop r28 + 2934: 08 95 ret + + break; + + case STATE_RECEIVE_DATA: + /* Process byte and update checksum */ + TerminalBuffer[BufferIdx++] = Byte; + 2936: 20 91 a6 28 lds r18, 0x28A6 + 293a: 30 91 a7 28 lds r19, 0x28A7 + 293e: f9 01 movw r30, r18 + 2940: e4 5c subi r30, 0xC4 ; 196 + 2942: f6 4d sbci r31, 0xD6 ; 214 + 2944: 80 83 st Z, r24 + 2946: c9 01 movw r24, r18 + 2948: 01 96 adiw r24, 0x01 ; 1 + 294a: 80 93 a6 28 sts 0x28A6, r24 + 294e: 90 93 a7 28 sts 0x28A7, r25 + + if (BufferIdx == XMODEM_BLOCK_SIZE) { + 2952: 80 38 cpi r24, 0x80 ; 128 + 2954: 91 05 cpc r25, r1 + 2956: 09 f0 breq .+2 ; 0x295a + 2958: ad cf rjmp .-166 ; 0x28b4 + /* Block full */ + State = STATE_RECEIVE_PROCESS; + 295a: 86 e0 ldi r24, 0x06 ; 6 + 295c: 80 93 9b 28 sts 0x289B, r24 + default: + return false; + break; + } + + return true; + 2960: 81 e0 ldi r24, 0x01 ; 1 + 2962: 80 cf rjmp .-256 ; 0x2864 + 2964: 65 e1 ldi r22, 0x15 ; 21 + 2966: 80 e0 ldi r24, 0x00 ; 0 + 2968: 90 e2 ldi r25, 0x20 ; 32 + 296a: 0e 94 bf 2b call 0x577e ; 0x577e + State = STATE_RECEIVE_WAIT; + } + } else if (ReceivedFrameNumber == (CurrentFrameNumber - 1)) { + /* This is a retransmission */ + TerminalSendByte(BYTE_ACK); + State = STATE_RECEIVE_WAIT; + 296e: 82 e0 ldi r24, 0x02 ; 2 + 2970: 80 93 9b 28 sts 0x289B, r24 + default: + return false; + break; + } + + return true; + 2974: 81 e0 ldi r24, 0x01 ; 1 +} + 2976: cf 91 pop r28 + 2978: 08 95 ret + /* Start sending on NAK */ + if (Byte == BYTE_NAK) { + CurrentFrameNumber = FIRST_FRAME_NUMBER - 1; + Byte = BYTE_ACK; + } else if (Byte == BYTE_ESC) { + State = STATE_OFF; + 297a: 10 92 9b 28 sts 0x289B, r1 + default: + return false; + break; + } + + return true; + 297e: 81 e0 ldi r24, 0x01 ; 1 + 2980: 9a cf rjmp .-204 ; 0x28b6 + break; + + case STATE_SEND_INIT: + /* Start sending on NAK */ + if (Byte == BYTE_NAK) { + CurrentFrameNumber = FIRST_FRAME_NUMBER - 1; + 2982: 10 92 9c 28 sts 0x289C, r1 + /* Cancel */ + TerminalSendByte(BYTE_ACK); + State = STATE_OFF; + } else if (Byte == BYTE_ACK) { + /* Acknowledge. Proceed to next frame, get data and calc checksum */ + CurrentFrameNumber++; + 2986: 80 91 9c 28 lds r24, 0x289C + 298a: 8f 5f subi r24, 0xFF ; 255 + 298c: 80 93 9c 28 sts 0x289C, r24 + + if (CallbackFunc(TerminalBuffer, BlockAddress, XMODEM_BLOCK_SIZE)) { + 2990: 40 91 a0 28 lds r20, 0x28A0 + 2994: 50 91 a1 28 lds r21, 0x28A1 + 2998: 60 91 a2 28 lds r22, 0x28A2 + 299c: 70 91 a3 28 lds r23, 0x28A3 + 29a0: e0 91 a4 28 lds r30, 0x28A4 + 29a4: f0 91 a5 28 lds r31, 0x28A5 + 29a8: 20 e8 ldi r18, 0x80 ; 128 + 29aa: 30 e0 ldi r19, 0x00 ; 0 + 29ac: 8c e3 ldi r24, 0x3C ; 60 + 29ae: 99 e2 ldi r25, 0x29 ; 41 + 29b0: 09 95 icall + 29b2: 88 23 and r24, r24 + 29b4: 09 f4 brne .+2 ; 0x29b8 + 29b6: 6f c0 rjmp .+222 ; 0x2a96 + 29b8: 61 e0 ldi r22, 0x01 ; 1 + 29ba: 80 e0 ldi r24, 0x00 ; 0 + 29bc: 90 e2 ldi r25, 0x20 ; 32 + 29be: 0e 94 bf 2b call 0x577e ; 0x577e + 29c2: 60 91 9c 28 lds r22, 0x289C + 29c6: 80 e0 ldi r24, 0x00 ; 0 + 29c8: 90 e2 ldi r25, 0x20 ; 32 + 29ca: 0e 94 bf 2b call 0x577e ; 0x577e + TerminalSendByte(BYTE_SOH); + TerminalSendByte(CurrentFrameNumber); + TerminalSendByte(255 - CurrentFrameNumber); + 29ce: 60 91 9c 28 lds r22, 0x289C + 29d2: 60 95 com r22 + 29d4: 80 e0 ldi r24, 0x00 ; 0 + 29d6: 90 e2 ldi r25, 0x20 ; 32 + 29d8: 0e 94 bf 2b call 0x577e ; 0x577e + TerminalSendBlock(TerminalBuffer, XMODEM_BLOCK_SIZE); + 29dc: 60 e8 ldi r22, 0x80 ; 128 + 29de: 70 e0 ldi r23, 0x00 ; 0 + 29e0: 8c e3 ldi r24, 0x3C ; 60 + 29e2: 99 e2 ldi r25, 0x29 ; 41 + 29e4: e2 db rcall .-2108 ; 0x21aa + TerminalSendByte(CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE)); + 29e6: e1 de rcall .-574 ; 0x27aa + 29e8: 68 2f mov r22, r24 + 29ea: 80 e0 ldi r24, 0x00 ; 0 + 29ec: 90 e2 ldi r25, 0x20 ; 32 + 29ee: 0e 94 bf 2b call 0x577e ; 0x577e + + BlockAddress += XMODEM_BLOCK_SIZE; + 29f2: 80 91 a0 28 lds r24, 0x28A0 + 29f6: 90 91 a1 28 lds r25, 0x28A1 + 29fa: a0 91 a2 28 lds r26, 0x28A2 + 29fe: b0 91 a3 28 lds r27, 0x28A3 + 2a02: 80 58 subi r24, 0x80 ; 128 + 2a04: 9f 4f sbci r25, 0xFF ; 255 + 2a06: af 4f sbci r26, 0xFF ; 255 + 2a08: bf 4f sbci r27, 0xFF ; 255 + 2a0a: 80 93 a0 28 sts 0x28A0, r24 + 2a0e: 90 93 a1 28 sts 0x28A1, r25 + 2a12: a0 93 a2 28 sts 0x28A2, r26 + 2a16: b0 93 a3 28 sts 0x28A3, r27 + default: + return false; + break; + } + + return true; + 2a1a: 81 e0 ldi r24, 0x01 ; 1 + 2a1c: 4c cf rjmp .-360 ; 0x28b6 + + case STATE_RECEIVE_PROCESS: + if (ReceivedFrameNumber == CurrentFrameNumber) { + /* This is the expected frame. Calculate and verify checksum */ + + if (CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE) == Byte) { + 2a1e: c5 de rcall .-630 ; 0x27aa + 2a20: 8c 13 cpse r24, r28 + 2a22: a0 cf rjmp .-192 ; 0x2964 + /* Checksum is valid. Pass received data to callback function */ + if (CallbackFunc(TerminalBuffer, BlockAddress, XMODEM_BLOCK_SIZE)) { + 2a24: 40 91 a0 28 lds r20, 0x28A0 + 2a28: 50 91 a1 28 lds r21, 0x28A1 + 2a2c: 60 91 a2 28 lds r22, 0x28A2 + 2a30: 70 91 a3 28 lds r23, 0x28A3 + 2a34: e0 91 a4 28 lds r30, 0x28A4 + 2a38: f0 91 a5 28 lds r31, 0x28A5 + 2a3c: 20 e8 ldi r18, 0x80 ; 128 + 2a3e: 30 e0 ldi r19, 0x00 ; 0 + 2a40: 8c e3 ldi r24, 0x3C ; 60 + 2a42: 99 e2 ldi r25, 0x29 ; 41 + 2a44: 09 95 icall + 2a46: 88 23 and r24, r24 + 2a48: 81 f1 breq .+96 ; 0x2aaa + /* Proceed to next frame and send ACK */ + CurrentFrameNumber++; + 2a4a: 80 91 9c 28 lds r24, 0x289C + 2a4e: 8f 5f subi r24, 0xFF ; 255 + 2a50: 80 93 9c 28 sts 0x289C, r24 + BlockAddress += XMODEM_BLOCK_SIZE; + 2a54: 80 91 a0 28 lds r24, 0x28A0 + 2a58: 90 91 a1 28 lds r25, 0x28A1 + 2a5c: a0 91 a2 28 lds r26, 0x28A2 + 2a60: b0 91 a3 28 lds r27, 0x28A3 + 2a64: 80 58 subi r24, 0x80 ; 128 + 2a66: 9f 4f sbci r25, 0xFF ; 255 + 2a68: af 4f sbci r26, 0xFF ; 255 + 2a6a: bf 4f sbci r27, 0xFF ; 255 + 2a6c: 80 93 a0 28 sts 0x28A0, r24 + 2a70: 90 93 a1 28 sts 0x28A1, r25 + 2a74: a0 93 a2 28 sts 0x28A2, r26 + 2a78: b0 93 a3 28 sts 0x28A3, r27 + 2a7c: 66 e0 ldi r22, 0x06 ; 6 + 2a7e: 73 cf rjmp .-282 ; 0x2966 + switch(State) { + case STATE_RECEIVE_INIT: + case STATE_RECEIVE_WAIT: + if (Byte == BYTE_SOH) { + /* Next frame incoming */ + BufferIdx = 0; + 2a80: 10 92 a6 28 sts 0x28A6, r1 + 2a84: 10 92 a7 28 sts 0x28A7, r1 + Checksum = CHECKSUM_INIT_VALUE; + 2a88: 10 92 a8 28 sts 0x28A8, r1 + State = STATE_RECEIVE_FRAMENUM1; + 2a8c: 83 e0 ldi r24, 0x03 ; 3 + 2a8e: 80 93 9b 28 sts 0x289B, r24 + default: + return false; + break; + } + + return true; + 2a92: 81 e0 ldi r24, 0x01 ; 1 + 2a94: e7 ce rjmp .-562 ; 0x2864 + 2a96: 64 e0 ldi r22, 0x04 ; 4 + 2a98: 80 e0 ldi r24, 0x00 ; 0 + 2a9a: 90 e2 ldi r25, 0x20 ; 32 + 2a9c: 0e 94 bf 2b call 0x577e ; 0x577e + TerminalSendByte(CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE)); + + BlockAddress += XMODEM_BLOCK_SIZE; + } else { + TerminalSendByte(BYTE_EOT); + State = STATE_SEND_EOT; + 2aa0: 89 e0 ldi r24, 0x09 ; 9 + 2aa2: 80 93 9b 28 sts 0x289B, r24 + default: + return false; + break; + } + + return true; + 2aa6: 81 e0 ldi r24, 0x01 ; 1 + 2aa8: dd ce rjmp .-582 ; 0x2864 + 2aaa: 68 e1 ldi r22, 0x18 ; 24 + 2aac: 80 e0 ldi r24, 0x00 ; 0 + 2aae: 90 e2 ldi r25, 0x20 ; 32 + 2ab0: 0e 94 bf 2b call 0x577e ; 0x577e + 2ab4: cf ce rjmp .-610 ; 0x2854 + +00002ab6 : +} + +void XModemTick(void) +{ + /* Timeouts go here */ + switch(State) { + 2ab6: 80 91 9b 28 lds r24, 0x289B + 2aba: 81 30 cpi r24, 0x01 ; 1 + 2abc: 99 f0 breq .+38 ; 0x2ae4 + 2abe: 87 30 cpi r24, 0x07 ; 7 + 2ac0: 09 f0 breq .+2 ; 0x2ac4 + 2ac2: 08 95 ret + RetryTimeout = RECV_INIT_TIMEOUT; + } + break; + + case STATE_SEND_INIT: + if (RetryTimeout-- == 0) { + 2ac4: 80 91 9e 28 lds r24, 0x289E + 2ac8: 90 91 9f 28 lds r25, 0x289F + 2acc: 9c 01 movw r18, r24 + 2ace: 21 50 subi r18, 0x01 ; 1 + 2ad0: 31 09 sbc r19, r1 + 2ad2: 20 93 9e 28 sts 0x289E, r18 + 2ad6: 30 93 9f 28 sts 0x289F, r19 + 2ada: 89 2b or r24, r25 + 2adc: 91 f7 brne .-28 ; 0x2ac2 + /* Abort */ + State = STATE_OFF; + 2ade: 10 92 9b 28 sts 0x289B, r1 + 2ae2: 08 95 ret +void XModemTick(void) +{ + /* Timeouts go here */ + switch(State) { + case STATE_RECEIVE_INIT: + if (RetryTimeout-- == 0) { + 2ae4: 80 91 9e 28 lds r24, 0x289E + 2ae8: 90 91 9f 28 lds r25, 0x289F + 2aec: 9c 01 movw r18, r24 + 2aee: 21 50 subi r18, 0x01 ; 1 + 2af0: 31 09 sbc r19, r1 + 2af2: 20 93 9e 28 sts 0x289E, r18 + 2af6: 30 93 9f 28 sts 0x289F, r19 + 2afa: 89 2b or r24, r25 + 2afc: 11 f7 brne .-60 ; 0x2ac2 + if (RetryCount-- > 0) { + 2afe: 80 91 9d 28 lds r24, 0x289D + 2b02: 98 2f mov r25, r24 + 2b04: 91 50 subi r25, 0x01 ; 1 + 2b06: 90 93 9d 28 sts 0x289D, r25 + 2b0a: 81 11 cpse r24, r1 + 2b0c: 09 c0 rjmp .+18 ; 0x2b20 + /* Put out communication request */ + TerminalSendChar(BYTE_NAK); + } else { + /* Just shut off after some time. */ + State = STATE_OFF; + 2b0e: 10 92 9b 28 sts 0x289B, r1 + } + + RetryTimeout = RECV_INIT_TIMEOUT; + 2b12: 85 e0 ldi r24, 0x05 ; 5 + 2b14: 90 e0 ldi r25, 0x00 ; 0 + 2b16: 80 93 9e 28 sts 0x289E, r24 + 2b1a: 90 93 9f 28 sts 0x289F, r25 + 2b1e: 08 95 ret +void EVENT_USB_Device_Connect(void); +void EVENT_USB_Device_Disconnect(void); +void EVENT_USB_Device_ConfigurationChanged(void); +void EVENT_USB_Device_ControlRequest(void); + +INLINE void TerminalSendChar(char c) { CDC_Device_SendByte(&TerminalHandle, c); } + 2b20: 65 e1 ldi r22, 0x15 ; 21 + 2b22: 80 e0 ldi r24, 0x00 ; 0 + 2b24: 90 e2 ldi r25, 0x20 ; 32 + 2b26: 0e 94 bf 2b call 0x577e ; 0x577e + 2b2a: f3 cf rjmp .-26 ; 0x2b12 + +00002b2c : +void CommandLineInit(void) +{ + BufferIdx = 0; +} + +bool CommandLineProcessByte(uint8_t Byte) { + 2b2c: af 92 push r10 + 2b2e: bf 92 push r11 + 2b30: df 92 push r13 + 2b32: ef 92 push r14 + 2b34: ff 92 push r15 + 2b36: 0f 93 push r16 + 2b38: 1f 93 push r17 + 2b3a: cf 93 push r28 + 2b3c: df 93 push r29 + 2b3e: 1f 92 push r1 + 2b40: cd b7 in r28, 0x3d ; 61 + 2b42: de b7 in r29, 0x3e ; 62 + if (IS_CHARACTER(Byte)){ + 2b44: 98 2f mov r25, r24 + 2b46: 91 54 subi r25, 0x41 ; 65 + 2b48: 9a 31 cpi r25, 0x1A ; 26 + 2b4a: 20 f0 brcs .+8 ; 0x2b54 + 2b4c: 90 52 subi r25, 0x20 ; 32 + 2b4e: 9a 31 cpi r25, 0x1A ; 26 + 2b50: f0 f4 brcc .+60 ; 0x2b8e + /* Store uppercase character */ + if (IS_LOWERCASE(Byte)) { + Byte = TO_UPPERCASE(Byte); + 2b52: 80 52 subi r24, 0x20 ; 32 + } + + /* Prevent buffer overflow and account for '\0' */ + if (BufferIdx < (sizeof(TerminalBuffer) / sizeof(*TerminalBuffer) - 1)) { + 2b54: 20 91 aa 28 lds r18, 0x28AA + 2b58: 30 91 ab 28 lds r19, 0x28AB + 2b5c: 2f 3f cpi r18, 0xFF ; 255 + 2b5e: 31 05 cpc r19, r1 + 2b60: 50 f4 brcc .+20 ; 0x2b76 + TerminalBuffer[BufferIdx++] = Byte; + 2b62: f9 01 movw r30, r18 + 2b64: e4 5c subi r30, 0xC4 ; 196 + 2b66: f6 4d sbci r31, 0xD6 ; 214 + 2b68: 80 83 st Z, r24 + 2b6a: 2f 5f subi r18, 0xFF ; 255 + 2b6c: 3f 4f sbci r19, 0xFF ; 255 + 2b6e: 20 93 aa 28 sts 0x28AA, r18 + 2b72: 30 93 ab 28 sts 0x28AB, r19 + } else { + /* Ignore other chars */ + } + + return true; +} + 2b76: 81 e0 ldi r24, 0x01 ; 1 + 2b78: 0f 90 pop r0 + 2b7a: df 91 pop r29 + 2b7c: cf 91 pop r28 + 2b7e: 1f 91 pop r17 + 2b80: 0f 91 pop r16 + 2b82: ff 90 pop r15 + 2b84: ef 90 pop r14 + 2b86: df 90 pop r13 + 2b88: bf 90 pop r11 + 2b8a: af 90 pop r10 + 2b8c: 08 95 ret +{ + BufferIdx = 0; +} + +bool CommandLineProcessByte(uint8_t Byte) { + if (IS_CHARACTER(Byte)){ + 2b8e: 9f 5c subi r25, 0xCF ; 207 + 2b90: 9a 30 cpi r25, 0x0A ; 10 + 2b92: 00 f3 brcs .-64 ; 0x2b54 + 2b94: 8f 35 cpi r24, 0x5F ; 95 + 2b96: f1 f2 breq .-68 ; 0x2b54 + 2b98: 8f 33 cpi r24, 0x3F ; 63 + 2b9a: e1 f2 breq .-72 ; 0x2b54 + 2b9c: 8d 33 cpi r24, 0x3D ; 61 + 2b9e: d1 f2 breq .-76 ; 0x2b54 + + /* Prevent buffer overflow and account for '\0' */ + if (BufferIdx < (sizeof(TerminalBuffer) / sizeof(*TerminalBuffer) - 1)) { + TerminalBuffer[BufferIdx++] = Byte; + } + }else if (Byte == '\r') { + 2ba0: 8d 30 cpi r24, 0x0D ; 13 + 2ba2: a9 f0 breq .+42 ; 0x2bce + /* Process on \r. Terminate string and decode. */ + TerminalBuffer[BufferIdx] = '\0'; + BufferIdx = 0; + + DecodeCommand(); + }else if (Byte == '\b') { + 2ba4: 88 30 cpi r24, 0x08 ; 8 + 2ba6: 39 f0 breq .+14 ; 0x2bb6 + /* Backspace. Delete last character in buffer. */ + if (BufferIdx > 0) { + BufferIdx--; + } + } else if (Byte == 0x1B){ + 2ba8: 8b 31 cpi r24, 0x1B ; 27 + 2baa: 29 f7 brne .-54 ; 0x2b76 + /* Drop buffer on escape */ + BufferIdx = 0; + 2bac: 10 92 aa 28 sts 0x28AA, r1 + 2bb0: 10 92 ab 28 sts 0x28AB, r1 + 2bb4: e0 cf rjmp .-64 ; 0x2b76 + BufferIdx = 0; + + DecodeCommand(); + }else if (Byte == '\b') { + /* Backspace. Delete last character in buffer. */ + if (BufferIdx > 0) { + 2bb6: 80 91 aa 28 lds r24, 0x28AA + 2bba: 90 91 ab 28 lds r25, 0x28AB + 2bbe: 00 97 sbiw r24, 0x00 ; 0 + 2bc0: d1 f2 breq .-76 ; 0x2b76 + BufferIdx--; + 2bc2: 01 97 sbiw r24, 0x01 ; 1 + 2bc4: 80 93 aa 28 sts 0x28AA, r24 + 2bc8: 90 93 ab 28 sts 0x28AB, r25 + 2bcc: d4 cf rjmp .-88 ; 0x2b76 + if (BufferIdx < (sizeof(TerminalBuffer) / sizeof(*TerminalBuffer) - 1)) { + TerminalBuffer[BufferIdx++] = Byte; + } + }else if (Byte == '\r') { + /* Process on \r. Terminate string and decode. */ + TerminalBuffer[BufferIdx] = '\0'; + 2bce: e0 91 aa 28 lds r30, 0x28AA + 2bd2: f0 91 ab 28 lds r31, 0x28AB + 2bd6: e4 5c subi r30, 0xC4 ; 196 + 2bd8: f6 4d sbci r31, 0xD6 ; 214 + 2bda: 10 82 st Z, r1 + BufferIdx = 0; + 2bdc: 10 92 aa 28 sts 0x28AA, r1 + 2be0: 10 92 ab 28 sts 0x28AB, r1 + bool CommandFound = false; + CommandStatusIdType StatusId = COMMAND_ERR_UNKNOWN_CMD_ID; + char* pTerminalBuffer = (char*) TerminalBuffer; + + /* Do some sanity check first */ + if (!IS_COMMAND_DELIMITER(pTerminalBuffer[0])) { + 2be4: 80 91 3c 29 lds r24, 0x293C + 2be8: 88 23 and r24, r24 + 2bea: 69 f1 breq .+90 ; 0x2c46 + 2bec: 8f 33 cpi r24, 0x3F ; 63 + 2bee: 59 f1 breq .+86 ; 0x2c46 + 2bf0: 8d 33 cpi r24, 0x3D ; 61 + 2bf2: 49 f1 breq .+82 ; 0x2c46 + 2bf4: ed e3 ldi r30, 0x3D ; 61 + 2bf6: f9 e2 ldi r31, 0x29 ; 41 + 2bf8: 04 c0 rjmp .+8 ; 0x2c02 + char* pCommandDelimiter = pTerminalBuffer; + char CommandDelimiter = '\0'; + + /* Search for command delimiter, store it and replace with '\0' */ + while(!(IS_COMMAND_DELIMITER(*pCommandDelimiter))) + 2bfa: 2f 33 cpi r18, 0x3F ; 63 + 2bfc: 31 f0 breq .+12 ; 0x2c0a + 2bfe: 2d 33 cpi r18, 0x3D ; 61 + 2c00: 21 f0 breq .+8 ; 0x2c0a + pCommandDelimiter++; + 2c02: 7f 01 movw r14, r30 + if (!IS_COMMAND_DELIMITER(pTerminalBuffer[0])) { + char* pCommandDelimiter = pTerminalBuffer; + char CommandDelimiter = '\0'; + + /* Search for command delimiter, store it and replace with '\0' */ + while(!(IS_COMMAND_DELIMITER(*pCommandDelimiter))) + 2c04: 21 91 ld r18, Z+ + 2c06: 21 11 cpse r18, r1 + 2c08: f8 cf rjmp .-16 ; 0x2bfa + pCommandDelimiter++; + + CommandDelimiter = *pCommandDelimiter; + *pCommandDelimiter = '\0'; + 2c0a: f7 01 movw r30, r14 + 2c0c: 10 82 st Z, r1 + 2c0e: 00 e0 ldi r16, 0x00 ; 0 + 2c10: 10 e0 ldi r17, 0x00 ; 0 + + /* Search in command table */ + for (i=0; i<(sizeof(CommandTable) / sizeof(*CommandTable)); i++) { + if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { + 2c12: 86 e1 ldi r24, 0x16 ; 22 + 2c14: d8 2e mov r13, r24 + 2c16: d0 9e mul r13, r16 + 2c18: 50 01 movw r10, r0 + 2c1a: d1 9e mul r13, r17 + 2c1c: b0 0c add r11, r0 + 2c1e: 11 24 eor r1, r1 + 2c20: 81 e4 ldi r24, 0x41 ; 65 + 2c22: 96 e0 ldi r25, 0x06 ; 6 + 2c24: a8 0e add r10, r24 + 2c26: b9 1e adc r11, r25 + 2c28: b5 01 movw r22, r10 + 2c2a: 8c e3 ldi r24, 0x3C ; 60 + 2c2c: 99 e2 ldi r25, 0x29 ; 41 + 2c2e: 29 83 std Y+1, r18 ; 0x01 + 2c30: 0e 94 d5 2d call 0x5baa ; 0x5baa + 2c34: 29 81 ldd r18, Y+1 ; 0x01 + 2c36: 89 2b or r24, r25 + 2c38: 09 f4 brne .+2 ; 0x2c3c + 2c3a: 3f c0 rjmp .+126 ; 0x2cba + 2c3c: 0f 5f subi r16, 0xFF ; 255 + 2c3e: 1f 4f sbci r17, 0xFF ; 255 + + CommandDelimiter = *pCommandDelimiter; + *pCommandDelimiter = '\0'; + + /* Search in command table */ + for (i=0; i<(sizeof(CommandTable) / sizeof(*CommandTable)); i++) { + 2c40: 05 31 cpi r16, 0x15 ; 21 + 2c42: 11 05 cpc r17, r1 + 2c44: 41 f7 brne .-48 ; 0x2c16 + +static void DecodeCommand(void) +{ + uint8_t i; + bool CommandFound = false; + CommandStatusIdType StatusId = COMMAND_ERR_UNKNOWN_CMD_ID; + 2c46: 88 ec ldi r24, 0xC8 ; 200 +} + +static void DecodeCommand(void) +{ + uint8_t i; + bool CommandFound = false; + 2c48: 10 e0 ldi r17, 0x00 ; 0 +static const char* GetStatusMessageP(CommandStatusIdType StatusId) +{ + uint8_t i; + + for (i=0; i<(sizeof(StatusTable)/sizeof(*StatusTable)); i++) { + if (pgm_read_byte(&StatusTable[i].Id) == StatusId) + 2c4a: e5 e1 ldi r30, 0x15 ; 21 + 2c4c: f8 e0 ldi r31, 0x08 ; 8 + 2c4e: e4 91 lpm r30, Z + 2c50: 8e 17 cp r24, r30 + 2c52: 09 f4 brne .+2 ; 0x2c56 + 2c54: 63 c0 rjmp .+198 ; 0x2d1c + 2c56: e6 e3 ldi r30, 0x36 ; 54 + 2c58: f8 e0 ldi r31, 0x08 ; 8 + 2c5a: e4 91 lpm r30, Z + 2c5c: 8e 17 cp r24, r30 + 2c5e: 09 f4 brne .+2 ; 0x2c62 + 2c60: 5a c0 rjmp .+180 ; 0x2d16 + 2c62: e7 e5 ldi r30, 0x57 ; 87 + 2c64: f8 e0 ldi r31, 0x08 ; 8 + 2c66: e4 91 lpm r30, Z + 2c68: 8e 17 cp r24, r30 + 2c6a: 09 f4 brne .+2 ; 0x2c6e + 2c6c: 51 c0 rjmp .+162 ; 0x2d10 + 2c6e: e8 e7 ldi r30, 0x78 ; 120 + 2c70: f8 e0 ldi r31, 0x08 ; 8 + 2c72: e4 91 lpm r30, Z + 2c74: 8e 17 cp r24, r30 + 2c76: 09 f4 brne .+2 ; 0x2c7a + 2c78: 48 c0 rjmp .+144 ; 0x2d0a + 2c7a: e9 e9 ldi r30, 0x99 ; 153 + 2c7c: f8 e0 ldi r31, 0x08 ; 8 + 2c7e: e4 91 lpm r30, Z + 2c80: 8e 17 cp r24, r30 + 2c82: 09 f4 brne .+2 ; 0x2c86 + 2c84: 3f c0 rjmp .+126 ; 0x2d04 + 2c86: ea eb ldi r30, 0xBA ; 186 + 2c88: f8 e0 ldi r31, 0x08 ; 8 + 2c8a: e4 91 lpm r30, Z + 2c8c: 8e 17 cp r24, r30 + 2c8e: 79 f1 breq .+94 ; 0x2cee + return StatusTable[i].Message; + } + + return (void*) 0; + 2c90: 80 e0 ldi r24, 0x00 ; 0 + 2c92: 90 e0 ldi r25, 0x00 ; 0 + } + } + } + + /* Send command status message */ + TerminalSendStringP(GetStatusMessageP(StatusId)); + 2c94: 76 da rcall .-2836 ; 0x2182 + TerminalSendStringP(PSTR(STATUS_MESSAGE_TRAILER)); + 2c96: 8f e0 ldi r24, 0x0F ; 15 + 2c98: 98 e0 ldi r25, 0x08 ; 8 + 2c9a: 73 da rcall .-2842 ; 0x2182 + + if (CommandFound && (pTerminalBuffer[0] != '\0') ) { + 2c9c: 11 23 and r17, r17 + 2c9e: 09 f4 brne .+2 ; 0x2ca2 + 2ca0: 6a cf rjmp .-300 ; 0x2b76 + 2ca2: 80 91 3c 29 lds r24, 0x293C + 2ca6: 88 23 and r24, r24 + 2ca8: 09 f4 brne .+2 ; 0x2cac + 2caa: 65 cf rjmp .-310 ; 0x2b76 + /* Send optional answer */ + TerminalSendString(pTerminalBuffer); + 2cac: 8c e3 ldi r24, 0x3C ; 60 + 2cae: 99 e2 ldi r25, 0x29 ; 41 + 2cb0: 63 da rcall .-2874 ; 0x2178 + TerminalSendStringP(PSTR(OPTIONAL_ANSWER_TRAILER)); + 2cb2: 82 e1 ldi r24, 0x12 ; 18 + 2cb4: 98 e0 ldi r25, 0x08 ; 8 + 2cb6: 65 da rcall .-2870 ; 0x2182 + 2cb8: 5e cf rjmp .-324 ; 0x2b76 + for (i=0; i<(sizeof(CommandTable) / sizeof(*CommandTable)); i++) { + if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { + /* Command found. Clear buffer, and call appropriate function */ + char* pParam = ++pCommandDelimiter; + + pTerminalBuffer[0] = '\0'; + 2cba: 10 92 3c 29 sts 0x293C, r1 +static CommandStatusIdType CallCommandFunc( + const CommandEntryType* CommandEntry, char CommandDelimiter, char* pParam) { + char* pTerminalBuffer = (char*) TerminalBuffer; + + /* Call appropriate function depending on CommandDelimiter */ + if (CommandDelimiter == CHAR_GET_MODE) { + 2cbe: 2f 33 cpi r18, 0x3F ; 63 + 2cc0: 99 f0 breq .+38 ; 0x2ce8 + CommandGetFuncType GetFunc = pgm_read_ptr(&CommandEntry->GetFunc); + if (GetFunc != NO_FUNCTION) { + return GetFunc(pTerminalBuffer); + } + } else if (CommandDelimiter == CHAR_SET_MODE) { + 2cc2: 2d 33 cpi r18, 0x3D ; 61 + 2cc4: 71 f1 breq .+92 ; 0x2d22 + CommandSetFuncType SetFunc = pgm_read_ptr(&CommandEntry->SetFunc); + if (SetFunc != NO_FUNCTION) { + return SetFunc(pParam); + } + } else if (CommandDelimiter == CHAR_EXEC_MODE){ + 2cc6: 22 23 and r18, r18 + 2cc8: 19 f0 breq .+6 ; 0x2cd0 + } else { + /* This should not happen (TM) */ + } + + /* This delimiter has not been registered with this command */ + return COMMAND_ERR_INVALID_USAGE_ID; + 2cca: 89 ec ldi r24, 0xC9 ; 201 + if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { + /* Command found. Clear buffer, and call appropriate function */ + char* pParam = ++pCommandDelimiter; + + pTerminalBuffer[0] = '\0'; + CommandFound = true; + 2ccc: 11 e0 ldi r17, 0x01 ; 1 + 2cce: bd cf rjmp .-134 ; 0x2c4a + CommandSetFuncType SetFunc = pgm_read_ptr(&CommandEntry->SetFunc); + if (SetFunc != NO_FUNCTION) { + return SetFunc(pParam); + } + } else if (CommandDelimiter == CHAR_EXEC_MODE){ + CommandExecFuncType ExecFunc = pgm_read_ptr(&CommandEntry->ExecFunc); + 2cd0: f5 01 movw r30, r10 + 2cd2: 70 96 adiw r30, 0x10 ; 16 + 2cd4: 85 91 lpm r24, Z+ + 2cd6: 94 91 lpm r25, Z + 2cd8: fc 01 movw r30, r24 + if (ExecFunc != NO_FUNCTION) { + 2cda: 00 97 sbiw r24, 0x00 ; 0 + 2cdc: b1 f3 breq .-20 ; 0x2cca + return ExecFunc(pTerminalBuffer); + 2cde: 8c e3 ldi r24, 0x3C ; 60 + 2ce0: 99 e2 ldi r25, 0x29 ; 41 + 2ce2: 09 95 icall + if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { + /* Command found. Clear buffer, and call appropriate function */ + char* pParam = ++pCommandDelimiter; + + pTerminalBuffer[0] = '\0'; + CommandFound = true; + 2ce4: 11 e0 ldi r17, 0x01 ; 1 + 2ce6: b1 cf rjmp .-158 ; 0x2c4a + const CommandEntryType* CommandEntry, char CommandDelimiter, char* pParam) { + char* pTerminalBuffer = (char*) TerminalBuffer; + + /* Call appropriate function depending on CommandDelimiter */ + if (CommandDelimiter == CHAR_GET_MODE) { + CommandGetFuncType GetFunc = pgm_read_ptr(&CommandEntry->GetFunc); + 2ce8: f5 01 movw r30, r10 + 2cea: 74 96 adiw r30, 0x14 ; 20 + 2cec: f3 cf rjmp .-26 ; 0x2cd4 +static const char* GetStatusMessageP(CommandStatusIdType StatusId) +{ + uint8_t i; + + for (i=0; i<(sizeof(StatusTable)/sizeof(*StatusTable)); i++) { + if (pgm_read_byte(&StatusTable[i].Id) == StatusId) + 2cee: 25 e0 ldi r18, 0x05 ; 5 + 2cf0: 30 e0 ldi r19, 0x00 ; 0 + return StatusTable[i].Message; + 2cf2: 41 e2 ldi r20, 0x21 ; 33 + 2cf4: 42 9f mul r20, r18 + 2cf6: c0 01 movw r24, r0 + 2cf8: 43 9f mul r20, r19 + 2cfa: 90 0d add r25, r0 + 2cfc: 11 24 eor r1, r1 + 2cfe: 8a 5e subi r24, 0xEA ; 234 + 2d00: 97 4f sbci r25, 0xF7 ; 247 + 2d02: c8 cf rjmp .-112 ; 0x2c94 +static const char* GetStatusMessageP(CommandStatusIdType StatusId) +{ + uint8_t i; + + for (i=0; i<(sizeof(StatusTable)/sizeof(*StatusTable)); i++) { + if (pgm_read_byte(&StatusTable[i].Id) == StatusId) + 2d04: 24 e0 ldi r18, 0x04 ; 4 + 2d06: 30 e0 ldi r19, 0x00 ; 0 + 2d08: f4 cf rjmp .-24 ; 0x2cf2 + 2d0a: 23 e0 ldi r18, 0x03 ; 3 + 2d0c: 30 e0 ldi r19, 0x00 ; 0 + 2d0e: f1 cf rjmp .-30 ; 0x2cf2 + 2d10: 22 e0 ldi r18, 0x02 ; 2 + 2d12: 30 e0 ldi r19, 0x00 ; 0 + 2d14: ee cf rjmp .-36 ; 0x2cf2 + 2d16: 21 e0 ldi r18, 0x01 ; 1 + 2d18: 30 e0 ldi r19, 0x00 ; 0 + 2d1a: eb cf rjmp .-42 ; 0x2cf2 + 2d1c: 20 e0 ldi r18, 0x00 ; 0 + 2d1e: 30 e0 ldi r19, 0x00 ; 0 + 2d20: e8 cf rjmp .-48 ; 0x2cf2 + CommandGetFuncType GetFunc = pgm_read_ptr(&CommandEntry->GetFunc); + if (GetFunc != NO_FUNCTION) { + return GetFunc(pTerminalBuffer); + } + } else if (CommandDelimiter == CHAR_SET_MODE) { + CommandSetFuncType SetFunc = pgm_read_ptr(&CommandEntry->SetFunc); + 2d22: f5 01 movw r30, r10 + 2d24: 72 96 adiw r30, 0x12 ; 18 + 2d26: 85 91 lpm r24, Z+ + 2d28: 94 91 lpm r25, Z + 2d2a: fc 01 movw r30, r24 + if (SetFunc != NO_FUNCTION) { + 2d2c: 00 97 sbiw r24, 0x00 ; 0 + 2d2e: 69 f2 breq .-102 ; 0x2cca + return SetFunc(pParam); + 2d30: c7 01 movw r24, r14 + 2d32: 01 96 adiw r24, 0x01 ; 1 + 2d34: 09 95 icall + if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { + /* Command found. Clear buffer, and call appropriate function */ + char* pParam = ++pCommandDelimiter; + + pTerminalBuffer[0] = '\0'; + CommandFound = true; + 2d36: 11 e0 ldi r17, 0x01 ; 1 + 2d38: 88 cf rjmp .-240 ; 0x2c4a + +00002d3a : + + return true; +} + +void CommandLineTick(void) +{ + 2d3a: 08 95 ret + +00002d3c : +INLINE void CodecTask(void) { + ActiveConfiguration.CodecTaskFunc(); +} + +INLINE void CodecSetDemodPower(bool bOnOff) { + CODEC_DEMOD_POWER_PORT.DIRSET = CODEC_DEMOD_POWER_MASK; + 2d3c: a0 e2 ldi r26, 0x20 ; 32 + 2d3e: b6 e0 ldi r27, 0x06 ; 6 + 2d40: 82 e0 ldi r24, 0x02 ; 2 + 2d42: 11 96 adiw r26, 0x01 ; 1 + 2d44: 8c 93 st X, r24 + 2d46: 11 97 sbiw r26, 0x01 ; 1 + + if (bOnOff) { + CODEC_DEMOD_POWER_PORT.OUTSET = CODEC_DEMOD_POWER_MASK; + 2d48: 15 96 adiw r26, 0x05 ; 5 + 2d4a: 8c 93 st X, r24 + 2d4c: 15 97 sbiw r26, 0x05 ; 5 + +static void StartDemod(void) { + /* Activate Power for demodulator */ + CodecSetDemodPower(true); + + CodecBufferPtr = CodecBuffer; + 2d4e: 8c e3 ldi r24, 0x3C ; 60 + 2d50: 9a e2 ldi r25, 0x2A ; 42 + 2d52: 80 93 b8 28 sts 0x28B8, r24 + 2d56: 90 93 b9 28 sts 0x28B9, r25 + ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; + 2d5a: 8c eb ldi r24, 0xBC ; 188 + 2d5c: 9a e2 ldi r25, 0x2A ; 42 + 2d5e: 80 93 ba 28 sts 0x28BA, r24 + 2d62: 90 93 bb 28 sts 0x28BB, r25 + DataRegister = 0; + 2d66: 10 92 b1 28 sts 0x28B1, r1 + SampleRegister = 0; + 2d6a: 10 92 b0 28 sts 0x28B0, r1 + SamplePosition = 0; + 2d6e: 10 92 ac 28 sts 0x28AC, r1 + BitCount = 0; + 2d72: 10 92 b4 28 sts 0x28B4, r1 + 2d76: 10 92 b5 28 sts 0x28B5, r1 + IsParityBit = false; + 2d7a: 10 92 af 28 sts 0x28AF, r1 + + /* Configure sampling-timer free running and sync to first modulation-pause. */ + CODEC_TIMER_SAMPLING.CNT = 0; + 2d7e: e0 e4 ldi r30, 0x40 ; 64 + 2d80: f8 e0 ldi r31, 0x08 ; 8 + 2d82: 10 a2 std Z+32, r1 ; 0x20 + 2d84: 11 a2 std Z+33, r1 ; 0x21 + CODEC_TIMER_SAMPLING.PER = SAMPLE_RATE_SYSTEM_CYCLES - 1; + 2d86: 8d e2 ldi r24, 0x2D ; 45 + 2d88: 91 e0 ldi r25, 0x01 ; 1 + 2d8a: 86 a3 std Z+38, r24 ; 0x26 + 2d8c: 97 a3 std Z+39, r25 ; 0x27 + CODEC_TIMER_SAMPLING.CCA = 0xFFFF; /* CCA Interrupt is not active! */ + 2d8e: 8f ef ldi r24, 0xFF ; 255 + 2d90: 9f ef ldi r25, 0xFF ; 255 + 2d92: 80 a7 std Z+40, r24 ; 0x28 + 2d94: 91 a7 std Z+41, r25 ; 0x29 + CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_DIV1_gc; + 2d96: 81 e0 ldi r24, 0x01 ; 1 + 2d98: 80 83 st Z, r24 + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc; + 2d9a: 88 e8 ldi r24, 0x88 ; 136 + 2d9c: 83 83 std Z+3, r24 ; 0x03 + CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCAINTLVL_HI_gc; + 2d9e: 83 e0 ldi r24, 0x03 ; 3 + 2da0: 87 83 std Z+7, r24 ; 0x07 + + /* Start looking out for modulation pause via interrupt. */ + CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0; + 2da2: 84 e0 ldi r24, 0x04 ; 4 + 2da4: 1a 96 adiw r26, 0x0a ; 10 + 2da6: 8c 93 st X, r24 + SLEEP.CTRL &= ~SLEEP_SEN_bm; +} + +INLINE void SystemSleepSetMode(uint8_t SleepMode) +{ + SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SleepMode; + 2da8: e8 e4 ldi r30, 0x48 ; 72 + 2daa: f0 e0 ldi r31, 0x00 ; 0 + 2dac: 80 81 ld r24, Z + 2dae: 81 7f andi r24, 0xF1 ; 241 + 2db0: 86 60 ori r24, 0x06 ; 6 + 2db2: 80 83 st Z, r24 + 2db4: 08 95 ret + +00002db6 <__vector_34>: + SystemSleepSetMode(SYSTEM_SMODE_PSAVE); +} + +ISR(CODEC_DEMOD_IN_INT0_VECT) { + 2db6: 1f 92 push r1 + 2db8: 0f 92 push r0 + 2dba: 0f b6 in r0, 0x3f ; 63 + 2dbc: 0f 92 push r0 + 2dbe: 11 24 eor r1, r1 + 2dc0: 8f 93 push r24 + 2dc2: 9f 93 push r25 + 2dc4: ef 93 push r30 + 2dc6: ff 93 push r31 + 2dc8: e8 e4 ldi r30, 0x48 ; 72 + 2dca: f0 e0 ldi r31, 0x00 ; 0 + 2dcc: 80 81 ld r24, Z + 2dce: 81 7f andi r24, 0xF1 ; 241 + 2dd0: 80 83 st Z, r24 + * XYZBUF mechanism of the xmega to automatically double the sampling rate on the + * next overflow. For this we have to temporarily deactivate the automatical alignment + * in order to catch next overflow event for updating the BUF registers. + * We want to sample the demodulated data stream in the first quarter of the half-bit + * where the pulsed miller encoded is located. */ + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_OFF_gc; + 2dd2: e0 e4 ldi r30, 0x40 ; 64 + 2dd4: f8 e0 ldi r31, 0x08 ; 8 + 2dd6: 13 82 std Z+3, r1 ; 0x03 + CODEC_TIMER_SAMPLING.PERBUF = SAMPLE_RATE_SYSTEM_CYCLES/2 - 1; /* Half bit width */ + 2dd8: 86 e9 ldi r24, 0x96 ; 150 + 2dda: 90 e0 ldi r25, 0x00 ; 0 + 2ddc: 86 ab std Z+54, r24 ; 0x36 + 2dde: 97 ab std Z+55, r25 ; 0x37 + CODEC_TIMER_SAMPLING.CCABUF = SAMPLE_RATE_SYSTEM_CYCLES/8 - 10 - 1; /* Compensate for DIGFILT and ISR prolog */ + 2de0: 8a e1 ldi r24, 0x1A ; 26 + 2de2: 90 e0 ldi r25, 0x00 ; 0 + 2de4: 80 af std Z+56, r24 ; 0x38 + 2de6: 91 af std Z+57, r25 ; 0x39 + /* Setup Frame Delay Timer and wire to EVSYS. Frame delay time is + * measured from last change in RF field, therefore we use + * the event channel 1 (end of modulation pause) as the restart event. + * The preliminary frame delay time chosen here is irrelevant, because + * the correct FDT gets set automatically after demodulation. */ + CODEC_TIMER_LOADMOD.CNT = 0; + 2de8: e0 e4 ldi r30, 0x40 ; 64 + 2dea: f9 e0 ldi r31, 0x09 ; 9 + 2dec: 10 a2 std Z+32, r1 ; 0x20 + 2dee: 11 a2 std Z+33, r1 ; 0x21 + CODEC_TIMER_LOADMOD.PER = 0xFFFF; + 2df0: 8f ef ldi r24, 0xFF ; 255 + 2df2: 9f ef ldi r25, 0xFF ; 255 + 2df4: 86 a3 std Z+38, r24 ; 0x26 + 2df6: 97 a3 std Z+39, r25 ; 0x27 + CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH1_gc; + 2df8: 89 e8 ldi r24, 0x89 ; 137 + 2dfa: 83 83 std Z+3, r24 ; 0x03 + CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_EVCH6_gc; + 2dfc: 8e e0 ldi r24, 0x0E ; 14 + 2dfe: 80 83 st Z, r24 + + /* Disable this interrupt */ + CODEC_DEMOD_IN_PORT.INT0MASK = 0; + 2e00: e0 e2 ldi r30, 0x20 ; 32 + 2e02: f6 e0 ldi r31, 0x06 ; 6 + 2e04: 12 86 std Z+10, r1 ; 0x0a +} + 2e06: ff 91 pop r31 + 2e08: ef 91 pop r30 + 2e0a: 9f 91 pop r25 + 2e0c: 8f 91 pop r24 + 2e0e: 0f 90 pop r0 + 2e10: 0f be out 0x3f, r0 ; 63 + 2e12: 0f 90 pop r0 + 2e14: 1f 90 pop r1 + 2e16: 18 95 reti + +00002e18 <__vector_22>: + +ISR(CODEC_TIMER_SAMPLING_CCA_VECT) { + 2e18: 1f 92 push r1 + 2e1a: 0f 92 push r0 + 2e1c: 0f b6 in r0, 0x3f ; 63 + 2e1e: 0f 92 push r0 + 2e20: 11 24 eor r1, r1 + 2e22: 2f 93 push r18 + 2e24: 8f 93 push r24 + 2e26: 9f 93 push r25 + 2e28: ef 93 push r30 + 2e2a: ff 93 push r31 + /* This interrupt gets called twice for every bit to sample it. */ + uint8_t SamplePin = CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK; + 2e2c: 90 91 28 06 lds r25, 0x0628 + uint8_t NewSampleRegister; + + /* Shift sampled bit into sampling register and hold a local copy for fast access. */ + NewSampleRegister = SampleRegister << 1; + 2e30: 80 91 b0 28 lds r24, 0x28B0 + CODEC_DEMOD_IN_PORT.INT0MASK = 0; +} + +ISR(CODEC_TIMER_SAMPLING_CCA_VECT) { + /* This interrupt gets called twice for every bit to sample it. */ + uint8_t SamplePin = CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK; + 2e34: 95 70 andi r25, 0x05 ; 5 + uint8_t NewSampleRegister; + + /* Shift sampled bit into sampling register and hold a local copy for fast access. */ + NewSampleRegister = SampleRegister << 1; + NewSampleRegister |= (!SamplePin ? 0x01 : 0x00); + 2e36: 21 e0 ldi r18, 0x01 ; 1 + 2e38: 09 f0 breq .+2 ; 0x2e3c <__vector_22+0x24> + 2e3a: 20 e0 ldi r18, 0x00 ; 0 + /* This interrupt gets called twice for every bit to sample it. */ + uint8_t SamplePin = CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK; + uint8_t NewSampleRegister; + + /* Shift sampled bit into sampling register and hold a local copy for fast access. */ + NewSampleRegister = SampleRegister << 1; + 2e3c: 88 0f add r24, r24 + NewSampleRegister |= (!SamplePin ? 0x01 : 0x00); + 2e3e: 82 2b or r24, r18 + SampleRegister = NewSampleRegister; + 2e40: 80 93 b0 28 sts 0x28B0, r24 + + if (SamplePosition) { + 2e44: 90 91 ac 28 lds r25, 0x28AC + 2e48: 99 23 and r25, r25 + 2e4a: a1 f1 breq .+104 ; 0x2eb4 <__vector_22+0x9c> + /* Analyze the sampling register after 2 samples. */ + if ((NewSampleRegister & 0x07) == 0x07) { + 2e4c: 98 2f mov r25, r24 + 2e4e: 97 70 andi r25, 0x07 ; 7 + 2e50: 97 30 cpi r25, 0x07 ; 7 + 2e52: 09 f4 brne .+2 ; 0x2e56 <__vector_22+0x3e> + 2e54: 42 c0 rjmp .+132 ; 0x2eda <__vector_22+0xc2> + + /* Signal, that we have finished sampling */ + Flags.DemodFinished = 1; + } else { + /* Otherwise, we check the two sample bits from the bit before. */ + uint8_t BitSample = NewSampleRegister & 0xC; + 2e56: 98 2f mov r25, r24 + 2e58: 9c 70 andi r25, 0x0C ; 12 + uint8_t Bit = 0; + + if (BitSample != (0x0 << 2)) { + 2e5a: 61 f1 breq .+88 ; 0x2eb4 <__vector_22+0x9c> + /* We have a valid bit. decode and process it. */ + if (BitSample & (0x1 << 2)) { + 2e5c: 91 e0 ldi r25, 0x01 ; 1 + 2e5e: 82 fd sbrc r24, 2 + 2e60: 6b c0 rjmp .+214 ; 0x2f38 <__vector_22+0x120> + } else { + /* 10 sequence -> This is a one bit */ + Bit = 1; + } + + LastBit = Bit; + 2e62: 90 93 ae 28 sts 0x28AE, r25 + + if (!IsParityBit) { + 2e66: 80 91 af 28 lds r24, 0x28AF + 2e6a: 81 11 cpse r24, r1 + 2e6c: 6d c0 rjmp .+218 ; 0x2f48 <__vector_22+0x130> + /* This is a data bit, so shift it into the data register and + * hold a local copy of it. */ + uint8_t NewDataRegister = DataRegister >> 1; + 2e6e: 80 91 b1 28 lds r24, 0x28B1 + 2e72: 86 95 lsr r24 + NewDataRegister |= (Bit ? 0x80 : 0x00); + 2e74: 99 23 and r25, r25 + 2e76: 09 f4 brne .+2 ; 0x2e7a <__vector_22+0x62> + 2e78: 71 c0 rjmp .+226 ; 0x2f5c <__vector_22+0x144> + 2e7a: 20 e8 ldi r18, 0x80 ; 128 + 2e7c: 28 2b or r18, r24 + DataRegister = NewDataRegister; + 2e7e: 20 93 b1 28 sts 0x28B1, r18 + + /* Update bitcount */ + uint16_t NewBitCount = ++BitCount; + 2e82: 80 91 b4 28 lds r24, 0x28B4 + 2e86: 90 91 b5 28 lds r25, 0x28B5 + 2e8a: 01 96 adiw r24, 0x01 ; 1 + 2e8c: 80 93 b4 28 sts 0x28B4, r24 + 2e90: 90 93 b5 28 sts 0x28B5, r25 + if ((NewBitCount & 0x07) == 0) { + 2e94: 87 70 andi r24, 0x07 ; 7 + 2e96: 99 27 eor r25, r25 + 2e98: 89 2b or r24, r25 + 2e9a: 61 f4 brne .+24 ; 0x2eb4 <__vector_22+0x9c> + /* We have reached a byte boundary! Store the data register. */ + /* TODO: Prevent buffer overflow */ + *CodecBufferPtr++ = NewDataRegister; + 2e9c: e0 91 b8 28 lds r30, 0x28B8 + 2ea0: f0 91 b9 28 lds r31, 0x28B9 + 2ea4: 21 93 st Z+, r18 + 2ea6: e0 93 b8 28 sts 0x28B8, r30 + 2eaa: f0 93 b9 28 sts 0x28B9, r31 + + /* Store bit for determining FDT at EOC and enable parity + * handling on next bit. */ + IsParityBit = true; + 2eae: 81 e0 ldi r24, 0x01 ; 1 + 2eb0: 80 93 af 28 sts 0x28AF, r24 + } + } else { + /* On odd sample position just sample. */ + } + + SamplePosition = !SamplePosition; + 2eb4: 80 91 ac 28 lds r24, 0x28AC + 2eb8: 91 e0 ldi r25, 0x01 ; 1 + 2eba: 89 27 eor r24, r25 + 2ebc: 80 93 ac 28 sts 0x28AC, r24 + + /* Make sure the sampling timer gets automatically aligned to the + * modulation pauses by using the RESTART event. + * This can be understood as a "poor mans PLL" and makes sure that we are + * never too far out the bit-grid while sampling. */ + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc; + 2ec0: 88 e8 ldi r24, 0x88 ; 136 + 2ec2: 80 93 43 08 sts 0x0843, r24 +} + 2ec6: ff 91 pop r31 + 2ec8: ef 91 pop r30 + 2eca: 9f 91 pop r25 + 2ecc: 8f 91 pop r24 + 2ece: 2f 91 pop r18 + 2ed0: 0f 90 pop r0 + 2ed2: 0f be out 0x3f, r0 ; 63 + 2ed4: 0f 90 pop r0 + 2ed6: 1f 90 pop r1 + 2ed8: 18 95 reti + + if (SamplePosition) { + /* Analyze the sampling register after 2 samples. */ + if ((NewSampleRegister & 0x07) == 0x07) { + /* No carrier modulation for 3 sample points. EOC! */ + CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc; + 2eda: 10 92 40 08 sts 0x0840, r1 + CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCAIF_bm; + 2ede: 80 e1 ldi r24, 0x10 ; 16 + 2ee0: 80 93 4c 08 sts 0x084C, r24 + + /* By this time, the FDT timer is aligned to the last modulation + * edge of the reader. So we disable the auto-synchronization and + * let it count the frame delay time in the background, and generate + * an interrupt once it has reached the FDT. */ + CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc; + 2ee4: 10 92 43 09 sts 0x0943, r1 + + if (LastBit) { + 2ee8: 80 91 ae 28 lds r24, 0x28AE + 2eec: 88 23 and r24, r24 + 2eee: 79 f1 breq .+94 ; 0x2f4e <__vector_22+0x136> + CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV1; + 2ef0: 8c eb ldi r24, 0xBC ; 188 + 2ef2: 94 e0 ldi r25, 0x04 ; 4 + 2ef4: 80 93 66 09 sts 0x0966, r24 + 2ef8: 90 93 67 09 sts 0x0967, r25 + } else { + CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV0; + } + + LoadModState = LOADMOD_FDT; + 2efc: 10 92 ad 28 sts 0x28AD, r1 + + CODEC_TIMER_LOADMOD.INTFLAGS = TC1_OVFIF_bm; + 2f00: 81 e0 ldi r24, 0x01 ; 1 + 2f02: 80 93 4c 09 sts 0x094C, r24 + CODEC_TIMER_LOADMOD.INTCTRLA = TC_OVFINTLVL_HI_gc; + 2f06: 83 e0 ldi r24, 0x03 ; 3 + 2f08: 80 93 46 09 sts 0x0946, r24 + + /* Determine if we did not receive a multiple of 8 bits. + * If this is the case, right-align the remaining data and + * store it into the buffer. */ + uint8_t RemainingBits = BitCount % 8; + 2f0c: 80 91 b4 28 lds r24, 0x28B4 + 2f10: 90 91 b5 28 lds r25, 0x28B5 + 2f14: 87 70 andi r24, 0x07 ; 7 + if (RemainingBits != 0) { + 2f16: 61 f0 breq .+24 ; 0x2f30 <__vector_22+0x118> + uint8_t NewDataRegister = DataRegister; + 2f18: 90 91 b1 28 lds r25, 0x28B1 + + while (RemainingBits++ < 8) { + 2f1c: 8f 5f subi r24, 0xFF ; 255 + /* Pad with zeroes to right-align. */ + NewDataRegister >>= 1; + 2f1e: 96 95 lsr r25 + * store it into the buffer. */ + uint8_t RemainingBits = BitCount % 8; + if (RemainingBits != 0) { + uint8_t NewDataRegister = DataRegister; + + while (RemainingBits++ < 8) { + 2f20: 8f 5f subi r24, 0xFF ; 255 + 2f22: 89 30 cpi r24, 0x09 ; 9 + 2f24: e1 f7 brne .-8 ; 0x2f1e <__vector_22+0x106> + /* Pad with zeroes to right-align. */ + NewDataRegister >>= 1; + } + + /* TODO: Prevent buffer overflow */ + *CodecBufferPtr = NewDataRegister; + 2f26: e0 91 b8 28 lds r30, 0x28B8 + 2f2a: f0 91 b9 28 lds r31, 0x28B9 + 2f2e: 90 83 st Z, r25 + } + + /* Signal, that we have finished sampling */ + Flags.DemodFinished = 1; + 2f30: 81 e0 ldi r24, 0x01 ; 1 + 2f32: 80 93 b6 28 sts 0x28B6, r24 + 2f36: be cf rjmp .-132 ; 0x2eb4 <__vector_22+0x9c> + uint8_t BitSample = NewSampleRegister & 0xC; + uint8_t Bit = 0; + + if (BitSample != (0x0 << 2)) { + /* We have a valid bit. decode and process it. */ + if (BitSample & (0x1 << 2)) { + 2f38: 90 e0 ldi r25, 0x00 ; 0 + } else { + /* 10 sequence -> This is a one bit */ + Bit = 1; + } + + LastBit = Bit; + 2f3a: 90 93 ae 28 sts 0x28AE, r25 + + if (!IsParityBit) { + 2f3e: 80 91 af 28 lds r24, 0x28AF + 2f42: 88 23 and r24, r24 + 2f44: 09 f4 brne .+2 ; 0x2f48 <__vector_22+0x130> + 2f46: 93 cf rjmp .-218 ; 0x2e6e <__vector_22+0x56> + + } else { + /* This is a parity bit. Store it */ + /* TODO: Store parity and prevent overflow */ + //*ParityBufferPtr++ = Bit; + IsParityBit = false; + 2f48: 10 92 af 28 sts 0x28AF, r1 + 2f4c: b3 cf rjmp .-154 ; 0x2eb4 <__vector_22+0x9c> + CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc; + + if (LastBit) { + CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV1; + } else { + CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV0; + 2f4e: 8c e7 ldi r24, 0x7C ; 124 + 2f50: 94 e0 ldi r25, 0x04 ; 4 + 2f52: 80 93 66 09 sts 0x0966, r24 + 2f56: 90 93 67 09 sts 0x0967, r25 + 2f5a: d0 cf rjmp .-96 ; 0x2efc <__vector_22+0xe4> + + if (!IsParityBit) { + /* This is a data bit, so shift it into the data register and + * hold a local copy of it. */ + uint8_t NewDataRegister = DataRegister >> 1; + NewDataRegister |= (Bit ? 0x80 : 0x00); + 2f5c: 20 e0 ldi r18, 0x00 ; 0 + 2f5e: 8e cf rjmp .-228 ; 0x2e7c <__vector_22+0x64> + +00002f60 <__vector_83>: + * This can be understood as a "poor mans PLL" and makes sure that we are + * never too far out the bit-grid while sampling. */ + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc; +} + +ISR(CODEC_TIMER_OVF_VECT) { + 2f60: 1f 92 push r1 + 2f62: 0f 92 push r0 + 2f64: 0f b6 in r0, 0x3f ; 63 + 2f66: 0f 92 push r0 + 2f68: 11 24 eor r1, r1 + 2f6a: 2f 93 push r18 + 2f6c: 3f 93 push r19 + 2f6e: 8f 93 push r24 + 2f70: 9f 93 push r25 + 2f72: ef 93 push r30 + 2f74: ff 93 push r31 + /* Bit rate timer. Output a half bit on the output. */ + uint8_t Temp8; + uint16_t Temp16; + + switch (LoadModState) { + 2f76: 80 91 ad 28 lds r24, 0x28AD + 2f7a: 85 30 cpi r24, 0x05 ; 5 + 2f7c: 09 f4 brne .+2 ; 0x2f80 <__vector_83+0x20> + 2f7e: 4d c0 rjmp .+154 ; 0x301a <__stack+0x1b> + 2f80: a8 f0 brcs .+42 ; 0x2fac <__vector_83+0x4c> + 2f82: 88 30 cpi r24, 0x08 ; 8 + 2f84: 09 f4 brne .+2 ; 0x2f88 <__vector_83+0x28> + 2f86: 7c c0 rjmp .+248 ; 0x3080 <__stack+0x81> + 2f88: 20 f5 brcc .+72 ; 0x2fd2 <__vector_83+0x72> + 2f8a: 86 30 cpi r24, 0x06 ; 6 + 2f8c: 09 f4 brne .+2 ; 0x2f90 <__vector_83+0x30> + 2f8e: b8 c0 rjmp .+368 ; 0x3100 <__stack+0x101> + 2f90: 87 30 cpi r24, 0x07 ; 7 + 2f92: 09 f4 brne .+2 ; 0x2f96 <__vector_83+0x36> + 2f94: 8a c0 rjmp .+276 ; 0x30aa <__stack+0xab> + break; + + default: + break; + } +} + 2f96: ff 91 pop r31 + 2f98: ef 91 pop r30 + 2f9a: 9f 91 pop r25 + 2f9c: 8f 91 pop r24 + 2f9e: 3f 91 pop r19 + 2fa0: 2f 91 pop r18 + 2fa2: 0f 90 pop r0 + 2fa4: 0f be out 0x3f, r0 ; 63 + 2fa6: 0f 90 pop r0 + 2fa8: 1f 90 pop r1 + 2faa: 18 95 reti +ISR(CODEC_TIMER_OVF_VECT) { + /* Bit rate timer. Output a half bit on the output. */ + uint8_t Temp8; + uint16_t Temp16; + + switch (LoadModState) { + 2fac: 82 30 cpi r24, 0x02 ; 2 + 2fae: 71 f1 breq .+92 ; 0x300c <__stack+0xd> + 2fb0: f8 f0 brcs .+62 ; 0x2ff0 <__vector_83+0x90> + 2fb2: 83 30 cpi r24, 0x03 ; 3 + 2fb4: 09 f4 brne .+2 ; 0x2fb8 <__vector_83+0x58> + 2fb6: 56 c0 rjmp .+172 ; 0x3064 <__stack+0x65> + 2fb8: 84 30 cpi r24, 0x04 ; 4 + 2fba: 69 f7 brne .-38 ; 0x2f96 <__vector_83+0x36> + /* Fetch first byte */ + DataRegister = *CodecBufferPtr; + break; + + case LOADMOD_DATA0: + if (DataRegister & 1) { + 2fbc: 80 91 b1 28 lds r24, 0x28B1 + 2fc0: 80 fd sbrc r24, 0 + 2fc2: b7 c0 rjmp .+366 ; 0x3132 <__stack+0x133> + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + } else { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 2fc4: 80 e4 ldi r24, 0x40 ; 64 + 2fc6: 80 93 46 06 sts 0x0646, r24 + } + + LoadModState = LOADMOD_DATA1; + 2fca: 85 e0 ldi r24, 0x05 ; 5 + 2fcc: 80 93 ad 28 sts 0x28AD, r24 + break; + 2fd0: e2 cf rjmp .-60 ; 0x2f96 <__vector_83+0x36> +ISR(CODEC_TIMER_OVF_VECT) { + /* Bit rate timer. Output a half bit on the output. */ + uint8_t Temp8; + uint16_t Temp16; + + switch (LoadModState) { + 2fd2: 89 30 cpi r24, 0x09 ; 9 + 2fd4: 09 f4 brne .+2 ; 0x2fd8 <__vector_83+0x78> + 2fd6: 5b c0 rjmp .+182 ; 0x308e <__stack+0x8f> + 2fd8: 8a 30 cpi r24, 0x0A ; 10 + 2fda: e9 f6 brne .-70 ; 0x2f96 <__vector_83+0x36> + + case LOADMOD_FINISHED: + /* We have written all of our bits. Deactivate the loadmod + * timer. Also disable the bit-rate interrupt again. And + * stop the subcarrier divider. */ + CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; + 2fdc: 10 92 40 09 sts 0x0940, r1 + CODEC_TIMER_LOADMOD.INTCTRLA = 0; + 2fe0: 10 92 46 09 sts 0x0946, r1 + CODEC_SUBCARRIER_TIMER.CTRLA = TC_CLKSEL_OFF_gc; + 2fe4: 10 92 00 08 sts 0x0800, r1 + + /* Signal application that we have finished loadmod */ + Flags.LoadmodFinished = 1; + 2fe8: 81 e0 ldi r24, 0x01 ; 1 + 2fea: 80 93 b7 28 sts 0x28B7, r24 + break; + 2fee: d3 cf rjmp .-90 ; 0x2f96 <__vector_83+0x36> +ISR(CODEC_TIMER_OVF_VECT) { + /* Bit rate timer. Output a half bit on the output. */ + uint8_t Temp8; + uint16_t Temp16; + + switch (LoadModState) { + 2ff0: 88 23 and r24, r24 + 2ff2: 09 f4 brne .+2 ; 0x2ff6 <__vector_83+0x96> + 2ff4: 53 c0 rjmp .+166 ; 0x309c <__stack+0x9d> + 2ff6: 81 30 cpi r24, 0x01 ; 1 + 2ff8: 71 f6 brne .-100 ; 0x2f96 <__vector_83+0x36> + break; + + case LOADMOD_START: + /* Application produced data. With this interrupt we are aligned to the bit-grid. + * Start subcarrier generation and align to bitrate. */ + CODEC_TIMER_LOADMOD.PER = ISO14443A_BIT_RATE_CYCLES / 2 - 1; + 2ffa: 8f e3 ldi r24, 0x3F ; 63 + 2ffc: 90 e0 ldi r25, 0x00 ; 0 + 2ffe: 80 93 66 09 sts 0x0966, r24 + 3002: 90 93 67 09 sts 0x0967, r25 + CODEC_SUBCARRIER_TIMER.CTRLA = TC_CLKSEL_EVCH6_gc; + 3006: 8e e0 ldi r24, 0x0E ; 14 + 3008: 80 93 00 08 sts 0x0800, r24 + + /* Fallthrough to first bit */ + + case LOADMOD_START_BIT0: + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + 300c: 80 e4 ldi r24, 0x40 ; 64 + 300e: 80 93 45 06 sts 0x0645, r24 + LoadModState = LOADMOD_START_BIT1; + 3012: 83 e0 ldi r24, 0x03 ; 3 + 3014: 80 93 ad 28 sts 0x28AD, r24 + break; + 3018: be cf rjmp .-132 ; 0x2f96 <__vector_83+0x36> + + LoadModState = LOADMOD_DATA1; + break; + + case LOADMOD_DATA1: + Temp8 = DataRegister; + 301a: 80 91 b1 28 lds r24, 0x28B1 + + if (Temp8 & 1) { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 301e: 90 e4 ldi r25, 0x40 ; 64 + break; + + case LOADMOD_DATA1: + Temp8 = DataRegister; + + if (Temp8 & 1) { + 3020: 80 fd sbrc r24, 0 + 3022: 84 c0 rjmp .+264 ; 0x312c <__stack+0x12d> + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + } else { + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + 3024: 90 93 45 06 sts 0x0645, r25 + } + + DataRegister = Temp8 >> 1; + 3028: 86 95 lsr r24 + 302a: 80 93 b1 28 sts 0x28B1, r24 + + Temp16 = BitSent; + 302e: 80 91 b2 28 lds r24, 0x28B2 + 3032: 90 91 b3 28 lds r25, 0x28B3 + BitSent = ++Temp16; + 3036: 01 96 adiw r24, 0x01 ; 1 + 3038: 80 93 b2 28 sts 0x28B2, r24 + 303c: 90 93 b3 28 sts 0x28B3, r25 + + if ((Temp16 & 0x07) == 0) { + 3040: 9c 01 movw r18, r24 + 3042: 27 70 andi r18, 0x07 ; 7 + 3044: 33 27 eor r19, r19 + 3046: 23 2b or r18, r19 + 3048: 09 f4 brne .+2 ; 0x304c <__stack+0x4d> + 304a: 77 c0 rjmp .+238 ; 0x313a <__stack+0x13b> + /* Byte boundary. Load parity bit and output it later. */ + LoadModState = LOADMOD_PARITY0; + break; + } + + if (Temp16 == BitCount) { + 304c: 20 91 b4 28 lds r18, 0x28B4 + 3050: 30 91 b5 28 lds r19, 0x28B5 + 3054: 82 17 cp r24, r18 + 3056: 93 07 cpc r25, r19 + 3058: 09 f0 breq .+2 ; 0x305c <__stack+0x5d> + 305a: 4e c0 rjmp .+156 ; 0x30f8 <__stack+0xf9> + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + } + + if (BitSent == BitCount) { + /* No data left */ + LoadModState = LOADMOD_STOP_BIT0; + 305c: 88 e0 ldi r24, 0x08 ; 8 + 305e: 80 93 ad 28 sts 0x28AD, r24 + 3062: 99 cf rjmp .-206 ; 0x2f96 <__vector_83+0x36> + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + LoadModState = LOADMOD_START_BIT1; + break; + + case LOADMOD_START_BIT1: + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 3064: 80 e4 ldi r24, 0x40 ; 64 + 3066: 80 93 46 06 sts 0x0646, r24 + LoadModState = LOADMOD_DATA0; + 306a: 84 e0 ldi r24, 0x04 ; 4 + 306c: 80 93 ad 28 sts 0x28AD, r24 + + /* Fetch first byte */ + DataRegister = *CodecBufferPtr; + 3070: e0 91 b8 28 lds r30, 0x28B8 + 3074: f0 91 b9 28 lds r31, 0x28B9 + 3078: 80 81 ld r24, Z + 307a: 80 93 b1 28 sts 0x28B1, r24 + break; + 307e: 8b cf rjmp .-234 ; 0x2f96 <__vector_83+0x36> + } + + break; + + case LOADMOD_STOP_BIT0: + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 3080: 80 e4 ldi r24, 0x40 ; 64 + 3082: 80 93 46 06 sts 0x0646, r24 + LoadModState = LOADMOD_STOP_BIT1; + 3086: 89 e0 ldi r24, 0x09 ; 9 + 3088: 80 93 ad 28 sts 0x28AD, r24 + break; + 308c: 84 cf rjmp .-248 ; 0x2f96 <__vector_83+0x36> + + case LOADMOD_STOP_BIT1: + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 308e: 80 e4 ldi r24, 0x40 ; 64 + 3090: 80 93 46 06 sts 0x0646, r24 + LoadModState = LOADMOD_FINISHED; + 3094: 8a e0 ldi r24, 0x0A ; 10 + 3096: 80 93 ad 28 sts 0x28AD, r24 + break; + 309a: 7d cf rjmp .-262 ; 0x2f96 <__vector_83+0x36> + uint16_t Temp16; + + switch (LoadModState) { + case LOADMOD_FDT: + /* No data has been produced, but FDT has ended. Switch over to bit-grid aligning. */ + CODEC_TIMER_LOADMOD.PER = ISO14443A_BIT_GRID_CYCLES - 1; + 309c: 8f e7 ldi r24, 0x7F ; 127 + 309e: 90 e0 ldi r25, 0x00 ; 0 + 30a0: 80 93 66 09 sts 0x0966, r24 + 30a4: 90 93 67 09 sts 0x0967, r25 + break; + 30a8: 76 cf rjmp .-276 ; 0x2f96 <__vector_83+0x36> + + LoadModState = LOADMOD_PARITY1; + break; + + case LOADMOD_PARITY1: + if (*ParityBufferPtr) { + 30aa: e0 91 ba 28 lds r30, 0x28BA + 30ae: f0 91 bb 28 lds r31, 0x28BB + 30b2: 80 81 ld r24, Z + 30b4: 81 11 cpse r24, r1 + 30b6: 36 c0 rjmp .+108 ; 0x3124 <__stack+0x125> + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + } else { + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + 30b8: 80 e4 ldi r24, 0x40 ; 64 + 30ba: 80 93 45 06 sts 0x0645, r24 + } + + if (BitSent == BitCount) { + 30be: 20 91 b2 28 lds r18, 0x28B2 + 30c2: 30 91 b3 28 lds r19, 0x28B3 + 30c6: 80 91 b4 28 lds r24, 0x28B4 + 30ca: 90 91 b5 28 lds r25, 0x28B5 + 30ce: 28 17 cp r18, r24 + 30d0: 39 07 cpc r19, r25 + 30d2: 21 f2 breq .-120 ; 0x305c <__stack+0x5d> + /* No data left */ + LoadModState = LOADMOD_STOP_BIT0; + } else { + /* Fetch next data and continue sending bits. */ + ParityBufferPtr++; + 30d4: 31 96 adiw r30, 0x01 ; 1 + 30d6: e0 93 ba 28 sts 0x28BA, r30 + 30da: f0 93 bb 28 sts 0x28BB, r31 + DataRegister = *++CodecBufferPtr; + 30de: e0 91 b8 28 lds r30, 0x28B8 + 30e2: f0 91 b9 28 lds r31, 0x28B9 + 30e6: cf 01 movw r24, r30 + 30e8: 01 96 adiw r24, 0x01 ; 1 + 30ea: 80 93 b8 28 sts 0x28B8, r24 + 30ee: 90 93 b9 28 sts 0x28B9, r25 + 30f2: 81 81 ldd r24, Z+1 ; 0x01 + 30f4: 80 93 b1 28 sts 0x28B1, r24 + LoadModState = LOADMOD_DATA0; + 30f8: 84 e0 ldi r24, 0x04 ; 4 + 30fa: 80 93 ad 28 sts 0x28AD, r24 + 30fe: 4b cf rjmp .-362 ; 0x2f96 <__vector_83+0x36> + LoadModState = LOADMOD_DATA0; + + break; + + case LOADMOD_PARITY0: + if (*ParityBufferPtr) { + 3100: e0 91 ba 28 lds r30, 0x28BA + 3104: f0 91 bb 28 lds r31, 0x28BB + 3108: 80 81 ld r24, Z + 310a: 81 11 cpse r24, r1 + 310c: 07 c0 rjmp .+14 ; 0x311c <__stack+0x11d> + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + } else { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 310e: 80 e4 ldi r24, 0x40 ; 64 + 3110: 80 93 46 06 sts 0x0646, r24 + } + + LoadModState = LOADMOD_PARITY1; + 3114: 87 e0 ldi r24, 0x07 ; 7 + 3116: 80 93 ad 28 sts 0x28AD, r24 + break; + 311a: 3d cf rjmp .-390 ; 0x2f96 <__vector_83+0x36> + + break; + + case LOADMOD_PARITY0: + if (*ParityBufferPtr) { + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + 311c: 80 e4 ldi r24, 0x40 ; 64 + 311e: 80 93 45 06 sts 0x0645, r24 + 3122: f8 cf rjmp .-16 ; 0x3114 <__stack+0x115> + LoadModState = LOADMOD_PARITY1; + break; + + case LOADMOD_PARITY1: + if (*ParityBufferPtr) { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 3124: 80 e4 ldi r24, 0x40 ; 64 + 3126: 80 93 46 06 sts 0x0646, r24 + 312a: c9 cf rjmp .-110 ; 0x30be <__stack+0xbf> + + case LOADMOD_DATA1: + Temp8 = DataRegister; + + if (Temp8 & 1) { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 312c: 90 93 46 06 sts 0x0646, r25 + 3130: 7b cf rjmp .-266 ; 0x3028 <__stack+0x29> + DataRegister = *CodecBufferPtr; + break; + + case LOADMOD_DATA0: + if (DataRegister & 1) { + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + 3132: 80 e4 ldi r24, 0x40 ; 64 + 3134: 80 93 45 06 sts 0x0645, r24 + 3138: 48 cf rjmp .-368 ; 0x2fca <__vector_83+0x6a> + Temp16 = BitSent; + BitSent = ++Temp16; + + if ((Temp16 & 0x07) == 0) { + /* Byte boundary. Load parity bit and output it later. */ + LoadModState = LOADMOD_PARITY0; + 313a: 86 e0 ldi r24, 0x06 ; 6 + 313c: 80 93 ad 28 sts 0x28AD, r24 + break; + 3140: 2a cf rjmp .-428 ; 0x2f96 <__vector_83+0x36> + +00003142 : + default: + break; + } +} + +void ISO14443ACodecInit(void) { + 3142: cf 93 push r28 + 3144: df 93 push r29 +static volatile LoadModStateType LoadModState; +static volatile bool SamplePosition; + +static void Initialize(void) { + /* Configure CARRIER input pin and route it to EVSYS */ + CODEC_CARRIER_IN_PORT.DIRCLR = CODEC_CARRIER_IN_MASK; + 3146: e0 e4 ldi r30, 0x40 ; 64 + 3148: f6 e0 ldi r31, 0x06 ; 6 + 314a: 84 e0 ldi r24, 0x04 ; 4 + 314c: 82 83 std Z+2, r24 ; 0x02 + CODEC_CARRIER_IN_PORT.CODEC_CARRIER_IN_PINCTRL = PORT_ISC_BOTHEDGES_gc; + 314e: 12 8a std Z+18, r1 ; 0x12 + EVSYS.CH6MUX = CODEC_CARRIER_IN_EVMUX; + 3150: c0 e8 ldi r28, 0x80 ; 128 + 3152: d1 e0 ldi r29, 0x01 ; 1 + 3154: 82 e6 ldi r24, 0x62 ; 98 + 3156: 8e 83 std Y+6, r24 ; 0x06 + + /* Configure two DEMOD pins for input. + * Configure event channel 0 for rising edge (begin of modulation pause) + * Configure event channel 1 for falling edge (end of modulation pause) */ + CODEC_DEMOD_IN_PORT.DIRCLR = CODEC_DEMOD_IN_MASK; + 3158: a0 e2 ldi r26, 0x20 ; 32 + 315a: b6 e0 ldi r27, 0x06 ; 6 + 315c: 85 e0 ldi r24, 0x05 ; 5 + 315e: 12 96 adiw r26, 0x02 ; 2 + 3160: 8c 93 st X, r24 + 3162: 12 97 sbiw r26, 0x02 ; 2 + CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL0 = PORT_ISC_RISING_gc; + 3164: 81 e0 ldi r24, 0x01 ; 1 + 3166: 52 96 adiw r26, 0x12 ; 18 + 3168: 8c 93 st X, r24 + 316a: 52 97 sbiw r26, 0x12 ; 18 + CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL1 = PORT_ISC_FALLING_gc; + 316c: 82 e0 ldi r24, 0x02 ; 2 + 316e: 50 96 adiw r26, 0x10 ; 16 + 3170: 8c 93 st X, r24 + 3172: 50 97 sbiw r26, 0x10 ; 16 + CODEC_DEMOD_IN_PORT.INT0MASK = 0; + 3174: 1a 96 adiw r26, 0x0a ; 10 + 3176: 1c 92 st X, r1 + 3178: 1a 97 sbiw r26, 0x0a ; 10 + CODEC_DEMOD_IN_PORT.INTCTRL = PORT_INT0LVL_HI_gc; + 317a: 83 e0 ldi r24, 0x03 ; 3 + 317c: 19 96 adiw r26, 0x09 ; 9 + 317e: 8c 93 st X, r24 + EVSYS.CH0MUX = CODEC_DEMOD_IN_EVMUX0; + 3180: 9a e5 ldi r25, 0x5A ; 90 + 3182: 98 83 st Y, r25 + EVSYS.CH1MUX = CODEC_DEMOD_IN_EVMUX1; + 3184: 98 e5 ldi r25, 0x58 ; 88 + 3186: 99 83 std Y+1, r25 ; 0x01 + + /* Configure LOADMOD and SUBCARRIER output pins. + * Disable PSK modulation by setting pin to low. */ + CODEC_LOADMOD_PORT.DIRSET = CODEC_LOADMOD_MASK; + 3188: 90 e4 ldi r25, 0x40 ; 64 + 318a: 91 83 std Z+1, r25 ; 0x01 + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 318c: 96 83 std Z+6, r25 ; 0x06 + CODEC_SUBCARRIER_PORT.DIRSET = CODEC_SUBCARRIER_MASK; + 318e: 81 83 std Z+1, r24 ; 0x01 + CODEC_SUBCARRIER_PORT.OUTCLR = CODEC_SUBCARRIER_MASK; + 3190: 86 83 std Z+6, r24 ; 0x06 + + /* Configure subcarrier generation with 50% DC output using OOK */ + CODEC_SUBCARRIER_TIMER.PER = ISO14443A_SUBCARRIER_DIVIDER - 1; + 3192: e0 e0 ldi r30, 0x00 ; 0 + 3194: f8 e0 ldi r31, 0x08 ; 8 + 3196: 8f e0 ldi r24, 0x0F ; 15 + 3198: 90 e0 ldi r25, 0x00 ; 0 + 319a: 86 a3 std Z+38, r24 ; 0x26 + 319c: 97 a3 std Z+39, r25 ; 0x27 + CODEC_SUBCARRIER_TIMER.CODEC_SUBCARRIER_CC_OOK = ISO14443A_SUBCARRIER_DIVIDER/2; + 319e: 88 e0 ldi r24, 0x08 ; 8 + 31a0: 90 e0 ldi r25, 0x00 ; 0 + 31a2: 82 a7 std Z+42, r24 ; 0x2a + 31a4: 93 a7 std Z+43, r25 ; 0x2b + CODEC_SUBCARRIER_TIMER.CTRLB = CODEC_SUBCARRIER_CCEN_OOK | TC_WGMODE_SINGLESLOPE_gc; + 31a6: 83 e2 ldi r24, 0x23 ; 35 + 31a8: 81 83 std Z+1, r24 ; 0x01 +void ISO14443ACodecInit(void) { + /* Initialize common peripherals and start listening + * for incoming data. */ + Initialize(); + StartDemod(); +} + 31aa: df 91 pop r29 + 31ac: cf 91 pop r28 + +void ISO14443ACodecInit(void) { + /* Initialize common peripherals and start listening + * for incoming data. */ + Initialize(); + StartDemod(); + 31ae: c6 cd rjmp .-1140 ; 0x2d3c + +000031b0 : +} + +void ISO14443ACodecTask(void) { + 31b0: 0f 93 push r16 + 31b2: 1f 93 push r17 + 31b4: cf 93 push r28 + 31b6: df 93 push r29 + if (Flags.DemodFinished) { + 31b8: 80 91 b6 28 lds r24, 0x28B6 + 31bc: 88 23 and r24, r24 + 31be: c1 f0 breq .+48 ; 0x31f0 + Flags.DemodFinished = 0; + 31c0: 10 92 b6 28 sts 0x28B6, r1 +INLINE void CodecTask(void) { + ActiveConfiguration.CodecTaskFunc(); +} + +INLINE void CodecSetDemodPower(bool bOnOff) { + CODEC_DEMOD_POWER_PORT.DIRSET = CODEC_DEMOD_POWER_MASK; + 31c4: 82 e0 ldi r24, 0x02 ; 2 + 31c6: 80 93 21 06 sts 0x0621, r24 + + if (bOnOff) { + CODEC_DEMOD_POWER_PORT.OUTSET = CODEC_DEMOD_POWER_MASK; + } else { + CODEC_DEMOD_POWER_PORT.OUTCLR = CODEC_DEMOD_POWER_MASK; + 31ca: 80 93 26 06 sts 0x0626, r24 + /* Reception finished. Process the received bytes */ + CodecSetDemodPower(false); + + uint16_t DemodBitCount = BitCount; + 31ce: 00 91 b4 28 lds r16, 0x28B4 + 31d2: 10 91 b5 28 lds r17, 0x28B5 + uint16_t AnswerBitCount = ISO14443A_APP_NO_RESPONSE; + + if (DemodBitCount > 0) { + 31d6: 01 15 cp r16, r1 + 31d8: 11 05 cpc r17, r1 + 31da: 99 f4 brne .+38 ; 0x3202 +INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { + return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount); +} + +INLINE void ApplicationReset(void) { + ActiveConfiguration.ApplicationResetFunc(); + 31dc: e0 91 f9 28 lds r30, 0x28F9 + 31e0: f0 91 fa 28 lds r31, 0x28FA + 31e4: 09 95 icall + CodecBufferPtr = CodecBuffer; + ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; + LoadModState = LOADMOD_START; + } else { + /* No data to be processed. Disable loadmodding and start listening again */ + CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; + 31e6: 10 92 40 09 sts 0x0940, r1 + CODEC_TIMER_LOADMOD.INTCTRLA = 0; + 31ea: 10 92 46 09 sts 0x0946, r1 + + StartDemod(); + 31ee: a6 dd rcall .-1204 ; 0x2d3c + } + } + + if (Flags.LoadmodFinished) { + 31f0: 80 91 b7 28 lds r24, 0x28B7 + 31f4: 81 11 cpse r24, r1 + 31f6: 5a c0 rjmp .+180 ; 0x32ac + * for incoming data again. */ + StartDemod(); + } + + //SystemSleep(); +} + 31f8: df 91 pop r29 + 31fa: cf 91 pop r28 + 31fc: 1f 91 pop r17 + 31fe: 0f 91 pop r16 + 3200: 08 95 ret + + uint16_t DemodBitCount = BitCount; + uint16_t AnswerBitCount = ISO14443A_APP_NO_RESPONSE; + + if (DemodBitCount > 0) { + LogEntry(LOG_INFO_RX_DATA, CodecBuffer, (DemodBitCount+7)/8); + 3202: a8 01 movw r20, r16 + 3204: 49 5f subi r20, 0xF9 ; 249 + 3206: 5f 4f sbci r21, 0xFF ; 255 + 3208: 56 95 lsr r21 + 320a: 47 95 ror r20 + 320c: 56 95 lsr r21 + 320e: 47 95 ror r20 + 3210: 56 95 lsr r21 + 3212: 47 95 ror r20 +void LogSetModeById(LogModeEnum Mode); +bool LogSetModeByName(const char* Name); +void LogGetModeByName(char* Name, uint16_t BufferSize); +void LogGetModeList(char* List, uint16_t BufferSize); + +INLINE void LogEntry(LogEntryEnum Entry, void* Data, uint8_t Length) { LogFunc(Entry, Data, Length); } + 3214: e0 91 07 29 lds r30, 0x2907 + 3218: f0 91 08 29 lds r31, 0x2908 + 321c: 6c e3 ldi r22, 0x3C ; 60 + 321e: 7a e2 ldi r23, 0x2A ; 42 + 3220: 80 e2 ldi r24, 0x20 ; 32 + 3222: 09 95 icall + LEDTrigger(LED_CODEC_RX, LED_PULSE); + 3224: 63 e1 ldi r22, 0x13 ; 19 + 3226: 86 e0 ldi r24, 0x06 ; 6 + 3228: 0e 94 af 0f call 0x1f5e ; 0x1f5e +INLINE void ApplicationTask(void) { + ActiveConfiguration.ApplicationTaskFunc(); +} + +INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { + return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount); + 322c: e0 91 fd 28 lds r30, 0x28FD + 3230: f0 91 fe 28 lds r31, 0x28FE + 3234: b8 01 movw r22, r16 + 3236: 8c e3 ldi r24, 0x3C ; 60 + 3238: 9a e2 ldi r25, 0x2A ; 42 + 323a: 09 95 icall + 323c: 8c 01 movw r16, r24 + + /* Call application if we received data */ + AnswerBitCount = ApplicationProcess(CodecBuffer, DemodBitCount); + + if (AnswerBitCount & ISO14443A_APP_CUSTOM_PARITY) { + 323e: 94 ff sbrs r25, 4 + 3240: 3c c0 rjmp .+120 ; 0x32ba + /* Application has generated it's own parity bits. + * Clear this option bit. */ + AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; + 3242: 1f 7e andi r17, 0xEF ; 239 + } + } else { + ApplicationReset(); + } + + if (AnswerBitCount != ISO14443A_APP_NO_RESPONSE) { + 3244: 01 15 cp r16, r1 + 3246: 11 05 cpc r17, r1 + 3248: 71 f2 breq .-100 ; 0x31e6 + LogEntry(LOG_INFO_TX_DATA, CodecBuffer, (AnswerBitCount + 7) / 8); + 324a: a8 01 movw r20, r16 + 324c: 49 5f subi r20, 0xF9 ; 249 + 324e: 5f 4f sbci r21, 0xFF ; 255 + 3250: 56 95 lsr r21 + 3252: 47 95 ror r20 + 3254: 56 95 lsr r21 + 3256: 47 95 ror r20 + 3258: 56 95 lsr r21 + 325a: 47 95 ror r20 + 325c: e0 91 07 29 lds r30, 0x2907 + 3260: f0 91 08 29 lds r31, 0x2908 + 3264: 6c e3 ldi r22, 0x3C ; 60 + 3266: 7a e2 ldi r23, 0x2A ; 42 + 3268: 81 e2 ldi r24, 0x21 ; 33 + 326a: 09 95 icall + LEDTrigger(LED_CODEC_TX, LED_PULSE); + 326c: 63 e1 ldi r22, 0x13 ; 19 + 326e: 87 e0 ldi r24, 0x07 ; 7 + 3270: 0e 94 af 0f call 0x1f5e ; 0x1f5e + + BitCount = AnswerBitCount; + 3274: 00 93 b4 28 sts 0x28B4, r16 + 3278: 10 93 b5 28 sts 0x28B5, r17 + BitSent = 0; + 327c: 10 92 b2 28 sts 0x28B2, r1 + 3280: 10 92 b3 28 sts 0x28B3, r1 + CodecBufferPtr = CodecBuffer; + 3284: 8c e3 ldi r24, 0x3C ; 60 + 3286: 9a e2 ldi r25, 0x2A ; 42 + 3288: 80 93 b8 28 sts 0x28B8, r24 + 328c: 90 93 b9 28 sts 0x28B9, r25 + ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; + 3290: 8c eb ldi r24, 0xBC ; 188 + 3292: 9a e2 ldi r25, 0x2A ; 42 + 3294: 80 93 ba 28 sts 0x28BA, r24 + 3298: 90 93 bb 28 sts 0x28BB, r25 + LoadModState = LOADMOD_START; + 329c: 81 e0 ldi r24, 0x01 ; 1 + 329e: 80 93 ad 28 sts 0x28AD, r24 + + StartDemod(); + } + } + + if (Flags.LoadmodFinished) { + 32a2: 80 91 b7 28 lds r24, 0x28B7 + 32a6: 88 23 and r24, r24 + 32a8: 09 f4 brne .+2 ; 0x32ac + 32aa: a6 cf rjmp .-180 ; 0x31f8 + Flags.LoadmodFinished = 0; + 32ac: 10 92 b7 28 sts 0x28B7, r1 + * for incoming data again. */ + StartDemod(); + } + + //SystemSleep(); +} + 32b0: df 91 pop r29 + 32b2: cf 91 pop r28 + 32b4: 1f 91 pop r17 + 32b6: 0f 91 pop r16 + + if (Flags.LoadmodFinished) { + Flags.LoadmodFinished = 0; + /* Load modulation has been finished. Stop it and start to listen + * for incoming data again. */ + StartDemod(); + 32b8: 41 cd rjmp .-1406 ; 0x2d3c + /* Application has generated it's own parity bits. + * Clear this option bit. */ + AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; + } else { + /* We have to generate the parity bits ourself */ + for (uint8_t i = 0; i < (AnswerBitCount / 8); i++) { + 32ba: 96 95 lsr r25 + 32bc: 87 95 ror r24 + 32be: 96 95 lsr r25 + 32c0: 87 95 ror r24 + 32c2: 96 95 lsr r25 + 32c4: 87 95 ror r24 + 32c6: 00 97 sbiw r24, 0x00 ; 0 + 32c8: 09 f4 brne .+2 ; 0x32cc + 32ca: bc cf rjmp .-136 ; 0x3244 + 32cc: 40 e0 ldi r20, 0x00 ; 0 + 32ce: 20 e0 ldi r18, 0x00 ; 0 + 32d0: 30 e0 ldi r19, 0x00 ; 0 + /* For each whole byte, generate a parity bit. */ + CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = + ODD_PARITY(CodecBuffer[i]); + 32d2: f9 01 movw r30, r18 + 32d4: e4 5c subi r30, 0xC4 ; 196 + 32d6: f5 4d sbci r31, 0xD5 ; 213 + 32d8: 20 81 ld r18, Z + 32da: 02 2e mov r0, r18 + 32dc: 22 95 swap r18 + 32de: 20 25 eor r18, r0 + 32e0: 02 2e mov r0, r18 + 32e2: 26 95 lsr r18 + 32e4: 26 95 lsr r18 + 32e6: 20 25 eor r18, r0 + AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; + } else { + /* We have to generate the parity bits ourself */ + for (uint8_t i = 0; i < (AnswerBitCount / 8); i++) { + /* For each whole byte, generate a parity bit. */ + CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = + 32e8: e0 58 subi r30, 0x80 ; 128 + 32ea: ff 4f sbci r31, 0xFF ; 255 + ODD_PARITY(CodecBuffer[i]); + 32ec: 30 e0 ldi r19, 0x00 ; 0 + 32ee: 2f 5f subi r18, 0xFF ; 255 + 32f0: 3f 4f sbci r19, 0xFF ; 255 + 32f2: 21 fb bst r18, 1 + 32f4: 55 27 eor r21, r21 + 32f6: 50 f9 bld r21, 0 + 32f8: c5 2f mov r28, r21 + 32fa: 20 e0 ldi r18, 0x00 ; 0 + 32fc: d2 2f mov r29, r18 + 32fe: 51 e0 ldi r21, 0x01 ; 1 + 3300: c5 27 eor r28, r21 + 3302: c0 83 st Z, r28 + /* Application has generated it's own parity bits. + * Clear this option bit. */ + AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; + } else { + /* We have to generate the parity bits ourself */ + for (uint8_t i = 0; i < (AnswerBitCount / 8); i++) { + 3304: 4f 5f subi r20, 0xFF ; 255 + 3306: 24 2f mov r18, r20 + 3308: 30 e0 ldi r19, 0x00 ; 0 + 330a: 28 17 cp r18, r24 + 330c: 39 07 cpc r19, r25 + 330e: 08 f3 brcs .-62 ; 0x32d2 + 3310: 99 cf rjmp .-206 ; 0x3244 + +00003312 : + +static uint8_t CompatWritePageAddress; + +void MifareUltralightAppInit(void) +{ + State = STATE_IDLE; + 3312: 81 e0 ldi r24, 0x01 ; 1 + 3314: 80 93 bc 28 sts 0x28BC, r24 + 3318: 08 95 ret + +0000331a : +} + +void MifareUltralightAppReset(void) +{ + State = STATE_IDLE; + 331a: 81 e0 ldi r24, 0x01 ; 1 + 331c: 80 93 bc 28 sts 0x28BC, r24 + 3320: 08 95 ret + +00003322 : +} + +void MifareUltralightAppTask(void) +{ + 3322: 08 95 ret + +00003324 : + +} + + +uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + 3324: ff 92 push r15 + 3326: 0f 93 push r16 + 3328: 1f 93 push r17 + 332a: cf 93 push r28 + 332c: df 93 push r29 + 332e: 00 d0 rcall .+0 ; 0x3330 + 3330: 00 d0 rcall .+0 ; 0x3332 + 3332: cd b7 in r28, 0x3d ; 61 + 3334: de b7 in r29, 0x3e ; 62 + 3336: 8c 01 movw r16, r24 + uint8_t Cmd = Buffer[0]; + 3338: fc 01 movw r30, r24 + 333a: 90 81 ld r25, Z + + switch(State) { + 333c: 80 91 bc 28 lds r24, 0x28BC + 3340: 82 30 cpi r24, 0x02 ; 2 + 3342: 09 f4 brne .+2 ; 0x3346 + 3344: 5b c0 rjmp .+182 ; 0x33fc + 3346: 80 f4 brcc .+32 ; 0x3368 +INLINE +bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue) +{ + uint8_t* DataPtr = (uint8_t*) Buffer; + + if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){ + 3348: 96 32 cpi r25, 0x26 ; 38 + 334a: a9 f1 breq .+106 ; 0x33b6 + 334c: 92 35 cpi r25, 0x52 ; 82 + 334e: 99 f1 breq .+102 ; 0x33b6 + + *BitCount = ISO14443A_SAK_FRAME_SIZE; + return true; + } else { + /* We have not been selected. Don't send anything. */ + *BitCount = 0; + 3350: 20 e0 ldi r18, 0x00 ; 0 + 3352: 30 e0 ldi r19, 0x00 ; 0 + break; + } + + /* No response has been sent, when we reach here */ + return ISO14443A_APP_NO_RESPONSE; +} + 3354: c9 01 movw r24, r18 + 3356: 24 96 adiw r28, 0x04 ; 4 + 3358: cd bf out 0x3d, r28 ; 61 + 335a: de bf out 0x3e, r29 ; 62 + 335c: df 91 pop r29 + 335e: cf 91 pop r28 + 3360: 1f 91 pop r17 + 3362: 0f 91 pop r16 + 3364: ff 90 pop r15 + 3366: 08 95 ret + +uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + uint8_t Cmd = Buffer[0]; + + switch(State) { + 3368: 84 30 cpi r24, 0x04 ; 4 + 336a: 79 f1 breq .+94 ; 0x33ca + 336c: 68 f4 brcc .+26 ; 0x3388 +INLINE +bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue) +{ + uint8_t* DataPtr = (uint8_t*) Buffer; + + if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){ + 336e: 96 32 cpi r25, 0x26 ; 38 + 3370: 11 f1 breq .+68 ; 0x33b6 + 3372: 92 35 cpi r25, 0x52 ; 82 + 3374: 01 f1 breq .+64 ; 0x33b6 + + case STATE_READY2: + if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE)) { + State = STATE_READY1; + return BitCount; + } else if (Cmd == ISO14443A_CMD_SELECT_CL2) { + 3376: 95 39 cpi r25, 0x95 ; 149 + 3378: 09 f4 brne .+2 ; 0x337c + 337a: 90 c0 rjmp .+288 ; 0x349c + Buffer[0] = NAK_INVALID_ARG; + return NAK_FRAME_SIZE; + } + } else { + /* Unknown command. Enter halt state */ + State = STATE_IDLE; + 337c: 81 e0 ldi r24, 0x01 ; 1 + 337e: 80 93 bc 28 sts 0x28BC, r24 + /* Unknown state? Should never happen. */ + break; + } + + /* No response has been sent, when we reach here */ + return ISO14443A_APP_NO_RESPONSE; + 3382: 20 e0 ldi r18, 0x00 ; 0 + 3384: 30 e0 ldi r19, 0x00 ; 0 + } + } else { + /* Unknown command. Enter halt state */ + State = STATE_IDLE; + } + break; + 3386: e6 cf rjmp .-52 ; 0x3354 + +uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + uint8_t Cmd = Buffer[0]; + + switch(State) { + 3388: 85 30 cpi r24, 0x05 ; 5 + 338a: 11 f7 brne .-60 ; 0x3350 + } + break; + + case STATE_COMPAT_WRITE: + /* Compatibility write. Receiving 16 bytes of data of which 4 bytes are valid. */ + if (ISO14443ACheckCRCA(Buffer, BYTES_PER_COMPAT_WRITE)) { + 338c: 60 e1 ldi r22, 0x10 ; 16 + 338e: 70 e0 ldi r23, 0x00 ; 0 + 3390: c8 01 movw r24, r16 + 3392: e7 d7 rcall .+4046 ; 0x4362 + 3394: 88 23 and r24, r24 + 3396: 09 f4 brne .+2 ; 0x339a + 3398: 6b c0 rjmp .+214 ; 0x3470 + /* We don't perform any checks here. You will be able to program the + * whole memory. Also there is no OTP behaviour. */ + if (!ActiveConfiguration.ReadOnly) { + 339a: 80 91 06 29 lds r24, 0x2906 + 339e: 88 23 and r24, r24 + 33a0: 09 f4 brne .+2 ; 0x33a4 + 33a2: 6f c0 rjmp .+222 ; 0x3482 + } else { + /* If we are told to be read only, we silently ignore the write command + * and pretend to have written data. */ + } + + State = STATE_ACTIVE; + 33a4: 84 e0 ldi r24, 0x04 ; 4 + 33a6: 80 93 bc 28 sts 0x28BC, r24 + Buffer[0] = ACK_VALUE; + 33aa: 8a e0 ldi r24, 0x0A ; 10 + 33ac: f8 01 movw r30, r16 + 33ae: 80 83 st Z, r24 + return ACK_FRAME_SIZE; + 33b0: 24 e0 ldi r18, 0x04 ; 4 + 33b2: 30 e0 ldi r19, 0x00 ; 0 + 33b4: cf cf rjmp .-98 ; 0x3354 + DataPtr[0] = (ATQAValue >> 0) & 0x00FF; + 33b6: 84 e4 ldi r24, 0x44 ; 68 + 33b8: f8 01 movw r30, r16 + 33ba: 80 83 st Z, r24 + DataPtr[1] = (ATQAValue >> 8) & 0x00FF; + 33bc: 11 82 std Z+1, r1 ; 0x01 + } + break; + + case STATE_ACTIVE: + if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE)) { + State = STATE_READY1; + 33be: 82 e0 ldi r24, 0x02 ; 2 + 33c0: 80 93 bc 28 sts 0x28BC, r24 + + *BitCount = ISO14443A_ATQA_FRAME_SIZE; + 33c4: 20 e1 ldi r18, 0x10 ; 16 + 33c6: 30 e0 ldi r19, 0x00 ; 0 + return BitCount; + 33c8: c5 cf rjmp .-118 ; 0x3354 +INLINE +bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue) +{ + uint8_t* DataPtr = (uint8_t*) Buffer; + + if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){ + 33ca: 96 32 cpi r25, 0x26 ; 38 + 33cc: a1 f3 breq .-24 ; 0x33b6 + 33ce: 92 35 cpi r25, 0x52 ; 82 + 33d0: 91 f3 breq .-28 ; 0x33b6 + } else if (Cmd == CMD_READ) { + 33d2: 90 33 cpi r25, 0x30 ; 48 + 33d4: 09 f4 brne .+2 ; 0x33d8 + 33d6: 8e c0 rjmp .+284 ; 0x34f4 + } + } else { + Buffer[0] = NAK_CRC_ERROR; + return NAK_FRAME_SIZE; + } + } else if (Cmd == CMD_WRITE) { + 33d8: 92 3a cpi r25, 0xA2 ; 162 + 33da: 09 f4 brne .+2 ; 0x33de + 33dc: ba c0 rjmp .+372 ; 0x3552 + } + } else { + Buffer[0] = NAK_CRC_ERROR; + return NAK_FRAME_SIZE; + } + } else if (Cmd == CMD_COMPAT_WRITE) { + 33de: 90 3a cpi r25, 0xA0 ; 160 + 33e0: 09 f4 brne .+2 ; 0x33e4 + 33e2: d4 c0 rjmp .+424 ; 0x358c + } + } else { + Buffer[0] = NAK_CRC_ERROR; + return NAK_FRAME_SIZE; + } + } else if (Cmd == CMD_HALT) { + 33e4: 90 35 cpi r25, 0x50 ; 80 + 33e6: 51 f6 brne .-108 ; 0x337c + /* Halts the tag. According to the ISO14443, the second + * byte is supposed to be 0. */ + if (Buffer[1] == 0) { + 33e8: f8 01 movw r30, r16 + 33ea: 81 81 ldd r24, Z+1 ; 0x01 + 33ec: 88 23 and r24, r24 + 33ee: 09 f4 brne .+2 ; 0x33f2 + 33f0: df c0 rjmp .+446 ; 0x35b0 + } else { + Buffer[0] = NAK_CRC_ERROR; + return NAK_FRAME_SIZE; + } + } else { + Buffer[0] = NAK_INVALID_ARG; + 33f2: f8 01 movw r30, r16 + 33f4: 10 82 st Z, r1 + return NAK_FRAME_SIZE; + 33f6: 24 e0 ldi r18, 0x04 ; 4 + 33f8: 30 e0 ldi r19, 0x00 ; 0 + 33fa: ac cf rjmp .-168 ; 0x3354 + 33fc: 96 32 cpi r25, 0x26 ; 38 + 33fe: d9 f2 breq .-74 ; 0x33b6 + 3400: 92 35 cpi r25, 0x52 ; 82 + 3402: c9 f2 breq .-78 ; 0x33b6 + + case STATE_READY1: + if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE)) { + State = STATE_READY1; + return BitCount; + } else if (Cmd == ISO14443A_CMD_SELECT_CL1) { + 3404: 93 39 cpi r25, 0x93 ; 147 + 3406: 09 f0 breq .+2 ; 0x340a + 3408: b9 cf rjmp .-142 ; 0x337c + /* Load UID CL1 and perform anticollision. Since + * MF Ultralight use a double-sized UID, the first byte + * of CL1 has to be the cascade-tag byte. */ + uint8_t UidCL1[ISO14443A_CL_UID_SIZE] = { [0] = ISO14443A_UID0_CT }; + 340a: 19 82 std Y+1, r1 ; 0x01 + 340c: 1a 82 std Y+2, r1 ; 0x02 + 340e: 1b 82 std Y+3, r1 ; 0x03 + 3410: 1c 82 std Y+4, r1 ; 0x04 + 3412: 88 e8 ldi r24, 0x88 ; 136 + 3414: 89 83 std Y+1, r24 ; 0x01 + + MemoryReadBlock(&UidCL1[1], UID_CL1_ADDRESS, UID_CL1_SIZE); + 3416: 43 e0 ldi r20, 0x03 ; 3 + 3418: 50 e0 ldi r21, 0x00 ; 0 + 341a: 60 e0 ldi r22, 0x00 ; 0 + 341c: 70 e0 ldi r23, 0x00 ; 0 + 341e: ce 01 movw r24, r28 + 3420: 02 96 adiw r24, 0x02 ; 2 + 3422: 0e 94 de 06 call 0xdbc ; 0xdbc + uint8_t* DataPtr = (uint8_t*) Buffer; + uint8_t NVB = DataPtr[1]; + //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F; + //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F; + + switch (NVB) { + 3426: f8 01 movw r30, r16 + 3428: 81 81 ldd r24, Z+1 ; 0x01 + 342a: 80 32 cpi r24, 0x20 ; 32 + 342c: 09 f4 brne .+2 ; 0x3430 + 342e: 81 c0 rjmp .+258 ; 0x3532 + 3430: 80 37 cpi r24, 0x70 ; 112 + 3432: 09 f0 breq .+2 ; 0x3436 + 3434: 8d cf rjmp .-230 ; 0x3350 + return false; + + case ISO14443A_NVB_AC_END: + /* End of anticollision procedure. + * Send SAK CLn if we are selected. */ + if ( (DataPtr[2] == UidCL[0]) && + 3436: f8 01 movw r30, r16 + 3438: 92 81 ldd r25, Z+2 ; 0x02 + 343a: 89 81 ldd r24, Y+1 ; 0x01 + 343c: 98 13 cpse r25, r24 + 343e: 88 cf rjmp .-240 ; 0x3350 + 3440: 93 81 ldd r25, Z+3 ; 0x03 + 3442: 8a 81 ldd r24, Y+2 ; 0x02 + 3444: 98 13 cpse r25, r24 + 3446: 84 cf rjmp .-248 ; 0x3350 + (DataPtr[3] == UidCL[1]) && + 3448: 94 81 ldd r25, Z+4 ; 0x04 + 344a: 8b 81 ldd r24, Y+3 ; 0x03 + 344c: 98 13 cpse r25, r24 + 344e: 80 cf rjmp .-256 ; 0x3350 + (DataPtr[4] == UidCL[2]) && + 3450: 95 81 ldd r25, Z+5 ; 0x05 + 3452: 8c 81 ldd r24, Y+4 ; 0x04 + 3454: 98 13 cpse r25, r24 + 3456: 7c cf rjmp .-264 ; 0x3350 + (DataPtr[5] == UidCL[3]) ) { + + DataPtr[0] = SAKValue; + 3458: 84 e0 ldi r24, 0x04 ; 4 + 345a: 80 83 st Z, r24 + ISO14443AAppendCRCA(Buffer, 1); + 345c: 61 e0 ldi r22, 0x01 ; 1 + 345e: 70 e0 ldi r23, 0x00 ; 0 + 3460: c8 01 movw r24, r16 + 3462: 50 d7 rcall .+3744 ; 0x4304 + + if (ISO14443ASelect(Buffer, &BitCount, UidCL1, SAK_CL1_VALUE)) { + /* CL1 stage has ended successfully */ + State = STATE_READY2; + 3464: 83 e0 ldi r24, 0x03 ; 3 + 3466: 80 93 bc 28 sts 0x28BC, r24 + + *BitCount = ISO14443A_SAK_FRAME_SIZE; + 346a: 28 e1 ldi r18, 0x18 ; 24 + 346c: 30 e0 ldi r19, 0x00 ; 0 + 346e: 72 cf rjmp .-284 ; 0x3354 + + State = STATE_ACTIVE; + Buffer[0] = ACK_VALUE; + return ACK_FRAME_SIZE; + } else { + State = STATE_ACTIVE; + 3470: 84 e0 ldi r24, 0x04 ; 4 + 3472: 80 93 bc 28 sts 0x28BC, r24 + Buffer[0] = NAK_CRC_ERROR; + 3476: 81 e0 ldi r24, 0x01 ; 1 + 3478: f8 01 movw r30, r16 + 347a: 80 83 st Z, r24 + return NAK_FRAME_SIZE; + 347c: 24 e0 ldi r18, 0x04 ; 4 + 347e: 30 e0 ldi r19, 0x00 ; 0 + 3480: 69 cf rjmp .-302 ; 0x3354 + /* Compatibility write. Receiving 16 bytes of data of which 4 bytes are valid. */ + if (ISO14443ACheckCRCA(Buffer, BYTES_PER_COMPAT_WRITE)) { + /* We don't perform any checks here. You will be able to program the + * whole memory. Also there is no OTP behaviour. */ + if (!ActiveConfiguration.ReadOnly) { + MemoryWriteBlock(Buffer, CompatWritePageAddress * BYTES_PER_PAGE, BYTES_PER_WRITE); + 3482: 60 91 bd 28 lds r22, 0x28BD + 3486: 70 e0 ldi r23, 0x00 ; 0 + 3488: 66 0f add r22, r22 + 348a: 77 1f adc r23, r23 + 348c: 66 0f add r22, r22 + 348e: 77 1f adc r23, r23 + 3490: 44 e0 ldi r20, 0x04 ; 4 + 3492: 50 e0 ldi r21, 0x00 ; 0 + 3494: c8 01 movw r24, r16 + 3496: 0e 94 f6 06 call 0xdec ; 0xdec + 349a: 84 cf rjmp .-248 ; 0x33a4 + return BitCount; + } else if (Cmd == ISO14443A_CMD_SELECT_CL2) { + /* Load UID CL2 and perform anticollision */ + uint8_t UidCL2[ISO14443A_CL_UID_SIZE]; + + MemoryReadBlock(UidCL2, UID_CL2_ADDRESS, UID_CL2_SIZE); + 349c: 44 e0 ldi r20, 0x04 ; 4 + 349e: 50 e0 ldi r21, 0x00 ; 0 + 34a0: 64 e0 ldi r22, 0x04 ; 4 + 34a2: 70 e0 ldi r23, 0x00 ; 0 + 34a4: ce 01 movw r24, r28 + 34a6: 01 96 adiw r24, 0x01 ; 1 + 34a8: 0e 94 de 06 call 0xdbc ; 0xdbc + uint8_t* DataPtr = (uint8_t*) Buffer; + uint8_t NVB = DataPtr[1]; + //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F; + //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F; + + switch (NVB) { + 34ac: f8 01 movw r30, r16 + 34ae: 81 81 ldd r24, Z+1 ; 0x01 + 34b0: 80 32 cpi r24, 0x20 ; 32 + 34b2: 09 f4 brne .+2 ; 0x34b6 + 34b4: 3e c0 rjmp .+124 ; 0x3532 + 34b6: 80 37 cpi r24, 0x70 ; 112 + 34b8: 09 f0 breq .+2 ; 0x34bc + 34ba: 4a cf rjmp .-364 ; 0x3350 + return false; + + case ISO14443A_NVB_AC_END: + /* End of anticollision procedure. + * Send SAK CLn if we are selected. */ + if ( (DataPtr[2] == UidCL[0]) && + 34bc: f8 01 movw r30, r16 + 34be: 92 81 ldd r25, Z+2 ; 0x02 + 34c0: 89 81 ldd r24, Y+1 ; 0x01 + 34c2: 98 13 cpse r25, r24 + 34c4: 45 cf rjmp .-374 ; 0x3350 + 34c6: 93 81 ldd r25, Z+3 ; 0x03 + 34c8: 8a 81 ldd r24, Y+2 ; 0x02 + 34ca: 98 13 cpse r25, r24 + 34cc: 41 cf rjmp .-382 ; 0x3350 + (DataPtr[3] == UidCL[1]) && + 34ce: 94 81 ldd r25, Z+4 ; 0x04 + 34d0: 8b 81 ldd r24, Y+3 ; 0x03 + 34d2: 98 13 cpse r25, r24 + 34d4: 3d cf rjmp .-390 ; 0x3350 + (DataPtr[4] == UidCL[2]) && + 34d6: 95 81 ldd r25, Z+5 ; 0x05 + 34d8: 8c 81 ldd r24, Y+4 ; 0x04 + 34da: 98 13 cpse r25, r24 + 34dc: 39 cf rjmp .-398 ; 0x3350 + (DataPtr[5] == UidCL[3]) ) { + + DataPtr[0] = SAKValue; + 34de: 10 82 st Z, r1 + ISO14443AAppendCRCA(Buffer, 1); + 34e0: 61 e0 ldi r22, 0x01 ; 1 + 34e2: 70 e0 ldi r23, 0x00 ; 0 + 34e4: c8 01 movw r24, r16 + 34e6: 0e d7 rcall .+3612 ; 0x4304 + + if (ISO14443ASelect(Buffer, &BitCount, UidCL2, SAK_CL2_VALUE)) { + /* CL2 stage has ended successfully. This means + * our complete UID has been sent to the reader. */ + State = STATE_ACTIVE; + 34e8: 84 e0 ldi r24, 0x04 ; 4 + 34ea: 80 93 bc 28 sts 0x28BC, r24 + + *BitCount = ISO14443A_SAK_FRAME_SIZE; + 34ee: 28 e1 ldi r18, 0x18 ; 24 + 34f0: 30 e0 ldi r19, 0x00 ; 0 + 34f2: 30 cf rjmp .-416 ; 0x3354 + case STATE_ACTIVE: + if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE)) { + State = STATE_READY1; + return BitCount; + } else if (Cmd == CMD_READ) { + uint8_t PageAddress = Buffer[1]; + 34f4: f8 01 movw r30, r16 + 34f6: f1 80 ldd r15, Z+1 ; 0x01 + + if (ISO14443ACheckCRCA(Buffer, CMD_READ_FRAME_SIZE)) { + 34f8: 62 e0 ldi r22, 0x02 ; 2 + 34fa: 70 e0 ldi r23, 0x00 ; 0 + 34fc: c8 01 movw r24, r16 + 34fe: 31 d7 rcall .+3682 ; 0x4362 + 3500: 88 23 and r24, r24 + 3502: 09 f4 brne .+2 ; 0x3506 + 3504: b8 cf rjmp .-144 ; 0x3476 + if ( (PageAddress >= PAGE_READ_MIN) + 3506: ff e0 ldi r31, 0x0F ; 15 + 3508: ff 15 cp r31, r15 + 350a: 08 f4 brcc .+2 ; 0x350e + 350c: 72 cf rjmp .-284 ; 0x33f2 + && (PageAddress <= PAGE_READ_MAX) ) { + /* TODO: Missing address wrap around behaviour. + * Implement using a for-loop copying 4 bytes each iteration + * and mask pageaddress */ + MemoryReadBlock(Buffer, PageAddress * BYTES_PER_PAGE, BYTES_PER_READ); + 350e: 6f 2d mov r22, r15 + 3510: 70 e0 ldi r23, 0x00 ; 0 + 3512: 66 0f add r22, r22 + 3514: 77 1f adc r23, r23 + 3516: 66 0f add r22, r22 + 3518: 77 1f adc r23, r23 + 351a: 40 e1 ldi r20, 0x10 ; 16 + 351c: 50 e0 ldi r21, 0x00 ; 0 + 351e: c8 01 movw r24, r16 + 3520: 0e 94 de 06 call 0xdbc ; 0xdbc + ISO14443AAppendCRCA(Buffer, BYTES_PER_READ); + 3524: 60 e1 ldi r22, 0x10 ; 16 + 3526: 70 e0 ldi r23, 0x00 ; 0 + 3528: c8 01 movw r24, r16 + 352a: ec d6 rcall .+3544 ; 0x4304 + return (BYTES_PER_READ + ISO14443A_CRCA_SIZE) * 8; + 352c: 20 e9 ldi r18, 0x90 ; 144 + 352e: 30 e0 ldi r19, 0x00 ; 0 + 3530: 11 cf rjmp .-478 ; 0x3354 + + switch (NVB) { + case ISO14443A_NVB_AC_START: + /* Start of anticollision procedure. + * Send whole UID CLn + BCC */ + DataPtr[0] = UidCL[0]; + 3532: 89 81 ldd r24, Y+1 ; 0x01 + 3534: f8 01 movw r30, r16 + 3536: 80 83 st Z, r24 + DataPtr[1] = UidCL[1]; + 3538: 3a 81 ldd r19, Y+2 ; 0x02 + 353a: 31 83 std Z+1, r19 ; 0x01 + DataPtr[2] = UidCL[2]; + 353c: 2b 81 ldd r18, Y+3 ; 0x03 + 353e: 22 83 std Z+2, r18 ; 0x02 + DataPtr[3] = UidCL[3]; + 3540: 9c 81 ldd r25, Y+4 ; 0x04 + 3542: 93 83 std Z+3, r25 ; 0x03 + DataPtr[4] = ISO14443A_CALC_BCC(DataPtr); + 3544: 83 27 eor r24, r19 + 3546: 82 27 eor r24, r18 + 3548: 89 27 eor r24, r25 + 354a: 84 83 std Z+4, r24 ; 0x04 + + *BitCount = ISO14443A_CL_FRAME_SIZE; + 354c: 28 e2 ldi r18, 0x28 ; 40 + 354e: 30 e0 ldi r19, 0x00 ; 0 + 3550: 01 cf rjmp .-510 ; 0x3354 + return NAK_FRAME_SIZE; + } + } else if (Cmd == CMD_WRITE) { + /* This is a write command containing 4 bytes of data that + * should be written to the given page address. */ + uint8_t PageAddress = Buffer[1]; + 3552: f8 01 movw r30, r16 + 3554: f1 80 ldd r15, Z+1 ; 0x01 + if (ISO14443ACheckCRCA(Buffer, CMD_WRITE_FRAME_SIZE)) { + 3556: 66 e0 ldi r22, 0x06 ; 6 + 3558: 70 e0 ldi r23, 0x00 ; 0 + 355a: c8 01 movw r24, r16 + 355c: 02 d7 rcall .+3588 ; 0x4362 + 355e: 88 23 and r24, r24 + 3560: 09 f4 brne .+2 ; 0x3564 + 3562: 89 cf rjmp .-238 ; 0x3476 + /* CRC check passed */ + if ( (PageAddress >= PAGE_WRITE_MIN) + && (PageAddress <= PAGE_WRITE_MAX) ) { + 3564: 8f 2d mov r24, r15 + 3566: 82 50 subi r24, 0x02 ; 2 + /* This is a write command containing 4 bytes of data that + * should be written to the given page address. */ + uint8_t PageAddress = Buffer[1]; + if (ISO14443ACheckCRCA(Buffer, CMD_WRITE_FRAME_SIZE)) { + /* CRC check passed */ + if ( (PageAddress >= PAGE_WRITE_MIN) + 3568: 8e 30 cpi r24, 0x0E ; 14 + 356a: 08 f0 brcs .+2 ; 0x356e + 356c: 42 cf rjmp .-380 ; 0x33f2 + && (PageAddress <= PAGE_WRITE_MAX) ) { + /* PageAddress is within bounds. */ + + if (!ActiveConfiguration.ReadOnly) { + 356e: 80 91 06 29 lds r24, 0x2906 + 3572: 81 11 cpse r24, r1 + 3574: 1a cf rjmp .-460 ; 0x33aa + MemoryWriteBlock(&Buffer[2], PageAddress * BYTES_PER_PAGE, BYTES_PER_WRITE); + 3576: f4 e0 ldi r31, 0x04 ; 4 + 3578: ff 9e mul r15, r31 + 357a: b0 01 movw r22, r0 + 357c: 11 24 eor r1, r1 + 357e: 44 e0 ldi r20, 0x04 ; 4 + 3580: 50 e0 ldi r21, 0x00 ; 0 + 3582: c8 01 movw r24, r16 + 3584: 02 96 adiw r24, 0x02 ; 2 + 3586: 0e 94 f6 06 call 0xdec ; 0xdec + 358a: 0f cf rjmp .-482 ; 0x33aa + } + } else if (Cmd == CMD_COMPAT_WRITE) { + /* The Mifare compatbility write command is a 2-frame command. + * The first frame contains the page-address and the second frame + * holds the data. */ + uint8_t PageAddress = Buffer[1]; + 358c: f8 01 movw r30, r16 + 358e: f1 80 ldd r15, Z+1 ; 0x01 + + if (ISO14443ACheckCRCA(Buffer, CMD_COMPAT_WRITE_FRAME_SIZE)) { + 3590: 62 e0 ldi r22, 0x02 ; 2 + 3592: 70 e0 ldi r23, 0x00 ; 0 + 3594: c8 01 movw r24, r16 + 3596: e5 d6 rcall .+3530 ; 0x4362 + 3598: 88 23 and r24, r24 + 359a: 09 f4 brne .+2 ; 0x359e + 359c: 6c cf rjmp .-296 ; 0x3476 + if ( (PageAddress >= PAGE_WRITE_MIN) + && (PageAddress <= PAGE_WRITE_MAX) ) { + 359e: 8f 2d mov r24, r15 + 35a0: 82 50 subi r24, 0x02 ; 2 + * The first frame contains the page-address and the second frame + * holds the data. */ + uint8_t PageAddress = Buffer[1]; + + if (ISO14443ACheckCRCA(Buffer, CMD_COMPAT_WRITE_FRAME_SIZE)) { + if ( (PageAddress >= PAGE_WRITE_MIN) + 35a2: 8e 30 cpi r24, 0x0E ; 14 + 35a4: 08 f0 brcs .+2 ; 0x35a8 + 35a6: 25 cf rjmp .-438 ; 0x33f2 + && (PageAddress <= PAGE_WRITE_MAX) ) { + /* CRC check passed and page-address is within bounds. + * Store address and proceed to receiving the data. */ + CompatWritePageAddress = PageAddress; + 35a8: f0 92 bd 28 sts 0x28BD, r15 + State = STATE_COMPAT_WRITE; + 35ac: 85 e0 ldi r24, 0x05 ; 5 + 35ae: fb ce rjmp .-522 ; 0x33a6 + } + } else if (Cmd == CMD_HALT) { + /* Halts the tag. According to the ISO14443, the second + * byte is supposed to be 0. */ + if (Buffer[1] == 0) { + if (ISO14443ACheckCRCA(Buffer, 2)) { + 35b0: 62 e0 ldi r22, 0x02 ; 2 + 35b2: 70 e0 ldi r23, 0x00 ; 0 + 35b4: c8 01 movw r24, r16 + 35b6: d5 d6 rcall .+3498 ; 0x4362 + 35b8: 88 23 and r24, r24 + 35ba: 09 f4 brne .+2 ; 0x35be + 35bc: 5c cf rjmp .-328 ; 0x3476 + /* According to ISO14443, we must not send anything + * in order to acknowledge the HALT command. */ + State = STATE_HALT; + 35be: 10 92 bc 28 sts 0x28BC, r1 + return ISO14443A_APP_NO_RESPONSE; + 35c2: 20 e0 ldi r18, 0x00 ; 0 + 35c4: 30 e0 ldi r19, 0x00 ; 0 + 35c6: c6 ce rjmp .-628 ; 0x3354 + +000035c8 : + /* No response has been sent, when we reach here */ + return ISO14443A_APP_NO_RESPONSE; +} + +void MifareUltralightGetUid(ConfigurationUidType Uid) +{ + 35c8: cf 93 push r28 + 35ca: df 93 push r29 + 35cc: ec 01 movw r28, r24 + /* Read UID from memory */ + MemoryReadBlock(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE); + 35ce: 43 e0 ldi r20, 0x03 ; 3 + 35d0: 50 e0 ldi r21, 0x00 ; 0 + 35d2: 60 e0 ldi r22, 0x00 ; 0 + 35d4: 70 e0 ldi r23, 0x00 ; 0 + 35d6: 0e 94 de 06 call 0xdbc ; 0xdbc + MemoryReadBlock(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE); + 35da: 44 e0 ldi r20, 0x04 ; 4 + 35dc: 50 e0 ldi r21, 0x00 ; 0 + 35de: 64 e0 ldi r22, 0x04 ; 4 + 35e0: 70 e0 ldi r23, 0x00 ; 0 + 35e2: ce 01 movw r24, r28 + 35e4: 03 96 adiw r24, 0x03 ; 3 +} + 35e6: df 91 pop r29 + 35e8: cf 91 pop r28 + +void MifareUltralightGetUid(ConfigurationUidType Uid) +{ + /* Read UID from memory */ + MemoryReadBlock(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE); + MemoryReadBlock(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE); + 35ea: 0c 94 de 06 jmp 0xdbc ; 0xdbc + +000035ee : +} + +void MifareUltralightSetUid(ConfigurationUidType Uid) +{ + 35ee: 0f 93 push r16 + 35f0: 1f 93 push r17 + 35f2: cf 93 push r28 + 35f4: df 93 push r29 + 35f6: 00 d0 rcall .+0 ; 0x35f8 + 35f8: cd b7 in r28, 0x3d ; 61 + 35fa: de b7 in r29, 0x3e ; 62 + 35fc: 8c 01 movw r16, r24 + /* Calculate check bytes and write everything into memory */ + uint8_t BCC1 = ISO14443A_UID0_CT ^ Uid[0] ^ Uid[1] ^ Uid[2]; + 35fe: fc 01 movw r30, r24 + 3600: 80 81 ld r24, Z + 3602: 91 81 ldd r25, Z+1 ; 0x01 + 3604: 89 27 eor r24, r25 + 3606: 98 e8 ldi r25, 0x88 ; 136 + 3608: 89 27 eor r24, r25 + 360a: 92 81 ldd r25, Z+2 ; 0x02 + 360c: 89 27 eor r24, r25 + 360e: 8a 83 std Y+2, r24 ; 0x02 + uint8_t BCC2 = Uid[3] ^ Uid[4] ^ Uid[5] ^ Uid[6]; + 3610: 84 81 ldd r24, Z+4 ; 0x04 + 3612: 93 81 ldd r25, Z+3 ; 0x03 + 3614: 89 27 eor r24, r25 + 3616: 95 81 ldd r25, Z+5 ; 0x05 + 3618: 89 27 eor r24, r25 + 361a: 96 81 ldd r25, Z+6 ; 0x06 + 361c: 89 27 eor r24, r25 + 361e: 89 83 std Y+1, r24 ; 0x01 + + MemoryWriteBlock(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE); + 3620: 43 e0 ldi r20, 0x03 ; 3 + 3622: 50 e0 ldi r21, 0x00 ; 0 + 3624: 60 e0 ldi r22, 0x00 ; 0 + 3626: 70 e0 ldi r23, 0x00 ; 0 + 3628: c8 01 movw r24, r16 + 362a: 0e 94 f6 06 call 0xdec ; 0xdec + MemoryWriteBlock(&BCC1, UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE); + 362e: 41 e0 ldi r20, 0x01 ; 1 + 3630: 50 e0 ldi r21, 0x00 ; 0 + 3632: 63 e0 ldi r22, 0x03 ; 3 + 3634: 70 e0 ldi r23, 0x00 ; 0 + 3636: ce 01 movw r24, r28 + 3638: 02 96 adiw r24, 0x02 ; 2 + 363a: 0e 94 f6 06 call 0xdec ; 0xdec + MemoryWriteBlock(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE); + 363e: 44 e0 ldi r20, 0x04 ; 4 + 3640: 50 e0 ldi r21, 0x00 ; 0 + 3642: 64 e0 ldi r22, 0x04 ; 4 + 3644: 70 e0 ldi r23, 0x00 ; 0 + 3646: c8 01 movw r24, r16 + 3648: 03 96 adiw r24, 0x03 ; 3 + 364a: 0e 94 f6 06 call 0xdec ; 0xdec + MemoryWriteBlock(&BCC2, UID_BCC2_ADDRESS, ISO14443A_CL_BCC_SIZE); + 364e: 41 e0 ldi r20, 0x01 ; 1 + 3650: 50 e0 ldi r21, 0x00 ; 0 + 3652: 68 e0 ldi r22, 0x08 ; 8 + 3654: 70 e0 ldi r23, 0x00 ; 0 + 3656: ce 01 movw r24, r28 + 3658: 01 96 adiw r24, 0x01 ; 1 + 365a: 0e 94 f6 06 call 0xdec ; 0xdec +} + 365e: 0f 90 pop r0 + 3660: 0f 90 pop r0 + 3662: df 91 pop r29 + 3664: cf 91 pop r28 + 3666: 1f 91 pop r17 + 3668: 0f 91 pop r16 + 366a: 08 95 ret + +0000366c : + Block[11] = Block[3]; +} + +void MifareClassicAppInit1K(void) +{ + State = STATE_IDLE; + 366c: 81 e0 ldi r24, 0x01 ; 1 + 366e: 80 93 be 28 sts 0x28BE, r24 + CardATQAValue = MFCLASSIC_1K_ATQA_VALUE; + 3672: 84 e0 ldi r24, 0x04 ; 4 + 3674: 90 e0 ldi r25, 0x00 ; 0 + 3676: 80 93 bf 28 sts 0x28BF, r24 + 367a: 90 93 c0 28 sts 0x28C0, r25 + CardSAKValue = MFCLASSIC_1K_SAK_CL1_VALUE; + 367e: 88 e0 ldi r24, 0x08 ; 8 + 3680: 80 93 c1 28 sts 0x28C1, r24 + _7BUID = 0x00; + 3684: 10 92 c2 28 sts 0x28C2, r1 + 3688: 08 95 ret + +0000368a : +} + +void MifarePlus1kAppInit_7B(void) +{ + State = STATE_IDLE; + 368a: 81 e0 ldi r24, 0x01 ; 1 + 368c: 80 93 be 28 sts 0x28BE, r24 + CardATQAValue = MFPlus_ATQA_VALUE; + 3690: 84 e4 ldi r24, 0x44 ; 68 + 3692: 90 e0 ldi r25, 0x00 ; 0 + 3694: 80 93 bf 28 sts 0x28BF, r24 + 3698: 90 93 c0 28 sts 0x28C0, r25 + CardSAKValue = MFCLASSIC_1K_SAK_CL1_VALUE; + 369c: 88 e0 ldi r24, 0x08 ; 8 + 369e: 80 93 c1 28 sts 0x28C1, r24 + uint8_t UidSize = ActiveConfiguration.UidSize; + _7BUID = (UidSize == 7); + 36a2: 81 e0 ldi r24, 0x01 ; 1 + 36a4: 90 91 05 29 lds r25, 0x2905 + 36a8: 97 30 cpi r25, 0x07 ; 7 + 36aa: 09 f0 breq .+2 ; 0x36ae + 36ac: 80 e0 ldi r24, 0x00 ; 0 + 36ae: 80 93 c2 28 sts 0x28C2, r24 + 36b2: 08 95 ret + +000036b4 : +} + +void MifareClassicAppInit4K(void) +{ + State = STATE_IDLE; + 36b4: 81 e0 ldi r24, 0x01 ; 1 + 36b6: 80 93 be 28 sts 0x28BE, r24 + CardATQAValue = MFCLASSIC_4K_ATQA_VALUE; + 36ba: 82 e0 ldi r24, 0x02 ; 2 + 36bc: 90 e0 ldi r25, 0x00 ; 0 + 36be: 80 93 bf 28 sts 0x28BF, r24 + 36c2: 90 93 c0 28 sts 0x28C0, r25 + CardSAKValue = MFCLASSIC_4K_SAK_CL1_VALUE; + 36c6: 88 e1 ldi r24, 0x18 ; 24 + 36c8: 80 93 c1 28 sts 0x28C1, r24 + _7BUID = 0x00; + 36cc: 10 92 c2 28 sts 0x28C2, r1 + 36d0: 08 95 ret + +000036d2 : +} + +void MifareClassicAppReset(void) +{ + State = STATE_IDLE; + 36d2: 81 e0 ldi r24, 0x01 ; 1 + 36d4: 80 93 be 28 sts 0x28BE, r24 + 36d8: 08 95 ret + +000036da : +} + +void MifareClassicAppTask(void) +{ + 36da: 08 95 ret + +000036dc : + +} + +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + 36dc: 6f 92 push r6 + 36de: 7f 92 push r7 + 36e0: 8f 92 push r8 + 36e2: 9f 92 push r9 + 36e4: af 92 push r10 + 36e6: bf 92 push r11 + 36e8: cf 92 push r12 + 36ea: df 92 push r13 + 36ec: ef 92 push r14 + 36ee: ff 92 push r15 + 36f0: 0f 93 push r16 + 36f2: 1f 93 push r17 + 36f4: cf 93 push r28 + 36f6: df 93 push r29 + 36f8: cd b7 in r28, 0x3d ; 61 + 36fa: de b7 in r29, 0x3e ; 62 + 36fc: 2e 97 sbiw r28, 0x0e ; 14 + 36fe: cd bf out 0x3d, r28 ; 61 + 3700: de bf out 0x3e, r29 ; 62 + 3702: 8c 01 movw r16, r24 + switch(State) { + 3704: 80 91 be 28 lds r24, 0x28BE + 3708: 85 30 cpi r24, 0x05 ; 5 + 370a: 09 f4 brne .+2 ; 0x370e + 370c: d1 c0 rjmp .+418 ; 0x38b0 + 370e: f8 f0 brcs .+62 ; 0x374e + 3710: 88 30 cpi r24, 0x08 ; 8 + 3712: 09 f4 brne .+2 ; 0x3716 + 3714: 1b c1 rjmp .+566 ; 0x394c + 3716: b8 f5 brcc .+110 ; 0x3786 + 3718: 86 30 cpi r24, 0x06 ; 6 + 371a: 09 f4 brne .+2 ; 0x371e + 371c: f5 c1 rjmp .+1002 ; 0x3b08 + 371e: 87 30 cpi r24, 0x07 ; 7 + 3720: 09 f4 brne .+2 ; 0x3724 + 3722: c9 c1 rjmp .+914 ; 0x3ab6 + + *BitCount = ISO14443A_SAK_FRAME_SIZE; + return true; + } else { + /* We have not been selected. Don't send anything. */ + *BitCount = 0; + 3724: 20 e0 ldi r18, 0x00 ; 0 + 3726: 30 e0 ldi r19, 0x00 ; 0 + break; + } + + /* No response has been sent, when we reach here */ + return ISO14443A_APP_NO_RESPONSE; +} + 3728: c9 01 movw r24, r18 + 372a: 2e 96 adiw r28, 0x0e ; 14 + 372c: cd bf out 0x3d, r28 ; 61 + 372e: de bf out 0x3e, r29 ; 62 + 3730: df 91 pop r29 + 3732: cf 91 pop r28 + 3734: 1f 91 pop r17 + 3736: 0f 91 pop r16 + 3738: ff 90 pop r15 + 373a: ef 90 pop r14 + 373c: df 90 pop r13 + 373e: cf 90 pop r12 + 3740: bf 90 pop r11 + 3742: af 90 pop r10 + 3744: 9f 90 pop r9 + 3746: 8f 90 pop r8 + 3748: 7f 90 pop r7 + 374a: 6f 90 pop r6 + 374c: 08 95 ret + +} + +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + switch(State) { + 374e: 82 30 cpi r24, 0x02 ; 2 + 3750: 09 f4 brne .+2 ; 0x3754 + 3752: e1 c0 rjmp .+450 ; 0x3916 + 3754: 08 f0 brcs .+2 ; 0x3758 + 3756: 5a c0 rjmp .+180 ; 0x380c + case STATE_IDLE: + case STATE_HALT: + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + 3758: 20 91 bf 28 lds r18, 0x28BF + 375c: 90 91 c0 28 lds r25, 0x28C0 +INLINE +bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue) +{ + uint8_t* DataPtr = (uint8_t*) Buffer; + + if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){ + 3760: d8 01 movw r26, r16 + 3762: 8c 91 ld r24, X + 3764: 86 32 cpi r24, 0x26 ; 38 + 3766: 09 f4 brne .+2 ; 0x376a + 3768: ae c0 rjmp .+348 ; 0x38c6 + 376a: 82 35 cpi r24, 0x52 ; 82 + 376c: 09 f4 brne .+2 ; 0x3770 + 376e: ab c0 rjmp .+342 ; 0x38c6 + State = STATE_READY1; + return BitCount; + } +#ifdef SUPPORT_MF_CLASSIC_MAGIC_MODE + else if (Buffer[0] == CMD_CHINESE_UNLOCK) { + 3770: 80 34 cpi r24, 0x40 ; 64 + 3772: c1 f6 brne .-80 ; 0x3724 + State = STATE_CHINESE_IDLE; + 3774: 82 e0 ldi r24, 0x02 ; 2 + 3776: 80 93 be 28 sts 0x28BE, r24 + Buffer[0] = ACK_VALUE; + 377a: 8a e0 ldi r24, 0x0A ; 10 + 377c: d8 01 movw r26, r16 + 377e: 8c 93 st X, r24 + return ACK_NAK_FRAME_SIZE; + 3780: 24 e0 ldi r18, 0x04 ; 4 + 3782: 30 e0 ldi r19, 0x00 ; 0 + 3784: d1 cf rjmp .-94 ; 0x3728 + +} + +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + switch(State) { + 3786: 89 30 cpi r24, 0x09 ; 9 + 3788: 09 f4 brne .+2 ; 0x378c + 378a: a6 c0 rjmp .+332 ; 0x38d8 + 378c: 8d 30 cpi r24, 0x0D ; 13 + 378e: 50 f6 brcc .-108 ; 0x3724 + * decrypt the data and check CRC. Read data from the requested block + * address into the global block buffer and check for integrity. Then + * add or subtract according to issued command if necessary and store + * the block back into the global block buffer. */ + for (uint8_t i=0; i<(MEM_VALUE_SIZE + ISO14443A_CRCA_SIZE); i++) + Buffer[i] ^= Crypto1Byte(); + 3790: d8 01 movw r26, r16 + 3792: fc 90 ld r15, X + 3794: 0e 94 33 24 call 0x4866 ; 0x4866 + 3798: 8f 25 eor r24, r15 + 379a: f8 01 movw r30, r16 + 379c: 80 83 st Z, r24 + 379e: f1 80 ldd r15, Z+1 ; 0x01 + 37a0: 0e 94 33 24 call 0x4866 ; 0x4866 + 37a4: 8f 25 eor r24, r15 + 37a6: d8 01 movw r26, r16 + 37a8: 11 96 adiw r26, 0x01 ; 1 + 37aa: 8c 93 st X, r24 + 37ac: 11 97 sbiw r26, 0x01 ; 1 + 37ae: 12 96 adiw r26, 0x02 ; 2 + 37b0: fc 90 ld r15, X + 37b2: 0e 94 33 24 call 0x4866 ; 0x4866 + 37b6: 8f 25 eor r24, r15 + 37b8: f8 01 movw r30, r16 + 37ba: 82 83 std Z+2, r24 ; 0x02 + 37bc: f3 80 ldd r15, Z+3 ; 0x03 + 37be: 0e 94 33 24 call 0x4866 ; 0x4866 + 37c2: 8f 25 eor r24, r15 + 37c4: d8 01 movw r26, r16 + 37c6: 13 96 adiw r26, 0x03 ; 3 + 37c8: 8c 93 st X, r24 + 37ca: 13 97 sbiw r26, 0x03 ; 3 + 37cc: 14 96 adiw r26, 0x04 ; 4 + 37ce: fc 90 ld r15, X + 37d0: 0e 94 33 24 call 0x4866 ; 0x4866 + 37d4: 8f 25 eor r24, r15 + 37d6: f8 01 movw r30, r16 + 37d8: 84 83 std Z+4, r24 ; 0x04 + 37da: f5 80 ldd r15, Z+5 ; 0x05 + 37dc: 0e 94 33 24 call 0x4866 ; 0x4866 + 37e0: 8f 25 eor r24, r15 + 37e2: d8 01 movw r26, r16 + 37e4: 15 96 adiw r26, 0x05 ; 5 + 37e6: 8c 93 st X, r24 + + if (ISO14443ACheckCRCA(Buffer, MEM_VALUE_SIZE )) { + 37e8: 64 e0 ldi r22, 0x04 ; 4 + 37ea: 70 e0 ldi r23, 0x00 ; 0 + 37ec: c8 01 movw r24, r16 + 37ee: b9 d5 rcall .+2930 ; 0x4362 + 37f0: 81 11 cpse r24, r1 + 37f2: 99 c2 rjmp .+1330 ; 0x3d26 + /* Not sure if this is the correct error code.. */ + Buffer[0] = NAK_OTHER_ERROR ^ Crypto1Nibble(); + } + } else { + /* CRC Error. */ + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + 37f4: 0e 94 74 24 call 0x48e8 ; 0x48e8 + 37f8: 91 e0 ldi r25, 0x01 ; 1 + 37fa: 98 27 eor r25, r24 + 37fc: f8 01 movw r30, r16 + 37fe: 90 83 st Z, r25 + } + + State = STATE_AUTHED_IDLE; + 3800: 88 e0 ldi r24, 0x08 ; 8 + 3802: 80 93 be 28 sts 0x28BE, r24 + return ACK_NAK_FRAME_SIZE; + 3806: 24 e0 ldi r18, 0x04 ; 4 + 3808: 30 e0 ldi r19, 0x00 ; 0 + 380a: 8e cf rjmp .-228 ; 0x3728 + +} + +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + switch(State) { + 380c: 83 30 cpi r24, 0x03 ; 3 + 380e: 09 f4 brne .+2 ; 0x3812 + 3810: 42 c1 rjmp .+644 ; 0x3a96 + 3812: 84 30 cpi r24, 0x04 ; 4 + 3814: 09 f0 breq .+2 ; 0x3818 + 3816: 86 cf rjmp .-244 ; 0x3724 + + return ACK_NAK_FRAME_SIZE; +#endif + + case STATE_READY1: + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + 3818: 20 91 bf 28 lds r18, 0x28BF + 381c: 90 91 c0 28 lds r25, 0x28C0 + 3820: d8 01 movw r26, r16 + 3822: 8c 91 ld r24, X + 3824: 86 32 cpi r24, 0x26 ; 38 + 3826: 09 f4 brne .+2 ; 0x382a + 3828: 4e c0 rjmp .+156 ; 0x38c6 + 382a: 82 35 cpi r24, 0x52 ; 82 + 382c: 09 f4 brne .+2 ; 0x3830 + 382e: 4b c0 rjmp .+150 ; 0x38c6 + State = STATE_READY1; + return BitCount; + } else if (Buffer[0] == ISO14443A_CMD_SELECT_CL1) { + 3830: 83 39 cpi r24, 0x93 ; 147 + 3832: 09 f0 breq .+2 ; 0x3836 + 3834: 95 c1 rjmp .+810 ; 0x3b60 + /* Load UID CL1 and perform anticollision */ + uint8_t UidCL1[ISO14443A_CL_UID_SIZE]; + + if (_7BUID) { + 3836: 80 91 c2 28 lds r24, 0x28C2 + 383a: 88 23 and r24, r24 + 383c: 09 f4 brne .+2 ; 0x3840 + 383e: 34 c3 rjmp .+1640 ; 0x3ea8 + MemoryReadBlock(&UidCL1[1], MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE-1); + 3840: 43 e0 ldi r20, 0x03 ; 3 + 3842: 50 e0 ldi r21, 0x00 ; 0 + 3844: 60 e0 ldi r22, 0x00 ; 0 + 3846: 70 e0 ldi r23, 0x00 ; 0 + 3848: ce 01 movw r24, r28 + 384a: 02 96 adiw r24, 0x02 ; 2 + 384c: 0e 94 de 06 call 0xdbc ; 0xdbc + UidCL1[0] = ISO14443A_UID0_CT; + 3850: 88 e8 ldi r24, 0x88 ; 136 + 3852: 89 83 std Y+1, r24 ; 0x01 + uint8_t* DataPtr = (uint8_t*) Buffer; + uint8_t NVB = DataPtr[1]; + //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F; + //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F; + + switch (NVB) { + 3854: d8 01 movw r26, r16 + 3856: 11 96 adiw r26, 0x01 ; 1 + 3858: 9c 91 ld r25, X + 385a: 90 32 cpi r25, 0x20 ; 32 + 385c: 09 f4 brne .+2 ; 0x3860 + 385e: c2 c4 rjmp .+2436 ; 0x41e4 + 3860: 90 37 cpi r25, 0x70 ; 112 + 3862: 09 f0 breq .+2 ; 0x3866 + 3864: 5f cf rjmp .-322 ; 0x3724 + return false; + + case ISO14443A_NVB_AC_END: + /* End of anticollision procedure. + * Send SAK CLn if we are selected. */ + if ( (DataPtr[2] == UidCL[0]) && + 3866: d8 01 movw r26, r16 + 3868: 12 96 adiw r26, 0x02 ; 2 + 386a: 8c 91 ld r24, X + 386c: 12 97 sbiw r26, 0x02 ; 2 + 386e: 88 38 cpi r24, 0x88 ; 136 + 3870: 09 f0 breq .+2 ; 0x3874 + 3872: 58 cf rjmp .-336 ; 0x3724 + 3874: 13 96 adiw r26, 0x03 ; 3 + 3876: 9c 91 ld r25, X + 3878: 13 97 sbiw r26, 0x03 ; 3 + 387a: 8a 81 ldd r24, Y+2 ; 0x02 + 387c: 98 13 cpse r25, r24 + 387e: 52 cf rjmp .-348 ; 0x3724 + (DataPtr[3] == UidCL[1]) && + 3880: 14 96 adiw r26, 0x04 ; 4 + 3882: 9c 91 ld r25, X + 3884: 14 97 sbiw r26, 0x04 ; 4 + 3886: 8b 81 ldd r24, Y+3 ; 0x03 + 3888: 98 13 cpse r25, r24 + 388a: 4c cf rjmp .-360 ; 0x3724 + (DataPtr[4] == UidCL[2]) && + 388c: 15 96 adiw r26, 0x05 ; 5 + 388e: 9c 91 ld r25, X + 3890: 15 97 sbiw r26, 0x05 ; 5 + 3892: 8c 81 ldd r24, Y+4 ; 0x04 + 3894: 98 13 cpse r25, r24 + 3896: 46 cf rjmp .-372 ; 0x3724 + (DataPtr[5] == UidCL[3]) ) { + + DataPtr[0] = SAKValue; + 3898: 84 e0 ldi r24, 0x04 ; 4 + 389a: 8c 93 st X, r24 + ISO14443AAppendCRCA(Buffer, 1); + 389c: 61 e0 ldi r22, 0x01 ; 1 + 389e: 70 e0 ldi r23, 0x00 ; 0 + 38a0: c8 01 movw r24, r16 + 38a2: 30 d5 rcall .+2656 ; 0x4304 + if (ISO14443ASelect(Buffer, &BitCount, UidCL1, SAK_CL1_VALUE)) + State = STATE_READY2; + 38a4: 85 e0 ldi r24, 0x05 ; 5 + 38a6: 80 93 be 28 sts 0x28BE, r24 + + *BitCount = ISO14443A_SAK_FRAME_SIZE; + 38aa: 28 e1 ldi r18, 0x18 ; 24 + 38ac: 30 e0 ldi r19, 0x00 ; 0 + 38ae: 3c cf rjmp .-392 ; 0x3728 + State = STATE_HALT; + } + break; + + case STATE_READY2: + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + 38b0: 20 91 bf 28 lds r18, 0x28BF + 38b4: 90 91 c0 28 lds r25, 0x28C0 +INLINE +bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue) +{ + uint8_t* DataPtr = (uint8_t*) Buffer; + + if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){ + 38b8: d8 01 movw r26, r16 + 38ba: 8c 91 ld r24, X + 38bc: 86 32 cpi r24, 0x26 ; 38 + 38be: 19 f0 breq .+6 ; 0x38c6 + 38c0: 82 35 cpi r24, 0x52 ; 82 + 38c2: 09 f0 breq .+2 ; 0x38c6 + 38c4: 4a c1 rjmp .+660 ; 0x3b5a + DataPtr[0] = (ATQAValue >> 0) & 0x00FF; + 38c6: f8 01 movw r30, r16 + 38c8: 20 83 st Z, r18 + DataPtr[1] = (ATQAValue >> 8) & 0x00FF; + 38ca: 91 83 std Z+1, r25 ; 0x01 + State = STATE_READY1; + 38cc: 84 e0 ldi r24, 0x04 ; 4 + 38ce: 80 93 be 28 sts 0x28BE, r24 + + *BitCount = ISO14443A_ATQA_FRAME_SIZE; + 38d2: 20 e1 ldi r18, 0x10 ; 16 + 38d4: 30 e0 ldi r19, 0x00 ; 0 + return BitCount; + 38d6: 28 cf rjmp .-432 ; 0x3728 + 38d8: 78 01 movw r14, r16 + +} + +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + switch(State) { + 38da: d1 2c mov r13, r1 + * check for CRC. Then write the data when ReadOnly mode is not + * activated. */ + + /* We receive 16 bytes of data to be written and 2 bytes CRCA. Decrypt */ + for (uint8_t i=0; i<(MEM_BYTES_PER_BLOCK + ISO14443A_CRCA_SIZE); i++) + Buffer[i] ^= Crypto1Byte(); + 38dc: d7 01 movw r26, r14 + 38de: cc 90 ld r12, X + 38e0: c2 d7 rcall .+3972 ; 0x4866 + 38e2: 8c 25 eor r24, r12 + 38e4: f7 01 movw r30, r14 + 38e6: 81 93 st Z+, r24 + 38e8: 7f 01 movw r14, r30 + * sending the data to be written. Decrypt the data first and + * check for CRC. Then write the data when ReadOnly mode is not + * activated. */ + + /* We receive 16 bytes of data to be written and 2 bytes CRCA. Decrypt */ + for (uint8_t i=0; i<(MEM_BYTES_PER_BLOCK + ISO14443A_CRCA_SIZE); i++) + 38ea: d3 94 inc r13 + 38ec: f2 e1 ldi r31, 0x12 ; 18 + 38ee: df 12 cpse r13, r31 + 38f0: f5 cf rjmp .-22 ; 0x38dc + Buffer[i] ^= Crypto1Byte(); + + if (ISO14443ACheckCRCA(Buffer, MEM_BYTES_PER_BLOCK)) { + 38f2: 60 e1 ldi r22, 0x10 ; 16 + 38f4: 70 e0 ldi r23, 0x00 ; 0 + 38f6: c8 01 movw r24, r16 + 38f8: 34 d5 rcall .+2664 ; 0x4362 + 38fa: 88 23 and r24, r24 + 38fc: 09 f4 brne .+2 ; 0x3900 + 38fe: 7a cf rjmp .-268 ; 0x37f4 + if (!ActiveConfiguration.ReadOnly) { + 3900: 80 91 06 29 lds r24, 0x2906 + 3904: 88 23 and r24, r24 + 3906: 09 f4 brne .+2 ; 0x390a + 3908: 3e c1 rjmp .+636 ; 0x3b86 + MemoryWriteBlock(Buffer, CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + } else { + /* Silently ignore in ReadOnly mode */ + } + + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + 390a: ee d7 rcall .+4060 ; 0x48e8 + 390c: 9a e0 ldi r25, 0x0A ; 10 + 390e: 98 27 eor r25, r24 + 3910: d8 01 movw r26, r16 + 3912: 9c 93 st X, r25 + 3914: 75 cf rjmp .-278 ; 0x3800 + break; + +#ifdef SUPPORT_MF_CLASSIC_MAGIC_MODE + case STATE_CHINESE_IDLE: + /* Support special china commands that dont require authentication. */ + if (Buffer[0] == CMD_CHINESE_UNLOCK_RW) { + 3916: f8 01 movw r30, r16 + 3918: 80 81 ld r24, Z + 391a: 83 34 cpi r24, 0x43 ; 67 + 391c: 09 f4 brne .+2 ; 0x3920 + 391e: 6d c1 rjmp .+730 ; 0x3bfa + /* Unlock read and write commands */ + Buffer[0] = ACK_VALUE; + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_CHINESE_WIPE) { + 3920: 81 34 cpi r24, 0x41 ; 65 + 3922: 09 f4 brne .+2 ; 0x3926 + 3924: 2b c1 rjmp .+598 ; 0x3b7c + /* Wipe memory */ + Buffer[0] = ACK_VALUE; + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_READ) { + 3926: 80 33 cpi r24, 0x30 ; 48 + 3928: 09 f4 brne .+2 ; 0x392c + 392a: 34 c4 rjmp .+2152 ; 0x4194 + * BITS_PER_BYTE; + } else { + Buffer[0] = NAK_CRC_ERROR; + return ACK_NAK_FRAME_SIZE; + } + } else if (Buffer[0] == CMD_WRITE) { + 392c: 80 3a cpi r24, 0xA0 ; 160 + 392e: 09 f4 brne .+2 ; 0x3932 + 3930: 56 c1 rjmp .+684 ; 0x3bde + return ACK_NAK_FRAME_SIZE; + } else { + Buffer[0] = NAK_CRC_ERROR; + return ACK_NAK_FRAME_SIZE; + } + } else if (Buffer[0] == CMD_HALT) { + 3932: 80 35 cpi r24, 0x50 ; 80 + 3934: 09 f0 breq .+2 ; 0x3938 + 3936: f6 ce rjmp .-532 ; 0x3724 + State = STATE_READY1; + return BitCount; + } else if (Buffer[0] == CMD_HALT) { + /* Halts the tag. According to the ISO14443, the second + * byte is supposed to be 0. */ + if (Buffer[1] == 0) { + 3938: f8 01 movw r30, r16 + 393a: 81 81 ldd r24, Z+1 ; 0x01 + 393c: 88 23 and r24, r24 + 393e: 09 f4 brne .+2 ; 0x3942 + 3940: 1d c4 rjmp .+2106 ; 0x417c + } else { + Buffer[0] = NAK_CRC_ERROR; + return ACK_NAK_FRAME_SIZE; + } + } else { + Buffer[0] = NAK_INVALID_ARG; + 3942: f8 01 movw r30, r16 + 3944: 10 82 st Z, r1 + return ACK_NAK_FRAME_SIZE; + 3946: 24 e0 ldi r18, 0x04 ; 4 + 3948: 30 e0 ldi r19, 0x00 ; 0 + 394a: ee ce rjmp .-548 ; 0x3728 + + case STATE_AUTHED_IDLE: + /* In this state, all communication is encrypted. Thus we first have to encrypt + * the incoming data. */ + for (uint8_t i=0; i<4; i++) + Buffer[i] ^= Crypto1Byte(); + 394c: d8 01 movw r26, r16 + 394e: dc 90 ld r13, X + 3950: 8a d7 rcall .+3860 ; 0x4866 + 3952: 8d 25 eor r24, r13 + 3954: f8 01 movw r30, r16 + 3956: 80 83 st Z, r24 + 3958: d1 80 ldd r13, Z+1 ; 0x01 + 395a: 85 d7 rcall .+3850 ; 0x4866 + 395c: 8d 25 eor r24, r13 + 395e: d8 01 movw r26, r16 + 3960: 11 96 adiw r26, 0x01 ; 1 + 3962: 8c 93 st X, r24 + 3964: 11 97 sbiw r26, 0x01 ; 1 + 3966: 12 96 adiw r26, 0x02 ; 2 + 3968: dc 90 ld r13, X + 396a: 7d d7 rcall .+3834 ; 0x4866 + 396c: 8d 25 eor r24, r13 + 396e: f8 01 movw r30, r16 + 3970: 82 83 std Z+2, r24 ; 0x02 + 3972: d3 80 ldd r13, Z+3 ; 0x03 + 3974: 78 d7 rcall .+3824 ; 0x4866 + 3976: 8d 25 eor r24, r13 + 3978: d8 01 movw r26, r16 + 397a: 13 96 adiw r26, 0x03 ; 3 + 397c: 8c 93 st X, r24 + 397e: 13 97 sbiw r26, 0x03 ; 3 + + if (Buffer[0] == CMD_READ) { + 3980: 8c 91 ld r24, X + 3982: 80 33 cpi r24, 0x30 ; 48 + 3984: 09 f4 brne .+2 ; 0x3988 + 3986: fd c1 rjmp .+1018 ; 0x3d82 + * BITS_PER_BYTE) | ISO14443A_APP_CUSTOM_PARITY; + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + return ACK_NAK_FRAME_SIZE; + } + } else if (Buffer[0] == CMD_WRITE) { + 3988: 80 3a cpi r24, 0xA0 ; 160 + 398a: 09 f4 brne .+2 ; 0x398e + 398c: 6f c2 rjmp .+1246 ; 0x3e6c + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_DECREMENT) { + 398e: 80 3c cpi r24, 0xC0 ; 192 + 3990: 09 f4 brne .+2 ; 0x3994 + 3992: af c2 rjmp .+1374 ; 0x3ef2 + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_INCREMENT) { + 3994: 81 3c cpi r24, 0xC1 ; 193 + 3996: 09 f4 brne .+2 ; 0x399a + 3998: 46 c3 rjmp .+1676 ; 0x4026 + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_RESTORE) { + 399a: 82 3c cpi r24, 0xC2 ; 194 + 399c: 09 f4 brne .+2 ; 0x39a0 + 399e: 09 c1 rjmp .+530 ; 0x3bb2 + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + }else if (Buffer[0] == CMD_TRANSFER) { + 39a0: 80 3b cpi r24, 0xB0 ; 176 + 39a2: 09 f4 brne .+2 ; 0x39a6 + 39a4: 57 c3 rjmp .+1710 ; 0x4054 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + + return ACK_NAK_FRAME_SIZE; + } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B) ) { + 39a6: 80 56 subi r24, 0x60 ; 96 + 39a8: 82 30 cpi r24, 0x02 ; 2 + 39aa: 08 f0 brcs .+2 ; 0x39ae + 39ac: a7 c0 rjmp .+334 ; 0x3afc + if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { + 39ae: 62 e0 ldi r22, 0x02 ; 2 + 39b0: 70 e0 ldi r23, 0x00 ; 0 + 39b2: c8 01 movw r24, r16 + 39b4: d6 d4 rcall .+2476 ; 0x4362 + 39b6: 88 23 and r24, r24 + 39b8: 09 f4 brne .+2 ; 0x39bc + 39ba: cf c1 rjmp .+926 ; 0x3d5a + /* Nested authentication. */ + uint8_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; + 39bc: f8 01 movw r30, r16 + 39be: 81 81 ldd r24, Z+1 ; 0x01 + 39c0: 8c 73 andi r24, 0x3C ; 60 + uint8_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); + 39c2: 90 81 ld r25, Z + 39c4: 90 36 cpi r25, 0x60 ; 96 + 39c6: 09 f4 brne .+2 ; 0x39ca + 39c8: 47 c4 rjmp .+2190 ; 0x4258 + 39ca: 6a e3 ldi r22, 0x3A ; 58 + 39cc: 70 e0 ldi r23, 0x00 ; 0 + uint16_t KeyAddress = (uint16_t) SectorAddress * MEM_BYTES_PER_BLOCK + KeyOffset; + 39ce: 5b 01 movw r10, r22 + 39d0: f0 e1 ldi r31, 0x10 ; 16 + 39d2: 8f 9f mul r24, r31 + 39d4: a0 0c add r10, r0 + 39d6: b1 1c adc r11, r1 + 39d8: 11 24 eor r1, r1 + uint8_t Key[6]; + uint8_t Uid[4]; + uint8_t CardNonce[4]; + + /* Generate a random nonce and read UID and key from memory */ + RandomGetBuffer(CardNonce, sizeof(CardNonce)); + 39da: 6e 01 movw r12, r28 + 39dc: 37 e0 ldi r19, 0x07 ; 7 + 39de: c3 0e add r12, r19 + 39e0: d1 1c adc r13, r1 + 39e2: 64 e0 ldi r22, 0x04 ; 4 + 39e4: c6 01 movw r24, r12 + 39e6: 0e 94 3f 06 call 0xc7e ; 0xc7e + if (_7BUID) + 39ea: 80 91 c2 28 lds r24, 0x28C2 + MemoryReadBlock(Uid, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + 39ee: 7e 01 movw r14, r28 + uint8_t Uid[4]; + uint8_t CardNonce[4]; + + /* Generate a random nonce and read UID and key from memory */ + RandomGetBuffer(CardNonce, sizeof(CardNonce)); + if (_7BUID) + 39f0: 88 23 and r24, r24 + 39f2: 09 f4 brne .+2 ; 0x39f6 + 39f4: 15 c4 rjmp .+2090 ; 0x4220 + MemoryReadBlock(Uid, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + 39f6: 8b e0 ldi r24, 0x0B ; 11 + 39f8: e8 0e add r14, r24 + 39fa: f1 1c adc r15, r1 + 39fc: 44 e0 ldi r20, 0x04 ; 4 + 39fe: 50 e0 ldi r21, 0x00 ; 0 + 3a00: 63 e0 ldi r22, 0x03 ; 3 + 3a02: 70 e0 ldi r23, 0x00 ; 0 + 3a04: c7 01 movw r24, r14 + 3a06: 0e 94 de 06 call 0xdbc ; 0xdbc + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + MemoryReadBlock(Key, KeyAddress, MEM_KEY_SIZE); + 3a0a: 46 e0 ldi r20, 0x06 ; 6 + 3a0c: 50 e0 ldi r21, 0x00 ; 0 + 3a0e: b5 01 movw r22, r10 + 3a10: ce 01 movw r24, r28 + 3a12: 01 96 adiw r24, 0x01 ; 1 + 3a14: 0e 94 de 06 call 0xdbc ; 0xdbc + + /* Precalculate the reader response from card-nonce */ + for (uint8_t i=0; i + + /* Precalculate our response from the reader response */ + for (uint8_t i=0; i + + /* Setup crypto1 cipher. */ + Crypto1Setup(Key, Uid, CardNonce); + 3a64: a6 01 movw r20, r12 + 3a66: b7 01 movw r22, r14 + 3a68: ce 01 movw r24, r28 + 3a6a: 01 96 adiw r24, 0x01 ; 1 + 3a6c: 33 d5 rcall .+2662 ; 0x44d4 + + for (uint8_t i=0; i + } + } + break; + + case STATE_CHINESE_WRITE: + if (ISO14443ACheckCRCA(Buffer, MEM_BYTES_PER_BLOCK)) { + 3a96: 60 e1 ldi r22, 0x10 ; 16 + 3a98: 70 e0 ldi r23, 0x00 ; 0 + 3a9a: c8 01 movw r24, r16 + 3a9c: 62 d4 rcall .+2244 ; 0x4362 + 3a9e: 88 23 and r24, r24 + 3aa0: 09 f4 brne .+2 ; 0x3aa4 + 3aa2: 63 c0 rjmp .+198 ; 0x3b6a + /* CRC check passed. Write data into memory and send ACK. */ + if (!ActiveConfiguration.ReadOnly) { + 3aa4: 80 91 06 29 lds r24, 0x2906 + 3aa8: 88 23 and r24, r24 + 3aaa: 09 f4 brne .+2 ; 0x3aae + 3aac: 5e c1 rjmp .+700 ; 0x3d6a + MemoryWriteBlock(Buffer, CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + } + + Buffer[0] = ACK_VALUE; + 3aae: 8a e0 ldi r24, 0x0A ; 10 + 3ab0: d8 01 movw r26, r16 + 3ab2: 8c 93 st X, r24 + 3ab4: 5d c0 rjmp .+186 ; 0x3b70 + + case STATE_AUTHING: + /* Reader delivers an encrypted nonce. We use it + * to setup the crypto1 LFSR in nonlinear feedback mode. + * Furthermore it delivers an encrypted answer. Decrypt and check it */ + Crypto1Auth(&Buffer[0]); + 3ab6: c8 01 movw r24, r16 + 3ab8: ad d6 rcall .+3418 ; 0x4814 + + for (uint8_t i=0; i<4; i++) + Buffer[i+4] ^= Crypto1Byte(); + 3aba: f8 01 movw r30, r16 + 3abc: f4 80 ldd r15, Z+4 ; 0x04 + 3abe: d3 d6 rcall .+3494 ; 0x4866 + 3ac0: 8f 25 eor r24, r15 + 3ac2: d8 01 movw r26, r16 + 3ac4: 14 96 adiw r26, 0x04 ; 4 + 3ac6: 8c 93 st X, r24 + 3ac8: 14 97 sbiw r26, 0x04 ; 4 + 3aca: 15 96 adiw r26, 0x05 ; 5 + 3acc: fc 90 ld r15, X + 3ace: cb d6 rcall .+3478 ; 0x4866 + 3ad0: 8f 25 eor r24, r15 + 3ad2: f8 01 movw r30, r16 + 3ad4: 85 83 std Z+5, r24 ; 0x05 + 3ad6: f6 80 ldd r15, Z+6 ; 0x06 + 3ad8: c6 d6 rcall .+3468 ; 0x4866 + 3ada: 8f 25 eor r24, r15 + 3adc: d8 01 movw r26, r16 + 3ade: 16 96 adiw r26, 0x06 ; 6 + 3ae0: 8c 93 st X, r24 + 3ae2: 16 97 sbiw r26, 0x06 ; 6 + 3ae4: 17 96 adiw r26, 0x07 ; 7 + 3ae6: fc 90 ld r15, X + 3ae8: be d6 rcall .+3452 ; 0x4866 + 3aea: 8f 25 eor r24, r15 + 3aec: f8 01 movw r30, r16 + 3aee: 87 83 std Z+7, r24 ; 0x07 + + if ((Buffer[4] == ReaderResponse[0]) && + 3af0: 24 81 ldd r18, Z+4 ; 0x04 + 3af2: 90 91 c4 28 lds r25, 0x28C4 + 3af6: 29 17 cp r18, r25 + 3af8: 09 f4 brne .+2 ; 0x3afc + 3afa: 84 c0 rjmp .+264 ; 0x3c04 + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + return ACK_NAK_FRAME_SIZE; + } + } else { + /* Unknown command. Enter HALT state */ + State = STATE_IDLE; + 3afc: 81 e0 ldi r24, 0x01 ; 1 + 3afe: 80 93 be 28 sts 0x28BE, r24 + /* Unknown state? Should never happen. */ + break; + } + + /* No response has been sent, when we reach here */ + return ISO14443A_APP_NO_RESPONSE; + 3b02: 20 e0 ldi r18, 0x00 ; 0 + 3b04: 30 e0 ldi r19, 0x00 ; 0 + } else { + /* Unknown command. Enter HALT state */ + State = STATE_IDLE; + } + + break; + 3b06: 10 ce rjmp .-992 ; 0x3728 + State = STATE_HALT; + } + break; + + case STATE_ACTIVE: + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + 3b08: 20 91 bf 28 lds r18, 0x28BF + 3b0c: 90 91 c0 28 lds r25, 0x28C0 +INLINE +bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue) +{ + uint8_t* DataPtr = (uint8_t*) Buffer; + + if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){ + 3b10: f8 01 movw r30, r16 + 3b12: 80 81 ld r24, Z + 3b14: 86 32 cpi r24, 0x26 ; 38 + 3b16: 09 f4 brne .+2 ; 0x3b1a + 3b18: 42 c0 rjmp .+132 ; 0x3b9e + 3b1a: 82 35 cpi r24, 0x52 ; 82 + 3b1c: 09 f4 brne .+2 ; 0x3b20 + 3b1e: 3f c0 rjmp .+126 ; 0x3b9e + State = STATE_READY1; + return BitCount; + } else if (Buffer[0] == CMD_HALT) { + 3b20: 80 35 cpi r24, 0x50 ; 80 + 3b22: 09 f4 brne .+2 ; 0x3b26 + 3b24: 09 cf rjmp .-494 ; 0x3938 + } + } else { + Buffer[0] = NAK_INVALID_ARG; + return ACK_NAK_FRAME_SIZE; + } + } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B)) { + 3b26: 98 2f mov r25, r24 + 3b28: 90 56 subi r25, 0x60 ; 96 + 3b2a: 92 30 cpi r25, 0x02 ; 2 + 3b2c: 08 f4 brcc .+2 ; 0x3b30 + 3b2e: ab c2 rjmp .+1366 ; 0x4086 + return CMD_AUTH_RB_FRAME_SIZE * BITS_PER_BYTE; + } else { + Buffer[0] = NAK_CRC_ERROR; + return ACK_NAK_FRAME_SIZE; + } + } else if ( (Buffer[0] == CMD_READ) || (Buffer[0] == CMD_WRITE) || (Buffer[0] == CMD_DECREMENT) + 3b30: 80 33 cpi r24, 0x30 ; 48 + 3b32: 51 f0 breq .+20 ; 0x3b48 + 3b34: 80 3a cpi r24, 0xA0 ; 160 + 3b36: 41 f0 breq .+16 ; 0x3b48 + 3b38: 80 3c cpi r24, 0xC0 ; 192 + 3b3a: 31 f0 breq .+12 ; 0x3b48 + || (Buffer[0] == CMD_INCREMENT) || (Buffer[0] == CMD_RESTORE) || (Buffer[0] == CMD_TRANSFER) ) { + 3b3c: 81 3c cpi r24, 0xC1 ; 193 + 3b3e: 21 f0 breq .+8 ; 0x3b48 + 3b40: 82 3c cpi r24, 0xC2 ; 194 + 3b42: 11 f0 breq .+4 ; 0x3b48 + 3b44: 80 3b cpi r24, 0xB0 ; 176 + 3b46: d1 f6 brne .-76 ; 0x3afc + State = STATE_IDLE; + 3b48: 81 e0 ldi r24, 0x01 ; 1 + 3b4a: 80 93 be 28 sts 0x28BE, r24 + Buffer[0] = NAK_NOT_AUTHED; + 3b4e: 84 e0 ldi r24, 0x04 ; 4 + 3b50: d8 01 movw r26, r16 + 3b52: 8c 93 st X, r24 + return ACK_NAK_FRAME_SIZE; + 3b54: 24 e0 ldi r18, 0x04 ; 4 + 3b56: 30 e0 ldi r19, 0x00 ; 0 + 3b58: e7 cd rjmp .-1074 ; 0x3728 + + case STATE_READY2: + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + State = STATE_READY1; + return BitCount; + } else if (Buffer[0] == ISO14443A_CMD_SELECT_CL2) { + 3b5a: 85 39 cpi r24, 0x95 ; 149 + 3b5c: 09 f4 brne .+2 ; 0x3b60 + 3b5e: 4f c1 rjmp .+670 ; 0x3dfe + * byte is supposed to be 0. */ + if (Buffer[1] == 0) { + if (ISO14443ACheckCRCA(Buffer, CMD_HALT_FRAME_SIZE)) { + /* According to ISO14443, we must not send anything + * in order to acknowledge the HALT command. */ + State = STATE_HALT; + 3b60: 10 92 be 28 sts 0x28BE, r1 + return ISO14443A_APP_NO_RESPONSE; + 3b64: 20 e0 ldi r18, 0x00 ; 0 + 3b66: 30 e0 ldi r19, 0x00 ; 0 + 3b68: df cd rjmp .-1090 ; 0x3728 + } + + Buffer[0] = ACK_VALUE; + } else { + /* CRC Error. */ + Buffer[0] = NAK_CRC_ERROR; + 3b6a: 81 e0 ldi r24, 0x01 ; 1 + 3b6c: f8 01 movw r30, r16 + 3b6e: 80 83 st Z, r24 + } + + State = STATE_CHINESE_IDLE; + 3b70: 82 e0 ldi r24, 0x02 ; 2 + 3b72: 80 93 be 28 sts 0x28BE, r24 + + return ACK_NAK_FRAME_SIZE; + 3b76: 24 e0 ldi r18, 0x04 ; 4 + 3b78: 30 e0 ldi r19, 0x00 ; 0 + 3b7a: d6 cd rjmp .-1108 ; 0x3728 + /* Unlock read and write commands */ + Buffer[0] = ACK_VALUE; + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_CHINESE_WIPE) { + /* Wipe memory */ + Buffer[0] = ACK_VALUE; + 3b7c: 8a e0 ldi r24, 0x0A ; 10 + 3b7e: 80 83 st Z, r24 + return ACK_NAK_FRAME_SIZE; + 3b80: 24 e0 ldi r18, 0x04 ; 4 + 3b82: 30 e0 ldi r19, 0x00 ; 0 + 3b84: d1 cd rjmp .-1118 ; 0x3728 + for (uint8_t i=0; i<(MEM_BYTES_PER_BLOCK + ISO14443A_CRCA_SIZE); i++) + Buffer[i] ^= Crypto1Byte(); + + if (ISO14443ACheckCRCA(Buffer, MEM_BYTES_PER_BLOCK)) { + if (!ActiveConfiguration.ReadOnly) { + MemoryWriteBlock(Buffer, CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + 3b86: 60 91 c3 28 lds r22, 0x28C3 + 3b8a: 30 e1 ldi r19, 0x10 ; 16 + 3b8c: 63 9f mul r22, r19 + 3b8e: b0 01 movw r22, r0 + 3b90: 11 24 eor r1, r1 + 3b92: 40 e1 ldi r20, 0x10 ; 16 + 3b94: 50 e0 ldi r21, 0x00 ; 0 + 3b96: c8 01 movw r24, r16 + 3b98: 0e 94 f6 06 call 0xdec ; 0xdec + 3b9c: b6 ce rjmp .-660 ; 0x390a + DataPtr[0] = (ATQAValue >> 0) & 0x00FF; + 3b9e: d8 01 movw r26, r16 + 3ba0: 2c 93 st X, r18 + DataPtr[1] = (ATQAValue >> 8) & 0x00FF; + 3ba2: 11 96 adiw r26, 0x01 ; 1 + 3ba4: 9c 93 st X, r25 + } + break; + + case STATE_ACTIVE: + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + State = STATE_READY1; + 3ba6: 84 e0 ldi r24, 0x04 ; 4 + 3ba8: 80 93 be 28 sts 0x28BE, r24 + + *BitCount = ISO14443A_ATQA_FRAME_SIZE; + 3bac: 20 e1 ldi r18, 0x10 ; 16 + 3bae: 30 e0 ldi r19, 0x00 ; 0 + return BitCount; + 3bb0: bb cd rjmp .-1162 ; 0x3728 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_RESTORE) { + if (ISO14443ACheckCRCA(Buffer, CMD_DECREMENT_FRAME_SIZE)) { + 3bb2: 62 e0 ldi r22, 0x02 ; 2 + 3bb4: 70 e0 ldi r23, 0x00 ; 0 + 3bb6: c8 01 movw r24, r16 + 3bb8: d4 d3 rcall .+1960 ; 0x4362 + 3bba: 88 23 and r24, r24 + 3bbc: 09 f4 brne .+2 ; 0x3bc0 + 3bbe: cd c0 rjmp .+410 ; 0x3d5a + CurrentAddress = Buffer[1]; + 3bc0: f8 01 movw r30, r16 + 3bc2: 81 81 ldd r24, Z+1 ; 0x01 + 3bc4: 80 93 c3 28 sts 0x28C3, r24 + State = STATE_RESTORE; + 3bc8: 8c e0 ldi r24, 0x0C ; 12 + 3bca: 80 93 be 28 sts 0x28BE, r24 + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + 3bce: 8c d6 rcall .+3352 ; 0x48e8 + 3bd0: 9a e0 ldi r25, 0x0A ; 10 + 3bd2: 98 27 eor r25, r24 + 3bd4: d8 01 movw r26, r16 + 3bd6: 9c 93 st X, r25 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + 3bd8: 24 e0 ldi r18, 0x04 ; 4 + 3bda: 30 e0 ldi r19, 0x00 ; 0 + 3bdc: a5 cd rjmp .-1206 ; 0x3728 + } else { + Buffer[0] = NAK_CRC_ERROR; + return ACK_NAK_FRAME_SIZE; + } + } else if (Buffer[0] == CMD_WRITE) { + if (ISO14443ACheckCRCA(Buffer, CMD_WRITE_FRAME_SIZE)) { + 3bde: 62 e0 ldi r22, 0x02 ; 2 + 3be0: 70 e0 ldi r23, 0x00 ; 0 + 3be2: c8 01 movw r24, r16 + 3be4: be d3 rcall .+1916 ; 0x4362 + 3be6: 88 23 and r24, r24 + 3be8: 09 f4 brne .+2 ; 0x3bec + 3bea: ce c2 rjmp .+1436 ; 0x4188 + /* Write command. Store the address and prepare for the upcoming data. + * Respond with ACK. */ + CurrentAddress = Buffer[1]; + 3bec: f8 01 movw r30, r16 + 3bee: 81 81 ldd r24, Z+1 ; 0x01 + 3bf0: 80 93 c3 28 sts 0x28C3, r24 + State = STATE_CHINESE_WRITE; + 3bf4: 83 e0 ldi r24, 0x03 ; 3 + 3bf6: 80 93 be 28 sts 0x28BE, r24 + + Buffer[0] = ACK_VALUE; + 3bfa: 8a e0 ldi r24, 0x0A ; 10 + 3bfc: 80 83 st Z, r24 + return ACK_NAK_FRAME_SIZE; + 3bfe: 24 e0 ldi r18, 0x04 ; 4 + 3c00: 30 e0 ldi r19, 0x00 ; 0 + 3c02: 92 cd rjmp .-1244 ; 0x3728 + Crypto1Auth(&Buffer[0]); + + for (uint8_t i=0; i<4; i++) + Buffer[i+4] ^= Crypto1Byte(); + + if ((Buffer[4] == ReaderResponse[0]) && + 3c04: 25 81 ldd r18, Z+5 ; 0x05 + 3c06: 90 91 c5 28 lds r25, 0x28C5 + 3c0a: 29 13 cpse r18, r25 + 3c0c: 77 cf rjmp .-274 ; 0x3afc + (Buffer[5] == ReaderResponse[1]) && + 3c0e: 26 81 ldd r18, Z+6 ; 0x06 + 3c10: 90 91 c6 28 lds r25, 0x28C6 + 3c14: 29 13 cpse r18, r25 + 3c16: 72 cf rjmp .-284 ; 0x3afc + (Buffer[6] == ReaderResponse[2]) && + 3c18: 90 91 c7 28 lds r25, 0x28C7 + 3c1c: 89 13 cpse r24, r25 + 3c1e: 6e cf rjmp .-292 ; 0x3afc + (Buffer[7] == ReaderResponse[3])) { + /* Reader is authenticated. Encrypt the precalculated card response + * and generate the parity bits. */ + for (uint8_t i=0; i + 3c26: 8f 25 eor r24, r15 + 3c28: d8 01 movw r26, r16 + 3c2a: 8c 93 st X, r24 + Buffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = ODD_PARITY(CardResponse[i]) ^ Crypto1FilterOutput(); + 3c2c: f0 90 c8 28 lds r15, 0x28C8 + 3c30: 0f 2c mov r0, r15 + 3c32: f2 94 swap r15 + 3c34: f0 24 eor r15, r0 + 3c36: 0f 2c mov r0, r15 + 3c38: f6 94 lsr r15 + 3c3a: f6 94 lsr r15 + 3c3c: f0 24 eor r15, r0 + 3c3e: 16 d4 rcall .+2092 ; 0x446c + 3c40: f8 01 movw r30, r16 + 3c42: e0 58 subi r30, 0x80 ; 128 + 3c44: ff 4f sbci r31, 0xFF ; 255 + 3c46: 2f 2d mov r18, r15 + 3c48: 30 e0 ldi r19, 0x00 ; 0 + 3c4a: 2f 5f subi r18, 0xFF ; 255 + 3c4c: 3f 4f sbci r19, 0xFF ; 255 + 3c4e: 21 fb bst r18, 1 + 3c50: 88 24 eor r8, r8 + 3c52: 80 f8 bld r8, 0 + 3c54: 91 2c mov r9, r1 + 3c56: b1 e0 ldi r27, 0x01 ; 1 + 3c58: 8b 26 eor r8, r27 + 3c5a: 88 25 eor r24, r8 + 3c5c: 80 83 st Z, r24 + (Buffer[6] == ReaderResponse[2]) && + (Buffer[7] == ReaderResponse[3])) { + /* Reader is authenticated. Encrypt the precalculated card response + * and generate the parity bits. */ + for (uint8_t i=0; i + 3c64: 8f 25 eor r24, r15 + 3c66: f8 01 movw r30, r16 + 3c68: 81 83 std Z+1, r24 ; 0x01 + Buffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = ODD_PARITY(CardResponse[i]) ^ Crypto1FilterOutput(); + 3c6a: f0 90 c9 28 lds r15, 0x28C9 + 3c6e: 0f 2c mov r0, r15 + 3c70: f2 94 swap r15 + 3c72: f0 24 eor r15, r0 + 3c74: 0f 2c mov r0, r15 + 3c76: f6 94 lsr r15 + 3c78: f6 94 lsr r15 + 3c7a: f0 24 eor r15, r0 + 3c7c: f7 d3 rcall .+2030 ; 0x446c + 3c7e: f8 01 movw r30, r16 + 3c80: ef 57 subi r30, 0x7F ; 127 + 3c82: ff 4f sbci r31, 0xFF ; 255 + 3c84: 2f 2d mov r18, r15 + 3c86: 30 e0 ldi r19, 0x00 ; 0 + 3c88: 2f 5f subi r18, 0xFF ; 255 + 3c8a: 3f 4f sbci r19, 0xFF ; 255 + 3c8c: 21 fb bst r18, 1 + 3c8e: aa 24 eor r10, r10 + 3c90: a0 f8 bld r10, 0 + 3c92: b1 2c mov r11, r1 + 3c94: 31 e0 ldi r19, 0x01 ; 1 + 3c96: a3 26 eor r10, r19 + 3c98: 8a 25 eor r24, r10 + 3c9a: 80 83 st Z, r24 + (Buffer[6] == ReaderResponse[2]) && + (Buffer[7] == ReaderResponse[3])) { + /* Reader is authenticated. Encrypt the precalculated card response + * and generate the parity bits. */ + for (uint8_t i=0; i + 3ca2: 8f 25 eor r24, r15 + 3ca4: d8 01 movw r26, r16 + 3ca6: 12 96 adiw r26, 0x02 ; 2 + 3ca8: 8c 93 st X, r24 + Buffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = ODD_PARITY(CardResponse[i]) ^ Crypto1FilterOutput(); + 3caa: f0 90 ca 28 lds r15, 0x28CA + 3cae: 0f 2c mov r0, r15 + 3cb0: f2 94 swap r15 + 3cb2: f0 24 eor r15, r0 + 3cb4: 0f 2c mov r0, r15 + 3cb6: f6 94 lsr r15 + 3cb8: f6 94 lsr r15 + 3cba: f0 24 eor r15, r0 + 3cbc: d7 d3 rcall .+1966 ; 0x446c + 3cbe: f8 01 movw r30, r16 + 3cc0: ee 57 subi r30, 0x7E ; 126 + 3cc2: ff 4f sbci r31, 0xFF ; 255 + 3cc4: 2f 2d mov r18, r15 + 3cc6: 30 e0 ldi r19, 0x00 ; 0 + 3cc8: 2f 5f subi r18, 0xFF ; 255 + 3cca: 3f 4f sbci r19, 0xFF ; 255 + 3ccc: 21 fb bst r18, 1 + 3cce: cc 24 eor r12, r12 + 3cd0: c0 f8 bld r12, 0 + 3cd2: d1 2c mov r13, r1 + 3cd4: b1 e0 ldi r27, 0x01 ; 1 + 3cd6: cb 26 eor r12, r27 + 3cd8: 8c 25 eor r24, r12 + 3cda: 80 83 st Z, r24 + (Buffer[6] == ReaderResponse[2]) && + (Buffer[7] == ReaderResponse[3])) { + /* Reader is authenticated. Encrypt the precalculated card response + * and generate the parity bits. */ + for (uint8_t i=0; i + 3ce2: 8f 25 eor r24, r15 + 3ce4: f8 01 movw r30, r16 + 3ce6: 83 83 std Z+3, r24 ; 0x03 + Buffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = ODD_PARITY(CardResponse[i]) ^ Crypto1FilterOutput(); + 3ce8: f0 90 cb 28 lds r15, 0x28CB + 3cec: 0f 2c mov r0, r15 + 3cee: f2 94 swap r15 + 3cf0: f0 24 eor r15, r0 + 3cf2: 0f 2c mov r0, r15 + 3cf4: f6 94 lsr r15 + 3cf6: f6 94 lsr r15 + 3cf8: f0 24 eor r15, r0 + 3cfa: b8 d3 rcall .+1904 ; 0x446c + 3cfc: f8 01 movw r30, r16 + 3cfe: ed 57 subi r30, 0x7D ; 125 + 3d00: ff 4f sbci r31, 0xFF ; 255 + 3d02: 2f 2d mov r18, r15 + 3d04: 30 e0 ldi r19, 0x00 ; 0 + 3d06: 2f 5f subi r18, 0xFF ; 255 + 3d08: 3f 4f sbci r19, 0xFF ; 255 + 3d0a: 21 fb bst r18, 1 + 3d0c: 66 24 eor r6, r6 + 3d0e: 60 f8 bld r6, 0 + 3d10: 71 2c mov r7, r1 + 3d12: 31 e0 ldi r19, 0x01 ; 1 + 3d14: 63 26 eor r6, r19 + 3d16: 86 25 eor r24, r6 + 3d18: 80 83 st Z, r24 + } + + State = STATE_AUTHED_IDLE; + 3d1a: 88 e0 ldi r24, 0x08 ; 8 + 3d1c: 80 93 be 28 sts 0x28BE, r24 + + return (CMD_AUTH_BA_FRAME_SIZE * BITS_PER_BYTE) | ISO14443A_APP_CUSTOM_PARITY; + 3d20: 20 e2 ldi r18, 0x20 ; 32 + 3d22: 30 e1 ldi r19, 0x10 ; 16 + 3d24: 01 cd rjmp .-1534 ; 0x3728 + * the block back into the global block buffer. */ + for (uint8_t i=0; i<(MEM_VALUE_SIZE + ISO14443A_CRCA_SIZE); i++) + Buffer[i] ^= Crypto1Byte(); + + if (ISO14443ACheckCRCA(Buffer, MEM_VALUE_SIZE )) { + MemoryReadBlock(BlockBuffer, (uint16_t) CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + 3d26: 60 91 c3 28 lds r22, 0x28C3 + 3d2a: b0 e1 ldi r27, 0x10 ; 16 + 3d2c: 6b 9f mul r22, r27 + 3d2e: b0 01 movw r22, r0 + 3d30: 11 24 eor r1, r1 + 3d32: 40 e1 ldi r20, 0x10 ; 16 + 3d34: 50 e0 ldi r21, 0x00 ; 0 + 3d36: 8c ec ldi r24, 0xCC ; 204 + 3d38: 98 e2 ldi r25, 0x28 ; 40 + 3d3a: 0e 94 de 06 call 0xdbc ; 0xdbc + +INLINE bool CheckValueIntegrity(uint8_t* Block) +{ + /* Value Blocks contain a value stored three times, with + * the middle portion inverted. */ + if ( (Block[0] == (uint8_t) ~Block[4]) && (Block[0] == Block[8]) + 3d3e: 20 91 cc 28 lds r18, 0x28CC + 3d42: 80 91 d0 28 lds r24, 0x28D0 + 3d46: 80 95 com r24 + 3d48: 28 17 cp r18, r24 + 3d4a: 09 f4 brne .+2 ; 0x3d4e + 3d4c: df c0 rjmp .+446 ; 0x3f0c + State = STATE_AUTHED_IDLE; + /* No ACK response on value commands part 2 */ + return ISO14443A_APP_NO_RESPONSE; + } else { + /* Not sure if this is the correct error code.. */ + Buffer[0] = NAK_OTHER_ERROR ^ Crypto1Nibble(); + 3d4e: cc d5 rcall .+2968 ; 0x48e8 + 3d50: 96 e0 ldi r25, 0x06 ; 6 + 3d52: 98 27 eor r25, r24 + 3d54: d8 01 movw r26, r16 + 3d56: 9c 93 st X, r25 + 3d58: 53 cd rjmp .-1370 ; 0x3800 + * form the reader in the next frame. */ + State = STATE_AUTHING; + + return CMD_AUTH_RB_FRAME_SIZE * BITS_PER_BYTE; + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + 3d5a: c6 d5 rcall .+2956 ; 0x48e8 + 3d5c: 91 e0 ldi r25, 0x01 ; 1 + 3d5e: 98 27 eor r25, r24 + 3d60: f8 01 movw r30, r16 + 3d62: 90 83 st Z, r25 + return ACK_NAK_FRAME_SIZE; + 3d64: 24 e0 ldi r18, 0x04 ; 4 + 3d66: 30 e0 ldi r19, 0x00 ; 0 + 3d68: df cc rjmp .-1602 ; 0x3728 + + case STATE_CHINESE_WRITE: + if (ISO14443ACheckCRCA(Buffer, MEM_BYTES_PER_BLOCK)) { + /* CRC check passed. Write data into memory and send ACK. */ + if (!ActiveConfiguration.ReadOnly) { + MemoryWriteBlock(Buffer, CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + 3d6a: 60 91 c3 28 lds r22, 0x28C3 + 3d6e: f0 e1 ldi r31, 0x10 ; 16 + 3d70: 6f 9f mul r22, r31 + 3d72: b0 01 movw r22, r0 + 3d74: 11 24 eor r1, r1 + 3d76: 40 e1 ldi r20, 0x10 ; 16 + 3d78: 50 e0 ldi r21, 0x00 ; 0 + 3d7a: c8 01 movw r24, r16 + 3d7c: 0e 94 f6 06 call 0xdec ; 0xdec + 3d80: 96 ce rjmp .-724 ; 0x3aae + * the incoming data. */ + for (uint8_t i=0; i<4; i++) + Buffer[i] ^= Crypto1Byte(); + + if (Buffer[0] == CMD_READ) { + if (ISO14443ACheckCRCA(Buffer, CMD_READ_FRAME_SIZE)) { + 3d82: 62 e0 ldi r22, 0x02 ; 2 + 3d84: 70 e0 ldi r23, 0x00 ; 0 + 3d86: c8 01 movw r24, r16 + 3d88: ec d2 rcall .+1496 ; 0x4362 + 3d8a: 88 23 and r24, r24 + 3d8c: 31 f3 breq .-52 ; 0x3d5a + /* Read command. Read data from memory and append CRCA. */ + MemoryReadBlock(Buffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + 3d8e: f8 01 movw r30, r16 + 3d90: 61 81 ldd r22, Z+1 ; 0x01 + 3d92: f0 e1 ldi r31, 0x10 ; 16 + 3d94: 6f 9f mul r22, r31 + 3d96: b0 01 movw r22, r0 + 3d98: 11 24 eor r1, r1 + 3d9a: 40 e1 ldi r20, 0x10 ; 16 + 3d9c: 50 e0 ldi r21, 0x00 ; 0 + 3d9e: c8 01 movw r24, r16 + 3da0: 0e 94 de 06 call 0xdbc ; 0xdbc + ISO14443AAppendCRCA(Buffer, MEM_BYTES_PER_BLOCK); + 3da4: 60 e1 ldi r22, 0x10 ; 16 + 3da6: 70 e0 ldi r23, 0x00 ; 0 + 3da8: c8 01 movw r24, r16 + 3daa: ac d2 rcall .+1368 ; 0x4304 +void MifareClassicAppTask(void) +{ + +} + +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) + 3dac: 68 01 movw r12, r16 + 3dae: 30 e8 ldi r19, 0x80 ; 128 + 3db0: c3 0e add r12, r19 + 3db2: d1 1c adc r13, r1 + /* Read command. Read data from memory and append CRCA. */ + MemoryReadBlock(Buffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + ISO14443AAppendCRCA(Buffer, MEM_BYTES_PER_BLOCK); + + /* Encrypt and calculate parity bits. */ + for (uint8_t i=0; i<(ISO14443A_CRCA_SIZE + MEM_BYTES_PER_BLOCK); i++) { + 3db4: a1 2c mov r10, r1 + uint8_t Plain = Buffer[i]; + 3db6: d8 01 movw r26, r16 + 3db8: bc 90 ld r11, X + Buffer[i] = Plain ^ Crypto1Byte(); + 3dba: 55 d5 rcall .+2730 ; 0x4866 + 3dbc: 8b 25 eor r24, r11 + 3dbe: f8 01 movw r30, r16 + 3dc0: 81 93 st Z+, r24 + 3dc2: 8f 01 movw r16, r30 + Buffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = ODD_PARITY(Plain) ^ Crypto1FilterOutput(); + 3dc4: 0b 2c mov r0, r11 + 3dc6: b2 94 swap r11 + 3dc8: b0 24 eor r11, r0 + 3dca: 0b 2c mov r0, r11 + 3dcc: b6 94 lsr r11 + 3dce: b6 94 lsr r11 + 3dd0: b0 24 eor r11, r0 + 3dd2: 4c d3 rcall .+1688 ; 0x446c + 3dd4: 2b 2d mov r18, r11 + 3dd6: 30 e0 ldi r19, 0x00 ; 0 + 3dd8: 2f 5f subi r18, 0xFF ; 255 + 3dda: 3f 4f sbci r19, 0xFF ; 255 + 3ddc: 21 fb bst r18, 1 + 3dde: ee 24 eor r14, r14 + 3de0: e0 f8 bld r14, 0 + 3de2: f1 2c mov r15, r1 + 3de4: f1 e0 ldi r31, 0x01 ; 1 + 3de6: ef 26 eor r14, r31 + 3de8: 8e 25 eor r24, r14 + 3dea: d6 01 movw r26, r12 + 3dec: 8d 93 st X+, r24 + 3dee: 6d 01 movw r12, r26 + /* Read command. Read data from memory and append CRCA. */ + MemoryReadBlock(Buffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + ISO14443AAppendCRCA(Buffer, MEM_BYTES_PER_BLOCK); + + /* Encrypt and calculate parity bits. */ + for (uint8_t i=0; i<(ISO14443A_CRCA_SIZE + MEM_BYTES_PER_BLOCK); i++) { + 3df0: a3 94 inc r10 + 3df2: b2 e1 ldi r27, 0x12 ; 18 + 3df4: ab 12 cpse r10, r27 + 3df6: df cf rjmp .-66 ; 0x3db6 + uint8_t Plain = Buffer[i]; + Buffer[i] = Plain ^ Crypto1Byte(); + Buffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = ODD_PARITY(Plain) ^ Crypto1FilterOutput(); + } + + return ( (CMD_READ_RESPONSE_FRAME_SIZE + ISO14443A_CRCA_SIZE ) + 3df8: 20 e9 ldi r18, 0x90 ; 144 + 3dfa: 30 e1 ldi r19, 0x10 ; 16 + 3dfc: 95 cc rjmp .-1750 ; 0x3728 + State = STATE_READY1; + return BitCount; + } else if (Buffer[0] == ISO14443A_CMD_SELECT_CL2) { + /* Load UID CL2 and perform anticollision */ + uint8_t UidCL2[ISO14443A_CL_UID_SIZE]; + MemoryReadBlock(UidCL2, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + 3dfe: 44 e0 ldi r20, 0x04 ; 4 + 3e00: 50 e0 ldi r21, 0x00 ; 0 + 3e02: 63 e0 ldi r22, 0x03 ; 3 + 3e04: 70 e0 ldi r23, 0x00 ; 0 + 3e06: ce 01 movw r24, r28 + 3e08: 01 96 adiw r24, 0x01 ; 1 + 3e0a: 0e 94 de 06 call 0xdbc ; 0xdbc + + if (ISO14443ASelect(Buffer, &BitCount, UidCL2, CardSAKValue)) { + 3e0e: 90 91 c1 28 lds r25, 0x28C1 + uint8_t* DataPtr = (uint8_t*) Buffer; + uint8_t NVB = DataPtr[1]; + //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F; + //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F; + + switch (NVB) { + 3e12: d8 01 movw r26, r16 + 3e14: 11 96 adiw r26, 0x01 ; 1 + 3e16: 8c 91 ld r24, X + 3e18: 80 32 cpi r24, 0x20 ; 32 + 3e1a: 09 f4 brne .+2 ; 0x3e1e + 3e1c: d3 c1 rjmp .+934 ; 0x41c4 + 3e1e: 80 37 cpi r24, 0x70 ; 112 + 3e20: 09 f0 breq .+2 ; 0x3e24 + 3e22: 80 cc rjmp .-1792 ; 0x3724 + return false; + + case ISO14443A_NVB_AC_END: + /* End of anticollision procedure. + * Send SAK CLn if we are selected. */ + if ( (DataPtr[2] == UidCL[0]) && + 3e24: d8 01 movw r26, r16 + 3e26: 12 96 adiw r26, 0x02 ; 2 + 3e28: 2c 91 ld r18, X + 3e2a: 12 97 sbiw r26, 0x02 ; 2 + 3e2c: 89 81 ldd r24, Y+1 ; 0x01 + 3e2e: 28 13 cpse r18, r24 + 3e30: 79 cc rjmp .-1806 ; 0x3724 + 3e32: 13 96 adiw r26, 0x03 ; 3 + 3e34: 2c 91 ld r18, X + 3e36: 13 97 sbiw r26, 0x03 ; 3 + 3e38: 8a 81 ldd r24, Y+2 ; 0x02 + 3e3a: 28 13 cpse r18, r24 + 3e3c: 73 cc rjmp .-1818 ; 0x3724 + (DataPtr[3] == UidCL[1]) && + 3e3e: 14 96 adiw r26, 0x04 ; 4 + 3e40: 2c 91 ld r18, X + 3e42: 14 97 sbiw r26, 0x04 ; 4 + 3e44: 8b 81 ldd r24, Y+3 ; 0x03 + 3e46: 28 13 cpse r18, r24 + 3e48: 6d cc rjmp .-1830 ; 0x3724 + (DataPtr[4] == UidCL[2]) && + 3e4a: 15 96 adiw r26, 0x05 ; 5 + 3e4c: 2c 91 ld r18, X + 3e4e: 15 97 sbiw r26, 0x05 ; 5 + 3e50: 8c 81 ldd r24, Y+4 ; 0x04 + 3e52: 28 13 cpse r18, r24 + 3e54: 67 cc rjmp .-1842 ; 0x3724 + (DataPtr[5] == UidCL[3]) ) { + + DataPtr[0] = SAKValue; + 3e56: 9c 93 st X, r25 + ISO14443AAppendCRCA(Buffer, 1); + 3e58: 61 e0 ldi r22, 0x01 ; 1 + 3e5a: 70 e0 ldi r23, 0x00 ; 0 + 3e5c: c8 01 movw r24, r16 + 3e5e: 52 d2 rcall .+1188 ; 0x4304 + State = STATE_ACTIVE; + 3e60: 86 e0 ldi r24, 0x06 ; 6 + 3e62: 80 93 be 28 sts 0x28BE, r24 + + *BitCount = ISO14443A_SAK_FRAME_SIZE; + 3e66: 28 e1 ldi r18, 0x18 ; 24 + 3e68: 30 e0 ldi r19, 0x00 ; 0 + 3e6a: 5e cc rjmp .-1860 ; 0x3728 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + return ACK_NAK_FRAME_SIZE; + } + } else if (Buffer[0] == CMD_WRITE) { + if (ISO14443ACheckCRCA(Buffer, CMD_WRITE_FRAME_SIZE)) { + 3e6c: 62 e0 ldi r22, 0x02 ; 2 + 3e6e: 70 e0 ldi r23, 0x00 ; 0 + 3e70: c8 01 movw r24, r16 + 3e72: 77 d2 rcall .+1262 ; 0x4362 + 3e74: 88 23 and r24, r24 + 3e76: 81 f0 breq .+32 ; 0x3e98 + /* Write command. Store the address and prepare for the upcoming data. + * Respond with ACK. */ + CurrentAddress = Buffer[1]; + 3e78: d8 01 movw r26, r16 + 3e7a: 11 96 adiw r26, 0x01 ; 1 + 3e7c: 8c 91 ld r24, X + 3e7e: 80 93 c3 28 sts 0x28C3, r24 + State = STATE_WRITE; + 3e82: 89 e0 ldi r24, 0x09 ; 9 + 3e84: 80 93 be 28 sts 0x28BE, r24 + MemoryWriteBlock(BlockBuffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK ); + } else { + /* In read only mode, silently ignore the write */ + } + + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + 3e88: 2f d5 rcall .+2654 ; 0x48e8 + 3e8a: 9a e0 ldi r25, 0x0A ; 10 + 3e8c: 98 27 eor r25, r24 + 3e8e: f8 01 movw r30, r16 + 3e90: 90 83 st Z, r25 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + + return ACK_NAK_FRAME_SIZE; + 3e92: 24 e0 ldi r18, 0x04 ; 4 + 3e94: 30 e0 ldi r19, 0x00 ; 0 + 3e96: 48 cc rjmp .-1904 ; 0x3728 + /* In read only mode, silently ignore the write */ + } + + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + 3e98: 27 d5 rcall .+2638 ; 0x48e8 + 3e9a: 91 e0 ldi r25, 0x01 ; 1 + 3e9c: 98 27 eor r25, r24 + 3e9e: d8 01 movw r26, r16 + 3ea0: 9c 93 st X, r25 + } + + return ACK_NAK_FRAME_SIZE; + 3ea2: 24 e0 ldi r18, 0x04 ; 4 + 3ea4: 30 e0 ldi r19, 0x00 ; 0 + 3ea6: 40 cc rjmp .-1920 ; 0x3728 + MemoryReadBlock(&UidCL1[1], MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE-1); + UidCL1[0] = ISO14443A_UID0_CT; + if (ISO14443ASelect(Buffer, &BitCount, UidCL1, SAK_CL1_VALUE)) + State = STATE_READY2; + } else { + MemoryReadBlock(UidCL1, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + 3ea8: 44 e0 ldi r20, 0x04 ; 4 + 3eaa: 50 e0 ldi r21, 0x00 ; 0 + 3eac: 60 e0 ldi r22, 0x00 ; 0 + 3eae: 70 e0 ldi r23, 0x00 ; 0 + 3eb0: ce 01 movw r24, r28 + 3eb2: 01 96 adiw r24, 0x01 ; 1 + 3eb4: 0e 94 de 06 call 0xdbc ; 0xdbc + if (ISO14443ASelect(Buffer, &BitCount, UidCL1, CardSAKValue)) + 3eb8: 90 91 c1 28 lds r25, 0x28C1 + uint8_t* DataPtr = (uint8_t*) Buffer; + uint8_t NVB = DataPtr[1]; + //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F; + //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F; + + switch (NVB) { + 3ebc: f8 01 movw r30, r16 + 3ebe: 81 81 ldd r24, Z+1 ; 0x01 + 3ec0: 80 32 cpi r24, 0x20 ; 32 + 3ec2: 09 f4 brne .+2 ; 0x3ec6 + 3ec4: 9e c1 rjmp .+828 ; 0x4202 + 3ec6: 80 37 cpi r24, 0x70 ; 112 + 3ec8: 09 f0 breq .+2 ; 0x3ecc + 3eca: 2c cc rjmp .-1960 ; 0x3724 + return false; + + case ISO14443A_NVB_AC_END: + /* End of anticollision procedure. + * Send SAK CLn if we are selected. */ + if ( (DataPtr[2] == UidCL[0]) && + 3ecc: f8 01 movw r30, r16 + 3ece: 22 81 ldd r18, Z+2 ; 0x02 + 3ed0: 89 81 ldd r24, Y+1 ; 0x01 + 3ed2: 28 13 cpse r18, r24 + 3ed4: 27 cc rjmp .-1970 ; 0x3724 + 3ed6: 23 81 ldd r18, Z+3 ; 0x03 + 3ed8: 8a 81 ldd r24, Y+2 ; 0x02 + 3eda: 28 13 cpse r18, r24 + 3edc: 23 cc rjmp .-1978 ; 0x3724 + (DataPtr[3] == UidCL[1]) && + 3ede: 24 81 ldd r18, Z+4 ; 0x04 + 3ee0: 8b 81 ldd r24, Y+3 ; 0x03 + 3ee2: 28 13 cpse r18, r24 + 3ee4: 1f cc rjmp .-1986 ; 0x3724 + (DataPtr[4] == UidCL[2]) && + 3ee6: 25 81 ldd r18, Z+5 ; 0x05 + 3ee8: 8c 81 ldd r24, Y+4 ; 0x04 + 3eea: 28 13 cpse r18, r24 + 3eec: 1b cc rjmp .-1994 ; 0x3724 + (DataPtr[5] == UidCL[3]) ) { + + DataPtr[0] = SAKValue; + 3eee: 90 83 st Z, r25 + 3ef0: b3 cf rjmp .-154 ; 0x3e58 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_DECREMENT) { + if (ISO14443ACheckCRCA(Buffer, CMD_DECREMENT_FRAME_SIZE)) { + 3ef2: 62 e0 ldi r22, 0x02 ; 2 + 3ef4: 70 e0 ldi r23, 0x00 ; 0 + 3ef6: c8 01 movw r24, r16 + 3ef8: 34 d2 rcall .+1128 ; 0x4362 + 3efa: 88 23 and r24, r24 + 3efc: 09 f4 brne .+2 ; 0x3f00 + 3efe: 2d cf rjmp .-422 ; 0x3d5a + CurrentAddress = Buffer[1]; + 3f00: f8 01 movw r30, r16 + 3f02: 81 81 ldd r24, Z+1 ; 0x01 + 3f04: 80 93 c3 28 sts 0x28C3, r24 + State = STATE_DECREMENT; + 3f08: 8b e0 ldi r24, 0x0B ; 11 + 3f0a: 5f ce rjmp .-834 ; 0x3bca + +INLINE bool CheckValueIntegrity(uint8_t* Block) +{ + /* Value Blocks contain a value stored three times, with + * the middle portion inverted. */ + if ( (Block[0] == (uint8_t) ~Block[4]) && (Block[0] == Block[8]) + 3f0c: 80 91 d4 28 lds r24, 0x28D4 + 3f10: 28 13 cpse r18, r24 + 3f12: 1d cf rjmp .-454 ; 0x3d4e + && (Block[1] == (uint8_t) ~Block[5]) && (Block[1] == Block[9]) + 3f14: e0 91 cd 28 lds r30, 0x28CD + 3f18: 80 91 d1 28 lds r24, 0x28D1 + 3f1c: 80 95 com r24 + 3f1e: e8 13 cpse r30, r24 + 3f20: 16 cf rjmp .-468 ; 0x3d4e + 3f22: 80 91 d5 28 lds r24, 0x28D5 + 3f26: e8 13 cpse r30, r24 + 3f28: 12 cf rjmp .-476 ; 0x3d4e + && (Block[2] == (uint8_t) ~Block[6]) && (Block[2] == Block[10]) + 3f2a: 80 91 ce 28 lds r24, 0x28CE + 3f2e: 90 91 d2 28 lds r25, 0x28D2 + 3f32: 90 95 com r25 + 3f34: 89 13 cpse r24, r25 + 3f36: 0b cf rjmp .-490 ; 0x3d4e + 3f38: 90 91 d6 28 lds r25, 0x28D6 + 3f3c: 89 13 cpse r24, r25 + 3f3e: 07 cf rjmp .-498 ; 0x3d4e + && (Block[3] == (uint8_t) ~Block[7]) && (Block[3] == Block[11]) + 3f40: 30 91 cf 28 lds r19, 0x28CF + 3f44: 90 91 d3 28 lds r25, 0x28D3 + 3f48: 90 95 com r25 + 3f4a: 39 13 cpse r19, r25 + 3f4c: 00 cf rjmp .-512 ; 0x3d4e + 3f4e: 90 91 d7 28 lds r25, 0x28D7 + 3f52: 39 13 cpse r19, r25 + 3f54: fc ce rjmp .-520 ; 0x3d4e + && (Block[12] == (uint8_t) ~Block[13]) + 3f56: 40 91 d8 28 lds r20, 0x28D8 + 3f5a: 90 91 d9 28 lds r25, 0x28D9 + 3f5e: 90 95 com r25 + 3f60: 49 13 cpse r20, r25 + 3f62: f5 ce rjmp .-534 ; 0x3d4e + && (Block[12] == Block[14]) + 3f64: 90 91 da 28 lds r25, 0x28DA + 3f68: 49 13 cpse r20, r25 + 3f6a: f1 ce rjmp .-542 ; 0x3d4e + && (Block[14] == (uint8_t) ~Block[15])) { + 3f6c: 90 91 db 28 lds r25, 0x28DB + 3f70: 90 95 com r25 + 3f72: 49 13 cpse r20, r25 + 3f74: ec ce rjmp .-552 ; 0x3d4e +} + +INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) +{ + *Value = 0; + *Value |= ((uint32_t) Block[0] << 0); + 3f76: d8 01 movw r26, r16 + 3f78: 9c 91 ld r25, X + *Value |= ((uint32_t) Block[1] << 8); + 3f7a: 11 96 adiw r26, 0x01 ; 1 + 3f7c: fc 91 ld r31, X + 3f7e: 11 97 sbiw r26, 0x01 ; 1 + *Value |= ((uint32_t) Block[2] << 16); + 3f80: 12 96 adiw r26, 0x02 ; 2 + 3f82: 4c 91 ld r20, X + 3f84: 12 97 sbiw r26, 0x02 ; 2 + 3f86: 50 e0 ldi r21, 0x00 ; 0 + 3f88: 60 e0 ldi r22, 0x00 ; 0 + 3f8a: 70 e0 ldi r23, 0x00 ; 0 + 3f8c: ba 01 movw r22, r20 + 3f8e: 55 27 eor r21, r21 + 3f90: 44 27 eor r20, r20 + +INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) +{ + *Value = 0; + *Value |= ((uint32_t) Block[0] << 0); + *Value |= ((uint32_t) Block[1] << 8); + 3f92: 5f 2b or r21, r31 + *Value |= ((uint32_t) Block[2] << 16); + 3f94: 49 2b or r20, r25 + *Value |= ((uint32_t) Block[3] << 24); + 3f96: 13 96 adiw r26, 0x03 ; 3 + 3f98: 9c 91 ld r25, X + 3f9a: 79 2b or r23, r25 +INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) +{ + *Value = 0; + *Value |= ((uint32_t) Block[0] << 0); + *Value |= ((uint32_t) Block[1] << 8); + *Value |= ((uint32_t) Block[2] << 16); + 3f9c: 90 e0 ldi r25, 0x00 ; 0 + 3f9e: a0 e0 ldi r26, 0x00 ; 0 + 3fa0: b0 e0 ldi r27, 0x00 ; 0 + 3fa2: dc 01 movw r26, r24 + 3fa4: 99 27 eor r25, r25 + 3fa6: 88 27 eor r24, r24 + +INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) +{ + *Value = 0; + *Value |= ((uint32_t) Block[0] << 0); + *Value |= ((uint32_t) Block[1] << 8); + 3fa8: 9e 2b or r25, r30 + *Value |= ((uint32_t) Block[2] << 16); + 3faa: 82 2b or r24, r18 + *Value |= ((uint32_t) Block[3] << 24); + 3fac: b3 2b or r27, r19 + uint32_t BlockValue; + + ValueFromBlock(&ParamValue, Buffer); + ValueFromBlock(&BlockValue, BlockBuffer); + + if (State == STATE_DECREMENT) { + 3fae: 20 91 be 28 lds r18, 0x28BE + 3fb2: 2b 30 cpi r18, 0x0B ; 11 + 3fb4: 09 f4 brne .+2 ; 0x3fb8 + 3fb6: dd c0 rjmp .+442 ; 0x4172 + BlockValue -= ParamValue; + } else if (State == STATE_INCREMENT) { + 3fb8: 2a 30 cpi r18, 0x0A ; 10 + 3fba: 21 f4 brne .+8 ; 0x3fc4 + BlockValue += ParamValue; + 3fbc: 84 0f add r24, r20 + 3fbe: 95 1f adc r25, r21 + 3fc0: a6 1f adc r26, r22 + 3fc2: b7 1f adc r27, r23 + *Value |= ((uint32_t) Block[3] << 24); +} + +INLINE void ValueToBlock(uint8_t* Block, uint32_t Value) +{ + Block[0] = (uint8_t) (Value >> 0); + 3fc4: 80 93 cc 28 sts 0x28CC, r24 + Block[1] = (uint8_t) (Value >> 8); + 3fc8: c9 2e mov r12, r25 + 3fca: da 2e mov r13, r26 + 3fcc: eb 2e mov r14, r27 + 3fce: ff 24 eor r15, r15 + 3fd0: c0 92 cd 28 sts 0x28CD, r12 + Block[2] = (uint8_t) (Value >> 16); + 3fd4: 8d 01 movw r16, r26 + 3fd6: 22 27 eor r18, r18 + 3fd8: 33 27 eor r19, r19 + 3fda: 00 93 ce 28 sts 0x28CE, r16 + Block[3] = (uint8_t) (Value >> 24); + 3fde: 4b 2f mov r20, r27 + 3fe0: 55 27 eor r21, r21 + 3fe2: 66 27 eor r22, r22 + 3fe4: 77 27 eor r23, r23 + 3fe6: 40 93 cf 28 sts 0x28CF, r20 + Block[4] = ~Block[0]; + 3fea: e8 2f mov r30, r24 + 3fec: e0 95 com r30 + 3fee: e0 93 d0 28 sts 0x28D0, r30 + Block[5] = ~Block[1]; + 3ff2: ec 2d mov r30, r12 + 3ff4: e0 95 com r30 + 3ff6: e0 93 d1 28 sts 0x28D1, r30 + Block[6] = ~Block[2]; + 3ffa: e0 2f mov r30, r16 + 3ffc: e0 95 com r30 + 3ffe: e0 93 d2 28 sts 0x28D2, r30 + Block[7] = ~Block[3]; + 4002: e4 2f mov r30, r20 + 4004: e0 95 com r30 + 4006: e0 93 d3 28 sts 0x28D3, r30 + Block[8] = Block[0]; + 400a: 80 93 d4 28 sts 0x28D4, r24 + Block[9] = Block[1]; + 400e: c0 92 d5 28 sts 0x28D5, r12 + Block[10] = Block[2]; + 4012: 00 93 d6 28 sts 0x28D6, r16 + Block[11] = Block[3]; + 4016: 40 93 d7 28 sts 0x28D7, r20 + /* Do nothing */ + } + + ValueToBlock(BlockBuffer, BlockValue); + + State = STATE_AUTHED_IDLE; + 401a: 88 e0 ldi r24, 0x08 ; 8 + 401c: 80 93 be 28 sts 0x28BE, r24 + /* No ACK response on value commands part 2 */ + return ISO14443A_APP_NO_RESPONSE; + 4020: 20 e0 ldi r18, 0x00 ; 0 + 4022: 30 e0 ldi r19, 0x00 ; 0 + 4024: 81 cb rjmp .-2302 ; 0x3728 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_INCREMENT) { + if (ISO14443ACheckCRCA(Buffer, CMD_DECREMENT_FRAME_SIZE)) { + 4026: 62 e0 ldi r22, 0x02 ; 2 + 4028: 70 e0 ldi r23, 0x00 ; 0 + 402a: c8 01 movw r24, r16 + 402c: 9a d1 rcall .+820 ; 0x4362 + 402e: 88 23 and r24, r24 + 4030: 09 f4 brne .+2 ; 0x4034 + 4032: 32 cf rjmp .-412 ; 0x3e98 + CurrentAddress = Buffer[1]; + 4034: d8 01 movw r26, r16 + 4036: 11 96 adiw r26, 0x01 ; 1 + 4038: 8c 91 ld r24, X + 403a: 80 93 c3 28 sts 0x28C3, r24 + State = STATE_INCREMENT; + 403e: 5a e0 ldi r21, 0x0A ; 10 + 4040: f5 2e mov r15, r21 + 4042: f0 92 be 28 sts 0x28BE, r15 + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + 4046: 50 d4 rcall .+2208 ; 0x48e8 + 4048: 8f 25 eor r24, r15 + 404a: f8 01 movw r30, r16 + 404c: 80 83 st Z, r24 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + 404e: 24 e0 ldi r18, 0x04 ; 4 + 4050: 30 e0 ldi r19, 0x00 ; 0 + 4052: 6a cb rjmp .-2348 ; 0x3728 + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + }else if (Buffer[0] == CMD_TRANSFER) { + /* Write back the global block buffer to the desired block address */ + if (ISO14443ACheckCRCA(Buffer, CMD_TRANSFER_FRAME_SIZE)) { + 4054: 62 e0 ldi r22, 0x02 ; 2 + 4056: 70 e0 ldi r23, 0x00 ; 0 + 4058: c8 01 movw r24, r16 + 405a: 83 d1 rcall .+774 ; 0x4362 + 405c: 88 23 and r24, r24 + 405e: 09 f4 brne .+2 ; 0x4062 + 4060: 1b cf rjmp .-458 ; 0x3e98 + if (!ActiveConfiguration.ReadOnly) { + 4062: 80 91 06 29 lds r24, 0x2906 + 4066: 81 11 cpse r24, r1 + 4068: 0f cf rjmp .-482 ; 0x3e88 + MemoryWriteBlock(BlockBuffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK ); + 406a: d8 01 movw r26, r16 + 406c: 11 96 adiw r26, 0x01 ; 1 + 406e: 6c 91 ld r22, X + 4070: b0 e1 ldi r27, 0x10 ; 16 + 4072: 6b 9f mul r22, r27 + 4074: b0 01 movw r22, r0 + 4076: 11 24 eor r1, r1 + 4078: 40 e1 ldi r20, 0x10 ; 16 + 407a: 50 e0 ldi r21, 0x00 ; 0 + 407c: 8c ec ldi r24, 0xCC ; 204 + 407e: 98 e2 ldi r25, 0x28 ; 40 + 4080: 0e 94 f6 06 call 0xdec ; 0xdec + 4084: 01 cf rjmp .-510 ; 0x3e88 + } else { + Buffer[0] = NAK_INVALID_ARG; + return ACK_NAK_FRAME_SIZE; + } + } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B)) { + if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { + 4086: 62 e0 ldi r22, 0x02 ; 2 + 4088: 70 e0 ldi r23, 0x00 ; 0 + 408a: c8 01 movw r24, r16 + 408c: 6a d1 rcall .+724 ; 0x4362 + 408e: 88 23 and r24, r24 + 4090: 09 f4 brne .+2 ; 0x4094 + 4092: d1 c0 rjmp .+418 ; 0x4236 + uint8_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; + 4094: d8 01 movw r26, r16 + 4096: 11 96 adiw r26, 0x01 ; 1 + 4098: 2c 91 ld r18, X + 409a: 11 97 sbiw r26, 0x01 ; 1 + 409c: 2c 73 andi r18, 0x3C ; 60 + uint8_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); + 409e: 8c 91 ld r24, X + 40a0: 80 36 cpi r24, 0x60 ; 96 + 40a2: 09 f4 brne .+2 ; 0x40a6 + 40a4: dc c0 rjmp .+440 ; 0x425e + 40a6: 8a e3 ldi r24, 0x3A ; 58 + 40a8: 90 e0 ldi r25, 0x00 ; 0 + uint16_t KeyAddress = (uint16_t) SectorAddress * MEM_BYTES_PER_BLOCK + KeyOffset; + 40aa: 5c 01 movw r10, r24 + 40ac: b0 e1 ldi r27, 0x10 ; 16 + 40ae: 2b 9f mul r18, r27 + 40b0: a0 0c add r10, r0 + 40b2: b1 1c adc r11, r1 + 40b4: 11 24 eor r1, r1 + uint8_t Key[6]; + uint8_t Uid[4]; + uint8_t CardNonce[4]; + + /* Generate a random nonce and read UID and key from memory */ + RandomGetBuffer(CardNonce, sizeof(CardNonce)); + 40b6: 6e 01 movw r12, r28 + 40b8: e7 e0 ldi r30, 0x07 ; 7 + 40ba: ce 0e add r12, r30 + 40bc: d1 1c adc r13, r1 + 40be: 64 e0 ldi r22, 0x04 ; 4 + 40c0: c6 01 movw r24, r12 + 40c2: 0e 94 3f 06 call 0xc7e ; 0xc7e + if (_7BUID) + 40c6: 80 91 c2 28 lds r24, 0x28C2 + MemoryReadBlock(Uid, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + 40ca: 7e 01 movw r14, r28 + uint8_t Uid[4]; + uint8_t CardNonce[4]; + + /* Generate a random nonce and read UID and key from memory */ + RandomGetBuffer(CardNonce, sizeof(CardNonce)); + if (_7BUID) + 40cc: 88 23 and r24, r24 + 40ce: 09 f4 brne .+2 ; 0x40d2 + 40d0: b8 c0 rjmp .+368 ; 0x4242 + MemoryReadBlock(Uid, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + 40d2: fb e0 ldi r31, 0x0B ; 11 + 40d4: ef 0e add r14, r31 + 40d6: f1 1c adc r15, r1 + 40d8: 44 e0 ldi r20, 0x04 ; 4 + 40da: 50 e0 ldi r21, 0x00 ; 0 + 40dc: 63 e0 ldi r22, 0x03 ; 3 + 40de: 70 e0 ldi r23, 0x00 ; 0 + 40e0: c7 01 movw r24, r14 + 40e2: 0e 94 de 06 call 0xdbc ; 0xdbc + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + MemoryReadBlock(Key, KeyAddress, MEM_KEY_SIZE); + 40e6: 46 e0 ldi r20, 0x06 ; 6 + 40e8: 50 e0 ldi r21, 0x00 ; 0 + 40ea: b5 01 movw r22, r10 + 40ec: ce 01 movw r24, r28 + 40ee: 01 96 adiw r24, 0x01 ; 1 + 40f0: 0e 94 de 06 call 0xdbc ; 0xdbc + + /* Precalculate the reader response from card-nonce */ + for (uint8_t i=0; i + + /* Precalculate our response from the reader response */ + for (uint8_t i=0; i + + /* Respond with the random card nonce and expect further authentication + * form the reader in the next frame. */ + State = STATE_AUTHING; + 4140: 87 e0 ldi r24, 0x07 ; 7 + 4142: 80 93 be 28 sts 0x28BE, r24 + + for (uint8_t i=0; i + + return CMD_AUTH_RB_FRAME_SIZE * BITS_PER_BYTE; + 416c: 20 e2 ldi r18, 0x20 ; 32 + 416e: 30 e0 ldi r19, 0x00 ; 0 + 4170: db ca rjmp .-2634 ; 0x3728 + + ValueFromBlock(&ParamValue, Buffer); + ValueFromBlock(&BlockValue, BlockBuffer); + + if (State == STATE_DECREMENT) { + BlockValue -= ParamValue; + 4172: 84 1b sub r24, r20 + 4174: 95 0b sbc r25, r21 + 4176: a6 0b sbc r26, r22 + 4178: b7 0b sbc r27, r23 + 417a: 24 cf rjmp .-440 ; 0x3fc4 + return BitCount; + } else if (Buffer[0] == CMD_HALT) { + /* Halts the tag. According to the ISO14443, the second + * byte is supposed to be 0. */ + if (Buffer[1] == 0) { + if (ISO14443ACheckCRCA(Buffer, CMD_HALT_FRAME_SIZE)) { + 417c: 62 e0 ldi r22, 0x02 ; 2 + 417e: 70 e0 ldi r23, 0x00 ; 0 + 4180: c8 01 movw r24, r16 + 4182: ef d0 rcall .+478 ; 0x4362 + 4184: 81 11 cpse r24, r1 + 4186: ec cc rjmp .-1576 ; 0x3b60 + /* According to ISO14443, we must not send anything + * in order to acknowledge the HALT command. */ + State = STATE_HALT; + return ISO14443A_APP_NO_RESPONSE; + } else { + Buffer[0] = NAK_CRC_ERROR; + 4188: 81 e0 ldi r24, 0x01 ; 1 + 418a: d8 01 movw r26, r16 + 418c: 8c 93 st X, r24 + return ACK_NAK_FRAME_SIZE; + 418e: 24 e0 ldi r18, 0x04 ; 4 + 4190: 30 e0 ldi r19, 0x00 ; 0 + 4192: ca ca rjmp .-2668 ; 0x3728 + } else if (Buffer[0] == CMD_CHINESE_WIPE) { + /* Wipe memory */ + Buffer[0] = ACK_VALUE; + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_READ) { + if (ISO14443ACheckCRCA(Buffer, CMD_READ_FRAME_SIZE)) { + 4194: 62 e0 ldi r22, 0x02 ; 2 + 4196: 70 e0 ldi r23, 0x00 ; 0 + 4198: c8 01 movw r24, r16 + 419a: e3 d0 rcall .+454 ; 0x4362 + 419c: 88 23 and r24, r24 + 419e: a1 f3 breq .-24 ; 0x4188 + /* Read command. Read data from memory and append CRCA. */ + MemoryReadBlock(Buffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + 41a0: f8 01 movw r30, r16 + 41a2: 61 81 ldd r22, Z+1 ; 0x01 + 41a4: f0 e1 ldi r31, 0x10 ; 16 + 41a6: 6f 9f mul r22, r31 + 41a8: b0 01 movw r22, r0 + 41aa: 11 24 eor r1, r1 + 41ac: 40 e1 ldi r20, 0x10 ; 16 + 41ae: 50 e0 ldi r21, 0x00 ; 0 + 41b0: c8 01 movw r24, r16 + 41b2: 0e 94 de 06 call 0xdbc ; 0xdbc + ISO14443AAppendCRCA(Buffer, MEM_BYTES_PER_BLOCK); + 41b6: 60 e1 ldi r22, 0x10 ; 16 + 41b8: 70 e0 ldi r23, 0x00 ; 0 + 41ba: c8 01 movw r24, r16 + 41bc: a3 d0 rcall .+326 ; 0x4304 + + return (CMD_READ_RESPONSE_FRAME_SIZE + ISO14443A_CRCA_SIZE ) + 41be: 20 e9 ldi r18, 0x90 ; 144 + 41c0: 30 e0 ldi r19, 0x00 ; 0 + 41c2: b2 ca rjmp .-2716 ; 0x3728 + + switch (NVB) { + case ISO14443A_NVB_AC_START: + /* Start of anticollision procedure. + * Send whole UID CLn + BCC */ + DataPtr[0] = UidCL[0]; + 41c4: 89 81 ldd r24, Y+1 ; 0x01 + 41c6: f8 01 movw r30, r16 + 41c8: 80 83 st Z, r24 + DataPtr[1] = UidCL[1]; + 41ca: 3a 81 ldd r19, Y+2 ; 0x02 + 41cc: 31 83 std Z+1, r19 ; 0x01 + DataPtr[2] = UidCL[2]; + 41ce: 2b 81 ldd r18, Y+3 ; 0x03 + 41d0: 22 83 std Z+2, r18 ; 0x02 + DataPtr[3] = UidCL[3]; + 41d2: 9c 81 ldd r25, Y+4 ; 0x04 + 41d4: 93 83 std Z+3, r25 ; 0x03 + DataPtr[4] = ISO14443A_CALC_BCC(DataPtr); + 41d6: 83 27 eor r24, r19 + 41d8: 82 27 eor r24, r18 + 41da: 89 27 eor r24, r25 + 41dc: 84 83 std Z+4, r24 ; 0x04 + + *BitCount = ISO14443A_CL_FRAME_SIZE; + 41de: 28 e2 ldi r18, 0x28 ; 40 + 41e0: 30 e0 ldi r19, 0x00 ; 0 + 41e2: a2 ca rjmp .-2748 ; 0x3728 + + switch (NVB) { + case ISO14443A_NVB_AC_START: + /* Start of anticollision procedure. + * Send whole UID CLn + BCC */ + DataPtr[0] = UidCL[0]; + 41e4: f8 01 movw r30, r16 + 41e6: 80 83 st Z, r24 + DataPtr[1] = UidCL[1]; + 41e8: 3a 81 ldd r19, Y+2 ; 0x02 + 41ea: 31 83 std Z+1, r19 ; 0x01 + DataPtr[2] = UidCL[2]; + 41ec: 9b 81 ldd r25, Y+3 ; 0x03 + 41ee: 92 83 std Z+2, r25 ; 0x02 + DataPtr[3] = UidCL[3]; + 41f0: 2c 81 ldd r18, Y+4 ; 0x04 + 41f2: 23 83 std Z+3, r18 ; 0x03 + DataPtr[4] = ISO14443A_CALC_BCC(DataPtr); + 41f4: 93 27 eor r25, r19 + 41f6: 98 27 eor r25, r24 + 41f8: 92 27 eor r25, r18 + 41fa: 94 83 std Z+4, r25 ; 0x04 + + *BitCount = ISO14443A_CL_FRAME_SIZE; + 41fc: 28 e2 ldi r18, 0x28 ; 40 + 41fe: 30 e0 ldi r19, 0x00 ; 0 + 4200: 93 ca rjmp .-2778 ; 0x3728 + + switch (NVB) { + case ISO14443A_NVB_AC_START: + /* Start of anticollision procedure. + * Send whole UID CLn + BCC */ + DataPtr[0] = UidCL[0]; + 4202: 89 81 ldd r24, Y+1 ; 0x01 + 4204: 80 83 st Z, r24 + DataPtr[1] = UidCL[1]; + 4206: 3a 81 ldd r19, Y+2 ; 0x02 + 4208: 31 83 std Z+1, r19 ; 0x01 + DataPtr[2] = UidCL[2]; + 420a: 2b 81 ldd r18, Y+3 ; 0x03 + 420c: 22 83 std Z+2, r18 ; 0x02 + DataPtr[3] = UidCL[3]; + 420e: 9c 81 ldd r25, Y+4 ; 0x04 + 4210: 93 83 std Z+3, r25 ; 0x03 + DataPtr[4] = ISO14443A_CALC_BCC(DataPtr); + 4212: 83 27 eor r24, r19 + 4214: 82 27 eor r24, r18 + 4216: 89 27 eor r24, r25 + 4218: 84 83 std Z+4, r24 ; 0x04 + + *BitCount = ISO14443A_CL_FRAME_SIZE; + 421a: 28 e2 ldi r18, 0x28 ; 40 + 421c: 30 e0 ldi r19, 0x00 ; 0 + 421e: 84 ca rjmp .-2808 ; 0x3728 + /* Generate a random nonce and read UID and key from memory */ + RandomGetBuffer(CardNonce, sizeof(CardNonce)); + if (_7BUID) + MemoryReadBlock(Uid, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + 4220: 9b e0 ldi r25, 0x0B ; 11 + 4222: e9 0e add r14, r25 + 4224: f1 1c adc r15, r1 + 4226: 44 e0 ldi r20, 0x04 ; 4 + 4228: 50 e0 ldi r21, 0x00 ; 0 + 422a: 60 e0 ldi r22, 0x00 ; 0 + 422c: 70 e0 ldi r23, 0x00 ; 0 + 422e: c7 01 movw r24, r14 + 4230: 0e 94 de 06 call 0xdbc ; 0xdbc + 4234: ea cb rjmp .-2092 ; 0x3a0a + /* Setup crypto1 cipher. Discard in-place encrypted CardNonce. */ + Crypto1Setup(Key, Uid, CardNonce); + + return CMD_AUTH_RB_FRAME_SIZE * BITS_PER_BYTE; + } else { + Buffer[0] = NAK_CRC_ERROR; + 4236: 81 e0 ldi r24, 0x01 ; 1 + 4238: f8 01 movw r30, r16 + 423a: 80 83 st Z, r24 + return ACK_NAK_FRAME_SIZE; + 423c: 24 e0 ldi r18, 0x04 ; 4 + 423e: 30 e0 ldi r19, 0x00 ; 0 + 4240: 73 ca rjmp .-2842 ; 0x3728 + /* Generate a random nonce and read UID and key from memory */ + RandomGetBuffer(CardNonce, sizeof(CardNonce)); + if (_7BUID) + MemoryReadBlock(Uid, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + 4242: 3b e0 ldi r19, 0x0B ; 11 + 4244: e3 0e add r14, r19 + 4246: f1 1c adc r15, r1 + 4248: 44 e0 ldi r20, 0x04 ; 4 + 424a: 50 e0 ldi r21, 0x00 ; 0 + 424c: 60 e0 ldi r22, 0x00 ; 0 + 424e: 70 e0 ldi r23, 0x00 ; 0 + 4250: c7 01 movw r24, r14 + 4252: 0e 94 de 06 call 0xdbc ; 0xdbc + 4256: 47 cf rjmp .-370 ; 0x40e6 + return ACK_NAK_FRAME_SIZE; + } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B) ) { + if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { + /* Nested authentication. */ + uint8_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; + uint8_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); + 4258: 60 e3 ldi r22, 0x30 ; 48 + 425a: 70 e0 ldi r23, 0x00 ; 0 + 425c: b8 cb rjmp .-2192 ; 0x39ce + return ACK_NAK_FRAME_SIZE; + } + } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B)) { + if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { + uint8_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; + uint8_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); + 425e: 80 e3 ldi r24, 0x30 ; 48 + 4260: 90 e0 ldi r25, 0x00 ; 0 + 4262: 23 cf rjmp .-442 ; 0x40aa + +00004264 : + /* No response has been sent, when we reach here */ + return ISO14443A_APP_NO_RESPONSE; +} + +void MifareClassicGetUid(ConfigurationUidType Uid) +{ + 4264: cf 93 push r28 + 4266: df 93 push r29 + 4268: ec 01 movw r28, r24 + if (_7BUID) { + 426a: 80 91 c2 28 lds r24, 0x28C2 + 426e: 81 11 cpse r24, r1 + 4270: 09 c0 rjmp .+18 ; 0x4284 + //Uid[0]=0x88; + MemoryReadBlock(&Uid[0], MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE-1); + MemoryReadBlock(&Uid[3], MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + } + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + 4272: 44 e0 ldi r20, 0x04 ; 4 + 4274: 50 e0 ldi r21, 0x00 ; 0 + 4276: 60 e0 ldi r22, 0x00 ; 0 + 4278: 70 e0 ldi r23, 0x00 ; 0 + 427a: ce 01 movw r24, r28 +} + 427c: df 91 pop r29 + 427e: cf 91 pop r28 + //Uid[0]=0x88; + MemoryReadBlock(&Uid[0], MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE-1); + MemoryReadBlock(&Uid[3], MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + } + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + 4280: 0c 94 de 06 jmp 0xdbc ; 0xdbc + +void MifareClassicGetUid(ConfigurationUidType Uid) +{ + if (_7BUID) { + //Uid[0]=0x88; + MemoryReadBlock(&Uid[0], MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE-1); + 4284: 43 e0 ldi r20, 0x03 ; 3 + 4286: 50 e0 ldi r21, 0x00 ; 0 + 4288: 60 e0 ldi r22, 0x00 ; 0 + 428a: 70 e0 ldi r23, 0x00 ; 0 + 428c: ce 01 movw r24, r28 + 428e: 0e 94 de 06 call 0xdbc ; 0xdbc + MemoryReadBlock(&Uid[3], MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + 4292: 44 e0 ldi r20, 0x04 ; 4 + 4294: 50 e0 ldi r21, 0x00 ; 0 + 4296: 63 e0 ldi r22, 0x03 ; 3 + 4298: 70 e0 ldi r23, 0x00 ; 0 + 429a: ce 01 movw r24, r28 + 429c: 03 96 adiw r24, 0x03 ; 3 + } + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); +} + 429e: df 91 pop r29 + 42a0: cf 91 pop r28 +void MifareClassicGetUid(ConfigurationUidType Uid) +{ + if (_7BUID) { + //Uid[0]=0x88; + MemoryReadBlock(&Uid[0], MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE-1); + MemoryReadBlock(&Uid[3], MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + 42a2: 0c 94 de 06 jmp 0xdbc ; 0xdbc + +000042a6 : + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); +} + +void MifareClassicSetUid(ConfigurationUidType Uid) +{ + 42a6: cf 93 push r28 + 42a8: df 93 push r29 + 42aa: 1f 92 push r1 + 42ac: cd b7 in r28, 0x3d ; 61 + 42ae: de b7 in r29, 0x3e ; 62 + if (_7BUID) { + 42b0: 20 91 c2 28 lds r18, 0x28C2 + 42b4: 21 11 cpse r18, r1 + 42b6: 1b c0 rjmp .+54 ; 0x42ee + //Uid[0]=0x88; + MemoryWriteBlock(Uid, MEM_UID_CL1_ADDRESS, ActiveConfiguration.UidSize); + } + else { + uint8_t BCC = Uid[0] ^ Uid[1] ^ Uid[2] ^ Uid[3]; + 42b8: fc 01 movw r30, r24 + 42ba: 21 81 ldd r18, Z+1 ; 0x01 + 42bc: 30 81 ld r19, Z + 42be: 23 27 eor r18, r19 + 42c0: 32 81 ldd r19, Z+2 ; 0x02 + 42c2: 23 27 eor r18, r19 + 42c4: 33 81 ldd r19, Z+3 ; 0x03 + 42c6: 23 27 eor r18, r19 + 42c8: 29 83 std Y+1, r18 ; 0x01 + + MemoryWriteBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + 42ca: 44 e0 ldi r20, 0x04 ; 4 + 42cc: 50 e0 ldi r21, 0x00 ; 0 + 42ce: 60 e0 ldi r22, 0x00 ; 0 + 42d0: 70 e0 ldi r23, 0x00 ; 0 + 42d2: 0e 94 f6 06 call 0xdec ; 0xdec + MemoryWriteBlock(&BCC, MEM_UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE); + 42d6: 41 e0 ldi r20, 0x01 ; 1 + 42d8: 50 e0 ldi r21, 0x00 ; 0 + 42da: 64 e0 ldi r22, 0x04 ; 4 + 42dc: 70 e0 ldi r23, 0x00 ; 0 + 42de: ce 01 movw r24, r28 + 42e0: 01 96 adiw r24, 0x01 ; 1 + 42e2: 0e 94 f6 06 call 0xdec ; 0xdec + } +} + 42e6: 0f 90 pop r0 + 42e8: df 91 pop r29 + 42ea: cf 91 pop r28 + 42ec: 08 95 ret + +void MifareClassicSetUid(ConfigurationUidType Uid) +{ + if (_7BUID) { + //Uid[0]=0x88; + MemoryWriteBlock(Uid, MEM_UID_CL1_ADDRESS, ActiveConfiguration.UidSize); + 42ee: 40 91 05 29 lds r20, 0x2905 + 42f2: 50 e0 ldi r21, 0x00 ; 0 + 42f4: 60 e0 ldi r22, 0x00 ; 0 + 42f6: 70 e0 ldi r23, 0x00 ; 0 + 42f8: 0e 94 f6 06 call 0xdec ; 0xdec + uint8_t BCC = Uid[0] ^ Uid[1] ^ Uid[2] ^ Uid[3]; + + MemoryWriteBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + MemoryWriteBlock(&BCC, MEM_UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE); + } +} + 42fc: 0f 90 pop r0 + 42fe: df 91 pop r29 + 4300: cf 91 pop r28 + 4302: 08 95 ret + +00004304 : + +void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 4304: 61 15 cp r22, r1 + 4306: 71 05 cpc r23, r1 + 4308: 41 f1 breq .+80 ; 0x435a + * Author: skuser + */ + +#include "ISO14443-3A.h" + +void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { + 430a: 68 0f add r22, r24 + 430c: 79 1f adc r23, r25 + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + 430e: fc 01 movw r30, r24 + */ + +#include "ISO14443-3A.h" + +void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { + uint16_t Checksum = 0x6363; + 4310: 23 e6 ldi r18, 0x63 ; 99 + 4312: 33 e6 ldi r19, 0x63 ; 99 + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + uint8_t Byte = *DataPtr++; + 4314: 41 91 ld r20, Z+ + + Byte ^= (uint8_t) (Checksum & 0x00FF); + 4316: 42 27 eor r20, r18 + Byte ^= Byte << 4; + 4318: 50 e1 ldi r21, 0x10 ; 16 + 431a: 45 9f mul r20, r21 + 431c: c0 01 movw r24, r0 + 431e: 11 24 eor r1, r1 + 4320: a4 2f mov r26, r20 + 4322: a8 27 eor r26, r24 + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + 4324: 8a 2f mov r24, r26 + 4326: 90 e0 ldi r25, 0x00 ; 0 + 4328: 58 2f mov r21, r24 + 432a: 44 27 eor r20, r20 + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + 432c: 88 0f add r24, r24 + 432e: 99 1f adc r25, r25 + 4330: 88 0f add r24, r24 + 4332: 99 1f adc r25, r25 + 4334: 88 0f add r24, r24 + 4336: 99 1f adc r25, r25 + uint8_t Byte = *DataPtr++; + + Byte ^= (uint8_t) (Checksum & 0x00FF); + Byte ^= Byte << 4; + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + 4338: 48 27 eor r20, r24 + 433a: 59 27 eor r21, r25 + 433c: 23 2f mov r18, r19 + 433e: 33 27 eor r19, r19 + 4340: 24 27 eor r18, r20 + 4342: 35 27 eor r19, r21 + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + 4344: a2 95 swap r26 + 4346: af 70 andi r26, 0x0F ; 15 + uint8_t Byte = *DataPtr++; + + Byte ^= (uint8_t) (Checksum & 0x00FF); + Byte ^= Byte << 4; + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + 4348: 2a 27 eor r18, r26 + +void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 434a: e6 17 cp r30, r22 + 434c: f7 07 cpc r31, r23 + 434e: 11 f7 brne .-60 ; 0x4314 + 4350: 92 2f mov r25, r18 + 4352: 83 2f mov r24, r19 + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + } + + *DataPtr++ = (Checksum >> 0) & 0x00FF; + 4354: 90 83 st Z, r25 + *DataPtr = (Checksum >> 8) & 0x00FF; + 4356: 81 83 std Z+1, r24 ; 0x01 + 4358: 08 95 ret + +#include "ISO14443-3A.h" + +void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + 435a: fc 01 movw r30, r24 + + while(ByteCount--) { + 435c: 83 e6 ldi r24, 0x63 ; 99 + 435e: 93 e6 ldi r25, 0x63 ; 99 + 4360: f9 cf rjmp .-14 ; 0x4354 + +00004362 : +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) +{ + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 4362: 61 15 cp r22, r1 + 4364: 71 05 cpc r23, r1 + 4366: b1 f1 breq .+108 ; 0x43d4 + + *DataPtr++ = (Checksum >> 0) & 0x00FF; + *DataPtr = (Checksum >> 8) & 0x00FF; +} + +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) + 4368: 68 0f add r22, r24 + 436a: 79 1f adc r23, r25 +{ + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + 436c: fc 01 movw r30, r24 + *DataPtr = (Checksum >> 8) & 0x00FF; +} + +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) +{ + uint16_t Checksum = 0x6363; + 436e: 23 e6 ldi r18, 0x63 ; 99 + 4370: 33 e6 ldi r19, 0x63 ; 99 + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + uint8_t Byte = *DataPtr++; + 4372: 41 91 ld r20, Z+ + + Byte ^= (uint8_t) (Checksum & 0x00FF); + 4374: 42 27 eor r20, r18 + Byte ^= Byte << 4; + 4376: 50 e1 ldi r21, 0x10 ; 16 + 4378: 45 9f mul r20, r21 + 437a: c0 01 movw r24, r0 + 437c: 11 24 eor r1, r1 + 437e: a4 2f mov r26, r20 + 4380: a8 27 eor r26, r24 + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + 4382: 8a 2f mov r24, r26 + 4384: 90 e0 ldi r25, 0x00 ; 0 + 4386: 58 2f mov r21, r24 + 4388: 44 27 eor r20, r20 + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + 438a: 88 0f add r24, r24 + 438c: 99 1f adc r25, r25 + 438e: 88 0f add r24, r24 + 4390: 99 1f adc r25, r25 + 4392: 88 0f add r24, r24 + 4394: 99 1f adc r25, r25 + uint8_t Byte = *DataPtr++; + + Byte ^= (uint8_t) (Checksum & 0x00FF); + Byte ^= Byte << 4; + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + 4396: 48 27 eor r20, r24 + 4398: 59 27 eor r21, r25 + 439a: 23 2f mov r18, r19 + 439c: 33 27 eor r19, r19 + 439e: 24 27 eor r18, r20 + 43a0: 35 27 eor r19, r21 + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + 43a2: a2 95 swap r26 + 43a4: af 70 andi r26, 0x0F ; 15 + uint8_t Byte = *DataPtr++; + + Byte ^= (uint8_t) (Checksum & 0x00FF); + Byte ^= Byte << 4; + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + 43a6: 2a 27 eor r18, r26 +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) +{ + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 43a8: e6 17 cp r30, r22 + 43aa: f7 07 cpc r31, r23 + 43ac: 11 f7 brne .-60 ; 0x4372 + 43ae: a9 01 movw r20, r18 + 43b0: 55 27 eor r21, r21 + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + } + + return (DataPtr[0] == ((Checksum >> 0) & 0xFF)) && (DataPtr[1] == ((Checksum >> 8) & 0xFF)); + 43b2: 80 81 ld r24, Z + 43b4: 90 e0 ldi r25, 0x00 ; 0 + 43b6: 84 17 cp r24, r20 + 43b8: 95 07 cpc r25, r21 + 43ba: 11 f0 breq .+4 ; 0x43c0 + 43bc: 80 e0 ldi r24, 0x00 ; 0 +} + 43be: 08 95 ret + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + } + + return (DataPtr[0] == ((Checksum >> 0) & 0xFF)) && (DataPtr[1] == ((Checksum >> 8) & 0xFF)); + 43c0: 41 81 ldd r20, Z+1 ; 0x01 + 43c2: 50 e0 ldi r21, 0x00 ; 0 + 43c4: 23 2f mov r18, r19 + 43c6: 33 27 eor r19, r19 + 43c8: 81 e0 ldi r24, 0x01 ; 1 + 43ca: 42 17 cp r20, r18 + 43cc: 53 07 cpc r21, r19 + 43ce: b9 f3 breq .-18 ; 0x43be + 43d0: 80 e0 ldi r24, 0x00 ; 0 + 43d2: f5 cf rjmp .-22 ; 0x43be +} + +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) +{ + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + 43d4: fc 01 movw r30, r24 + + while(ByteCount--) { + 43d6: 43 e6 ldi r20, 0x63 ; 99 + 43d8: 50 e0 ldi r21, 0x00 ; 0 + *DataPtr = (Checksum >> 8) & 0x00FF; +} + +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) +{ + uint16_t Checksum = 0x6363; + 43da: 23 e6 ldi r18, 0x63 ; 99 + 43dc: 33 e6 ldi r19, 0x63 ; 99 + 43de: e9 cf rjmp .-46 ; 0x43b2 + +000043e0 : +/* Split Crypto1 state into even and odd bits to speed up the output filter network */ +static uint8_t StateEven[LFSR_SIZE/2] = {0}; +static uint8_t StateOdd[LFSR_SIZE/2] = {0}; + +/* Proceed LFSR by one clock cycle */ +static void Crypto1LFSR(uint8_t In) { + 43e0: cf 93 push r28 + uint8_t Feedback = 0; + + /* Calculate feedback according to LFSR taps. XOR all 6 state bytes + * into a single bit. */ + Feedback ^= StateEven[0] & (uint8_t) (LFSR_MASK_EVEN >> 0); + 43e2: b0 91 df 28 lds r27, 0x28DF + Feedback ^= StateEven[1] & (uint8_t) (LFSR_MASK_EVEN >> 8); + 43e6: c0 91 e0 28 lds r28, 0x28E0 + Feedback ^= StateEven[2] & (uint8_t) (LFSR_MASK_EVEN >> 16); + 43ea: 40 91 e1 28 lds r20, 0x28E1 + + Feedback ^= StateOdd[0] & (uint8_t) (LFSR_MASK_ODD >> 0); + 43ee: a0 91 dc 28 lds r26, 0x28DC + Feedback ^= StateOdd[1] & (uint8_t) (LFSR_MASK_ODD >> 8); + 43f2: f0 91 dd 28 lds r31, 0x28DD + Feedback ^= StateOdd[2] & (uint8_t) (LFSR_MASK_ODD >> 16); + 43f6: e0 91 de 28 lds r30, 0x28DE + uint8_t Feedback = 0; + + /* Calculate feedback according to LFSR taps. XOR all 6 state bytes + * into a single bit. */ + Feedback ^= StateEven[0] & (uint8_t) (LFSR_MASK_EVEN >> 0); + Feedback ^= StateEven[1] & (uint8_t) (LFSR_MASK_EVEN >> 8); + 43fa: 9c 2f mov r25, r28 + 43fc: 90 71 andi r25, 0x10 ; 16 +static void Crypto1LFSR(uint8_t In) { + uint8_t Feedback = 0; + + /* Calculate feedback according to LFSR taps. XOR all 6 state bytes + * into a single bit. */ + Feedback ^= StateEven[0] & (uint8_t) (LFSR_MASK_EVEN >> 0); + 43fe: 2b 2f mov r18, r27 + 4400: 21 7e andi r18, 0xE1 ; 225 + Feedback ^= StateEven[1] & (uint8_t) (LFSR_MASK_EVEN >> 8); + 4402: 92 27 eor r25, r18 + Feedback ^= StateEven[2] & (uint8_t) (LFSR_MASK_EVEN >> 16); + 4404: 24 2f mov r18, r20 + 4406: 20 72 andi r18, 0x20 ; 32 + 4408: 92 27 eor r25, r18 + + Feedback ^= StateOdd[0] & (uint8_t) (LFSR_MASK_ODD >> 0); + 440a: 2a 2f mov r18, r26 + 440c: 24 79 andi r18, 0x94 ; 148 + 440e: 92 27 eor r25, r18 + Feedback ^= StateOdd[1] & (uint8_t) (LFSR_MASK_ODD >> 8); + 4410: 2f 2f mov r18, r31 + 4412: 23 77 andi r18, 0x73 ; 115 + 4414: 92 27 eor r25, r18 + Feedback ^= StateOdd[2] & (uint8_t) (LFSR_MASK_ODD >> 16); + 4416: 2e 2f mov r18, r30 + 4418: 2a 73 andi r18, 0x3A ; 58 + 441a: 92 27 eor r25, r18 + + Feedback ^= Feedback >> 4; + 441c: 39 2f mov r19, r25 + 441e: 32 95 swap r19 + 4420: 3f 70 andi r19, 0x0F ; 15 + 4422: 39 27 eor r19, r25 + Feedback ^= Feedback >> 2; + 4424: 23 2f mov r18, r19 + 4426: 26 95 lsr r18 + 4428: 26 95 lsr r18 + 442a: 23 27 eor r18, r19 + Feedback ^= Feedback >> 1; + 442c: 92 2f mov r25, r18 + 442e: 96 95 lsr r25 + * - the new odd state becomes the old even state right-shifted by 1. + * For shifting the even state, we convert it into a 32 bit int first */ + uint32_t Temp = 0; + Temp |= ((uint32_t) StateEven[0] << 0); + Temp |= ((uint32_t) StateEven[1] << 8); + Temp |= ((uint32_t) StateEven[2] << 16); + 4430: 50 e0 ldi r21, 0x00 ; 0 + 4432: 60 e0 ldi r22, 0x00 ; 0 + 4434: 70 e0 ldi r23, 0x00 ; 0 + 4436: ba 01 movw r22, r20 + 4438: 55 27 eor r21, r21 + 443a: 44 27 eor r20, r20 + * - the new even state becomes the old odd state + * - the new odd state becomes the old even state right-shifted by 1. + * For shifting the even state, we convert it into a 32 bit int first */ + uint32_t Temp = 0; + Temp |= ((uint32_t) StateEven[0] << 0); + Temp |= ((uint32_t) StateEven[1] << 8); + 443c: 5c 2b or r21, r28 + Temp |= ((uint32_t) StateEven[2] << 16); + 443e: 4b 2b or r20, r27 + + /* Proceed LFSR. Try to force compiler not to shift the unneded upper bits. */ + Temp = (Temp >> 1) & 0x00FFFFFF; + 4440: 76 95 lsr r23 + 4442: 67 95 ror r22 + 4444: 57 95 ror r21 + 4446: 47 95 ror r20 + Feedback ^= StateOdd[1] & (uint8_t) (LFSR_MASK_ODD >> 8); + Feedback ^= StateOdd[2] & (uint8_t) (LFSR_MASK_ODD >> 16); + + Feedback ^= Feedback >> 4; + Feedback ^= Feedback >> 2; + Feedback ^= Feedback >> 1; + 4448: 92 27 eor r25, r18 + + /* Proceed LFSR. Try to force compiler not to shift the unneded upper bits. */ + Temp = (Temp >> 1) & 0x00FFFFFF; + + /* Calculate MSBit of even state as input bit to LFSR */ + if ( (Feedback & 0x01) ^ In ) { + 444a: 91 70 andi r25, 0x01 ; 1 + 444c: 98 13 cpse r25, r24 + Temp |= (uint32_t) 1 << (8 * LFSR_SIZE/2 - 1); + 444e: 60 68 ori r22, 0x80 ; 128 + } + + /* Convert even state back into byte array and swap odd/even state + * as explained above. */ + StateEven[0] = StateOdd[0]; + 4450: a0 93 df 28 sts 0x28DF, r26 + StateEven[1] = StateOdd[1]; + 4454: f0 93 e0 28 sts 0x28E0, r31 + StateEven[2] = StateOdd[2]; + 4458: e0 93 e1 28 sts 0x28E1, r30 + + StateOdd[0] = (uint8_t) (Temp >> 0); + 445c: 40 93 dc 28 sts 0x28DC, r20 + StateOdd[1] = (uint8_t) (Temp >> 8); + 4460: 50 93 dd 28 sts 0x28DD, r21 + StateOdd[2] = (uint8_t) (Temp >> 16); + 4464: 60 93 de 28 sts 0x28DE, r22 +} + 4468: cf 91 pop r28 + 446a: 08 95 ret + +0000446c : + +uint8_t Crypto1FilterOutput(void) { + 446c: cf 93 push r28 + 446e: df 93 push r29 + * 5 bits that are used to lookup the output bit. + */ + uint8_t Sum = 0; + + Sum |= TableAB[0][(StateOdd[0] >> 4) & 0x0F]; + Sum |= TableAB[1][(StateOdd[1] >> 0) & 0x0F]; + 4470: c0 91 dd 28 lds r28, 0x28DD + Sum |= TableAB[2][(StateOdd[1] >> 4) & 0x0F]; + Sum |= TableAB[3][(StateOdd[2] >> 0) & 0x0F]; + 4474: 90 91 de 28 lds r25, 0x28DE + 4478: a9 2f mov r26, r25 + 447a: af 70 andi r26, 0x0F ; 15 + 447c: b0 e0 ldi r27, 0x00 ; 0 + 447e: a0 5e subi r26, 0xE0 ; 224 + 4480: bf 4d sbci r27, 0xDF ; 223 + * 5 bits that are used to lookup the output bit. + */ + uint8_t Sum = 0; + + Sum |= TableAB[0][(StateOdd[0] >> 4) & 0x0F]; + Sum |= TableAB[1][(StateOdd[1] >> 0) & 0x0F]; + 4482: ec 2f mov r30, r28 + 4484: ef 70 andi r30, 0x0F ; 15 + 4486: f0 e0 ldi r31, 0x00 ; 0 + 4488: e0 5e subi r30, 0xE0 ; 224 + 448a: ff 4d sbci r31, 0xDF ; 223 + 448c: d0 96 adiw r26, 0x30 ; 48 + 448e: 8c 91 ld r24, X + 4490: 20 89 ldd r18, Z+16 ; 0x10 + 4492: 82 2b or r24, r18 + * can simply be ORed together to produce the resulting + * 5 bits that are used to lookup the output bit. + */ + uint8_t Sum = 0; + + Sum |= TableAB[0][(StateOdd[0] >> 4) & 0x0F]; + 4494: e0 91 dc 28 lds r30, 0x28DC + 4498: e2 95 swap r30 + 449a: ef 70 andi r30, 0x0F ; 15 + 449c: f0 e0 ldi r31, 0x00 ; 0 + 449e: e0 5e subi r30, 0xE0 ; 224 + 44a0: ff 4d sbci r31, 0xDF ; 223 + Sum |= TableAB[1][(StateOdd[1] >> 0) & 0x0F]; + Sum |= TableAB[2][(StateOdd[1] >> 4) & 0x0F]; + 44a2: 20 81 ld r18, Z + 44a4: 82 2b or r24, r18 + 44a6: c2 95 swap r28 + 44a8: cf 70 andi r28, 0x0F ; 15 + 44aa: d0 e0 ldi r29, 0x00 ; 0 + 44ac: c0 5e subi r28, 0xE0 ; 224 + 44ae: df 4d sbci r29, 0xDF ; 223 + Sum |= TableAB[3][(StateOdd[2] >> 0) & 0x0F]; + 44b0: 28 a1 ldd r18, Y+32 ; 0x20 + 44b2: 82 2b or r24, r18 + Sum |= TableAB[4][(StateOdd[2] >> 4) & 0x0F]; + 44b4: 92 95 swap r25 + 44b6: 9f 70 andi r25, 0x0F ; 15 + 44b8: a9 2f mov r26, r25 + 44ba: b0 e0 ldi r27, 0x00 ; 0 + 44bc: a0 5a subi r26, 0xA0 ; 160 + 44be: bf 4d sbci r27, 0xDF ; 223 + 44c0: 9c 91 ld r25, X + 44c2: 89 2b or r24, r25 + + return TableC[Sum]; + 44c4: e8 2f mov r30, r24 + 44c6: f0 e0 ldi r31, 0x00 ; 0 + 44c8: e0 59 subi r30, 0x90 ; 144 + 44ca: ff 4d sbci r31, 0xDF ; 223 +} + 44cc: 80 81 ld r24, Z + 44ce: df 91 pop r29 + 44d0: cf 91 pop r28 + 44d2: 08 95 ret + +000044d4 : + +void Crypto1Setup(uint8_t Key[6], uint8_t Uid[4], uint8_t CardNonce[4]) +{ + 44d4: cf 92 push r12 + 44d6: df 92 push r13 + 44d8: ef 92 push r14 + 44da: ff 92 push r15 + 44dc: 0f 93 push r16 + 44de: 1f 93 push r17 + 44e0: cf 93 push r28 + 44e2: df 93 push r29 + 44e4: fc 01 movw r30, r24 + 44e6: db 01 movw r26, r22 + 44e8: ea 01 movw r28, r20 + * The inner loop generates 8 even and 8 odd bits from 16 key bits and + * the outer loop stores them. */ + for (i=0; i<(LFSR_SIZE/2); i++) { + uint8_t EvenByte = 0; + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + 44ea: 91 81 ldd r25, Z+1 ; 0x01 + 44ec: 80 e0 ldi r24, 0x00 ; 0 + 44ee: 20 81 ld r18, Z + 44f0: 82 2b or r24, r18 + 44f2: 80 fd sbrc r24, 0 + 44f4: 8d c1 rjmp .+794 ; 0x4810 + 44f6: 30 e0 ldi r19, 0x00 ; 0 + 44f8: 81 fd sbrc r24, 1 + 44fa: 88 c1 rjmp .+784 ; 0x480c + 44fc: 20 e0 ldi r18, 0x00 ; 0 + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + } + + KeyWord >>= 2; + 44fe: 96 95 lsr r25 + 4500: 87 95 ror r24 + 4502: 96 95 lsr r25 + 4504: 87 95 ror r24 + for (j=0; j<8; j++) { + EvenByte >>= 1; + OddByte >>= 1; + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 4506: 43 2f mov r20, r19 + 4508: 40 68 ori r20, 0x80 ; 128 + 450a: 80 fd sbrc r24, 0 + 450c: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 450e: 42 2f mov r20, r18 + 4510: 40 68 ori r20, 0x80 ; 128 + 4512: 81 fd sbrc r24, 1 + 4514: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 4516: 96 95 lsr r25 + 4518: 87 95 ror r24 + 451a: 96 95 lsr r25 + 451c: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 451e: 36 95 lsr r19 + OddByte >>= 1; + 4520: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 4522: 43 2f mov r20, r19 + 4524: 40 68 ori r20, 0x80 ; 128 + 4526: 80 fd sbrc r24, 0 + 4528: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 452a: 42 2f mov r20, r18 + 452c: 40 68 ori r20, 0x80 ; 128 + 452e: 81 fd sbrc r24, 1 + 4530: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 4532: 96 95 lsr r25 + 4534: 87 95 ror r24 + 4536: 96 95 lsr r25 + 4538: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 453a: 36 95 lsr r19 + OddByte >>= 1; + 453c: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 453e: 43 2f mov r20, r19 + 4540: 40 68 ori r20, 0x80 ; 128 + 4542: 80 fd sbrc r24, 0 + 4544: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 4546: 42 2f mov r20, r18 + 4548: 40 68 ori r20, 0x80 ; 128 + 454a: 81 fd sbrc r24, 1 + 454c: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 454e: 96 95 lsr r25 + 4550: 87 95 ror r24 + 4552: 96 95 lsr r25 + 4554: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 4556: 36 95 lsr r19 + OddByte >>= 1; + 4558: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 455a: 43 2f mov r20, r19 + 455c: 40 68 ori r20, 0x80 ; 128 + 455e: 80 fd sbrc r24, 0 + 4560: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 4562: 42 2f mov r20, r18 + 4564: 40 68 ori r20, 0x80 ; 128 + 4566: 81 fd sbrc r24, 1 + 4568: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 456a: 96 95 lsr r25 + 456c: 87 95 ror r24 + 456e: 96 95 lsr r25 + 4570: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 4572: 36 95 lsr r19 + OddByte >>= 1; + 4574: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 4576: 43 2f mov r20, r19 + 4578: 40 68 ori r20, 0x80 ; 128 + 457a: 80 fd sbrc r24, 0 + 457c: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 457e: 42 2f mov r20, r18 + 4580: 40 68 ori r20, 0x80 ; 128 + 4582: 81 fd sbrc r24, 1 + 4584: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 4586: 96 95 lsr r25 + 4588: 87 95 ror r24 + 458a: 96 95 lsr r25 + 458c: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 458e: 36 95 lsr r19 + OddByte >>= 1; + 4590: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 4592: 43 2f mov r20, r19 + 4594: 40 68 ori r20, 0x80 ; 128 + 4596: 80 fd sbrc r24, 0 + 4598: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 459a: 42 2f mov r20, r18 + 459c: 40 68 ori r20, 0x80 ; 128 + 459e: 81 fd sbrc r24, 1 + 45a0: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 45a2: 96 95 lsr r25 + 45a4: 87 95 ror r24 + 45a6: 96 95 lsr r25 + 45a8: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 45aa: 36 95 lsr r19 + OddByte >>= 1; + 45ac: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 45ae: 53 2f mov r21, r19 + 45b0: 50 68 ori r21, 0x80 ; 128 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 45b2: 42 2f mov r20, r18 + 45b4: 40 68 ori r20, 0x80 ; 128 + } + + KeyWord >>= 2; + } + + StateEven[i] = EvenByte; + 45b6: 80 fd sbrc r24, 0 + 45b8: 35 2f mov r19, r21 + 45ba: 30 93 df 28 sts 0x28DF, r19 + StateOdd[i] = OddByte; + 45be: 81 fd sbrc r24, 1 + 45c0: 24 2f mov r18, r20 + 45c2: 20 93 dc 28 sts 0x28DC, r18 + * The inner loop generates 8 even and 8 odd bits from 16 key bits and + * the outer loop stores them. */ + for (i=0; i<(LFSR_SIZE/2); i++) { + uint8_t EvenByte = 0; + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + 45c6: 93 81 ldd r25, Z+3 ; 0x03 + 45c8: 80 e0 ldi r24, 0x00 ; 0 + 45ca: 22 81 ldd r18, Z+2 ; 0x02 + 45cc: 82 2b or r24, r18 + 45ce: 80 fd sbrc r24, 0 + 45d0: 1b c1 rjmp .+566 ; 0x4808 + 45d2: 30 e0 ldi r19, 0x00 ; 0 + 45d4: 81 fd sbrc r24, 1 + 45d6: 16 c1 rjmp .+556 ; 0x4804 + 45d8: 20 e0 ldi r18, 0x00 ; 0 + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + } + + KeyWord >>= 2; + 45da: 96 95 lsr r25 + 45dc: 87 95 ror r24 + 45de: 96 95 lsr r25 + 45e0: 87 95 ror r24 + for (j=0; j<8; j++) { + EvenByte >>= 1; + OddByte >>= 1; + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 45e2: 43 2f mov r20, r19 + 45e4: 40 68 ori r20, 0x80 ; 128 + 45e6: 80 fd sbrc r24, 0 + 45e8: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 45ea: 42 2f mov r20, r18 + 45ec: 40 68 ori r20, 0x80 ; 128 + 45ee: 81 fd sbrc r24, 1 + 45f0: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 45f2: 96 95 lsr r25 + 45f4: 87 95 ror r24 + 45f6: 96 95 lsr r25 + 45f8: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 45fa: 36 95 lsr r19 + OddByte >>= 1; + 45fc: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 45fe: 43 2f mov r20, r19 + 4600: 40 68 ori r20, 0x80 ; 128 + 4602: 80 fd sbrc r24, 0 + 4604: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 4606: 42 2f mov r20, r18 + 4608: 40 68 ori r20, 0x80 ; 128 + 460a: 81 fd sbrc r24, 1 + 460c: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 460e: 96 95 lsr r25 + 4610: 87 95 ror r24 + 4612: 96 95 lsr r25 + 4614: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 4616: 36 95 lsr r19 + OddByte >>= 1; + 4618: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 461a: 43 2f mov r20, r19 + 461c: 40 68 ori r20, 0x80 ; 128 + 461e: 80 fd sbrc r24, 0 + 4620: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 4622: 42 2f mov r20, r18 + 4624: 40 68 ori r20, 0x80 ; 128 + 4626: 81 fd sbrc r24, 1 + 4628: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 462a: 96 95 lsr r25 + 462c: 87 95 ror r24 + 462e: 96 95 lsr r25 + 4630: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 4632: 36 95 lsr r19 + OddByte >>= 1; + 4634: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 4636: 43 2f mov r20, r19 + 4638: 40 68 ori r20, 0x80 ; 128 + 463a: 80 fd sbrc r24, 0 + 463c: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 463e: 42 2f mov r20, r18 + 4640: 40 68 ori r20, 0x80 ; 128 + 4642: 81 fd sbrc r24, 1 + 4644: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 4646: 96 95 lsr r25 + 4648: 87 95 ror r24 + 464a: 96 95 lsr r25 + 464c: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 464e: 36 95 lsr r19 + OddByte >>= 1; + 4650: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 4652: 43 2f mov r20, r19 + 4654: 40 68 ori r20, 0x80 ; 128 + 4656: 80 fd sbrc r24, 0 + 4658: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 465a: 42 2f mov r20, r18 + 465c: 40 68 ori r20, 0x80 ; 128 + 465e: 81 fd sbrc r24, 1 + 4660: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 4662: 96 95 lsr r25 + 4664: 87 95 ror r24 + 4666: 96 95 lsr r25 + 4668: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 466a: 36 95 lsr r19 + OddByte >>= 1; + 466c: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 466e: 43 2f mov r20, r19 + 4670: 40 68 ori r20, 0x80 ; 128 + 4672: 80 fd sbrc r24, 0 + 4674: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 4676: 42 2f mov r20, r18 + 4678: 40 68 ori r20, 0x80 ; 128 + 467a: 81 fd sbrc r24, 1 + 467c: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 467e: 96 95 lsr r25 + 4680: 87 95 ror r24 + 4682: 96 95 lsr r25 + 4684: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 4686: 36 95 lsr r19 + OddByte >>= 1; + 4688: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 468a: 53 2f mov r21, r19 + 468c: 50 68 ori r21, 0x80 ; 128 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 468e: 42 2f mov r20, r18 + 4690: 40 68 ori r20, 0x80 ; 128 + } + + KeyWord >>= 2; + } + + StateEven[i] = EvenByte; + 4692: 80 fd sbrc r24, 0 + 4694: 35 2f mov r19, r21 + 4696: 30 93 e0 28 sts 0x28E0, r19 + StateOdd[i] = OddByte; + 469a: 81 fd sbrc r24, 1 + 469c: 24 2f mov r18, r20 + 469e: 20 93 dd 28 sts 0x28DD, r18 + * The inner loop generates 8 even and 8 odd bits from 16 key bits and + * the outer loop stores them. */ + for (i=0; i<(LFSR_SIZE/2); i++) { + uint8_t EvenByte = 0; + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + 46a2: 95 81 ldd r25, Z+5 ; 0x05 + 46a4: 80 e0 ldi r24, 0x00 ; 0 + 46a6: 24 81 ldd r18, Z+4 ; 0x04 + 46a8: 82 2b or r24, r18 + 46aa: 80 fd sbrc r24, 0 + 46ac: a9 c0 rjmp .+338 ; 0x4800 + 46ae: 30 e0 ldi r19, 0x00 ; 0 + 46b0: 81 fd sbrc r24, 1 + 46b2: a4 c0 rjmp .+328 ; 0x47fc + 46b4: 20 e0 ldi r18, 0x00 ; 0 + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + } + + KeyWord >>= 2; + 46b6: 96 95 lsr r25 + 46b8: 87 95 ror r24 + 46ba: 96 95 lsr r25 + 46bc: 87 95 ror r24 + for (j=0; j<8; j++) { + EvenByte >>= 1; + OddByte >>= 1; + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 46be: 43 2f mov r20, r19 + 46c0: 40 68 ori r20, 0x80 ; 128 + 46c2: 80 fd sbrc r24, 0 + 46c4: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 46c6: 42 2f mov r20, r18 + 46c8: 40 68 ori r20, 0x80 ; 128 + 46ca: 81 fd sbrc r24, 1 + 46cc: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 46ce: 96 95 lsr r25 + 46d0: 87 95 ror r24 + 46d2: 96 95 lsr r25 + 46d4: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 46d6: 36 95 lsr r19 + OddByte >>= 1; + 46d8: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 46da: 43 2f mov r20, r19 + 46dc: 40 68 ori r20, 0x80 ; 128 + 46de: 80 fd sbrc r24, 0 + 46e0: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 46e2: 42 2f mov r20, r18 + 46e4: 40 68 ori r20, 0x80 ; 128 + 46e6: 81 fd sbrc r24, 1 + 46e8: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 46ea: 96 95 lsr r25 + 46ec: 87 95 ror r24 + 46ee: 96 95 lsr r25 + 46f0: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 46f2: 36 95 lsr r19 + OddByte >>= 1; + 46f4: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 46f6: 43 2f mov r20, r19 + 46f8: 40 68 ori r20, 0x80 ; 128 + 46fa: 80 fd sbrc r24, 0 + 46fc: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 46fe: 42 2f mov r20, r18 + 4700: 40 68 ori r20, 0x80 ; 128 + 4702: 81 fd sbrc r24, 1 + 4704: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 4706: 96 95 lsr r25 + 4708: 87 95 ror r24 + 470a: 96 95 lsr r25 + 470c: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 470e: 36 95 lsr r19 + OddByte >>= 1; + 4710: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 4712: 43 2f mov r20, r19 + 4714: 40 68 ori r20, 0x80 ; 128 + 4716: 80 fd sbrc r24, 0 + 4718: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 471a: 42 2f mov r20, r18 + 471c: 40 68 ori r20, 0x80 ; 128 + 471e: 81 fd sbrc r24, 1 + 4720: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 4722: 96 95 lsr r25 + 4724: 87 95 ror r24 + 4726: 96 95 lsr r25 + 4728: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 472a: 36 95 lsr r19 + OddByte >>= 1; + 472c: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 472e: 43 2f mov r20, r19 + 4730: 40 68 ori r20, 0x80 ; 128 + 4732: 80 fd sbrc r24, 0 + 4734: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 4736: 42 2f mov r20, r18 + 4738: 40 68 ori r20, 0x80 ; 128 + 473a: 81 fd sbrc r24, 1 + 473c: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 473e: 96 95 lsr r25 + 4740: 87 95 ror r24 + 4742: 96 95 lsr r25 + 4744: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 4746: 36 95 lsr r19 + OddByte >>= 1; + 4748: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 474a: 43 2f mov r20, r19 + 474c: 40 68 ori r20, 0x80 ; 128 + 474e: 80 fd sbrc r24, 0 + 4750: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 4752: 42 2f mov r20, r18 + 4754: 40 68 ori r20, 0x80 ; 128 + 4756: 81 fd sbrc r24, 1 + 4758: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 475a: 96 95 lsr r25 + 475c: 87 95 ror r24 + 475e: 96 95 lsr r25 + 4760: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 4762: 36 95 lsr r19 + OddByte >>= 1; + 4764: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 4766: 53 2f mov r21, r19 + 4768: 50 68 ori r21, 0x80 ; 128 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 476a: 42 2f mov r20, r18 + 476c: 40 68 ori r20, 0x80 ; 128 + } + + KeyWord >>= 2; + } + + StateEven[i] = EvenByte; + 476e: 80 fd sbrc r24, 0 + 4770: 35 2f mov r19, r21 + 4772: 30 93 e1 28 sts 0x28E1, r19 + StateOdd[i] = OddByte; + 4776: 81 fd sbrc r24, 1 + 4778: 24 2f mov r18, r20 + 477a: 20 93 de 28 sts 0x28DE, r18 + /* Use Uid XOR CardNonce as feed-in and do 32 clocks on the + * Crypto1 LFSR.*/ + uint32_t Temp = 0; + + Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; + Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; + 477e: 89 81 ldd r24, Y+1 ; 0x01 + 4780: 11 96 adiw r26, 0x01 ; 1 + 4782: 9c 91 ld r25, X + 4784: 11 97 sbiw r26, 0x01 ; 1 + 4786: 89 27 eor r24, r25 + Temp |= (uint32_t) (Uid[2] ^ CardNonce[2]) << 16; + 4788: ca 80 ldd r12, Y+2 ; 0x02 + 478a: 12 96 adiw r26, 0x02 ; 2 + 478c: 9c 91 ld r25, X + 478e: 12 97 sbiw r26, 0x02 ; 2 + 4790: c9 26 eor r12, r25 + 4792: d1 2c mov r13, r1 + 4794: e1 2c mov r14, r1 + 4796: f1 2c mov r15, r1 + 4798: 76 01 movw r14, r12 + 479a: dd 24 eor r13, r13 + 479c: cc 24 eor r12, r12 + /* Use Uid XOR CardNonce as feed-in and do 32 clocks on the + * Crypto1 LFSR.*/ + uint32_t Temp = 0; + + Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; + Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; + 479e: d8 2a or r13, r24 + + /* Use Uid XOR CardNonce as feed-in and do 32 clocks on the + * Crypto1 LFSR.*/ + uint32_t Temp = 0; + + Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; + 47a0: 88 81 ld r24, Y + 47a2: 9c 91 ld r25, X + 47a4: 89 27 eor r24, r25 + Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; + Temp |= (uint32_t) (Uid[2] ^ CardNonce[2]) << 16; + 47a6: c8 2a or r12, r24 + Temp |= (uint32_t) (Uid[3] ^ CardNonce[3]) << 24; + 47a8: 8b 81 ldd r24, Y+3 ; 0x03 + 47aa: 13 96 adiw r26, 0x03 ; 3 + 47ac: 9c 91 ld r25, X + 47ae: 89 27 eor r24, r25 + 47b0: f8 2a or r15, r24 + 47b2: 10 e2 ldi r17, 0x20 ; 32 + + for (i=0; i<32; i++) { + uint8_t Out = Crypto1FilterOutput(); + 47b4: 5b de rcall .-842 ; 0x446c + 47b6: 08 2f mov r16, r24 + + Crypto1LFSR(Temp & 0x01); + 47b8: 8c 2d mov r24, r12 + 47ba: 81 70 andi r24, 0x01 ; 1 + 47bc: 11 de rcall .-990 ; 0x43e0 + Temp >>= 1; + 47be: f6 94 lsr r15 + 47c0: e7 94 ror r14 + 47c2: d7 94 ror r13 + 47c4: c7 94 ror r12 + + /* Store the keystream for later use */ + if (Out) { + 47c6: 00 23 and r16, r16 + 47c8: 11 f0 breq .+4 ; 0x47ce + Temp |= (uint32_t) 1 << 31; + 47ca: 68 94 set + 47cc: f7 f8 bld r15, 7 + 47ce: 11 50 subi r17, 0x01 ; 1 + Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; + Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; + Temp |= (uint32_t) (Uid[2] ^ CardNonce[2]) << 16; + Temp |= (uint32_t) (Uid[3] ^ CardNonce[3]) << 24; + + for (i=0; i<32; i++) { + 47d0: 89 f7 brne .-30 ; 0x47b4 + } + + /* Crypto1 state register is now set up to be used for authentication. + * In case of nested authentication, we need to use the produced keystream + * to encrypt the CardNonce. For this case we do the encryption in-place. */ + CardNonce[0] ^= (uint8_t) (Temp >> 0); + 47d2: 88 81 ld r24, Y + 47d4: 8c 25 eor r24, r12 + 47d6: 88 83 st Y, r24 + CardNonce[1] ^= (uint8_t) (Temp >> 8); + 47d8: 89 81 ldd r24, Y+1 ; 0x01 + 47da: 8d 25 eor r24, r13 + 47dc: 89 83 std Y+1, r24 ; 0x01 + CardNonce[2] ^= (uint8_t) (Temp >> 16); + 47de: 8a 81 ldd r24, Y+2 ; 0x02 + 47e0: 8e 25 eor r24, r14 + 47e2: 8a 83 std Y+2, r24 ; 0x02 + CardNonce[3] ^= (uint8_t) (Temp >> 24); + 47e4: 8b 81 ldd r24, Y+3 ; 0x03 + 47e6: 8f 25 eor r24, r15 + 47e8: 8b 83 std Y+3, r24 ; 0x03 +} + 47ea: df 91 pop r29 + 47ec: cf 91 pop r28 + 47ee: 1f 91 pop r17 + 47f0: 0f 91 pop r16 + 47f2: ff 90 pop r15 + 47f4: ef 90 pop r14 + 47f6: df 90 pop r13 + 47f8: cf 90 pop r12 + 47fa: 08 95 ret + 47fc: 20 e4 ldi r18, 0x40 ; 64 + 47fe: 5b cf rjmp .-330 ; 0x46b6 + 4800: 30 e4 ldi r19, 0x40 ; 64 + 4802: 56 cf rjmp .-340 ; 0x46b0 + 4804: 20 e4 ldi r18, 0x40 ; 64 + 4806: e9 ce rjmp .-558 ; 0x45da + 4808: 30 e4 ldi r19, 0x40 ; 64 + 480a: e4 ce rjmp .-568 ; 0x45d4 + 480c: 20 e4 ldi r18, 0x40 ; 64 + 480e: 77 ce rjmp .-786 ; 0x44fe + 4810: 30 e4 ldi r19, 0x40 ; 64 + 4812: 72 ce rjmp .-796 ; 0x44f8 + +00004814 : + +void Crypto1Auth(uint8_t EncryptedReaderNonce[4]) +{ + 4814: cf 92 push r12 + 4816: df 92 push r13 + 4818: ef 92 push r14 + 481a: ff 92 push r15 + 481c: cf 93 push r28 + 481e: fc 01 movw r30, r24 + uint32_t Temp = 0; + + /* For ease of processing, we convert the encrypted reader nonce + * into a 32 bit integer */ + Temp |= (uint32_t) EncryptedReaderNonce[0] << 0; + Temp |= (uint32_t) EncryptedReaderNonce[1] << 8; + 4820: 81 81 ldd r24, Z+1 ; 0x01 + Temp |= (uint32_t) EncryptedReaderNonce[2] << 16; + 4822: c2 80 ldd r12, Z+2 ; 0x02 + 4824: d1 2c mov r13, r1 + 4826: e1 2c mov r14, r1 + 4828: f1 2c mov r15, r1 + 482a: 76 01 movw r14, r12 + 482c: dd 24 eor r13, r13 + 482e: cc 24 eor r12, r12 + uint32_t Temp = 0; + + /* For ease of processing, we convert the encrypted reader nonce + * into a 32 bit integer */ + Temp |= (uint32_t) EncryptedReaderNonce[0] << 0; + Temp |= (uint32_t) EncryptedReaderNonce[1] << 8; + 4830: d8 2a or r13, r24 +{ + uint32_t Temp = 0; + + /* For ease of processing, we convert the encrypted reader nonce + * into a 32 bit integer */ + Temp |= (uint32_t) EncryptedReaderNonce[0] << 0; + 4832: 80 81 ld r24, Z + Temp |= (uint32_t) EncryptedReaderNonce[1] << 8; + Temp |= (uint32_t) EncryptedReaderNonce[2] << 16; + 4834: c8 2a or r12, r24 + Temp |= (uint32_t) EncryptedReaderNonce[3] << 24; + 4836: 83 81 ldd r24, Z+3 ; 0x03 + 4838: f8 2a or r15, r24 + 483a: c0 e2 ldi r28, 0x20 ; 32 + uint8_t i; + + for (i=0; i<32; i++) { + /* Decrypt one output bit of the given encrypted nonce using the + * filter output as keystream. */ + uint8_t Out = Crypto1FilterOutput(); + 483c: 17 de rcall .-978 ; 0x446c + uint8_t Bit = Out ^ (Temp & 0x01); + 483e: b7 01 movw r22, r14 + 4840: a6 01 movw r20, r12 + 4842: 41 70 andi r20, 0x01 ; 1 + 4844: 55 27 eor r21, r21 + 4846: 66 27 eor r22, r22 + 4848: 77 27 eor r23, r23 + + /* Feed back the bit to load the LFSR with the (decrypted) nonce */ + Crypto1LFSR(Bit); + 484a: 84 27 eor r24, r20 + 484c: c9 dd rcall .-1134 ; 0x43e0 + Temp >>= 1; + 484e: f6 94 lsr r15 + 4850: e7 94 ror r14 + 4852: d7 94 ror r13 + 4854: c7 94 ror r12 + 4856: c1 50 subi r28, 0x01 ; 1 + Temp |= (uint32_t) EncryptedReaderNonce[2] << 16; + Temp |= (uint32_t) EncryptedReaderNonce[3] << 24; + + uint8_t i; + + for (i=0; i<32; i++) { + 4858: 89 f7 brne .-30 ; 0x483c + + /* Feed back the bit to load the LFSR with the (decrypted) nonce */ + Crypto1LFSR(Bit); + Temp >>= 1; + } +} + 485a: cf 91 pop r28 + 485c: ff 90 pop r15 + 485e: ef 90 pop r14 + 4860: df 90 pop r13 + 4862: cf 90 pop r12 + 4864: 08 95 ret + +00004866 : + +uint8_t Crypto1Byte(void) +{ + 4866: cf 93 push r28 + 4868: df 93 push r29 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 486a: 00 de rcall .-1024 ; 0x446c + 486c: c8 2f mov r28, r24 + Crypto1LFSR(0); + 486e: 80 e0 ldi r24, 0x00 ; 0 + 4870: b7 dd rcall .-1170 ; 0x43e0 + + /* Store keystream bit */ + KeyStream >>= 1; + + if (Out) { + 4872: cc 23 and r28, r28 + 4874: 09 f4 brne .+2 ; 0x4878 + 4876: 36 c0 rjmp .+108 ; 0x48e4 + KeyStream |= (1<<7); + 4878: c0 e8 ldi r28, 0x80 ; 128 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 487a: f8 dd rcall .-1040 ; 0x446c + 487c: d8 2f mov r29, r24 + Crypto1LFSR(0); + 487e: 80 e0 ldi r24, 0x00 ; 0 + 4880: af dd rcall .-1186 ; 0x43e0 + + /* Store keystream bit */ + KeyStream >>= 1; + 4882: c6 95 lsr r28 + + if (Out) { + 4884: d1 11 cpse r29, r1 + KeyStream |= (1<<7); + 4886: c0 68 ori r28, 0x80 ; 128 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 4888: f1 dd rcall .-1054 ; 0x446c + 488a: d8 2f mov r29, r24 + Crypto1LFSR(0); + 488c: 80 e0 ldi r24, 0x00 ; 0 + 488e: a8 dd rcall .-1200 ; 0x43e0 + + /* Store keystream bit */ + KeyStream >>= 1; + 4890: c6 95 lsr r28 + + if (Out) { + 4892: d1 11 cpse r29, r1 + KeyStream |= (1<<7); + 4894: c0 68 ori r28, 0x80 ; 128 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 4896: ea dd rcall .-1068 ; 0x446c + 4898: d8 2f mov r29, r24 + Crypto1LFSR(0); + 489a: 80 e0 ldi r24, 0x00 ; 0 + 489c: a1 dd rcall .-1214 ; 0x43e0 + + /* Store keystream bit */ + KeyStream >>= 1; + 489e: c6 95 lsr r28 + + if (Out) { + 48a0: d1 11 cpse r29, r1 + KeyStream |= (1<<7); + 48a2: c0 68 ori r28, 0x80 ; 128 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 48a4: e3 dd rcall .-1082 ; 0x446c + 48a6: d8 2f mov r29, r24 + Crypto1LFSR(0); + 48a8: 80 e0 ldi r24, 0x00 ; 0 + 48aa: 9a dd rcall .-1228 ; 0x43e0 + + /* Store keystream bit */ + KeyStream >>= 1; + 48ac: c6 95 lsr r28 + + if (Out) { + 48ae: d1 11 cpse r29, r1 + KeyStream |= (1<<7); + 48b0: c0 68 ori r28, 0x80 ; 128 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 48b2: dc dd rcall .-1096 ; 0x446c + 48b4: d8 2f mov r29, r24 + Crypto1LFSR(0); + 48b6: 80 e0 ldi r24, 0x00 ; 0 + 48b8: 93 dd rcall .-1242 ; 0x43e0 + + /* Store keystream bit */ + KeyStream >>= 1; + 48ba: c6 95 lsr r28 + + if (Out) { + 48bc: d1 11 cpse r29, r1 + KeyStream |= (1<<7); + 48be: c0 68 ori r28, 0x80 ; 128 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 48c0: d5 dd rcall .-1110 ; 0x446c + 48c2: d8 2f mov r29, r24 + Crypto1LFSR(0); + 48c4: 80 e0 ldi r24, 0x00 ; 0 + 48c6: 8c dd rcall .-1256 ; 0x43e0 + + /* Store keystream bit */ + KeyStream >>= 1; + 48c8: c6 95 lsr r28 + + if (Out) { + 48ca: d1 11 cpse r29, r1 + KeyStream |= (1<<7); + 48cc: c0 68 ori r28, 0x80 ; 128 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 48ce: ce dd rcall .-1124 ; 0x446c + 48d0: d8 2f mov r29, r24 + Crypto1LFSR(0); + 48d2: 80 e0 ldi r24, 0x00 ; 0 + 48d4: 85 dd rcall .-1270 ; 0x43e0 + + /* Store keystream bit */ + KeyStream >>= 1; + 48d6: 8c 2f mov r24, r28 + 48d8: 86 95 lsr r24 + + if (Out) { + 48da: d1 11 cpse r29, r1 + KeyStream |= (1<<7); + 48dc: 80 68 ori r24, 0x80 ; 128 + } + } + + return KeyStream; +} + 48de: df 91 pop r29 + 48e0: cf 91 pop r28 + 48e2: 08 95 ret + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + Crypto1LFSR(0); + + /* Store keystream bit */ + KeyStream >>= 1; + 48e4: c0 e0 ldi r28, 0x00 ; 0 + 48e6: c9 cf rjmp .-110 ; 0x487a + +000048e8 : + + return KeyStream; +} + +uint8_t Crypto1Nibble(void) +{ + 48e8: cf 93 push r28 + 48ea: df 93 push r29 + /* Generate 4 keystream-bits */ + for (i=0; i<4; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 48ec: bf dd rcall .-1154 ; 0x446c + 48ee: c8 2f mov r28, r24 + Crypto1LFSR(0); + 48f0: 80 e0 ldi r24, 0x00 ; 0 + 48f2: 76 dd rcall .-1300 ; 0x43e0 + + /* Store keystream bit */ + KeyStream >>= 1; + + if (Out) { + 48f4: cc 23 and r28, r28 + 48f6: d1 f0 breq .+52 ; 0x492c + KeyStream |= (1<<3); + 48f8: c8 e0 ldi r28, 0x08 ; 8 + /* Generate 4 keystream-bits */ + for (i=0; i<4; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 48fa: b8 dd rcall .-1168 ; 0x446c + 48fc: d8 2f mov r29, r24 + Crypto1LFSR(0); + 48fe: 80 e0 ldi r24, 0x00 ; 0 + 4900: 6f dd rcall .-1314 ; 0x43e0 + + /* Store keystream bit */ + KeyStream >>= 1; + 4902: c6 95 lsr r28 + + if (Out) { + 4904: d1 11 cpse r29, r1 + KeyStream |= (1<<3); + 4906: c8 60 ori r28, 0x08 ; 8 + /* Generate 4 keystream-bits */ + for (i=0; i<4; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 4908: b1 dd rcall .-1182 ; 0x446c + 490a: d8 2f mov r29, r24 + Crypto1LFSR(0); + 490c: 80 e0 ldi r24, 0x00 ; 0 + 490e: 68 dd rcall .-1328 ; 0x43e0 + + /* Store keystream bit */ + KeyStream >>= 1; + 4910: c6 95 lsr r28 + + if (Out) { + 4912: d1 11 cpse r29, r1 + KeyStream |= (1<<3); + 4914: c8 60 ori r28, 0x08 ; 8 + /* Generate 4 keystream-bits */ + for (i=0; i<4; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 4916: aa dd rcall .-1196 ; 0x446c + 4918: d8 2f mov r29, r24 + Crypto1LFSR(0); + 491a: 80 e0 ldi r24, 0x00 ; 0 + 491c: 61 dd rcall .-1342 ; 0x43e0 + + /* Store keystream bit */ + KeyStream >>= 1; + 491e: 8c 2f mov r24, r28 + 4920: 86 95 lsr r24 + + if (Out) { + 4922: d1 11 cpse r29, r1 + KeyStream |= (1<<3); + 4924: 88 60 ori r24, 0x08 ; 8 + } + } + + return KeyStream; +} + 4926: df 91 pop r29 + 4928: cf 91 pop r28 + 492a: 08 95 ret + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + Crypto1LFSR(0); + + /* Store keystream bit */ + KeyStream >>= 1; + 492c: c0 e0 ldi r28, 0x00 ; 0 + 492e: e5 cf rjmp .-54 ; 0x48fa + +00004930 : + + return KeyStream; +} + +void Crypto1PRNG(uint8_t State[4], uint16_t ClockCount) +{ + 4930: 6f 92 push r6 + 4932: 7f 92 push r7 + 4934: 8f 92 push r8 + 4936: 9f 92 push r9 + 4938: af 92 push r10 + 493a: bf 92 push r11 + 493c: cf 92 push r12 + 493e: df 92 push r13 + 4940: ef 92 push r14 + 4942: ff 92 push r15 + 4944: 0f 93 push r16 + 4946: 1f 93 push r17 + 4948: cf 93 push r28 + 494a: df 93 push r29 + 494c: 3c 01 movw r6, r24 + while(ClockCount--) { + 494e: cb 01 movw r24, r22 + 4950: 01 97 sbiw r24, 0x01 ; 1 + 4952: 67 2b or r22, r23 + 4954: c9 f1 breq .+114 ; 0x49c8 + 4956: f3 01 movw r30, r6 + 4958: a2 81 ldd r26, Z+2 ; 0x02 + 495a: c0 81 ld r28, Z + 495c: b1 81 ldd r27, Z+1 ; 0x01 + 495e: d3 81 ldd r29, Z+3 ; 0x03 + * XOR all tapped bits to a single feedback bit. */ + uint8_t Feedback = 0; + + Feedback ^= State[0] & (uint8_t) (PRNG_MASK >> 0); + Feedback ^= State[1] & (uint8_t) (PRNG_MASK >> 8); + Feedback ^= State[2] & (uint8_t) (PRNG_MASK >> 16); + 4960: 2a 2f mov r18, r26 + 4962: 2d 72 andi r18, 0x2D ; 45 + Feedback ^= State[3] & (uint8_t) (PRNG_MASK >> 24); + + Feedback ^= Feedback >> 4; + 4964: 32 2f mov r19, r18 + 4966: 32 95 swap r19 + 4968: 3f 70 andi r19, 0x0F ; 15 + 496a: 32 27 eor r19, r18 + Feedback ^= Feedback >> 2; + 496c: 23 2f mov r18, r19 + 496e: 26 95 lsr r18 + 4970: 26 95 lsr r18 + 4972: 23 27 eor r18, r19 + Feedback ^= Feedback >> 1; + 4974: 32 2f mov r19, r18 + 4976: 36 95 lsr r19 + uint32_t Temp = 0; + + Temp |= (uint32_t) State[0] << 0; + Temp |= (uint32_t) State[1] << 8; + Temp |= (uint32_t) State[2] << 16; + Temp |= (uint32_t) State[3] << 24; + 4978: 4d 2f mov r20, r29 + 497a: 50 e0 ldi r21, 0x00 ; 0 + 497c: 60 e0 ldi r22, 0x00 ; 0 + 497e: 70 e0 ldi r23, 0x00 ; 0 + 4980: 74 2f mov r23, r20 + 4982: 66 27 eor r22, r22 + 4984: 55 27 eor r21, r21 + 4986: 44 27 eor r20, r20 + + /* For ease of processing convert the state into a 32 bit integer first */ + uint32_t Temp = 0; + + Temp |= (uint32_t) State[0] << 0; + Temp |= (uint32_t) State[1] << 8; + 4988: 5b 2b or r21, r27 + Temp |= (uint32_t) State[2] << 16; + 498a: 4c 2b or r20, r28 + Temp |= (uint32_t) State[3] << 24; + 498c: 6a 2b or r22, r26 + + /* Cycle LFSR and feed back. */ + Temp >>= 1; + 498e: 76 95 lsr r23 + 4990: 67 95 ror r22 + 4992: 57 95 ror r21 + 4994: 47 95 ror r20 + Feedback ^= State[2] & (uint8_t) (PRNG_MASK >> 16); + Feedback ^= State[3] & (uint8_t) (PRNG_MASK >> 24); + + Feedback ^= Feedback >> 4; + Feedback ^= Feedback >> 2; + Feedback ^= Feedback >> 1; + 4996: 32 27 eor r19, r18 + Temp |= (uint32_t) State[3] << 24; + + /* Cycle LFSR and feed back. */ + Temp >>= 1; + + if (Feedback & 0x01) { + 4998: 30 fd sbrc r19, 0 + Temp |= (uint32_t) 1 << (8 * PRNG_SIZE - 1); + 499a: 70 68 ori r23, 0x80 ; 128 + } + + /* Store back state */ + State[0] = (uint8_t) (Temp >> 0); + 499c: c4 2f mov r28, r20 + State[1] = (uint8_t) (Temp >> 8); + 499e: 85 2e mov r8, r21 + 49a0: 96 2e mov r9, r22 + 49a2: a7 2e mov r10, r23 + 49a4: bb 24 eor r11, r11 + 49a6: b8 2d mov r27, r8 + State[2] = (uint8_t) (Temp >> 16); + 49a8: 6b 01 movw r12, r22 + 49aa: ee 24 eor r14, r14 + 49ac: ff 24 eor r15, r15 + 49ae: ac 2d mov r26, r12 + State[3] = (uint8_t) (Temp >> 24); + 49b0: 07 2f mov r16, r23 + 49b2: 11 27 eor r17, r17 + 49b4: 22 27 eor r18, r18 + 49b6: 33 27 eor r19, r19 + 49b8: d0 2f mov r29, r16 + return KeyStream; +} + +void Crypto1PRNG(uint8_t State[4], uint16_t ClockCount) +{ + while(ClockCount--) { + 49ba: 01 97 sbiw r24, 0x01 ; 1 + 49bc: 88 f6 brcc .-94 ; 0x4960 + 49be: f3 01 movw r30, r6 + 49c0: 40 83 st Z, r20 + 49c2: 81 82 std Z+1, r8 ; 0x01 + 49c4: c2 82 std Z+2, r12 ; 0x02 + 49c6: 03 83 std Z+3, r16 ; 0x03 + State[2] = (uint8_t) (Temp >> 16); + State[3] = (uint8_t) (Temp >> 24); + } + + +} + 49c8: df 91 pop r29 + 49ca: cf 91 pop r28 + 49cc: 1f 91 pop r17 + 49ce: 0f 91 pop r16 + 49d0: ff 90 pop r15 + 49d2: ef 90 pop r14 + 49d4: df 90 pop r13 + 49d6: cf 90 pop r12 + 49d8: bf 90 pop r11 + 49da: af 90 pop r10 + 49dc: 9f 90 pop r9 + 49de: 8f 90 pop r8 + 49e0: 7f 90 pop r7 + 49e2: 6f 90 pop r6 + 49e4: 08 95 ret + +000049e6 : +#if !defined(NO_DEVICE_REMOTE_WAKEUP) +bool USB_Device_RemoteWakeupEnabled; +#endif + +void USB_Device_ProcessControlRequest(void) +{ + 49e6: 0f 93 push r16 + 49e8: 1f 93 push r17 + 49ea: cf 93 push r28 + 49ec: df 93 push r29 + 49ee: cd b7 in r28, 0x3d ; 61 + 49f0: de b7 in r29, 0x3e ; 62 + 49f2: ec 97 sbiw r28, 0x3c ; 60 + 49f4: cd bf out 0x3d, r28 ; 61 + 49f6: de bf out 0x3e, r29 ; 62 + USB_ControlRequest.wLength = Endpoint_Read_16_LE(); + #else + uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest; + + for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++) + *(RequestHeader++) = Endpoint_Read_8(); + 49f8: 2b d3 rcall .+1622 ; 0x5050 + 49fa: 80 93 41 2b sts 0x2B41, r24 + 49fe: 28 d3 rcall .+1616 ; 0x5050 + 4a00: 80 93 42 2b sts 0x2B42, r24 + 4a04: 25 d3 rcall .+1610 ; 0x5050 + 4a06: 80 93 43 2b sts 0x2B43, r24 + 4a0a: 22 d3 rcall .+1604 ; 0x5050 + 4a0c: 80 93 44 2b sts 0x2B44, r24 + 4a10: 1f d3 rcall .+1598 ; 0x5050 + 4a12: 80 93 45 2b sts 0x2B45, r24 + 4a16: 1c d3 rcall .+1592 ; 0x5050 + 4a18: 80 93 46 2b sts 0x2B46, r24 + 4a1c: 19 d3 rcall .+1586 ; 0x5050 + 4a1e: 80 93 47 2b sts 0x2B47, r24 + 4a22: 16 d3 rcall .+1580 ; 0x5050 + 4a24: 80 93 48 2b sts 0x2B48, r24 + #endif + + EVENT_USB_Device_ControlRequest(); + 4a28: 0e 94 4b 11 call 0x2296 ; 0x2296 + + if (Endpoint_IsSETUPReceived()) + 4a2c: b0 d3 rcall .+1888 ; 0x518e + 4a2e: 88 23 and r24, r24 + 4a30: 89 f0 breq .+34 ; 0x4a54 + { + uint8_t bmRequestType = USB_ControlRequest.bmRequestType; + 4a32: 90 91 41 2b lds r25, 0x2B41 + + switch (USB_ControlRequest.bRequest) + 4a36: 80 91 42 2b lds r24, 0x2B42 + 4a3a: 85 30 cpi r24, 0x05 ; 5 + 4a3c: 09 f4 brne .+2 ; 0x4a40 + 4a3e: 52 c0 rjmp .+164 ; 0x4ae4 + 4a40: b0 f0 brcs .+44 ; 0x4a6e + 4a42: 88 30 cpi r24, 0x08 ; 8 + 4a44: 09 f4 brne .+2 ; 0x4a48 + 4a46: b3 c0 rjmp .+358 ; 0x4bae + 4a48: 89 30 cpi r24, 0x09 ; 9 + 4a4a: 09 f4 brne .+2 ; 0x4a4e + 4a4c: 98 c0 rjmp .+304 ; 0x4b7e + 4a4e: 86 30 cpi r24, 0x06 ; 6 + 4a50: 09 f4 brne .+2 ; 0x4a54 + 4a52: 5a c0 rjmp .+180 ; 0x4b08 + default: + break; + } + } + + if (Endpoint_IsSETUPReceived()) + 4a54: 9c d3 rcall .+1848 ; 0x518e + 4a56: 88 23 and r24, r24 + 4a58: 11 f0 breq .+4 ; 0x4a5e + { + Endpoint_ClearSETUP(); + 4a5a: 6d d3 rcall .+1754 ; 0x5136 + Endpoint_StallTransaction(); + 4a5c: 50 d3 rcall .+1696 ; 0x50fe + } +} + 4a5e: ec 96 adiw r28, 0x3c ; 60 + 4a60: cd bf out 0x3d, r28 ; 61 + 4a62: de bf out 0x3e, r29 ; 62 + 4a64: df 91 pop r29 + 4a66: cf 91 pop r28 + 4a68: 1f 91 pop r17 + 4a6a: 0f 91 pop r16 + 4a6c: 08 95 ret + + if (Endpoint_IsSETUPReceived()) + { + uint8_t bmRequestType = USB_ControlRequest.bmRequestType; + + switch (USB_ControlRequest.bRequest) + 4a6e: 81 30 cpi r24, 0x01 ; 1 + 4a70: 21 f0 breq .+8 ; 0x4a7a + 4a72: 08 f4 brcc .+2 ; 0x4a76 + 4a74: 68 c0 rjmp .+208 ; 0x4b46 + 4a76: 83 30 cpi r24, 0x03 ; 3 + 4a78: 69 f7 brne .-38 ; 0x4a54 + } + + break; + case REQ_ClearFeature: + case REQ_SetFeature: + if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) || + 4a7a: 99 23 and r25, r25 + 4a7c: 09 f4 brne .+2 ; 0x4a80 + 4a7e: a1 c0 rjmp .+322 ; 0x4bc2 + 4a80: 92 30 cpi r25, 0x02 ; 2 + 4a82: 41 f7 brne .-48 ; 0x4a54 + + break; + #endif + #if !defined(CONTROL_ONLY_DEVICE) + case REQREC_ENDPOINT: + if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_EndpointHalt) + 4a84: 80 91 43 2b lds r24, 0x2B43 + 4a88: 81 11 cpse r24, r1 + 4a8a: 27 c0 rjmp .+78 ; 0x4ada + { + uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK); + 4a8c: 00 91 45 2b lds r16, 0x2B45 + 4a90: 10 91 46 2b lds r17, 0x2B46 + 4a94: 0f 70 andi r16, 0x0F ; 15 + 4a96: 11 27 eor r17, r17 + + if (EndpointIndex == ENDPOINT_CONTROLEP) + 4a98: 01 15 cp r16, r1 + 4a9a: 11 05 cpc r17, r1 + 4a9c: d9 f2 breq .-74 ; 0x4a54 + return; + + Endpoint_SelectEndpoint(EndpointIndex); + 4a9e: 80 2f mov r24, r16 + 4aa0: f5 d2 rcall .+1514 ; 0x508c + + if (Endpoint_IsEnabled()) + { + if (USB_ControlRequest.bRequest == REQ_SetFeature) + 4aa2: 80 91 42 2b lds r24, 0x2B42 + 4aa6: 83 30 cpi r24, 0x03 ; 3 + 4aa8: 09 f4 brne .+2 ; 0x4aac + 4aaa: e6 c0 rjmp .+460 ; 0x4c78 + * \ingroup Group_EndpointPacketManagement_XMEGA + */ + static inline void Endpoint_ClearStall(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearStall(void) + { + USB_Endpoint_SelectedHandle->CTRL &= ~USB_EP_STALL_bm; + 4aac: e0 91 4b 2b lds r30, 0x2B4B + 4ab0: f0 91 4c 2b lds r31, 0x2B4C + 4ab4: 81 81 ldd r24, Z+1 ; 0x01 + 4ab6: 8b 7f andi r24, 0xFB ; 251 + 4ab8: 81 83 std Z+1, r24 ; 0x01 + static inline void Endpoint_ResetEndpoint(const uint8_t Address) + { + if (Address & ENDPOINT_DIR_IN) + USB_Endpoint_FIFOs[Address & ENDPOINT_EPNUM_MASK].IN.Position = 0; + else + USB_Endpoint_FIFOs[Address & ENDPOINT_EPNUM_MASK].OUT.Position = 0; + 4aba: 84 e8 ldi r24, 0x84 ; 132 + 4abc: 80 9f mul r24, r16 + 4abe: f0 01 movw r30, r0 + 4ac0: 81 9f mul r24, r17 + 4ac2: f0 0d add r31, r0 + 4ac4: 11 24 eor r1, r1 + 4ac6: e1 57 subi r30, 0x71 ; 113 + 4ac8: f4 4d sbci r31, 0xD4 ; 212 + 4aca: 10 82 st Z, r1 + + /** Resets the data toggle of the currently selected endpoint. */ + static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ResetDataToggle(void) + { + USB_Endpoint_SelectedHandle->STATUS &= ~USB_EP_TOGGLE_bm; + 4acc: e0 91 4b 2b lds r30, 0x2B4B + 4ad0: f0 91 4c 2b lds r31, 0x2B4C + 4ad4: 80 81 ld r24, Z + 4ad6: 8e 7f andi r24, 0xFE ; 254 + 4ad8: 80 83 st Z, r24 + #endif + default: + return; + } + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + 4ada: 80 e0 ldi r24, 0x00 ; 0 + 4adc: d7 d2 rcall .+1454 ; 0x508c + + Endpoint_ClearSETUP(); + 4ade: 2b d3 rcall .+1622 ; 0x5136 + + Endpoint_ClearStatusStage(); + 4ae0: 8f d4 rcall .+2334 ; 0x5400 + 4ae2: b8 cf rjmp .-144 ; 0x4a54 + USB_Device_ClearSetFeature(); + } + + break; + case REQ_SetAddress: + if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) + 4ae4: 91 11 cpse r25, r1 + 4ae6: b6 cf rjmp .-148 ; 0x4a54 + } +} + +static void USB_Device_SetAddress(void) +{ + uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F); + 4ae8: 10 91 43 2b lds r17, 0x2B43 + 4aec: 1f 77 andi r17, 0x7F ; 127 + + USB_Device_SetDeviceAddress(DeviceAddress); + + Endpoint_ClearSETUP(); + 4aee: 23 d3 rcall .+1606 ; 0x5136 + + Endpoint_ClearStatusStage(); + 4af0: 87 d4 rcall .+2318 ; 0x5400 + + while (!(Endpoint_IsINReady())); + 4af2: 7f d3 rcall .+1790 ; 0x51f2 + 4af4: 88 23 and r24, r24 + 4af6: e9 f3 breq .-6 ; 0x4af2 + } + + static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) + { + USB.ADDR = Address; + 4af8: 10 93 c3 04 sts 0x04C3, r17 + + USB_Device_EnableDeviceAddress(DeviceAddress); + + USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default; + 4afc: 11 11 cpse r17, r1 + 4afe: 76 c0 rjmp .+236 ; 0x4bec + 4b00: 82 e0 ldi r24, 0x02 ; 2 + 4b02: 80 93 40 2b sts 0x2B40, r24 + 4b06: a6 cf rjmp .-180 ; 0x4a54 + if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) + USB_Device_SetAddress(); + + break; + case REQ_GetDescriptor: + if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) || + 4b08: 90 58 subi r25, 0x80 ; 128 + 4b0a: 92 30 cpi r25, 0x02 ; 2 + 4b0c: 08 f0 brcs .+2 ; 0x4b10 + 4b0e: a2 cf rjmp .-188 ; 0x4a54 + !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS)) + uint8_t DescriptorAddressSpace; + #endif + + #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) + if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL)) + 4b10: 80 91 43 2b lds r24, 0x2B43 + 4b14: 90 91 44 2b lds r25, 0x2B44 + 4b18: 8c 3d cpi r24, 0xDC ; 220 + 4b1a: 23 e0 ldi r18, 0x03 ; 3 + 4b1c: 92 07 cpc r25, r18 + 4b1e: 09 f4 brne .+2 ; 0x4b22 + 4b20: 67 c0 rjmp .+206 ; 0x4bf0 + USB_Device_GetInternalSerialDescriptor(); + return; + } + #endif + + if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex, + 4b22: ae 01 movw r20, r28 + 4b24: 45 5c subi r20, 0xC5 ; 197 + 4b26: 5f 4f sbci r21, 0xFF ; 255 + 4b28: 60 91 45 2b lds r22, 0x2B45 + 4b2c: 0e 94 d1 04 call 0x9a2 ; 0x9a2 + 4b30: 8c 01 movw r16, r24 + 4b32: 00 97 sbiw r24, 0x00 ; 0 + 4b34: 09 f4 brne .+2 ; 0x4b38 + 4b36: 8e cf rjmp .-228 ; 0x4a54 + )) == NO_DESCRIPTOR) + { + return; + } + + Endpoint_ClearSETUP(); + 4b38: fe d2 rcall .+1532 ; 0x5136 + #if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE) + Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize); + #elif defined(USE_EEPROM_DESCRIPTORS) + Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize); + #elif defined(USE_FLASH_DESCRIPTORS) + Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize); + 4b3a: b8 01 movw r22, r16 + 4b3c: 8b ad ldd r24, Y+59 ; 0x3b + 4b3e: 9c ad ldd r25, Y+60 ; 0x3c + 4b40: c0 d1 rcall .+896 ; 0x4ec2 + Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize); + else + Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize); + #endif + + Endpoint_ClearOUT(); + 4b42: 77 d2 rcall .+1262 ; 0x5032 + 4b44: 87 cf rjmp .-242 ; 0x4a54 + uint8_t bmRequestType = USB_ControlRequest.bmRequestType; + + switch (USB_ControlRequest.bRequest) + { + case REQ_GetStatus: + if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) || + 4b46: 90 38 cpi r25, 0x80 ; 128 + 4b48: 09 f4 brne .+2 ; 0x4b4c + 4b4a: 47 c0 rjmp .+142 ; 0x4bda + 4b4c: 92 38 cpi r25, 0x82 ; 130 + 4b4e: 09 f0 breq .+2 ; 0x4b52 + 4b50: 81 cf rjmp .-254 ; 0x4a54 + CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED; + #endif + break; + case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT): + #if !defined(CONTROL_ONLY_DEVICE) + Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK); + 4b52: 80 91 45 2b lds r24, 0x2B45 + 4b56: 8f 70 andi r24, 0x0F ; 15 + 4b58: 99 d2 rcall .+1330 ; 0x508c + * \return Boolean \c true if the currently selected endpoint is stalled, \c false otherwise. + */ + static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsStalled(void) + { + return ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_STALL_bm) ? true : false); + 4b5a: e0 91 4b 2b lds r30, 0x2B4B + 4b5e: f0 91 4c 2b lds r31, 0x2B4C + 4b62: 11 81 ldd r17, Z+1 ; 0x01 + 4b64: 12 fb bst r17, 2 + 4b66: 11 27 eor r17, r17 + 4b68: 10 f9 bld r17, 0 + + CurrentStatus = Endpoint_IsStalled(); + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + 4b6a: 80 e0 ldi r24, 0x00 ; 0 + 4b6c: 8f d2 rcall .+1310 ; 0x508c + break; + default: + return; + } + + Endpoint_ClearSETUP(); + 4b6e: e3 d2 rcall .+1478 ; 0x5136 + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_16_LE(const uint16_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_16_LE(const uint16_t Data) + { + Endpoint_Write_8(Data & 0xFF); + 4b70: 81 2f mov r24, r17 + 4b72: 7d d2 rcall .+1274 ; 0x506e + Endpoint_Write_8(Data >> 8); + 4b74: 80 e0 ldi r24, 0x00 ; 0 + 4b76: 7b d2 rcall .+1270 ; 0x506e + + Endpoint_Write_16_LE(CurrentStatus); + Endpoint_ClearIN(); + 4b78: 43 d2 rcall .+1158 ; 0x5000 + + Endpoint_ClearStatusStage(); + 4b7a: 42 d4 rcall .+2180 ; 0x5400 + 4b7c: 6b cf rjmp .-298 ; 0x4a54 + if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) + USB_Device_GetConfiguration(); + + break; + case REQ_SetConfiguration: + if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) + 4b7e: 91 11 cpse r25, r1 + 4b80: 69 cf rjmp .-302 ; 0x4a54 +} + +static void USB_Device_SetConfiguration(void) +{ + #if defined(FIXED_NUM_CONFIGURATIONS) + if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS) + 4b82: 80 91 43 2b lds r24, 0x2B43 + 4b86: 82 30 cpi r24, 0x02 ; 2 + 4b88: 08 f0 brcs .+2 ; 0x4b8c + 4b8a: 64 cf rjmp .-312 ; 0x4a54 + if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations) + return; + #endif + #endif + + Endpoint_ClearSETUP(); + 4b8c: d4 d2 rcall .+1448 ; 0x5136 + + USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue; + 4b8e: 80 91 43 2b lds r24, 0x2B43 + 4b92: 80 93 3c 2b sts 0x2B3C, r24 + + Endpoint_ClearStatusStage(); + 4b96: 34 d4 rcall .+2152 ; 0x5400 + + if (USB_Device_ConfigurationNumber) + 4b98: 80 91 3c 2b lds r24, 0x2B3C + 4b9c: 88 23 and r24, r24 + 4b9e: 09 f4 brne .+2 ; 0x4ba2 + 4ba0: 61 c0 rjmp .+194 ; 0x4c64 + USB_DeviceState = DEVICE_STATE_Configured; + 4ba2: 84 e0 ldi r24, 0x04 ; 4 + 4ba4: 80 93 40 2b sts 0x2B40, r24 + else + USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered; + + EVENT_USB_Device_ConfigurationChanged(); + 4ba8: 0e 94 47 11 call 0x228e ; 0x228e + 4bac: 53 cf rjmp .-346 ; 0x4a54 + USB_Device_GetDescriptor(); + } + + break; + case REQ_GetConfiguration: + if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) + 4bae: 90 38 cpi r25, 0x80 ; 128 + 4bb0: 09 f0 breq .+2 ; 0x4bb4 + 4bb2: 50 cf rjmp .-352 ; 0x4a54 + EVENT_USB_Device_ConfigurationChanged(); +} + +static void USB_Device_GetConfiguration(void) +{ + Endpoint_ClearSETUP(); + 4bb4: c0 d2 rcall .+1408 ; 0x5136 + + Endpoint_Write_8(USB_Device_ConfigurationNumber); + 4bb6: 80 91 3c 2b lds r24, 0x2B3C + 4bba: 59 d2 rcall .+1202 ; 0x506e + Endpoint_ClearIN(); + 4bbc: 21 d2 rcall .+1090 ; 0x5000 + + Endpoint_ClearStatusStage(); + 4bbe: 20 d4 rcall .+2112 ; 0x5400 + 4bc0: 49 cf rjmp .-366 ; 0x4a54 +{ + switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) + { + #if !defined(NO_DEVICE_REMOTE_WAKEUP) + case REQREC_DEVICE: + if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup) + 4bc2: 90 91 43 2b lds r25, 0x2B43 + 4bc6: 91 30 cpi r25, 0x01 ; 1 + 4bc8: 09 f0 breq .+2 ; 0x4bcc + 4bca: 44 cf rjmp .-376 ; 0x4a54 + USB_Device_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature); + 4bcc: 91 e0 ldi r25, 0x01 ; 1 + 4bce: 83 30 cpi r24, 0x03 ; 3 + 4bd0: 09 f0 breq .+2 ; 0x4bd4 + 4bd2: 90 e0 ldi r25, 0x00 ; 0 + 4bd4: 90 93 3e 2b sts 0x2B3E, r25 + 4bd8: 80 cf rjmp .-256 ; 0x4ada + Endpoint_ClearOUT(); +} + +static void USB_Device_GetStatus(void) +{ + uint8_t CurrentStatus = 0; + 4bda: 10 91 3d 2b lds r17, 0x2B3D + if (USB_Device_CurrentlySelfPowered) + CurrentStatus |= FEATURE_SELFPOWERED_ENABLED; + #endif + + #if !defined(NO_DEVICE_REMOTE_WAKEUP) + if (USB_Device_RemoteWakeupEnabled) + 4bde: 80 91 3e 2b lds r24, 0x2B3E + 4be2: 88 23 and r24, r24 + 4be4: 09 f4 brne .+2 ; 0x4be8 + 4be6: c3 cf rjmp .-122 ; 0x4b6e + CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED; + 4be8: 12 60 ori r17, 0x02 ; 2 + 4bea: c1 cf rjmp .-126 ; 0x4b6e + + while (!(Endpoint_IsINReady())); + + USB_Device_EnableDeviceAddress(DeviceAddress); + + USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default; + 4bec: 83 e0 ldi r24, 0x03 ; 3 + 4bee: 89 cf rjmp .-238 ; 0x4b02 + { + USB_Descriptor_Header_t Header; + uint16_t UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4]; + } SignatureDescriptor; + + SignatureDescriptor.Header.Type = DTYPE_String; + 4bf0: 83 e0 ldi r24, 0x03 ; 3 + 4bf2: 8a 83 std Y+2, r24 ; 0x02 + SignatureDescriptor.Header.Size = USB_STRING_LEN(INTERNAL_SERIAL_LENGTH_BITS / 4); + 4bf4: 8a e3 ldi r24, 0x3A ; 58 + 4bf6: 89 83 std Y+1, r24 ; 0x01 + #if (ARCH == ARCH_AVR8) + return SREG; + #elif (ARCH == ARCH_UC3) + return __builtin_mfsr(AVR32_SR); + #elif (ARCH == ARCH_XMEGA) + return SREG; + 4bf8: 5f b7 in r21, 0x3f ; 63 + #if (ARCH == ARCH_AVR8) + cli(); + #elif (ARCH == ARCH_UC3) + __builtin_ssrf(AVR32_SR_GM_OFFSET); + #elif (ARCH == ARCH_XMEGA) + cli(); + 4bfa: f8 94 cli + + for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) + { + uint8_t SerialByte; + + NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; + 4bfc: 82 e0 ldi r24, 0x02 ; 2 + 4bfe: 80 93 ca 01 sts 0x01CA, r24 + SerialByte = pgm_read_byte(SigReadAddress); + 4c02: e8 e0 ldi r30, 0x08 ; 8 + 4c04: f0 e0 ldi r31, 0x00 ; 0 + 4c06: e4 91 lpm r30, Z + NVM.CMD = 0; + 4c08: 10 92 ca 01 sts 0x01CA, r1 + + USB_Device_GetSerialString(SignatureDescriptor.UnicodeString); + 4c0c: de 01 movw r26, r28 + 4c0e: 13 96 adiw r26, 0x03 ; 3 + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS; + + for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) + 4c10: 20 e0 ldi r18, 0x00 ; 0 + static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) + { + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS; + 4c12: 38 e0 ldi r19, 0x08 ; 8 + + for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) + { + uint8_t SerialByte; + + NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; + 4c14: 42 e0 ldi r20, 0x02 ; 2 + { + SerialByte >>= 4; + SigReadAddress++; + } + + SerialByte &= 0x0F; + 4c16: ef 70 andi r30, 0x0F ; 15 + + UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ? + 4c18: 8e 2f mov r24, r30 + 4c1a: 90 e0 ldi r25, 0x00 ; 0 + 4c1c: ea 30 cpi r30, 0x0A ; 10 + 4c1e: b8 f0 brcs .+46 ; 0x4c4e + 4c20: c7 96 adiw r24, 0x37 ; 55 + 4c22: 8d 93 st X+, r24 + 4c24: 9d 93 st X+, r25 + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS; + + for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) + 4c26: 2f 5f subi r18, 0xFF ; 255 + 4c28: 2c 31 cpi r18, 0x1C ; 28 + 4c2a: 99 f0 breq .+38 ; 0x4c52 + { + uint8_t SerialByte; + + NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; + 4c2c: 40 93 ca 01 sts 0x01CA, r20 + SerialByte = pgm_read_byte(SigReadAddress); + 4c30: e3 2f mov r30, r19 + 4c32: f0 e0 ldi r31, 0x00 ; 0 + 4c34: e4 91 lpm r30, Z + NVM.CMD = 0; + 4c36: 10 92 ca 01 sts 0x01CA, r1 + + if (SerialCharNum & 0x01) + 4c3a: 20 ff sbrs r18, 0 + 4c3c: ec cf rjmp .-40 ; 0x4c16 + { + SerialByte >>= 4; + 4c3e: e2 95 swap r30 + 4c40: ef 70 andi r30, 0x0F ; 15 + SigReadAddress++; + 4c42: 3f 5f subi r19, 0xFF ; 255 + } + + SerialByte &= 0x0F; + 4c44: ef 70 andi r30, 0x0F ; 15 + + UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ? + 4c46: 8e 2f mov r24, r30 + 4c48: 90 e0 ldi r25, 0x00 ; 0 + 4c4a: ea 30 cpi r30, 0x0A ; 10 + 4c4c: 48 f7 brcc .-46 ; 0x4c20 + 4c4e: c0 96 adiw r24, 0x30 ; 48 + 4c50: e8 cf rjmp .-48 ; 0x4c22 + if (GlobalIntState & AVR32_SR_GM) + __builtin_ssrf(AVR32_SR_GM_OFFSET); + else + __builtin_csrf(AVR32_SR_GM_OFFSET); + #elif (ARCH == ARCH_XMEGA) + SREG = GlobalIntState; + 4c52: 5f bf out 0x3f, r21 ; 63 + + Endpoint_ClearSETUP(); + 4c54: 70 d2 rcall .+1248 ; 0x5136 + + Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor)); + 4c56: 6a e3 ldi r22, 0x3A ; 58 + 4c58: 70 e0 ldi r23, 0x00 ; 0 + 4c5a: ce 01 movw r24, r28 + 4c5c: 01 96 adiw r24, 0x01 ; 1 + 4c5e: 90 d0 rcall .+288 ; 0x4d80 + Endpoint_ClearOUT(); + 4c60: e8 d1 rcall .+976 ; 0x5032 + 4c62: f8 ce rjmp .-528 ; 0x4a54 + } + + static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline bool USB_Device_IsAddressSet(void) + { + return ((USB.ADDR != 0) ? true : false); + 4c64: 80 91 c3 04 lds r24, 0x04C3 + Endpoint_ClearStatusStage(); + + if (USB_Device_ConfigurationNumber) + USB_DeviceState = DEVICE_STATE_Configured; + else + USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered; + 4c68: 88 23 and r24, r24 + 4c6a: 21 f0 breq .+8 ; 0x4c74 + 4c6c: 84 e0 ldi r24, 0x04 ; 4 + 4c6e: 80 93 40 2b sts 0x2B40, r24 + 4c72: 9a cf rjmp .-204 ; 0x4ba8 + 4c74: 81 e0 ldi r24, 0x01 ; 1 + 4c76: fb cf rjmp .-10 ; 0x4c6e + + if (Endpoint_IsEnabled()) + { + if (USB_ControlRequest.bRequest == REQ_SetFeature) + { + Endpoint_StallTransaction(); + 4c78: 42 d2 rcall .+1156 ; 0x50fe + 4c7a: 2f cf rjmp .-418 ; 0x4ada + +00004c7c : +#define __INCLUDE_FROM_EVENTS_C +#define __INCLUDE_FROM_USB_DRIVER +#include "Events.h" + +void USB_Event_Stub(void) +{ + 4c7c: 08 95 ret + +00004c7e : +#if defined(USB_CAN_BE_DEVICE) && !defined(DEVICE_STATE_AS_GPIOR) +volatile uint8_t USB_DeviceState; +#endif + +void USB_USBTask(void) +{ + 4c7e: cf 93 push r28 +} + +#if defined(USB_CAN_BE_DEVICE) +static void USB_DeviceTask(void) +{ + if (USB_DeviceState == DEVICE_STATE_Unattached) + 4c80: 80 91 40 2b lds r24, 0x2B40 + 4c84: 81 11 cpse r24, r1 + 4c86: 02 c0 rjmp .+4 ; 0x4c8c + #elif defined(USB_CAN_BE_HOST) + USB_HostTask(); + #elif defined(USB_CAN_BE_DEVICE) + USB_DeviceTask(); + #endif +} + 4c88: cf 91 pop r28 + 4c8a: 08 95 ret + * \return Index of the currently selected endpoint. + */ + static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_GetCurrentEndpoint(void) + { + return USB_Endpoint_SelectedEndpoint; + 4c8c: c0 91 4d 2b lds r28, 0x2B4D + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + + uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint(); + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + 4c90: 80 e0 ldi r24, 0x00 ; 0 + 4c92: fc d1 rcall .+1016 ; 0x508c + + if (Endpoint_IsSETUPReceived()) + 4c94: 7c d2 rcall .+1272 ; 0x518e + 4c96: 81 11 cpse r24, r1 + 4c98: 03 c0 rjmp .+6 ; 0x4ca0 + USB_Device_ProcessControlRequest(); + + Endpoint_SelectEndpoint(PrevEndpoint); + 4c9a: 8c 2f mov r24, r28 + #elif defined(USB_CAN_BE_HOST) + USB_HostTask(); + #elif defined(USB_CAN_BE_DEVICE) + USB_DeviceTask(); + #endif +} + 4c9c: cf 91 pop r28 + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + + if (Endpoint_IsSETUPReceived()) + USB_Device_ProcessControlRequest(); + + Endpoint_SelectEndpoint(PrevEndpoint); + 4c9e: f6 c1 rjmp .+1004 ; 0x508c + uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint(); + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + + if (Endpoint_IsSETUPReceived()) + USB_Device_ProcessControlRequest(); + 4ca0: a2 de rcall .-700 ; 0x49e6 + + Endpoint_SelectEndpoint(PrevEndpoint); + 4ca2: 8c 2f mov r24, r28 + #elif defined(USB_CAN_BE_HOST) + USB_HostTask(); + #elif defined(USB_CAN_BE_DEVICE) + USB_DeviceTask(); + #endif +} + 4ca4: cf 91 pop r28 + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + + if (Endpoint_IsSETUPReceived()) + USB_Device_ProcessControlRequest(); + + Endpoint_SelectEndpoint(PrevEndpoint); + 4ca6: f2 c1 rjmp .+996 ; 0x508c + +00004ca8 : + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + } + + return ENDPOINT_RWCSTREAM_NoError; + 4ca8: af 92 push r10 + 4caa: bf 92 push r11 + 4cac: df 92 push r13 + 4cae: ef 92 push r14 + 4cb0: ff 92 push r15 + 4cb2: 0f 93 push r16 + 4cb4: 1f 93 push r17 + 4cb6: cf 93 push r28 + 4cb8: df 93 push r29 + 4cba: 8c 01 movw r16, r24 + 4cbc: eb 01 movw r28, r22 + 4cbe: 7a 01 movw r14, r20 + 4cc0: b5 d3 rcall .+1898 ; 0x542c + 4cc2: d8 2e mov r13, r24 + 4cc4: 81 11 cpse r24, r1 + 4cc6: 27 c0 rjmp .+78 ; 0x4d16 + 4cc8: e1 14 cp r14, r1 + 4cca: f1 04 cpc r15, r1 + 4ccc: a1 f1 breq .+104 ; 0x4d36 + 4cce: f7 01 movw r30, r14 + 4cd0: 20 81 ld r18, Z + 4cd2: 31 81 ldd r19, Z+1 ; 0x01 + 4cd4: c2 1b sub r28, r18 + 4cd6: d3 0b sbc r29, r19 + 4cd8: 02 0f add r16, r18 + 4cda: 13 1f adc r17, r19 + 4cdc: 20 97 sbiw r28, 0x00 ; 0 + 4cde: d9 f0 breq .+54 ; 0x4d16 + 4ce0: a1 2c mov r10, r1 + 4ce2: b1 2c mov r11, r1 + 4ce4: 80 91 49 2b lds r24, 0x2B49 + 4ce8: 90 91 4a 2b lds r25, 0x2B4A + 4cec: fc 01 movw r30, r24 + 4cee: ef 5b subi r30, 0xBF ; 191 + 4cf0: ff 4f sbci r31, 0xFF ; 255 + 4cf2: 20 81 ld r18, Z + 4cf4: fc 01 movw r30, r24 + 4cf6: e0 5c subi r30, 0xC0 ; 192 + 4cf8: ff 4f sbci r31, 0xFF ; 255 + 4cfa: 80 81 ld r24, Z + 4cfc: 28 17 cp r18, r24 + 4cfe: 90 f1 brcs .+100 ; 0x4d64 + 4d00: 7f d1 rcall .+766 ; 0x5000 + 4d02: bd df rcall .-134 ; 0x4c7e + 4d04: f7 01 movw r30, r14 + 4d06: 80 81 ld r24, Z + 4d08: 91 81 ldd r25, Z+1 ; 0x01 + 4d0a: 8a 0d add r24, r10 + 4d0c: 9b 1d adc r25, r11 + 4d0e: 80 83 st Z, r24 + 4d10: 91 83 std Z+1, r25 ; 0x01 + 4d12: 25 e0 ldi r18, 0x05 ; 5 + 4d14: d2 2e mov r13, r18 + 4d16: 8d 2d mov r24, r13 + 4d18: df 91 pop r29 + 4d1a: cf 91 pop r28 + 4d1c: 1f 91 pop r17 + 4d1e: 0f 91 pop r16 + 4d20: ff 90 pop r15 + 4d22: ef 90 pop r14 + 4d24: df 90 pop r13 + 4d26: bf 90 pop r11 + 4d28: af 90 pop r10 + 4d2a: 08 95 ret + 4d2c: 69 d1 rcall .+722 ; 0x5000 + 4d2e: a7 df rcall .-178 ; 0x4c7e + 4d30: 7d d3 rcall .+1786 ; 0x542c + 4d32: 81 11 cpse r24, r1 + 4d34: 23 c0 rjmp .+70 ; 0x4d7c + 4d36: 20 97 sbiw r28, 0x00 ; 0 + 4d38: 71 f3 breq .-36 ; 0x4d16 + 4d3a: 20 91 49 2b lds r18, 0x2B49 + 4d3e: 30 91 4a 2b lds r19, 0x2B4A + 4d42: f9 01 movw r30, r18 + 4d44: ef 5b subi r30, 0xBF ; 191 + 4d46: ff 4f sbci r31, 0xFF ; 255 + 4d48: 90 81 ld r25, Z + 4d4a: f9 01 movw r30, r18 + 4d4c: e0 5c subi r30, 0xC0 ; 192 + 4d4e: ff 4f sbci r31, 0xFF ; 255 + 4d50: 80 81 ld r24, Z + 4d52: 98 17 cp r25, r24 + 4d54: 58 f7 brcc .-42 ; 0x4d2c + 4d56: f8 01 movw r30, r16 + 4d58: 81 91 ld r24, Z+ + 4d5a: 8f 01 movw r16, r30 + 4d5c: 88 d1 rcall .+784 ; 0x506e + 4d5e: 21 97 sbiw r28, 0x01 ; 1 + 4d60: 61 f7 brne .-40 ; 0x4d3a + 4d62: d9 cf rjmp .-78 ; 0x4d16 + 4d64: f8 01 movw r30, r16 + 4d66: 81 91 ld r24, Z+ + 4d68: 8f 01 movw r16, r30 + 4d6a: 81 d1 rcall .+770 ; 0x506e + 4d6c: ff ef ldi r31, 0xFF ; 255 + 4d6e: af 1a sub r10, r31 + 4d70: bf 0a sbc r11, r31 + 4d72: ca 15 cp r28, r10 + 4d74: db 05 cpc r29, r11 + 4d76: 09 f0 breq .+2 ; 0x4d7a + 4d78: b5 cf rjmp .-150 ; 0x4ce4 + 4d7a: cd cf rjmp .-102 ; 0x4d16 + 4d7c: d8 2e mov r13, r24 + 4d7e: cb cf rjmp .-106 ; 0x4d16 + +00004d80 : + 4d80: cf 92 push r12 + 4d82: df 92 push r13 + 4d84: ef 92 push r14 + 4d86: ff 92 push r15 + 4d88: 0f 93 push r16 + 4d8a: 1f 93 push r17 + 4d8c: cf 93 push r28 + 4d8e: df 93 push r29 + 4d90: 6c 01 movw r12, r24 + 4d92: eb 01 movw r28, r22 + 4d94: 80 91 4d 2b lds r24, 0x2B4D + 4d98: 80 68 ori r24, 0x80 ; 128 + 4d9a: 78 d1 rcall .+752 ; 0x508c + 4d9c: 00 91 47 2b lds r16, 0x2B47 + 4da0: 10 91 48 2b lds r17, 0x2B48 + 4da4: 0c 17 cp r16, r28 + 4da6: 1d 07 cpc r17, r29 + 4da8: 20 f0 brcs .+8 ; 0x4db2 + 4daa: 20 97 sbiw r28, 0x00 ; 0 + 4dac: 09 f4 brne .+2 ; 0x4db0 + 4dae: 83 c0 rjmp .+262 ; 0x4eb6 + 4db0: 8e 01 movw r16, r28 + 4db2: c0 e0 ldi r28, 0x00 ; 0 + 4db4: 01 15 cp r16, r1 + 4db6: 11 05 cpc r17, r1 + 4db8: 09 f0 breq .+2 ; 0x4dbc + 4dba: 4a c0 rjmp .+148 ; 0x4e50 + 4dbc: cc 23 and r28, r28 + 4dbe: 09 f4 brne .+2 ; 0x4dc2 + 4dc0: 5c c0 rjmp .+184 ; 0x4e7a + 4dc2: 80 91 40 2b lds r24, 0x2B40 + 4dc6: 88 23 and r24, r24 + 4dc8: 09 f4 brne .+2 ; 0x4dcc + 4dca: 55 c0 rjmp .+170 ; 0x4e76 + 4dcc: 85 30 cpi r24, 0x05 ; 5 + 4dce: 09 f4 brne .+2 ; 0x4dd2 + 4dd0: 5d c0 rjmp .+186 ; 0x4e8c + 4dd2: dd d1 rcall .+954 ; 0x518e + 4dd4: 81 11 cpse r24, r1 + 4dd6: 6d c0 rjmp .+218 ; 0x4eb2 + 4dd8: f3 d1 rcall .+998 ; 0x51c0 + 4dda: 81 11 cpse r24, r1 + 4ddc: 4e c0 rjmp .+156 ; 0x4e7a + 4dde: 09 d2 rcall .+1042 ; 0x51f2 + 4de0: 88 23 and r24, r24 + 4de2: 79 f3 breq .-34 ; 0x4dc2 + 4de4: 80 91 4d 2b lds r24, 0x2B4D + 4de8: 87 fd sbrc r24, 7 + 4dea: 5a c0 rjmp .+180 ; 0x4ea0 + 4dec: 20 91 49 2b lds r18, 0x2B49 + 4df0: 30 91 4a 2b lds r19, 0x2B4A + 4df4: f9 01 movw r30, r18 + 4df6: e0 5c subi r30, 0xC0 ; 192 + 4df8: ff 4f sbci r31, 0xFF ; 255 + 4dfa: e0 80 ld r14, Z + 4dfc: f9 01 movw r30, r18 + 4dfe: ef 5b subi r30, 0xBF ; 191 + 4e00: ff 4f sbci r31, 0xFF ; 255 + 4e02: 80 81 ld r24, Z + 4e04: f1 2c mov r15, r1 + 4e06: e8 1a sub r14, r24 + 4e08: f1 08 sbc r15, r1 + 4e0a: 01 15 cp r16, r1 + 4e0c: 11 05 cpc r17, r1 + 4e0e: a9 f0 breq .+42 ; 0x4e3a + 4e10: 88 e0 ldi r24, 0x08 ; 8 + 4e12: e8 16 cp r14, r24 + 4e14: f1 04 cpc r15, r1 + 4e16: 88 f4 brcc .+34 ; 0x4e3a + 4e18: e6 01 movw r28, r12 + 4e1a: 04 c0 rjmp .+8 ; 0x4e24 + 4e1c: 88 e0 ldi r24, 0x08 ; 8 + 4e1e: e8 16 cp r14, r24 + 4e20: f1 04 cpc r15, r1 + 4e22: 59 f0 breq .+22 ; 0x4e3a + 4e24: 89 91 ld r24, Y+ + 4e26: 23 d1 rcall .+582 ; 0x506e + 4e28: 6e 01 movw r12, r28 + 4e2a: 01 50 subi r16, 0x01 ; 1 + 4e2c: 11 09 sbc r17, r1 + 4e2e: 8f ef ldi r24, 0xFF ; 255 + 4e30: e8 1a sub r14, r24 + 4e32: f8 0a sbc r15, r24 + 4e34: 01 15 cp r16, r1 + 4e36: 11 05 cpc r17, r1 + 4e38: 89 f7 brne .-30 ; 0x4e1c + 4e3a: c1 e0 ldi r28, 0x01 ; 1 + 4e3c: 88 e0 ldi r24, 0x08 ; 8 + 4e3e: e8 16 cp r14, r24 + 4e40: f1 04 cpc r15, r1 + 4e42: 09 f0 breq .+2 ; 0x4e46 + 4e44: c0 e0 ldi r28, 0x00 ; 0 + 4e46: dc d0 rcall .+440 ; 0x5000 + 4e48: 01 15 cp r16, r1 + 4e4a: 11 05 cpc r17, r1 + 4e4c: 09 f4 brne .+2 ; 0x4e50 + 4e4e: b6 cf rjmp .-148 ; 0x4dbc + 4e50: 80 91 40 2b lds r24, 0x2B40 + 4e54: 88 23 and r24, r24 + 4e56: 79 f0 breq .+30 ; 0x4e76 + 4e58: 85 30 cpi r24, 0x05 ; 5 + 4e5a: c1 f0 breq .+48 ; 0x4e8c + 4e5c: 98 d1 rcall .+816 ; 0x518e + 4e5e: 81 11 cpse r24, r1 + 4e60: 28 c0 rjmp .+80 ; 0x4eb2 + 4e62: ae d1 rcall .+860 ; 0x51c0 + 4e64: 81 11 cpse r24, r1 + 4e66: 09 c0 rjmp .+18 ; 0x4e7a + 4e68: c4 d1 rcall .+904 ; 0x51f2 + 4e6a: 81 11 cpse r24, r1 + 4e6c: bb cf rjmp .-138 ; 0x4de4 + 4e6e: 80 91 40 2b lds r24, 0x2B40 + 4e72: 81 11 cpse r24, r1 + 4e74: f1 cf rjmp .-30 ; 0x4e58 + 4e76: 82 e0 ldi r24, 0x02 ; 2 + 4e78: 0a c0 rjmp .+20 ; 0x4e8e + 4e7a: a2 d1 rcall .+836 ; 0x51c0 + 4e7c: 81 11 cpse r24, r1 + 4e7e: 1f c0 rjmp .+62 ; 0x4ebe + 4e80: 80 91 40 2b lds r24, 0x2B40 + 4e84: 88 23 and r24, r24 + 4e86: b9 f3 breq .-18 ; 0x4e76 + 4e88: 85 30 cpi r24, 0x05 ; 5 + 4e8a: b9 f7 brne .-18 ; 0x4e7a + 4e8c: 83 e0 ldi r24, 0x03 ; 3 + 4e8e: df 91 pop r29 + 4e90: cf 91 pop r28 + 4e92: 1f 91 pop r17 + 4e94: 0f 91 pop r16 + 4e96: ff 90 pop r15 + 4e98: ef 90 pop r14 + 4e9a: df 90 pop r13 + 4e9c: cf 90 pop r12 + 4e9e: 08 95 ret + 4ea0: e0 91 49 2b lds r30, 0x2B49 + 4ea4: f0 91 4a 2b lds r31, 0x2B4A + 4ea8: ef 5b subi r30, 0xBF ; 191 + 4eaa: ff 4f sbci r31, 0xFF ; 255 + 4eac: e0 80 ld r14, Z + 4eae: f1 2c mov r15, r1 + 4eb0: ac cf rjmp .-168 ; 0x4e0a + 4eb2: 81 e0 ldi r24, 0x01 ; 1 + 4eb4: ec cf rjmp .-40 ; 0x4e8e + 4eb6: a4 d0 rcall .+328 ; 0x5000 + 4eb8: 00 e0 ldi r16, 0x00 ; 0 + 4eba: 10 e0 ldi r17, 0x00 ; 0 + 4ebc: 7a cf rjmp .-268 ; 0x4db2 + 4ebe: 80 e0 ldi r24, 0x00 ; 0 + 4ec0: e6 cf rjmp .-52 ; 0x4e8e + +00004ec2 : + +#if defined(TEMPLATE_FUNC_NAME) + +uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer, + uint16_t Length) +{ + 4ec2: cf 92 push r12 + 4ec4: df 92 push r13 + 4ec6: ef 92 push r14 + 4ec8: ff 92 push r15 + 4eca: 0f 93 push r16 + 4ecc: 1f 93 push r17 + 4ece: cf 93 push r28 + 4ed0: df 93 push r29 + 4ed2: d8 2e mov r13, r24 + 4ed4: c9 2e mov r12, r25 + 4ed6: 8b 01 movw r16, r22 + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + bool LastPacketFull = false; + + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); + 4ed8: 80 91 4d 2b lds r24, 0x2B4D + 4edc: 80 68 ori r24, 0x80 ; 128 + 4ede: d6 d0 rcall .+428 ; 0x508c + + if (Length > USB_ControlRequest.wLength) + 4ee0: c0 91 47 2b lds r28, 0x2B47 + 4ee4: d0 91 48 2b lds r29, 0x2B48 + 4ee8: c0 17 cp r28, r16 + 4eea: d1 07 cpc r29, r17 + 4eec: 28 f0 brcs .+10 ; 0x4ef8 + Length = USB_ControlRequest.wLength; + else if (!(Length)) + 4eee: 01 15 cp r16, r1 + 4ef0: 11 05 cpc r17, r1 + 4ef2: 09 f4 brne .+2 ; 0x4ef6 + 4ef4: 7f c0 rjmp .+254 ; 0x4ff4 + 4ef6: e8 01 movw r28, r16 + 4ef8: ed 2c mov r14, r13 + 4efa: fc 2c mov r15, r12 + 4efc: d1 2c mov r13, r1 + 4efe: 20 97 sbiw r28, 0x00 ; 0 + 4f00: 09 f0 breq .+2 ; 0x4f04 + 4f02: 45 c0 rjmp .+138 ; 0x4f8e + 4f04: dd 20 and r13, r13 + 4f06: 09 f4 brne .+2 ; 0x4f0a + 4f08: 57 c0 rjmp .+174 ; 0x4fb8 + Endpoint_ClearIN(); + + while (Length || LastPacketFull) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 4f0a: 80 91 40 2b lds r24, 0x2B40 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 4f0e: 88 23 and r24, r24 + 4f10: 09 f4 brne .+2 ; 0x4f14 + 4f12: 50 c0 rjmp .+160 ; 0x4fb4 + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + 4f14: 85 30 cpi r24, 0x05 ; 5 + 4f16: 09 f4 brne .+2 ; 0x4f1a + 4f18: 58 c0 rjmp .+176 ; 0x4fca + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + 4f1a: 39 d1 rcall .+626 ; 0x518e + 4f1c: 81 11 cpse r24, r1 + 4f1e: 68 c0 rjmp .+208 ; 0x4ff0 + return ENDPOINT_RWCSTREAM_HostAborted; + else if (Endpoint_IsOUTReceived()) + 4f20: 4f d1 rcall .+670 ; 0x51c0 + 4f22: 81 11 cpse r24, r1 + 4f24: 49 c0 rjmp .+146 ; 0x4fb8 + break; + + if (Endpoint_IsINReady()) + 4f26: 65 d1 rcall .+714 ; 0x51f2 + 4f28: 88 23 and r24, r24 + 4f2a: 79 f3 breq .-34 ; 0x4f0a + * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + 4f2c: 80 91 4d 2b lds r24, 0x2B4D + 4f30: 87 fd sbrc r24, 7 + 4f32: 55 c0 rjmp .+170 ; 0x4fde + return USB_Endpoint_SelectedFIFO->Position; + else + return (USB_Endpoint_SelectedFIFO->Length - USB_Endpoint_SelectedFIFO->Position); + 4f34: 80 91 49 2b lds r24, 0x2B49 + 4f38: 90 91 4a 2b lds r25, 0x2B4A + 4f3c: fc 01 movw r30, r24 + 4f3e: e0 5c subi r30, 0xC0 ; 192 + 4f40: ff 4f sbci r31, 0xFF ; 255 + 4f42: 00 81 ld r16, Z + 4f44: fc 01 movw r30, r24 + 4f46: ef 5b subi r30, 0xBF ; 191 + 4f48: ff 4f sbci r31, 0xFF ; 255 + 4f4a: 80 81 ld r24, Z + 4f4c: 10 e0 ldi r17, 0x00 ; 0 + 4f4e: 08 1b sub r16, r24 + 4f50: 11 09 sbc r17, r1 + { + uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint(); + + while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize)) + 4f52: 20 97 sbiw r28, 0x00 ; 0 + 4f54: 91 f0 breq .+36 ; 0x4f7a + 4f56: 08 30 cpi r16, 0x08 ; 8 + 4f58: 11 05 cpc r17, r1 + 4f5a: 20 f0 brcs .+8 ; 0x4f64 + 4f5c: 0e c0 rjmp .+28 ; 0x4f7a + 4f5e: 08 30 cpi r16, 0x08 ; 8 + 4f60: 11 05 cpc r17, r1 + 4f62: 59 f0 breq .+22 ; 0x4f7a + { + TEMPLATE_TRANSFER_BYTE(DataStream); + 4f64: f7 01 movw r30, r14 + 4f66: 84 91 lpm r24, Z + 4f68: 82 d0 rcall .+260 ; 0x506e + TEMPLATE_BUFFER_MOVE(DataStream, 1); + 4f6a: ff ef ldi r31, 0xFF ; 255 + 4f6c: ef 1a sub r14, r31 + 4f6e: ff 0a sbc r15, r31 + Length--; + 4f70: 21 97 sbiw r28, 0x01 ; 1 + BytesInEndpoint++; + 4f72: 0f 5f subi r16, 0xFF ; 255 + 4f74: 1f 4f sbci r17, 0xFF ; 255 + + if (Endpoint_IsINReady()) + { + uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint(); + + while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize)) + 4f76: 20 97 sbiw r28, 0x00 ; 0 + 4f78: 91 f7 brne .-28 ; 0x4f5e + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + BytesInEndpoint++; + } + + LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); + 4f7a: dd 24 eor r13, r13 + 4f7c: d3 94 inc r13 + 4f7e: 08 30 cpi r16, 0x08 ; 8 + 4f80: 11 05 cpc r17, r1 + 4f82: 09 f0 breq .+2 ; 0x4f86 + 4f84: d1 2c mov r13, r1 + Endpoint_ClearIN(); + 4f86: 3c d0 rcall .+120 ; 0x5000 + 4f88: 20 97 sbiw r28, 0x00 ; 0 + 4f8a: 09 f4 brne .+2 ; 0x4f8e + 4f8c: bb cf rjmp .-138 ; 0x4f04 + else if (!(Length)) + Endpoint_ClearIN(); + + while (Length || LastPacketFull) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 4f8e: 80 91 40 2b lds r24, 0x2B40 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 4f92: 88 23 and r24, r24 + 4f94: 79 f0 breq .+30 ; 0x4fb4 + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + 4f96: 85 30 cpi r24, 0x05 ; 5 + 4f98: c1 f0 breq .+48 ; 0x4fca + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + 4f9a: f9 d0 rcall .+498 ; 0x518e + 4f9c: 81 11 cpse r24, r1 + 4f9e: 28 c0 rjmp .+80 ; 0x4ff0 + return ENDPOINT_RWCSTREAM_HostAborted; + else if (Endpoint_IsOUTReceived()) + 4fa0: 0f d1 rcall .+542 ; 0x51c0 + 4fa2: 81 11 cpse r24, r1 + 4fa4: 09 c0 rjmp .+18 ; 0x4fb8 + break; + + if (Endpoint_IsINReady()) + 4fa6: 25 d1 rcall .+586 ; 0x51f2 + 4fa8: 81 11 cpse r24, r1 + 4faa: c0 cf rjmp .-128 ; 0x4f2c + else if (!(Length)) + Endpoint_ClearIN(); + + while (Length || LastPacketFull) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 4fac: 80 91 40 2b lds r24, 0x2B40 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 4fb0: 81 11 cpse r24, r1 + 4fb2: f1 cf rjmp .-30 ; 0x4f96 + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + 4fb4: 82 e0 ldi r24, 0x02 ; 2 + 4fb6: 0a c0 rjmp .+20 ; 0x4fcc + LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); + Endpoint_ClearIN(); + } + } + + while (!(Endpoint_IsOUTReceived())) + 4fb8: 03 d1 rcall .+518 ; 0x51c0 + 4fba: 81 11 cpse r24, r1 + 4fbc: 1f c0 rjmp .+62 ; 0x4ffc + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 4fbe: 80 91 40 2b lds r24, 0x2B40 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 4fc2: 88 23 and r24, r24 + 4fc4: b9 f3 breq .-18 ; 0x4fb4 + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + 4fc6: 85 30 cpi r24, 0x05 ; 5 + 4fc8: b9 f7 brne .-18 ; 0x4fb8 + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + 4fca: 83 e0 ldi r24, 0x03 ; 3 + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + } + + return ENDPOINT_RWCSTREAM_NoError; +} + 4fcc: df 91 pop r29 + 4fce: cf 91 pop r28 + 4fd0: 1f 91 pop r17 + 4fd2: 0f 91 pop r16 + 4fd4: ff 90 pop r15 + 4fd6: ef 90 pop r14 + 4fd8: df 90 pop r13 + 4fda: cf 90 pop r12 + 4fdc: 08 95 ret + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + return USB_Endpoint_SelectedFIFO->Position; + 4fde: e0 91 49 2b lds r30, 0x2B49 + 4fe2: f0 91 4a 2b lds r31, 0x2B4A + 4fe6: ef 5b subi r30, 0xBF ; 191 + 4fe8: ff 4f sbci r31, 0xFF ; 255 + 4fea: 00 81 ld r16, Z + 4fec: 10 e0 ldi r17, 0x00 ; 0 + 4fee: b1 cf rjmp .-158 ; 0x4f52 + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + return ENDPOINT_RWCSTREAM_HostAborted; + 4ff0: 81 e0 ldi r24, 0x01 ; 1 + 4ff2: ec cf rjmp .-40 ; 0x4fcc + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); + + if (Length > USB_ControlRequest.wLength) + Length = USB_ControlRequest.wLength; + else if (!(Length)) + Endpoint_ClearIN(); + 4ff4: 05 d0 rcall .+10 ; 0x5000 + 4ff6: c0 e0 ldi r28, 0x00 ; 0 + 4ff8: d0 e0 ldi r29, 0x00 ; 0 + 4ffa: 7e cf rjmp .-260 ; 0x4ef8 + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + } + + return ENDPOINT_RWCSTREAM_NoError; + 4ffc: 80 e0 ldi r24, 0x00 ; 0 + 4ffe: e6 cf rjmp .-52 ; 0x4fcc + +00005000 : + USB_Endpoint_SelectedFIFO->Position = 0; +} + +void Endpoint_ClearIN(void) +{ + USB_Endpoint_SelectedHandle->CNT = USB_Endpoint_SelectedFIFO->Position; + 5000: e0 91 4b 2b lds r30, 0x2B4B + 5004: f0 91 4c 2b lds r31, 0x2B4C + 5008: a0 91 49 2b lds r26, 0x2B49 + 500c: b0 91 4a 2b lds r27, 0x2B4A + 5010: af 5b subi r26, 0xBF ; 191 + 5012: bf 4f sbci r27, 0xFF ; 255 + 5014: 8c 91 ld r24, X + 5016: 90 e0 ldi r25, 0x00 ; 0 + 5018: 82 83 std Z+2, r24 ; 0x02 + 501a: 93 83 std Z+3, r25 ; 0x03 + USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm); + 501c: 80 81 ld r24, Z + 501e: 8d 79 andi r24, 0x9D ; 157 + 5020: 80 83 st Z, r24 + USB_Endpoint_SelectedFIFO->Position = 0; + 5022: e0 91 49 2b lds r30, 0x2B49 + 5026: f0 91 4a 2b lds r31, 0x2B4A + 502a: ef 5b subi r30, 0xBF ; 191 + 502c: ff 4f sbci r31, 0xFF ; 255 + 502e: 10 82 st Z, r1 + 5030: 08 95 ret + +00005032 : +} + +void Endpoint_ClearOUT(void) +{ + USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm); + 5032: e0 91 4b 2b lds r30, 0x2B4B + 5036: f0 91 4c 2b lds r31, 0x2B4C + 503a: 80 81 ld r24, Z + 503c: 8d 79 andi r24, 0x9D ; 157 + 503e: 80 83 st Z, r24 + USB_Endpoint_SelectedFIFO->Position = 0; + 5040: e0 91 49 2b lds r30, 0x2B49 + 5044: f0 91 4a 2b lds r31, 0x2B4A + 5048: ef 5b subi r30, 0xBF ; 191 + 504a: ff 4f sbci r31, 0xFF ; 255 + 504c: 10 82 st Z, r1 + 504e: 08 95 ret + +00005050 : + } +} + +uint8_t Endpoint_Read_8(void) +{ + return USB_Endpoint_SelectedFIFO->Data[USB_Endpoint_SelectedFIFO->Position++]; + 5050: 80 91 49 2b lds r24, 0x2B49 + 5054: 90 91 4a 2b lds r25, 0x2B4A + 5058: fc 01 movw r30, r24 + 505a: ef 5b subi r30, 0xBF ; 191 + 505c: ff 4f sbci r31, 0xFF ; 255 + 505e: 20 81 ld r18, Z + 5060: dc 01 movw r26, r24 + 5062: a2 0f add r26, r18 + 5064: b1 1d adc r27, r1 + 5066: 8c 91 ld r24, X + 5068: 2f 5f subi r18, 0xFF ; 255 + 506a: 20 83 st Z, r18 +} + 506c: 08 95 ret + +0000506e : + +void Endpoint_Write_8(const uint8_t Data) +{ + USB_Endpoint_SelectedFIFO->Data[USB_Endpoint_SelectedFIFO->Position++] = Data; + 506e: 20 91 49 2b lds r18, 0x2B49 + 5072: 30 91 4a 2b lds r19, 0x2B4A + 5076: f9 01 movw r30, r18 + 5078: ef 5b subi r30, 0xBF ; 191 + 507a: ff 4f sbci r31, 0xFF ; 255 + 507c: 90 81 ld r25, Z + 507e: d9 01 movw r26, r18 + 5080: a9 0f add r26, r25 + 5082: b1 1d adc r27, r1 + 5084: 8c 93 st X, r24 + 5086: 9f 5f subi r25, 0xFF ; 255 + 5088: 90 83 st Z, r25 + 508a: 08 95 ret + +0000508c : + +void Endpoint_SelectEndpoint(const uint8_t Address) +{ + uint8_t EndpointNumber = (Address & ENDPOINT_EPNUM_MASK); + + USB_Endpoint_SelectedEndpoint = Address; + 508c: 80 93 4d 2b sts 0x2B4D, r24 + USB_Endpoint_SelectedFIFO->Data[USB_Endpoint_SelectedFIFO->Position++] = Data; +} + +void Endpoint_SelectEndpoint(const uint8_t Address) +{ + uint8_t EndpointNumber = (Address & ENDPOINT_EPNUM_MASK); + 5090: 28 2f mov r18, r24 + 5092: 2f 70 andi r18, 0x0F ; 15 + + USB_Endpoint_SelectedEndpoint = Address; + + Endpoint_FIFOPair_t* EndpointFIFOPair = &USB_Endpoint_FIFOs[EndpointNumber]; + 5094: 62 2f mov r22, r18 + 5096: 70 e0 ldi r23, 0x00 ; 0 + 5098: 94 e8 ldi r25, 0x84 ; 132 + 509a: 29 9f mul r18, r25 + 509c: 90 01 movw r18, r0 + 509e: 11 24 eor r1, r1 + 50a0: 22 5b subi r18, 0xB2 ; 178 + 50a2: 34 4d sbci r19, 0xD4 ; 212 + USB_EndpointTable_t* EndpointTable = (USB_EndpointTable_t*)USB.EPPTR; + 50a4: 40 91 c6 04 lds r20, 0x04C6 + 50a8: 50 91 c7 04 lds r21, 0x04C7 + + if (Address & ENDPOINT_DIR_IN) + 50ac: 87 fd sbrc r24, 7 + 50ae: 12 c0 rjmp .+36 ; 0x50d4 + USB_Endpoint_SelectedFIFO = &EndpointFIFOPair->IN; + USB_Endpoint_SelectedHandle = &EndpointTable->Endpoints[EndpointNumber].IN; + } + else + { + USB_Endpoint_SelectedFIFO = &EndpointFIFOPair->OUT; + 50b0: 20 93 49 2b sts 0x2B49, r18 + 50b4: 30 93 4a 2b sts 0x2B4A, r19 + USB_Endpoint_SelectedHandle = &EndpointTable->Endpoints[EndpointNumber].OUT; + 50b8: cb 01 movw r24, r22 + 50ba: 82 95 swap r24 + 50bc: 92 95 swap r25 + 50be: 90 7f andi r25, 0xF0 ; 240 + 50c0: 98 27 eor r25, r24 + 50c2: 80 7f andi r24, 0xF0 ; 240 + 50c4: 98 27 eor r25, r24 + 50c6: 84 0f add r24, r20 + 50c8: 95 1f adc r25, r21 + 50ca: 80 93 4b 2b sts 0x2B4B, r24 + 50ce: 90 93 4c 2b sts 0x2B4C, r25 + 50d2: 08 95 ret + Endpoint_FIFOPair_t* EndpointFIFOPair = &USB_Endpoint_FIFOs[EndpointNumber]; + USB_EndpointTable_t* EndpointTable = (USB_EndpointTable_t*)USB.EPPTR; + + if (Address & ENDPOINT_DIR_IN) + { + USB_Endpoint_SelectedFIFO = &EndpointFIFOPair->IN; + 50d4: 2e 5b subi r18, 0xBE ; 190 + 50d6: 3f 4f sbci r19, 0xFF ; 255 + 50d8: 20 93 49 2b sts 0x2B49, r18 + 50dc: 30 93 4a 2b sts 0x2B4A, r19 + USB_Endpoint_SelectedHandle = &EndpointTable->Endpoints[EndpointNumber].IN; + 50e0: 62 95 swap r22 + 50e2: 72 95 swap r23 + 50e4: 70 7f andi r23, 0xF0 ; 240 + 50e6: 76 27 eor r23, r22 + 50e8: 60 7f andi r22, 0xF0 ; 240 + 50ea: 76 27 eor r23, r22 + 50ec: 68 5f subi r22, 0xF8 ; 248 + 50ee: 7f 4f sbci r23, 0xFF ; 255 + 50f0: 64 0f add r22, r20 + 50f2: 75 1f adc r23, r21 + 50f4: 60 93 4b 2b sts 0x2B4B, r22 + 50f8: 70 93 4c 2b sts 0x2B4C, r23 + 50fc: 08 95 ret + +000050fe : + USB_Endpoint_SelectedFIFO->Position = 0; +} + +void Endpoint_StallTransaction(void) +{ + USB_Endpoint_SelectedHandle->CTRL |= USB_EP_STALL_bm; + 50fe: e0 91 4b 2b lds r30, 0x2B4B + 5102: f0 91 4c 2b lds r31, 0x2B4C + 5106: 81 81 ldd r24, Z+1 ; 0x01 + 5108: 84 60 ori r24, 0x04 ; 4 + 510a: 81 83 std Z+1, r24 ; 0x01 + + if ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_TYPE_gm) == USB_EP_TYPE_CONTROL_gc) + 510c: e0 91 4b 2b lds r30, 0x2B4B + 5110: f0 91 4c 2b lds r31, 0x2B4C + 5114: 81 81 ldd r24, Z+1 ; 0x01 + 5116: 80 7c andi r24, 0xC0 ; 192 + 5118: 80 34 cpi r24, 0x40 ; 64 + 511a: 09 f0 breq .+2 ; 0x511e + 511c: 08 95 ret + { + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint ^ ENDPOINT_DIR_IN); + 511e: 80 91 4d 2b lds r24, 0x2B4D + 5122: 80 58 subi r24, 0x80 ; 128 + 5124: b3 df rcall .-154 ; 0x508c + USB_Endpoint_SelectedHandle->CTRL |= USB_EP_STALL_bm; + 5126: e0 91 4b 2b lds r30, 0x2B4B + 512a: f0 91 4c 2b lds r31, 0x2B4C + 512e: 81 81 ldd r24, Z+1 ; 0x01 + 5130: 84 60 ori r24, 0x04 ; 4 + 5132: 81 83 std Z+1, r24 ; 0x01 + 5134: 08 95 ret + +00005136 : + return false; +} + +void Endpoint_ClearSETUP(void) +{ + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); + 5136: 80 91 4d 2b lds r24, 0x2B4D + 513a: 8f 77 andi r24, 0x7F ; 127 + 513c: a7 df rcall .-178 ; 0x508c + USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_SETUP_bm | USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm); + 513e: e0 91 4b 2b lds r30, 0x2B4B + 5142: f0 91 4c 2b lds r31, 0x2B4C + 5146: 80 81 ld r24, Z + 5148: 8d 78 andi r24, 0x8D ; 141 + 514a: 80 83 st Z, r24 + USB_Endpoint_SelectedHandle->STATUS |= USB_EP_TOGGLE_bm; + 514c: e0 91 4b 2b lds r30, 0x2B4B + 5150: f0 91 4c 2b lds r31, 0x2B4C + 5154: 80 81 ld r24, Z + 5156: 81 60 ori r24, 0x01 ; 1 + 5158: 80 83 st Z, r24 + USB_Endpoint_SelectedFIFO->Position = 0; + 515a: e0 91 49 2b lds r30, 0x2B49 + 515e: f0 91 4a 2b lds r31, 0x2B4A + 5162: ef 5b subi r30, 0xBF ; 191 + 5164: ff 4f sbci r31, 0xFF ; 255 + 5166: 10 82 st Z, r1 + + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); + 5168: 80 91 4d 2b lds r24, 0x2B4D + 516c: 80 68 ori r24, 0x80 ; 128 + 516e: 8e df rcall .-228 ; 0x508c + USB_Endpoint_SelectedHandle->STATUS |= USB_EP_TOGGLE_bm; + 5170: e0 91 4b 2b lds r30, 0x2B4B + 5174: f0 91 4c 2b lds r31, 0x2B4C + 5178: 80 81 ld r24, Z + 517a: 81 60 ori r24, 0x01 ; 1 + 517c: 80 83 st Z, r24 + USB_Endpoint_SelectedFIFO->Position = 0; + 517e: e0 91 49 2b lds r30, 0x2B49 + 5182: f0 91 4a 2b lds r31, 0x2B4A + 5186: ef 5b subi r30, 0xBF ; 191 + 5188: ff 4f sbci r31, 0xFF ; 255 + 518a: 10 82 st Z, r1 + 518c: 08 95 ret + +0000518e : + return false; +} + +bool Endpoint_IsSETUPReceived(void) +{ + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); + 518e: 80 91 4d 2b lds r24, 0x2B4D + 5192: 8f 77 andi r24, 0x7F ; 127 + 5194: 7b df rcall .-266 ; 0x508c + + if (USB_Endpoint_SelectedHandle->STATUS & USB_EP_SETUP_bm) + 5196: e0 91 4b 2b lds r30, 0x2B4B + 519a: f0 91 4c 2b lds r31, 0x2B4C + 519e: 80 81 ld r24, Z + 51a0: 84 ff sbrs r24, 4 + 51a2: 0c c0 rjmp .+24 ; 0x51bc + { + USB_Endpoint_SelectedFIFO->Length = USB_Endpoint_SelectedHandle->CNT; + 51a4: 20 91 49 2b lds r18, 0x2B49 + 51a8: 30 91 4a 2b lds r19, 0x2B4A + 51ac: 82 81 ldd r24, Z+2 ; 0x02 + 51ae: 93 81 ldd r25, Z+3 ; 0x03 + 51b0: f9 01 movw r30, r18 + 51b2: e0 5c subi r30, 0xC0 ; 192 + 51b4: ff 4f sbci r31, 0xFF ; 255 + 51b6: 80 83 st Z, r24 + return true; + 51b8: 81 e0 ldi r24, 0x01 ; 1 + 51ba: 08 95 ret + } + + return false; + 51bc: 80 e0 ldi r24, 0x00 ; 0 +} + 51be: 08 95 ret + +000051c0 : + return ((USB_Endpoint_SelectedHandle->STATUS & USB_EP_BUSNACK0_bm) ? true : false); +} + +bool Endpoint_IsOUTReceived(void) +{ + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); + 51c0: 80 91 4d 2b lds r24, 0x2B4D + 51c4: 8f 77 andi r24, 0x7F ; 127 + 51c6: 62 df rcall .-316 ; 0x508c + + if (USB_Endpoint_SelectedHandle->STATUS & USB_EP_TRNCOMPL0_bm) + 51c8: e0 91 4b 2b lds r30, 0x2B4B + 51cc: f0 91 4c 2b lds r31, 0x2B4C + 51d0: 80 81 ld r24, Z + 51d2: 85 ff sbrs r24, 5 + 51d4: 0c c0 rjmp .+24 ; 0x51ee + { + USB_Endpoint_SelectedFIFO->Length = USB_Endpoint_SelectedHandle->CNT; + 51d6: 20 91 49 2b lds r18, 0x2B49 + 51da: 30 91 4a 2b lds r19, 0x2B4A + 51de: 82 81 ldd r24, Z+2 ; 0x02 + 51e0: 93 81 ldd r25, Z+3 ; 0x03 + 51e2: f9 01 movw r30, r18 + 51e4: e0 5c subi r30, 0xC0 ; 192 + 51e6: ff 4f sbci r31, 0xFF ; 255 + 51e8: 80 83 st Z, r24 + return true; + 51ea: 81 e0 ldi r24, 0x01 ; 1 + 51ec: 08 95 ret + } + + return false; + 51ee: 80 e0 ldi r24, 0x00 ; 0 +} + 51f0: 08 95 ret + +000051f2 : +volatile USB_EP_t* USB_Endpoint_SelectedHandle; +volatile Endpoint_FIFO_t* USB_Endpoint_SelectedFIFO; + +bool Endpoint_IsINReady(void) +{ + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); + 51f2: 80 91 4d 2b lds r24, 0x2B4D + 51f6: 80 68 ori r24, 0x80 ; 128 + 51f8: 49 df rcall .-366 ; 0x508c + + return ((USB_Endpoint_SelectedHandle->STATUS & USB_EP_BUSNACK0_bm) ? true : false); + 51fa: e0 91 4b 2b lds r30, 0x2B4B + 51fe: f0 91 4c 2b lds r31, 0x2B4C + 5202: 80 81 ld r24, Z +} + 5204: 86 95 lsr r24 + 5206: 81 70 andi r24, 0x01 ; 1 + 5208: 08 95 ret + +0000520a : +} + +bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Address, + const uint8_t Config, + const uint8_t Size) +{ + 520a: 1f 93 push r17 + 520c: cf 93 push r28 + 520e: df 93 push r29 + 5210: 00 d0 rcall .+0 ; 0x5212 + 5212: cd b7 in r28, 0x3d ; 61 + 5214: de b7 in r29, 0x3e ; 62 + 5216: 18 2f mov r17, r24 + Endpoint_SelectEndpoint(Address); + 5218: 4a 83 std Y+2, r20 ; 0x02 + 521a: 69 83 std Y+1, r22 ; 0x01 + 521c: 37 df rcall .-402 ; 0x508c + + USB_Endpoint_SelectedHandle->CTRL = 0; + 521e: e0 91 4b 2b lds r30, 0x2B4B + 5222: f0 91 4c 2b lds r31, 0x2B4C + 5226: 11 82 std Z+1, r1 ; 0x01 + USB_Endpoint_SelectedHandle->STATUS = (Address & ENDPOINT_DIR_IN) ? USB_EP_BUSNACK0_bm : 0; + 5228: e0 91 4b 2b lds r30, 0x2B4B + 522c: f0 91 4c 2b lds r31, 0x2B4C + 5230: 4a 81 ldd r20, Y+2 ; 0x02 + 5232: 69 81 ldd r22, Y+1 ; 0x01 + 5234: 17 fd sbrc r17, 7 + 5236: 22 c0 rjmp .+68 ; 0x527c + 5238: 10 82 st Z, r1 + USB_Endpoint_SelectedHandle->CTRL = Config; + 523a: e0 91 4b 2b lds r30, 0x2B4B + 523e: f0 91 4c 2b lds r31, 0x2B4C + 5242: 61 83 std Z+1, r22 ; 0x01 + USB_Endpoint_SelectedHandle->CNT = 0; + 5244: e0 91 4b 2b lds r30, 0x2B4B + 5248: f0 91 4c 2b lds r31, 0x2B4C + 524c: 12 82 std Z+2, r1 ; 0x02 + 524e: 13 82 std Z+3, r1 ; 0x03 + USB_Endpoint_SelectedHandle->DATAPTR = (intptr_t)USB_Endpoint_SelectedFIFO->Data; + 5250: 80 91 49 2b lds r24, 0x2B49 + 5254: 90 91 4a 2b lds r25, 0x2B4A + 5258: 84 83 std Z+4, r24 ; 0x04 + 525a: 95 83 std Z+5, r25 ; 0x05 + + USB_Endpoint_SelectedFIFO->Length = (Address & ENDPOINT_DIR_IN) ? Size : 0; + 525c: 40 e0 ldi r20, 0x00 ; 0 + 525e: fc 01 movw r30, r24 + 5260: e0 5c subi r30, 0xC0 ; 192 + 5262: ff 4f sbci r31, 0xFF ; 255 + 5264: 40 83 st Z, r20 + USB_Endpoint_SelectedFIFO->Position = 0; + 5266: fc 01 movw r30, r24 + 5268: ef 5b subi r30, 0xBF ; 191 + 526a: ff 4f sbci r31, 0xFF ; 255 + 526c: 10 82 st Z, r1 + + return true; +} + 526e: 81 e0 ldi r24, 0x01 ; 1 + 5270: 0f 90 pop r0 + 5272: 0f 90 pop r0 + 5274: df 91 pop r29 + 5276: cf 91 pop r28 + 5278: 1f 91 pop r17 + 527a: 08 95 ret + const uint8_t Size) +{ + Endpoint_SelectEndpoint(Address); + + USB_Endpoint_SelectedHandle->CTRL = 0; + USB_Endpoint_SelectedHandle->STATUS = (Address & ENDPOINT_DIR_IN) ? USB_EP_BUSNACK0_bm : 0; + 527c: 82 e0 ldi r24, 0x02 ; 2 + 527e: 80 83 st Z, r24 + USB_Endpoint_SelectedHandle->CTRL = Config; + 5280: e0 91 4b 2b lds r30, 0x2B4B + 5284: f0 91 4c 2b lds r31, 0x2B4C + 5288: 61 83 std Z+1, r22 ; 0x01 + USB_Endpoint_SelectedHandle->CNT = 0; + 528a: e0 91 4b 2b lds r30, 0x2B4B + 528e: f0 91 4c 2b lds r31, 0x2B4C + 5292: 12 82 std Z+2, r1 ; 0x02 + 5294: 13 82 std Z+3, r1 ; 0x03 + USB_Endpoint_SelectedHandle->DATAPTR = (intptr_t)USB_Endpoint_SelectedFIFO->Data; + 5296: 80 91 49 2b lds r24, 0x2B49 + 529a: 90 91 4a 2b lds r25, 0x2B4A + 529e: 84 83 std Z+4, r24 ; 0x04 + 52a0: 95 83 std Z+5, r25 ; 0x05 + 52a2: dd cf rjmp .-70 ; 0x525e + +000052a4 : + } +} + +bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + const uint8_t Entries) +{ + 52a4: af 92 push r10 + 52a6: bf 92 push r11 + 52a8: df 92 push r13 + 52aa: ef 92 push r14 + 52ac: ff 92 push r15 + 52ae: 0f 93 push r16 + 52b0: 1f 93 push r17 + 52b2: cf 93 push r28 + 52b4: df 93 push r29 + 52b6: 00 d0 rcall .+0 ; 0x52b8 + 52b8: cd b7 in r28, 0x3d ; 61 + 52ba: de b7 in r29, 0x3e ; 62 + 52bc: e6 2e mov r14, r22 + for (uint8_t i = 0; i < Entries; i++) + 52be: 66 23 and r22, r22 + 52c0: 09 f4 brne .+2 ; 0x52c4 + 52c2: 4a c0 rjmp .+148 ; 0x5358 + 52c4: 5c 01 movw r10, r24 + USB_Endpoint_SelectedFIFO = &EndpointFIFOPair->OUT; + USB_Endpoint_SelectedHandle = &EndpointTable->Endpoints[EndpointNumber].OUT; + } +} + +bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + 52c6: 8c 01 movw r16, r24 + 52c8: 0c 5f subi r16, 0xFC ; 252 + 52ca: 1f 4f sbci r17, 0xFF ; 255 + const uint8_t Entries) +{ + for (uint8_t i = 0; i < Entries; i++) + 52cc: f1 2c mov r15, r1 + { + if (!(Table[i].Address)) + 52ce: d5 01 movw r26, r10 + 52d0: 5c 91 ld r21, X + 52d2: 55 23 and r21, r21 + 52d4: c9 f1 breq .+114 ; 0x5348 + continue; + + if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks))) + 52d6: d5 01 movw r26, r10 + 52d8: 11 96 adiw r26, 0x01 ; 1 + 52da: ed 91 ld r30, X+ + 52dc: fc 91 ld r31, X + 52de: 12 97 sbiw r26, 0x02 ; 2 + USB_Endpoint_SelectedFIFO = &EndpointFIFOPair->OUT; + USB_Endpoint_SelectedHandle = &EndpointTable->Endpoints[EndpointNumber].OUT; + } +} + +bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + 52e0: d8 01 movw r26, r16 + 52e2: 11 97 sbiw r26, 0x01 ; 1 + for (uint8_t i = 0; i < Entries; i++) + { + if (!(Table[i].Address)) + continue; + + if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks))) + 52e4: 4c 91 ld r20, X + static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address, + const uint8_t Type, + const uint16_t Size, + const uint8_t Banks) + { + uint8_t EPConfigMask = (USB_EP_INTDSBL_bm | ((Banks > 1) ? USB_EP_PINGPONG_bm : 0) | Endpoint_BytesToEPSizeMask(Size)); + 52e6: d8 01 movw r26, r16 + 52e8: 8c 91 ld r24, X + 52ea: 82 30 cpi r24, 0x02 ; 2 + 52ec: 08 f4 brcc .+2 ; 0x52f0 + 52ee: 43 c0 rjmp .+134 ; 0x5376 + 52f0: 98 e1 ldi r25, 0x18 ; 24 + 52f2: 88 e1 ldi r24, 0x18 ; 24 + static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) + { + uint8_t MaskVal = 0; + uint16_t CheckBytes = 8; + + while (CheckBytes < Bytes) + 52f4: e9 30 cpi r30, 0x09 ; 9 + 52f6: f1 05 cpc r31, r1 + 52f8: 50 f0 brcs .+20 ; 0x530e + 52fa: 28 e0 ldi r18, 0x08 ; 8 + 52fc: 30 e0 ldi r19, 0x00 ; 0 + 52fe: 90 e0 ldi r25, 0x00 ; 0 + { + MaskVal++; + 5300: 9f 5f subi r25, 0xFF ; 255 + CheckBytes <<= 1; + 5302: 22 0f add r18, r18 + 5304: 33 1f adc r19, r19 + static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) + { + uint8_t MaskVal = 0; + uint16_t CheckBytes = 8; + + while (CheckBytes < Bytes) + 5306: 2e 17 cp r18, r30 + 5308: 3f 07 cpc r19, r31 + 530a: d0 f3 brcs .-12 ; 0x5300 + 530c: 98 2b or r25, r24 + const uint16_t Size, + const uint8_t Banks) + { + uint8_t EPConfigMask = (USB_EP_INTDSBL_bm | ((Banks > 1) ? USB_EP_PINGPONG_bm : 0) | Endpoint_BytesToEPSizeMask(Size)); + + if ((Address & ENDPOINT_EPNUM_MASK) >= ENDPOINT_TOTAL_ENDPOINTS) + 530e: 25 2f mov r18, r21 + 5310: 2f 70 andi r18, 0x0F ; 15 + 5312: 30 e0 ldi r19, 0x00 ; 0 + 5314: 26 30 cpi r18, 0x06 ; 6 + 5316: 31 05 cpc r19, r1 + 5318: 64 f5 brge .+88 ; 0x5372 + return false; + + // TODO - Fix once limitations are lifted + EPConfigMask &= ~USB_EP_PINGPONG_bm; + if (Size > 64) + 531a: e1 34 cpi r30, 0x41 ; 65 + 531c: f1 05 cpc r31, r1 + 531e: 48 f5 brcc .+82 ; 0x5372 + + if ((Address & ENDPOINT_EPNUM_MASK) >= ENDPOINT_TOTAL_ENDPOINTS) + return false; + + // TODO - Fix once limitations are lifted + EPConfigMask &= ~USB_EP_PINGPONG_bm; + 5320: 9f 7e andi r25, 0xEF ; 239 + if (Size > 64) + return false; + + switch (Type) + 5322: 41 11 cpse r20, r1 + 5324: 2b c0 rjmp .+86 ; 0x537c + { + case EP_TYPE_CONTROL: + EPConfigMask |= USB_EP_TYPE_CONTROL_gc; + 5326: 90 64 ori r25, 0x40 ; 64 + EPConfigMask |= USB_EP_TYPE_BULK_gc; + break; + } + + if (Type == EP_TYPE_CONTROL) + Endpoint_ConfigureEndpoint_PRV(Address ^ ENDPOINT_DIR_IN, EPConfigMask, Size); + 5328: de 2e mov r13, r30 + 532a: 4e 2f mov r20, r30 + 532c: 69 2f mov r22, r25 + 532e: 85 2f mov r24, r21 + 5330: 80 58 subi r24, 0x80 ; 128 + 5332: 59 83 std Y+1, r21 ; 0x01 + 5334: 9a 83 std Y+2, r25 ; 0x02 + 5336: 69 df rcall .-302 ; 0x520a + 5338: 9a 81 ldd r25, Y+2 ; 0x02 + 533a: 59 81 ldd r21, Y+1 ; 0x01 + + return Endpoint_ConfigureEndpoint_PRV(Address, EPConfigMask, Size); + 533c: 4d 2d mov r20, r13 + 533e: 69 2f mov r22, r25 + 5340: 85 2f mov r24, r21 + 5342: 63 df rcall .-314 ; 0x520a + 5344: 88 23 and r24, r24 + 5346: a9 f0 breq .+42 ; 0x5372 +} + +bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + const uint8_t Entries) +{ + for (uint8_t i = 0; i < Entries; i++) + 5348: f3 94 inc r15 + 534a: b5 e0 ldi r27, 0x05 ; 5 + 534c: ab 0e add r10, r27 + 534e: b1 1c adc r11, r1 + 5350: 0b 5f subi r16, 0xFB ; 251 + 5352: 1f 4f sbci r17, 0xFF ; 255 + 5354: fe 10 cpse r15, r14 + 5356: bb cf rjmp .-138 ; 0x52ce + { + return false; + } + } + + return true; + 5358: 81 e0 ldi r24, 0x01 ; 1 +} + 535a: 0f 90 pop r0 + 535c: 0f 90 pop r0 + 535e: df 91 pop r29 + 5360: cf 91 pop r28 + 5362: 1f 91 pop r17 + 5364: 0f 91 pop r16 + 5366: ff 90 pop r15 + 5368: ef 90 pop r14 + 536a: df 90 pop r13 + 536c: bf 90 pop r11 + 536e: af 90 pop r10 + 5370: 08 95 ret + if (!(Table[i].Address)) + continue; + + if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks))) + { + return false; + 5372: 80 e0 ldi r24, 0x00 ; 0 + 5374: f2 cf rjmp .-28 ; 0x535a + static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address, + const uint8_t Type, + const uint16_t Size, + const uint8_t Banks) + { + uint8_t EPConfigMask = (USB_EP_INTDSBL_bm | ((Banks > 1) ? USB_EP_PINGPONG_bm : 0) | Endpoint_BytesToEPSizeMask(Size)); + 5376: 98 e0 ldi r25, 0x08 ; 8 + 5378: 88 e0 ldi r24, 0x08 ; 8 + 537a: bc cf rjmp .-136 ; 0x52f4 + // TODO - Fix once limitations are lifted + EPConfigMask &= ~USB_EP_PINGPONG_bm; + if (Size > 64) + return false; + + switch (Type) + 537c: 41 30 cpi r20, 0x01 ; 1 + 537e: 29 f0 breq .+10 ; 0x538a + break; + case EP_TYPE_ISOCHRONOUS: + EPConfigMask |= USB_EP_TYPE_ISOCHRONOUS_gc; + break; + default: + EPConfigMask |= USB_EP_TYPE_BULK_gc; + 5380: 90 68 ori r25, 0x80 ; 128 + break; + } + + if (Type == EP_TYPE_CONTROL) + 5382: 44 23 and r20, r20 + 5384: 89 f2 breq .-94 ; 0x5328 + 5386: de 2e mov r13, r30 + 5388: d9 cf rjmp .-78 ; 0x533c + { + case EP_TYPE_CONTROL: + EPConfigMask |= USB_EP_TYPE_CONTROL_gc; + break; + case EP_TYPE_ISOCHRONOUS: + EPConfigMask |= USB_EP_TYPE_ISOCHRONOUS_gc; + 538a: 90 6c ori r25, 0xC0 ; 192 + 538c: de 2e mov r13, r30 + 538e: d6 cf rjmp .-84 ; 0x533c + +00005390 : + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + 5390: e0 ec ldi r30, 0xC0 ; 192 + 5392: f4 e0 ldi r31, 0x04 ; 4 + 5394: a6 81 ldd r26, Z+6 ; 0x06 + 5396: b7 81 ldd r27, Z+7 ; 0x07 + 5398: 19 96 adiw r26, 0x09 ; 9 + 539a: 1c 92 st X, r1 + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + 539c: a6 81 ldd r26, Z+6 ; 0x06 + 539e: b7 81 ldd r27, Z+7 ; 0x07 + 53a0: 11 96 adiw r26, 0x01 ; 1 + 53a2: 1c 92 st X, r1 + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + 53a4: a6 81 ldd r26, Z+6 ; 0x06 + 53a6: b7 81 ldd r27, Z+7 ; 0x07 + 53a8: 59 96 adiw r26, 0x19 ; 25 + 53aa: 1c 92 st X, r1 + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + 53ac: a6 81 ldd r26, Z+6 ; 0x06 + 53ae: b7 81 ldd r27, Z+7 ; 0x07 + 53b0: 51 96 adiw r26, 0x11 ; 17 + 53b2: 1c 92 st X, r1 + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + 53b4: a6 81 ldd r26, Z+6 ; 0x06 + 53b6: b7 81 ldd r27, Z+7 ; 0x07 + 53b8: 99 96 adiw r26, 0x29 ; 41 + 53ba: 1c 92 st X, r1 + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + 53bc: a6 81 ldd r26, Z+6 ; 0x06 + 53be: b7 81 ldd r27, Z+7 ; 0x07 + 53c0: 91 96 adiw r26, 0x21 ; 33 + 53c2: 1c 92 st X, r1 + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + 53c4: a6 81 ldd r26, Z+6 ; 0x06 + 53c6: b7 81 ldd r27, Z+7 ; 0x07 + 53c8: d9 96 adiw r26, 0x39 ; 57 + 53ca: 1c 92 st X, r1 + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + 53cc: a6 81 ldd r26, Z+6 ; 0x06 + 53ce: b7 81 ldd r27, Z+7 ; 0x07 + 53d0: d1 96 adiw r26, 0x31 ; 49 + 53d2: 1c 92 st X, r1 + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + 53d4: a6 81 ldd r26, Z+6 ; 0x06 + 53d6: b7 81 ldd r27, Z+7 ; 0x07 + 53d8: a7 5b subi r26, 0xB7 ; 183 + 53da: bf 4f sbci r27, 0xFF ; 255 + 53dc: 1c 92 st X, r1 + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + 53de: a6 81 ldd r26, Z+6 ; 0x06 + 53e0: b7 81 ldd r27, Z+7 ; 0x07 + 53e2: af 5b subi r26, 0xBF ; 191 + 53e4: bf 4f sbci r27, 0xFF ; 255 + 53e6: 1c 92 st X, r1 + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + 53e8: a6 81 ldd r26, Z+6 ; 0x06 + 53ea: b7 81 ldd r27, Z+7 ; 0x07 + 53ec: a7 5a subi r26, 0xA7 ; 167 + 53ee: bf 4f sbci r27, 0xFF ; 255 + 53f0: 1c 92 st X, r1 + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + 53f2: 06 80 ldd r0, Z+6 ; 0x06 + 53f4: f7 81 ldd r31, Z+7 ; 0x07 + 53f6: e0 2d mov r30, r0 + 53f8: ef 5a subi r30, 0xAF ; 175 + 53fa: ff 4f sbci r31, 0xFF ; 255 + 53fc: 10 82 st Z, r1 + 53fe: 08 95 ret + +00005400 : + } +} + +void Endpoint_ClearStatusStage(void) +{ + if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) + 5400: 80 91 41 2b lds r24, 0x2B41 + 5404: 87 fd sbrc r24, 7 + 5406: 08 c0 rjmp .+16 ; 0x5418 + + Endpoint_ClearOUT(); + } + else + { + while (!(Endpoint_IsINReady())) + 5408: f4 de rcall .-536 ; 0x51f2 + 540a: 81 11 cpse r24, r1 + 540c: 0d c0 rjmp .+26 ; 0x5428 + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + 540e: 80 91 40 2b lds r24, 0x2B40 + 5412: 81 11 cpse r24, r1 + 5414: f9 cf rjmp .-14 ; 0x5408 + 5416: 08 95 ret + +void Endpoint_ClearStatusStage(void) +{ + if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) + { + while (!(Endpoint_IsOUTReceived())) + 5418: d3 de rcall .-602 ; 0x51c0 + 541a: 81 11 cpse r24, r1 + 541c: 06 c0 rjmp .+12 ; 0x542a + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + 541e: 80 91 40 2b lds r24, 0x2B40 + 5422: 81 11 cpse r24, r1 + 5424: f9 cf rjmp .-14 ; 0x5418 + 5426: 08 95 ret + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearIN(); + 5428: eb cd rjmp .-1066 ; 0x5000 + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearOUT(); + 542a: 03 ce rjmp .-1018 ; 0x5032 + +0000542c : + } +} + +#if !defined(CONTROL_ONLY_DEVICE) +uint8_t Endpoint_WaitUntilReady(void) +{ + 542c: 1f 93 push r17 + 542e: cf 93 push r28 + 5430: df 93 push r29 + * \return Current USB frame number from the USB controller. + */ + static inline uint16_t USB_Device_GetFrameNumber(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint16_t USB_Device_GetFrameNumber(void) + { + return ((USB_EndpointTable_t*)USB.EPPTR)->FrameNum; + 5432: e0 91 c6 04 lds r30, 0x04C6 + 5436: f0 91 c7 04 lds r31, 0x04C7 + 543a: e0 5a subi r30, 0xA0 ; 160 + 543c: ff 4f sbci r31, 0xFF ; 255 + 543e: c0 81 ld r28, Z + 5440: d1 81 ldd r29, Z+1 ; 0x01 + #if (USB_STREAM_TIMEOUT_MS < 0xFF) + uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + 5442: 14 e6 ldi r17, 0x64 ; 100 + * \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask. + */ + static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_GetEndpointDirection(void) + { + return (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN); + 5444: 80 91 4d 2b lds r24, 0x2B4D + 5448: 80 78 andi r24, 0x80 ; 128 + + uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber(); + + for (;;) + { + if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) + 544a: 80 38 cpi r24, 0x80 ; 128 + 544c: 31 f1 breq .+76 ; 0x549a + if (Endpoint_IsINReady()) + return ENDPOINT_READYWAIT_NoError; + } + else + { + if (Endpoint_IsOUTReceived()) + 544e: b8 de rcall .-656 ; 0x51c0 + 5450: 81 11 cpse r24, r1 + 5452: 26 c0 rjmp .+76 ; 0x54a0 + return ENDPOINT_READYWAIT_NoError; + } + + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 5454: 80 91 40 2b lds r24, 0x2B40 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 5458: 88 23 and r24, r24 + 545a: 39 f1 breq .+78 ; 0x54aa + return ENDPOINT_READYWAIT_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + 545c: 85 30 cpi r24, 0x05 ; 5 + 545e: 51 f1 breq .+84 ; 0x54b4 + * \return Boolean \c true if the currently selected endpoint is stalled, \c false otherwise. + */ + static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsStalled(void) + { + return ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_STALL_bm) ? true : false); + 5460: e0 91 4b 2b lds r30, 0x2B4B + 5464: f0 91 4c 2b lds r31, 0x2B4C + 5468: 81 81 ldd r24, Z+1 ; 0x01 + return ENDPOINT_READYWAIT_BusSuspended; + else if (Endpoint_IsStalled()) + 546a: 82 fd sbrc r24, 2 + 546c: 28 c0 rjmp .+80 ; 0x54be + 546e: e0 91 c6 04 lds r30, 0x04C6 + 5472: f0 91 c7 04 lds r31, 0x04C7 + 5476: e0 5a subi r30, 0xA0 ; 160 + 5478: ff 4f sbci r31, 0xFF ; 255 + 547a: 80 81 ld r24, Z + 547c: 91 81 ldd r25, Z+1 ; 0x01 + return ENDPOINT_READYWAIT_EndpointStalled; + + uint16_t CurrentFrameNumber = USB_Device_GetFrameNumber(); + + if (CurrentFrameNumber != PreviousFrameNumber) + 547e: c8 17 cp r28, r24 + 5480: d9 07 cpc r29, r25 + 5482: 01 f3 breq .-64 ; 0x5444 + { + PreviousFrameNumber = CurrentFrameNumber; + + if (!(TimeoutMSRem--)) + 5484: 21 2f mov r18, r17 + 5486: 21 50 subi r18, 0x01 ; 1 + 5488: 11 23 and r17, r17 + 548a: f1 f0 breq .+60 ; 0x54c8 + 548c: ec 01 movw r28, r24 + 548e: 12 2f mov r17, r18 + * \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask. + */ + static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_GetEndpointDirection(void) + { + return (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN); + 5490: 80 91 4d 2b lds r24, 0x2B4D + 5494: 80 78 andi r24, 0x80 ; 128 + + uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber(); + + for (;;) + { + if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) + 5496: 80 38 cpi r24, 0x80 ; 128 + 5498: d1 f6 brne .-76 ; 0x544e + { + if (Endpoint_IsINReady()) + 549a: ab de rcall .-682 ; 0x51f2 + 549c: 88 23 and r24, r24 + 549e: d1 f2 breq .-76 ; 0x5454 + return ENDPOINT_READYWAIT_NoError; + 54a0: 80 e0 ldi r24, 0x00 ; 0 + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + } + } +} + 54a2: df 91 pop r29 + 54a4: cf 91 pop r28 + 54a6: 1f 91 pop r17 + 54a8: 08 95 ret + } + + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_READYWAIT_DeviceDisconnected; + 54aa: 82 e0 ldi r24, 0x02 ; 2 + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + } + } +} + 54ac: df 91 pop r29 + 54ae: cf 91 pop r28 + 54b0: 1f 91 pop r17 + 54b2: 08 95 ret + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_READYWAIT_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_READYWAIT_BusSuspended; + 54b4: 83 e0 ldi r24, 0x03 ; 3 + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + } + } +} + 54b6: df 91 pop r29 + 54b8: cf 91 pop r28 + 54ba: 1f 91 pop r17 + 54bc: 08 95 ret + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_READYWAIT_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_READYWAIT_BusSuspended; + else if (Endpoint_IsStalled()) + return ENDPOINT_READYWAIT_EndpointStalled; + 54be: 81 e0 ldi r24, 0x01 ; 1 + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + } + } +} + 54c0: df 91 pop r29 + 54c2: cf 91 pop r28 + 54c4: 1f 91 pop r17 + 54c6: 08 95 ret + if (CurrentFrameNumber != PreviousFrameNumber) + { + PreviousFrameNumber = CurrentFrameNumber; + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + 54c8: 84 e0 ldi r24, 0x04 ; 4 + } + } +} + 54ca: df 91 pop r29 + 54cc: cf 91 pop r28 + 54ce: 1f 91 pop r17 + 54d0: 08 95 ret + +000054d2 : + USB_ResetInterface(); +} + +void USB_Disable(void) +{ + USB_INT_DisableAllInterrupts(); + 54d2: 63 d0 rcall .+198 ; 0x559a + USB_INT_ClearAllInterrupts(); + 54d4: 69 d0 rcall .+210 ; 0x55a8 + * enumerating the device once attached until \ref USB_Attach() is called. + */ + static inline void USB_Detach(void) ATTR_ALWAYS_INLINE; + static inline void USB_Detach(void) + { + USB.CTRLB &= ~USB_ATTACH_bm; + 54d6: e0 ec ldi r30, 0xC0 ; 192 + 54d8: f4 e0 ldi r31, 0x04 ; 4 + 54da: 81 81 ldd r24, Z+1 ; 0x01 + 54dc: 8e 7f andi r24, 0xFE ; 254 + 54de: 81 83 std Z+1, r24 ; 0x01 + } + + static inline void USB_Controller_Disable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Disable(void) + { + USB.CTRLA &= ~USB_ENABLE_bm; + 54e0: 80 81 ld r24, Z + 54e2: 8f 77 andi r24, 0x7F ; 127 + 54e4: 80 83 st Z, r24 + + USB_Detach(); + USB_Controller_Disable(); + + USB_IsInitialized = false; + 54e6: 10 92 3f 2b sts 0x2B3F, r1 + 54ea: 08 95 ret + +000054ec : +} + +void USB_ResetInterface(void) +{ + 54ec: cf 93 push r28 + 54ee: df 93 push r29 + #if defined(USB_DEVICE_OPT_FULLSPEED) + if (USB_Options & USB_DEVICE_OPT_LOWSPEED) + CLK.USBCTRL = (((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp); + else + CLK.USBCTRL = (((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp); + 54f0: e0 e4 ldi r30, 0x40 ; 64 + 54f2: f0 e0 ldi r31, 0x00 ; 0 + 54f4: 14 82 std Z+4, r1 ; 0x04 + #else + CLK.USBCTRL = (((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp); + #endif + + if (USB_Options & USB_OPT_PLLCLKSRC) + CLK.USBCTRL |= (CLK_USBSRC_PLL_gc | CLK_USBSEN_bm); + 54f6: 84 81 ldd r24, Z+4 ; 0x04 + 54f8: 81 60 ori r24, 0x01 ; 1 + 54fa: 84 83 std Z+4, r24 ; 0x04 + else + CLK.USBCTRL |= (CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm); + + USB_Device_SetDeviceAddress(0); + + USB_INT_DisableAllInterrupts(); + 54fc: 4e d0 rcall .+156 ; 0x559a + USB_INT_ClearAllInterrupts(); + 54fe: 54 d0 rcall .+168 ; 0x55a8 + } + + static inline void USB_Controller_Reset(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Reset(void) + { + USB.CTRLA &= ~USB_ENABLE_bm; + 5500: c0 ec ldi r28, 0xC0 ; 192 + 5502: d4 e0 ldi r29, 0x04 ; 4 + 5504: 88 81 ld r24, Y + 5506: 8f 77 andi r24, 0x7F ; 127 + 5508: 88 83 st Y, r24 + USB.CTRLA |= USB_ENABLE_bm; + 550a: 88 81 ld r24, Y + 550c: 80 68 ori r24, 0x80 ; 128 + 550e: 88 83 st Y, r24 +} + +#if defined(USB_CAN_BE_DEVICE) +static void USB_Init_Device(void) +{ + USB_DeviceState = DEVICE_STATE_Unattached; + 5510: 10 92 40 2b sts 0x2B40, r1 + USB_Device_ConfigurationNumber = 0; + 5514: 10 92 3c 2b sts 0x2B3C, r1 + + #if !defined(NO_DEVICE_REMOTE_WAKEUP) + USB_Device_RemoteWakeupEnabled = false; + 5518: 10 92 3e 2b sts 0x2B3E, r1 + #endif + + #if !defined(NO_DEVICE_SELF_POWER) + USB_Device_CurrentlySelfPowered = false; + 551c: 10 92 3d 2b sts 0x2B3D, r1 + } + + static inline void USB_Device_SetFullSpeed(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetFullSpeed(void) + { + USB.CTRLA |= USB_SPEED_bm; + 5520: 88 81 ld r24, Y + 5522: 80 64 ori r24, 0x40 ; 64 + 5524: 88 83 st Y, r24 + EPConfigMask |= USB_EP_TYPE_BULK_gc; + break; + } + + if (Type == EP_TYPE_CONTROL) + Endpoint_ConfigureEndpoint_PRV(Address ^ ENDPOINT_DIR_IN, EPConfigMask, Size); + 5526: 48 e0 ldi r20, 0x08 ; 8 + 5528: 68 e4 ldi r22, 0x48 ; 72 + 552a: 80 e8 ldi r24, 0x80 ; 128 + 552c: 6e de rcall .-804 ; 0x520a + + return Endpoint_ConfigureEndpoint_PRV(Address, EPConfigMask, Size); + 552e: 48 e0 ldi r20, 0x08 ; 8 + 5530: 68 e4 ldi r22, 0x48 ; 72 + 5532: 80 e0 ldi r24, 0x00 ; 0 + 5534: 6a de rcall .-812 ; 0x520a + static inline void USB_INT_Enable(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_BUSEVENTI: + USB.INTCTRLA |= USB_BUSEVIE_bm; + 5536: 88 85 ldd r24, Y+8 ; 0x08 + 5538: 80 64 ori r24, 0x40 ; 64 + 553a: 88 87 std Y+8, r24 ; 0x08 + * register and despite the datasheet making no mention of its requirement in host mode. + */ + static inline void USB_Attach(void) ATTR_ALWAYS_INLINE; + static inline void USB_Attach(void) + { + USB.CTRLB |= USB_ATTACH_bm; + 553c: 89 81 ldd r24, Y+1 ; 0x01 + 553e: 81 60 ori r24, 0x01 ; 1 + 5540: 89 83 std Y+1, r24 ; 0x01 + USB_INT_DisableAllInterrupts(); + USB_INT_ClearAllInterrupts(); + + USB_Controller_Reset(); + USB_Init_Device(); +} + 5542: df 91 pop r29 + 5544: cf 91 pop r28 + 5546: 08 95 ret + +00005548 : + + #if !defined(USE_STATIC_OPTIONS) + const uint8_t Options + #endif + ) +{ + 5548: cf 93 push r28 + 554a: df 93 push r29 + #if (ARCH == ARCH_AVR8) + return SREG; + #elif (ARCH == ARCH_UC3) + return __builtin_mfsr(AVR32_SR); + #elif (ARCH == ARCH_XMEGA) + return SREG; + 554c: 3f b7 in r19, 0x3f ; 63 + #if (ARCH == ARCH_AVR8) + cli(); + #elif (ARCH == ARCH_UC3) + __builtin_ssrf(AVR32_SR_GM_OFFSET); + #elif (ARCH == ARCH_XMEGA) + cli(); + 554e: f8 94 cli + #endif + + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; + 5550: c0 ec ldi r28, 0xC0 ; 192 + 5552: d1 e0 ldi r29, 0x01 ; 1 + 5554: 22 e0 ldi r18, 0x02 ; 2 + 5556: 2a 87 std Y+10, r18 ; 0x0a + USB.CAL0 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL0)); + 5558: ea e1 ldi r30, 0x1A ; 26 + 555a: f0 e0 ldi r31, 0x00 ; 0 + 555c: e4 91 lpm r30, Z + 555e: a0 ec ldi r26, 0xC0 ; 192 + 5560: b4 e0 ldi r27, 0x04 ; 4 + 5562: da 96 adiw r26, 0x3a ; 58 + 5564: ec 93 st X, r30 + 5566: da 97 sbiw r26, 0x3a ; 58 + USB.CAL1 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL1)); + 5568: eb e1 ldi r30, 0x1B ; 27 + 556a: f0 e0 ldi r31, 0x00 ; 0 + 556c: e4 91 lpm r30, Z + 556e: db 96 adiw r26, 0x3b ; 59 + 5570: ec 93 st X, r30 + 5572: db 97 sbiw r26, 0x3b ; 59 + NVM.CMD = NVM_CMD_NO_OPERATION_gc; + 5574: 1a 86 std Y+10, r1 ; 0x0a + + /* Ugly workaround to ensure an aligned table, since __BIGGEST_ALIGNMENT__ == 1 for the 8-bit AVR-GCC toolchain */ + USB.EPPTR = ((intptr_t)&USB_EndpointTable[1] & ~(1 << 0)); + 5576: 87 e6 ldi r24, 0x67 ; 103 + 5578: 9e e2 ldi r25, 0x2E ; 46 + 557a: 8e 7f andi r24, 0xFE ; 254 + 557c: 16 96 adiw r26, 0x06 ; 6 + 557e: 8d 93 st X+, r24 + 5580: 9c 93 st X, r25 + 5582: 17 97 sbiw r26, 0x07 ; 7 + USB.CTRLA = (USB_STFRNUM_bm | ((ENDPOINT_TOTAL_ENDPOINTS - 1) << USB_MAXEP_gp)); + 5584: 85 e1 ldi r24, 0x15 ; 21 + 5586: 8c 93 st X, r24 + + if ((USB_Options & USB_OPT_BUSEVENT_PRIHIGH) == USB_OPT_BUSEVENT_PRIHIGH) + USB.INTCTRLA = (3 << USB_INTLVL_gp); + else if ((USB_Options & USB_OPT_BUSEVENT_PRIMED) == USB_OPT_BUSEVENT_PRIMED) + USB.INTCTRLA = (2 << USB_INTLVL_gp); + 5588: 18 96 adiw r26, 0x08 ; 8 + 558a: 2c 93 st X, r18 + if (GlobalIntState & AVR32_SR_GM) + __builtin_ssrf(AVR32_SR_GM_OFFSET); + else + __builtin_csrf(AVR32_SR_GM_OFFSET); + #elif (ARCH == ARCH_XMEGA) + SREG = GlobalIntState; + 558c: 3f bf out 0x3f, r19 ; 63 + + #if defined(USB_CAN_BE_BOTH) + USB_CurrentMode = Mode; + #endif + + USB_IsInitialized = true; + 558e: 81 e0 ldi r24, 0x01 ; 1 + 5590: 80 93 3f 2b sts 0x2B3F, r24 + + USB_ResetInterface(); +} + 5594: df 91 pop r29 + 5596: cf 91 pop r28 + USB_CurrentMode = Mode; + #endif + + USB_IsInitialized = true; + + USB_ResetInterface(); + 5598: a9 cf rjmp .-174 ; 0x54ec + +0000559a : +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBInterrupt.h" + +void USB_INT_DisableAllInterrupts(void) +{ + USB.INTCTRLA &= USB_INTLVL_gm; + 559a: e0 ec ldi r30, 0xC0 ; 192 + 559c: f4 e0 ldi r31, 0x04 ; 4 + 559e: 80 85 ldd r24, Z+8 ; 0x08 + 55a0: 83 70 andi r24, 0x03 ; 3 + 55a2: 80 87 std Z+8, r24 ; 0x08 + USB.INTCTRLB = 0; + 55a4: 11 86 std Z+9, r1 ; 0x09 + 55a6: 08 95 ret + +000055a8 : +} + +void USB_INT_ClearAllInterrupts(void) +{ + USB.INTFLAGSACLR = 0xFF; + 55a8: e0 ec ldi r30, 0xC0 ; 192 + 55aa: f4 e0 ldi r31, 0x04 ; 4 + 55ac: 8f ef ldi r24, 0xFF ; 255 + 55ae: 82 87 std Z+10, r24 ; 0x0a + USB.INTFLAGSBCLR = 0xFF; + 55b0: 84 87 std Z+12, r24 ; 0x0c + 55b2: 08 95 ret + +000055b4 <__vector_125>: +} + +ISR(USB_BUSEVENT_vect) +{ + 55b4: 1f 92 push r1 + 55b6: 0f 92 push r0 + 55b8: 0f b6 in r0, 0x3f ; 63 + 55ba: 0f 92 push r0 + 55bc: 11 24 eor r1, r1 + 55be: 2f 93 push r18 + 55c0: 3f 93 push r19 + 55c2: 4f 93 push r20 + 55c4: 5f 93 push r21 + 55c6: 6f 93 push r22 + 55c8: 7f 93 push r23 + 55ca: 8f 93 push r24 + 55cc: 9f 93 push r25 + 55ce: af 93 push r26 + 55d0: bf 93 push r27 + 55d2: ef 93 push r30 + 55d4: ff 93 push r31 + case USB_INT_BUSEVENTI_Resume: + return ((USB.INTFLAGSACLR & USB_RESUMEIF_bm) ? true : false); + case USB_INT_BUSEVENTI_Reset: + return ((USB.INTFLAGSACLR & USB_RSTIF_bm) ? true : false); + case USB_INT_SOFI: + return ((USB.INTFLAGSACLR & USB_SOFIF_bm) ? true : false); + 55d6: 80 91 ca 04 lds r24, 0x04CA + #if !defined(NO_SOF_EVENTS) + if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI)) + 55da: 87 fd sbrc r24, 7 + 55dc: 4d c0 rjmp .+154 ; 0x5678 <__vector_125+0xc4> + static inline bool USB_INT_HasOccurred(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_BUSEVENTI_Suspend: + return ((USB.INTFLAGSACLR & USB_SUSPENDIF_bm) ? true : false); + 55de: 80 91 ca 04 lds r24, 0x04CA + + EVENT_USB_Device_StartOfFrame(); + } + #endif + + if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Suspend)) + 55e2: 86 fd sbrc r24, 6 + 55e4: 41 c0 rjmp .+130 ; 0x5668 <__vector_125+0xb4> + case USB_INT_BUSEVENTI_Resume: + return ((USB.INTFLAGSACLR & USB_RESUMEIF_bm) ? true : false); + 55e6: 80 91 ca 04 lds r24, 0x04CA + USB_DeviceState = DEVICE_STATE_Suspended; + EVENT_USB_Device_Suspend(); + #endif + } + + if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Resume)) + 55ea: 85 ff sbrs r24, 5 + 55ec: 0c c0 rjmp .+24 ; 0x5606 <__vector_125+0x52> + { + case USB_INT_BUSEVENTI_Suspend: + USB.INTFLAGSACLR = USB_SUSPENDIF_bm; + break; + case USB_INT_BUSEVENTI_Resume: + USB.INTFLAGSACLR = USB_RESUMEIF_bm; + 55ee: 80 e2 ldi r24, 0x20 ; 32 + 55f0: 80 93 ca 04 sts 0x04CA, r24 + { + USB_INT_Clear(USB_INT_BUSEVENTI_Resume); + + if (USB_Device_ConfigurationNumber) + 55f4: 80 91 3c 2b lds r24, 0x2B3C + 55f8: 88 23 and r24, r24 + 55fa: 71 f1 breq .+92 ; 0x5658 <__vector_125+0xa4> + USB_DeviceState = DEVICE_STATE_Configured; + 55fc: 84 e0 ldi r24, 0x04 ; 4 + 55fe: 80 93 40 2b sts 0x2B40, r24 + else + USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Addressed : DEVICE_STATE_Powered; + + #if !defined(NO_LIMITED_CONTROLLER_CONNECT) + EVENT_USB_Device_Connect(); + 5602: 0e 94 41 11 call 0x2282 ; 0x2282 + case USB_INT_BUSEVENTI_Suspend: + return ((USB.INTFLAGSACLR & USB_SUSPENDIF_bm) ? true : false); + case USB_INT_BUSEVENTI_Resume: + return ((USB.INTFLAGSACLR & USB_RESUMEIF_bm) ? true : false); + case USB_INT_BUSEVENTI_Reset: + return ((USB.INTFLAGSACLR & USB_RSTIF_bm) ? true : false); + 5606: 80 91 ca 04 lds r24, 0x04CA + #else + EVENT_USB_Device_WakeUp(); + #endif + } + + if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Reset)) + 560a: 84 ff sbrs r24, 4 + 560c: 14 c0 rjmp .+40 ; 0x5636 <__vector_125+0x82> + break; + case USB_INT_BUSEVENTI_Resume: + USB.INTFLAGSACLR = USB_RESUMEIF_bm; + break; + case USB_INT_BUSEVENTI_Reset: + USB.INTFLAGSACLR = USB_RSTIF_bm; + 560e: 80 e1 ldi r24, 0x10 ; 16 + 5610: 80 93 ca 04 sts 0x04CA, r24 + { + USB_INT_Clear(USB_INT_BUSEVENTI_Reset); + + USB_DeviceState = DEVICE_STATE_Default; + 5614: 82 e0 ldi r24, 0x02 ; 2 + 5616: 80 93 40 2b sts 0x2B40, r24 + USB_Device_ConfigurationNumber = 0; + 561a: 10 92 3c 2b sts 0x2B3C, r1 + } + + static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) + { + USB.ADDR = Address; + 561e: 10 92 c3 04 sts 0x04C3, r1 + + USB_Device_EnableDeviceAddress(0); + + Endpoint_ClearEndpoints(); + 5622: b6 de rcall .-660 ; 0x5390 + EPConfigMask |= USB_EP_TYPE_BULK_gc; + break; + } + + if (Type == EP_TYPE_CONTROL) + Endpoint_ConfigureEndpoint_PRV(Address ^ ENDPOINT_DIR_IN, EPConfigMask, Size); + 5624: 48 e0 ldi r20, 0x08 ; 8 + 5626: 68 e4 ldi r22, 0x48 ; 72 + 5628: 80 e8 ldi r24, 0x80 ; 128 + 562a: ef dd rcall .-1058 ; 0x520a + + return Endpoint_ConfigureEndpoint_PRV(Address, EPConfigMask, Size); + 562c: 48 e0 ldi r20, 0x08 ; 8 + 562e: 68 e4 ldi r22, 0x48 ; 72 + 5630: 80 e0 ldi r24, 0x00 ; 0 + 5632: eb dd rcall .-1066 ; 0x520a + Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, + USB_Device_ControlEndpointSize, 1); + + EVENT_USB_Device_Reset(); + 5634: 23 db rcall .-2490 ; 0x4c7c + } +} + 5636: ff 91 pop r31 + 5638: ef 91 pop r30 + 563a: bf 91 pop r27 + 563c: af 91 pop r26 + 563e: 9f 91 pop r25 + 5640: 8f 91 pop r24 + 5642: 7f 91 pop r23 + 5644: 6f 91 pop r22 + 5646: 5f 91 pop r21 + 5648: 4f 91 pop r20 + 564a: 3f 91 pop r19 + 564c: 2f 91 pop r18 + 564e: 0f 90 pop r0 + 5650: 0f be out 0x3f, r0 ; 63 + 5652: 0f 90 pop r0 + 5654: 1f 90 pop r1 + 5656: 18 95 reti + } + + static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline bool USB_Device_IsAddressSet(void) + { + return ((USB.ADDR != 0) ? true : false); + 5658: 80 91 c3 04 lds r24, 0x04C3 + USB_INT_Clear(USB_INT_BUSEVENTI_Resume); + + if (USB_Device_ConfigurationNumber) + USB_DeviceState = DEVICE_STATE_Configured; + else + USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Addressed : DEVICE_STATE_Powered; + 565c: 81 11 cpse r24, r1 + 565e: 15 c0 rjmp .+42 ; 0x568a <__vector_125+0xd6> + 5660: 81 e0 ldi r24, 0x01 ; 1 + 5662: 80 93 40 2b sts 0x2B40, r24 + 5666: cd cf rjmp .-102 ; 0x5602 <__vector_125+0x4e> + static inline void USB_INT_Clear(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_BUSEVENTI_Suspend: + USB.INTFLAGSACLR = USB_SUSPENDIF_bm; + 5668: 80 e4 ldi r24, 0x40 ; 64 + 566a: 80 93 ca 04 sts 0x04CA, r24 + if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Suspend)) + { + USB_INT_Clear(USB_INT_BUSEVENTI_Suspend); + + #if !defined(NO_LIMITED_CONTROLLER_CONNECT) + USB_DeviceState = DEVICE_STATE_Unattached; + 566e: 10 92 40 2b sts 0x2B40, r1 + EVENT_USB_Device_Disconnect(); + 5672: 0e 94 44 11 call 0x2288 ; 0x2288 + 5676: b7 cf rjmp .-146 ; 0x55e6 <__vector_125+0x32> + switch (Interrupt) + { + case USB_INT_BUSEVENTI: + return ((USB.INTCTRLA & USB_BUSEVIE_bm) ? true : false); + case USB_INT_SOFI: + return ((USB.INTCTRLA & USB_SOFIE_bm) ? true : false); + 5678: 80 91 c8 04 lds r24, 0x04C8 +} + +ISR(USB_BUSEVENT_vect) +{ + #if !defined(NO_SOF_EVENTS) + if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI)) + 567c: 87 ff sbrs r24, 7 + 567e: af cf rjmp .-162 ; 0x55de <__vector_125+0x2a> + break; + case USB_INT_BUSEVENTI_Reset: + USB.INTFLAGSACLR = USB_RSTIF_bm; + break; + case USB_INT_SOFI: + USB.INTFLAGSACLR = USB_SOFIF_bm; + 5680: 80 e8 ldi r24, 0x80 ; 128 + 5682: 80 93 ca 04 sts 0x04CA, r24 + { + USB_INT_Clear(USB_INT_SOFI); + + EVENT_USB_Device_StartOfFrame(); + 5686: fa da rcall .-2572 ; 0x4c7c + 5688: aa cf rjmp .-172 ; 0x55de <__vector_125+0x2a> + USB_INT_Clear(USB_INT_BUSEVENTI_Resume); + + if (USB_Device_ConfigurationNumber) + USB_DeviceState = DEVICE_STATE_Configured; + else + USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Addressed : DEVICE_STATE_Powered; + 568a: 83 e0 ldi r24, 0x03 ; 3 + 568c: ea cf rjmp .-44 ; 0x5662 <__vector_125+0xae> + +0000568e : + +void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + FILE* const Stream) +{ + *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW); + fdev_set_udata(Stream, CDCInterfaceInfo); + 568e: cf 93 push r28 + 5690: df 93 push r29 + 5692: ec 01 movw r28, r24 + 5694: 40 96 adiw r24, 0x10 ; 16 + 5696: fc 01 movw r30, r24 + 5698: 8b e0 ldi r24, 0x0B ; 11 + 569a: df 01 movw r26, r30 + 569c: 1d 92 st X+, r1 + 569e: 8a 95 dec r24 + 56a0: e9 f7 brne .-6 ; 0x569c + 56a2: 82 e0 ldi r24, 0x02 ; 2 + 56a4: 8c 83 std Y+4, r24 ; 0x04 + 56a6: 89 87 std Y+9, r24 ; 0x09 + 56a8: 83 e0 ldi r24, 0x03 ; 3 + 56aa: 8e 87 std Y+14, r24 ; 0x0e + 56ac: 61 e0 ldi r22, 0x01 ; 1 + 56ae: ce 01 movw r24, r28 + 56b0: 01 96 adiw r24, 0x01 ; 1 + 56b2: f8 dd rcall .-1040 ; 0x52a4 + 56b4: 81 11 cpse r24, r1 + 56b6: 04 c0 rjmp .+8 ; 0x56c0 + 56b8: 80 e0 ldi r24, 0x00 ; 0 + 56ba: df 91 pop r29 + 56bc: cf 91 pop r28 + 56be: 08 95 ret + 56c0: 61 e0 ldi r22, 0x01 ; 1 + 56c2: ce 01 movw r24, r28 + 56c4: 06 96 adiw r24, 0x06 ; 6 + 56c6: ee dd rcall .-1060 ; 0x52a4 + 56c8: 88 23 and r24, r24 + 56ca: b1 f3 breq .-20 ; 0x56b8 + 56cc: 61 e0 ldi r22, 0x01 ; 1 + 56ce: ce 01 movw r24, r28 + 56d0: 0b 96 adiw r24, 0x0b ; 11 + 56d2: df 91 pop r29 + 56d4: cf 91 pop r28 + 56d6: e6 cd rjmp .-1076 ; 0x52a4 + +000056d8 : + 56d8: cf 93 push r28 + 56da: df 93 push r29 + 56dc: d6 2f mov r29, r22 + 56de: c7 2f mov r28, r23 + 56e0: 20 91 40 2b lds r18, 0x2B40 + 56e4: 24 30 cpi r18, 0x04 ; 4 + 56e6: 21 f0 breq .+8 ; 0x56f0 + 56e8: 82 e0 ldi r24, 0x02 ; 2 + 56ea: df 91 pop r29 + 56ec: cf 91 pop r28 + 56ee: 08 95 ret + 56f0: fc 01 movw r30, r24 + 56f2: 44 89 ldd r20, Z+20 ; 0x14 + 56f4: 55 89 ldd r21, Z+21 ; 0x15 + 56f6: 66 89 ldd r22, Z+22 ; 0x16 + 56f8: 77 89 ldd r23, Z+23 ; 0x17 + 56fa: 45 2b or r20, r21 + 56fc: 46 2b or r20, r22 + 56fe: 47 2b or r20, r23 + 5700: 99 f3 breq .-26 ; 0x56e8 + 5702: 81 81 ldd r24, Z+1 ; 0x01 + 5704: c3 dc rcall .-1658 ; 0x508c + 5706: ad 2f mov r26, r29 + 5708: bc 2f mov r27, r28 + 570a: fd 01 movw r30, r26 + 570c: 01 90 ld r0, Z+ + 570e: 00 20 and r0, r0 + 5710: e9 f7 brne .-6 ; 0x570c + 5712: bf 01 movw r22, r30 + 5714: 61 50 subi r22, 0x01 ; 1 + 5716: 71 09 sbc r23, r1 + 5718: 6a 1b sub r22, r26 + 571a: 7b 0b sbc r23, r27 + 571c: 40 e0 ldi r20, 0x00 ; 0 + 571e: 50 e0 ldi r21, 0x00 ; 0 + 5720: 8d 2f mov r24, r29 + 5722: 9c 2f mov r25, r28 + 5724: df 91 pop r29 + 5726: cf 91 pop r28 + 5728: bf ca rjmp .-2690 ; 0x4ca8 + +0000572a : + 572a: ef 92 push r14 + 572c: ff 92 push r15 + 572e: 0f 93 push r16 + 5730: 1f 93 push r17 + 5732: cf 93 push r28 + 5734: df 93 push r29 + 5736: eb 01 movw r28, r22 + 5738: 7a 01 movw r14, r20 + 573a: 20 91 40 2b lds r18, 0x2B40 + 573e: 24 30 cpi r18, 0x04 ; 4 + 5740: 41 f0 breq .+16 ; 0x5752 + 5742: 82 e0 ldi r24, 0x02 ; 2 + 5744: df 91 pop r29 + 5746: cf 91 pop r28 + 5748: 1f 91 pop r17 + 574a: 0f 91 pop r16 + 574c: ff 90 pop r15 + 574e: ef 90 pop r14 + 5750: 08 95 ret + 5752: fc 01 movw r30, r24 + 5754: 04 89 ldd r16, Z+20 ; 0x14 + 5756: 15 89 ldd r17, Z+21 ; 0x15 + 5758: 26 89 ldd r18, Z+22 ; 0x16 + 575a: 37 89 ldd r19, Z+23 ; 0x17 + 575c: 01 2b or r16, r17 + 575e: 02 2b or r16, r18 + 5760: 03 2b or r16, r19 + 5762: 79 f3 breq .-34 ; 0x5742 + 5764: 81 81 ldd r24, Z+1 ; 0x01 + 5766: 92 dc rcall .-1756 ; 0x508c + 5768: 40 e0 ldi r20, 0x00 ; 0 + 576a: 50 e0 ldi r21, 0x00 ; 0 + 576c: b7 01 movw r22, r14 + 576e: ce 01 movw r24, r28 + 5770: df 91 pop r29 + 5772: cf 91 pop r28 + 5774: 1f 91 pop r17 + 5776: 0f 91 pop r16 + 5778: ff 90 pop r15 + 577a: ef 90 pop r14 + 577c: 95 ca rjmp .-2774 ; 0x4ca8 + +0000577e : + 577e: 0f 93 push r16 + 5780: 1f 93 push r17 + 5782: cf 93 push r28 + 5784: df 93 push r29 + 5786: 1f 92 push r1 + 5788: cd b7 in r28, 0x3d ; 61 + 578a: de b7 in r29, 0x3e ; 62 + 578c: 20 91 40 2b lds r18, 0x2B40 + 5790: 24 30 cpi r18, 0x04 ; 4 + 5792: 39 f0 breq .+14 ; 0x57a2 + 5794: 82 e0 ldi r24, 0x02 ; 2 + 5796: 0f 90 pop r0 + 5798: df 91 pop r29 + 579a: cf 91 pop r28 + 579c: 1f 91 pop r17 + 579e: 0f 91 pop r16 + 57a0: 08 95 ret + 57a2: fc 01 movw r30, r24 + 57a4: 04 89 ldd r16, Z+20 ; 0x14 + 57a6: 15 89 ldd r17, Z+21 ; 0x15 + 57a8: 26 89 ldd r18, Z+22 ; 0x16 + 57aa: 37 89 ldd r19, Z+23 ; 0x17 + 57ac: 01 2b or r16, r17 + 57ae: 02 2b or r16, r18 + 57b0: 03 2b or r16, r19 + 57b2: 81 f3 breq .-32 ; 0x5794 + 57b4: 81 81 ldd r24, Z+1 ; 0x01 + 57b6: 69 83 std Y+1, r22 ; 0x01 + 57b8: 69 dc rcall .-1838 ; 0x508c + 57ba: 20 91 49 2b lds r18, 0x2B49 + 57be: 30 91 4a 2b lds r19, 0x2B4A + 57c2: f9 01 movw r30, r18 + 57c4: ef 5b subi r30, 0xBF ; 191 + 57c6: ff 4f sbci r31, 0xFF ; 255 + 57c8: 90 81 ld r25, Z + 57ca: f9 01 movw r30, r18 + 57cc: e0 5c subi r30, 0xC0 ; 192 + 57ce: ff 4f sbci r31, 0xFF ; 255 + 57d0: 80 81 ld r24, Z + 57d2: 69 81 ldd r22, Y+1 ; 0x01 + 57d4: 98 17 cp r25, r24 + 57d6: 30 f0 brcs .+12 ; 0x57e4 + 57d8: 69 83 std Y+1, r22 ; 0x01 + 57da: 12 dc rcall .-2012 ; 0x5000 + 57dc: 27 de rcall .-946 ; 0x542c + 57de: 69 81 ldd r22, Y+1 ; 0x01 + 57e0: 81 11 cpse r24, r1 + 57e2: d9 cf rjmp .-78 ; 0x5796 + 57e4: 86 2f mov r24, r22 + 57e6: 43 dc rcall .-1914 ; 0x506e + 57e8: 80 e0 ldi r24, 0x00 ; 0 + 57ea: d5 cf rjmp .-86 ; 0x5796 + +000057ec : + 57ec: 0f 93 push r16 + 57ee: 1f 93 push r17 + 57f0: cf 93 push r28 + 57f2: df 93 push r29 + 57f4: 1f 92 push r1 + 57f6: cd b7 in r28, 0x3d ; 61 + 57f8: de b7 in r29, 0x3e ; 62 + 57fa: 20 91 40 2b lds r18, 0x2B40 + 57fe: 24 30 cpi r18, 0x04 ; 4 + 5800: 39 f0 breq .+14 ; 0x5810 + 5802: 82 e0 ldi r24, 0x02 ; 2 + 5804: 0f 90 pop r0 + 5806: df 91 pop r29 + 5808: cf 91 pop r28 + 580a: 1f 91 pop r17 + 580c: 0f 91 pop r16 + 580e: 08 95 ret + 5810: fc 01 movw r30, r24 + 5812: 44 89 ldd r20, Z+20 ; 0x14 + 5814: 55 89 ldd r21, Z+21 ; 0x15 + 5816: 66 89 ldd r22, Z+22 ; 0x16 + 5818: 77 89 ldd r23, Z+23 ; 0x17 + 581a: 45 2b or r20, r21 + 581c: 46 2b or r20, r22 + 581e: 47 2b or r20, r23 + 5820: 81 f3 breq .-32 ; 0x5802 + 5822: 81 81 ldd r24, Z+1 ; 0x01 + 5824: 33 dc rcall .-1946 ; 0x508c + 5826: 80 91 4d 2b lds r24, 0x2B4D + 582a: 20 91 49 2b lds r18, 0x2B49 + 582e: 30 91 4a 2b lds r19, 0x2B4A + 5832: f9 01 movw r30, r18 + 5834: 87 fd sbrc r24, 7 + 5836: 1d c0 rjmp .+58 ; 0x5872 + 5838: e0 5c subi r30, 0xC0 ; 192 + 583a: ff 4f sbci r31, 0xFF ; 255 + 583c: 80 81 ld r24, Z + 583e: f9 01 movw r30, r18 + 5840: ef 5b subi r30, 0xBF ; 191 + 5842: ff 4f sbci r31, 0xFF ; 255 + 5844: 40 81 ld r20, Z + 5846: 90 e0 ldi r25, 0x00 ; 0 + 5848: 84 1b sub r24, r20 + 584a: 91 09 sbc r25, r1 + 584c: 89 2b or r24, r25 + 584e: 11 f4 brne .+4 ; 0x5854 + 5850: 80 e0 ldi r24, 0x00 ; 0 + 5852: d8 cf rjmp .-80 ; 0x5804 + 5854: 00 81 ld r16, Z + 5856: f9 01 movw r30, r18 + 5858: e0 5c subi r30, 0xC0 ; 192 + 585a: ff 4f sbci r31, 0xFF ; 255 + 585c: 10 81 ld r17, Z + 585e: d0 db rcall .-2144 ; 0x5000 + 5860: 01 17 cp r16, r17 + 5862: b0 f3 brcs .-20 ; 0x5850 + 5864: e3 dd rcall .-1082 ; 0x542c + 5866: 81 11 cpse r24, r1 + 5868: cd cf rjmp .-102 ; 0x5804 + 586a: 89 83 std Y+1, r24 ; 0x01 + 586c: c9 db rcall .-2158 ; 0x5000 + 586e: 89 81 ldd r24, Y+1 ; 0x01 + 5870: c9 cf rjmp .-110 ; 0x5804 + 5872: ef 5b subi r30, 0xBF ; 191 + 5874: ff 4f sbci r31, 0xFF ; 255 + 5876: 80 81 ld r24, Z + 5878: 90 e0 ldi r25, 0x00 ; 0 + 587a: e8 cf rjmp .-48 ; 0x584c + +0000587c : + 587c: cf 93 push r28 + 587e: df 93 push r29 + 5880: ec 01 movw r28, r24 + 5882: 80 91 40 2b lds r24, 0x2B40 + 5886: 84 30 cpi r24, 0x04 ; 4 + 5888: 19 f0 breq .+6 ; 0x5890 + 588a: df 91 pop r29 + 588c: cf 91 pop r28 + 588e: 08 95 ret + 5890: 4c 89 ldd r20, Y+20 ; 0x14 + 5892: 5d 89 ldd r21, Y+21 ; 0x15 + 5894: 6e 89 ldd r22, Y+22 ; 0x16 + 5896: 7f 89 ldd r23, Y+23 ; 0x17 + 5898: 45 2b or r20, r21 + 589a: 46 2b or r20, r22 + 589c: 47 2b or r20, r23 + 589e: a9 f3 breq .-22 ; 0x588a + 58a0: 89 81 ldd r24, Y+1 ; 0x01 + 58a2: f4 db rcall .-2072 ; 0x508c + 58a4: a6 dc rcall .-1716 ; 0x51f2 + 58a6: 88 23 and r24, r24 + 58a8: 81 f3 breq .-32 ; 0x588a + 58aa: ce 01 movw r24, r28 + 58ac: df 91 pop r29 + 58ae: cf 91 pop r28 + 58b0: 9d cf rjmp .-198 ; 0x57ec + +000058b2 : + 58b2: cf 93 push r28 + 58b4: df 93 push r29 + 58b6: 20 91 40 2b lds r18, 0x2B40 + 58ba: 24 30 cpi r18, 0x04 ; 4 + 58bc: c1 f5 brne .+112 ; 0x592e + 58be: fc 01 movw r30, r24 + 58c0: 44 89 ldd r20, Z+20 ; 0x14 + 58c2: 55 89 ldd r21, Z+21 ; 0x15 + 58c4: 66 89 ldd r22, Z+22 ; 0x16 + 58c6: 77 89 ldd r23, Z+23 ; 0x17 + 58c8: 45 2b or r20, r21 + 58ca: 46 2b or r20, r22 + 58cc: 47 2b or r20, r23 + 58ce: 79 f1 breq .+94 ; 0x592e + 58d0: 86 81 ldd r24, Z+6 ; 0x06 + 58d2: dc db rcall .-2120 ; 0x508c + 58d4: 75 dc rcall .-1814 ; 0x51c0 + 58d6: 88 23 and r24, r24 + 58d8: 51 f1 breq .+84 ; 0x592e + 58da: 80 91 4d 2b lds r24, 0x2B4D + 58de: 87 fd sbrc r24, 7 + 58e0: 3d c0 rjmp .+122 ; 0x595c + 58e2: 80 91 49 2b lds r24, 0x2B49 + 58e6: 90 91 4a 2b lds r25, 0x2B4A + 58ea: fc 01 movw r30, r24 + 58ec: e0 5c subi r30, 0xC0 ; 192 + 58ee: ff 4f sbci r31, 0xFF ; 255 + 58f0: 20 81 ld r18, Z + 58f2: fc 01 movw r30, r24 + 58f4: ef 5b subi r30, 0xBF ; 191 + 58f6: ff 4f sbci r31, 0xFF ; 255 + 58f8: 40 81 ld r20, Z + 58fa: 30 e0 ldi r19, 0x00 ; 0 + 58fc: 24 1b sub r18, r20 + 58fe: 31 09 sbc r19, r1 + 5900: 23 2b or r18, r19 + 5902: d9 f4 brne .+54 ; 0x593a + 5904: cf ef ldi r28, 0xFF ; 255 + 5906: df ef ldi r29, 0xFF ; 255 + 5908: 20 91 4d 2b lds r18, 0x2B4D + 590c: 27 fd sbrc r18, 7 + 590e: 23 c0 rjmp .+70 ; 0x5956 + 5910: dc 01 movw r26, r24 + 5912: a0 5c subi r26, 0xC0 ; 192 + 5914: bf 4f sbci r27, 0xFF ; 255 + 5916: 8c 91 ld r24, X + 5918: 20 81 ld r18, Z + 591a: 90 e0 ldi r25, 0x00 ; 0 + 591c: 82 1b sub r24, r18 + 591e: 91 09 sbc r25, r1 + 5920: 89 2b or r24, r25 + 5922: 39 f4 brne .+14 ; 0x5932 + 5924: 86 db rcall .-2292 ; 0x5032 + 5926: ce 01 movw r24, r28 + 5928: df 91 pop r29 + 592a: cf 91 pop r28 + 592c: 08 95 ret + 592e: cf ef ldi r28, 0xFF ; 255 + 5930: df ef ldi r29, 0xFF ; 255 + 5932: ce 01 movw r24, r28 + 5934: df 91 pop r29 + 5936: cf 91 pop r28 + 5938: 08 95 ret + 593a: 8a db rcall .-2284 ; 0x5050 + 593c: c8 2f mov r28, r24 + 593e: d0 e0 ldi r29, 0x00 ; 0 + 5940: 80 91 49 2b lds r24, 0x2B49 + 5944: 90 91 4a 2b lds r25, 0x2B4A + 5948: fc 01 movw r30, r24 + 594a: ef 5b subi r30, 0xBF ; 191 + 594c: ff 4f sbci r31, 0xFF ; 255 + 594e: 20 91 4d 2b lds r18, 0x2B4D + 5952: 27 ff sbrs r18, 7 + 5954: dd cf rjmp .-70 ; 0x5910 + 5956: 80 81 ld r24, Z + 5958: 90 e0 ldi r25, 0x00 ; 0 + 595a: e2 cf rjmp .-60 ; 0x5920 + 595c: 80 91 49 2b lds r24, 0x2B49 + 5960: 90 91 4a 2b lds r25, 0x2B4A + 5964: fc 01 movw r30, r24 + 5966: ef 5b subi r30, 0xBF ; 191 + 5968: ff 4f sbci r31, 0xFF ; 255 + 596a: 20 81 ld r18, Z + 596c: 30 e0 ldi r19, 0x00 ; 0 + 596e: c8 cf rjmp .-112 ; 0x5900 + +00005970 : + return ReceivedByte; +} +#endif + +void CDC_Device_Event_Stub(void) +{ + 5970: 08 95 ret + +00005972 : +#define __INCLUDE_FROM_CDC_DRIVER +#define __INCLUDE_FROM_CDC_DEVICE_C +#include "CDCClassDevice.h" + +void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + 5972: ff 92 push r15 + 5974: 0f 93 push r16 + 5976: 1f 93 push r17 + 5978: cf 93 push r28 + 597a: df 93 push r29 + 597c: ec 01 movw r28, r24 + if (!(Endpoint_IsSETUPReceived())) + 597e: 07 dc rcall .-2034 ; 0x518e + 5980: 88 23 and r24, r24 + 5982: 49 f0 breq .+18 ; 0x5996 + return; + + if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber) + 5984: 88 81 ld r24, Y + 5986: 90 e0 ldi r25, 0x00 ; 0 + 5988: 20 91 45 2b lds r18, 0x2B45 + 598c: 30 91 46 2b lds r19, 0x2B46 + 5990: 28 17 cp r18, r24 + 5992: 39 07 cpc r19, r25 + 5994: 31 f0 breq .+12 ; 0x59a2 + EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); + } + + break; + } +} + 5996: df 91 pop r29 + 5998: cf 91 pop r28 + 599a: 1f 91 pop r17 + 599c: 0f 91 pop r16 + 599e: ff 90 pop r15 + 59a0: 08 95 ret + return; + + if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber) + return; + + switch (USB_ControlRequest.bRequest) + 59a2: 80 91 42 2b lds r24, 0x2B42 + 59a6: 81 32 cpi r24, 0x21 ; 33 + 59a8: 09 f4 brne .+2 ; 0x59ac + 59aa: 4b c0 rjmp .+150 ; 0x5a42 + 59ac: 08 f0 brcs .+2 ; 0x59b0 + 59ae: 33 c0 rjmp .+102 ; 0x5a16 + 59b0: 80 32 cpi r24, 0x20 ; 32 + 59b2: 89 f7 brne .-30 ; 0x5996 + Endpoint_ClearStatusStage(); + } + + break; + case CDC_REQ_SetLineEncoding: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + 59b4: 80 91 41 2b lds r24, 0x2B41 + 59b8: 81 32 cpi r24, 0x21 ; 33 + 59ba: 69 f7 brne .-38 ; 0x5996 + { + Endpoint_ClearSETUP(); + 59bc: bc db rcall .-2184 ; 0x5136 + + while (!(Endpoint_IsOUTReceived())) + 59be: 04 c0 rjmp .+8 ; 0x59c8 + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + 59c0: 80 91 40 2b lds r24, 0x2B40 + 59c4: 88 23 and r24, r24 + 59c6: 39 f3 breq .-50 ; 0x5996 + case CDC_REQ_SetLineEncoding: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + + while (!(Endpoint_IsOUTReceived())) + 59c8: fb db rcall .-2058 ; 0x51c0 + 59ca: 88 23 and r24, r24 + 59cc: c9 f3 breq .-14 ; 0x59c0 + * \return Next four bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_Read_32_LE(void) + { + uint32_t Byte0 = Endpoint_Read_8(); + 59ce: 40 db rcall .-2432 ; 0x5050 + 59d0: 08 2f mov r16, r24 + uint32_t Byte1 = Endpoint_Read_8(); + 59d2: 3e db rcall .-2436 ; 0x5050 + 59d4: 18 2f mov r17, r24 + uint32_t Byte2 = Endpoint_Read_8(); + 59d6: 3c db rcall .-2440 ; 0x5050 + 59d8: f8 2e mov r15, r24 + uint32_t Byte3 = Endpoint_Read_8(); + 59da: 3a db rcall .-2444 ; 0x5050 + static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_Read_32_LE(void) + { + uint32_t Byte0 = Endpoint_Read_8(); + uint32_t Byte1 = Endpoint_Read_8(); + uint32_t Byte2 = Endpoint_Read_8(); + 59dc: 4f 2d mov r20, r15 + 59de: 50 e0 ldi r21, 0x00 ; 0 + 59e0: 60 e0 ldi r22, 0x00 ; 0 + 59e2: 70 e0 ldi r23, 0x00 ; 0 + uint32_t Byte3 = Endpoint_Read_8(); + + return ((Byte3 << 24) | (Byte2 << 16) | (Byte1 << 8) | Byte0); + 59e4: ba 01 movw r22, r20 + 59e6: 55 27 eor r21, r21 + 59e8: 44 27 eor r20, r20 + 59ea: 78 2b or r23, r24 + 59ec: 40 2b or r20, r16 + 59ee: 51 2b or r21, r17 + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + CDCInterfaceInfo->State.LineEncoding.BaudRateBPS = Endpoint_Read_32_LE(); + 59f0: 4c 8b std Y+20, r20 ; 0x14 + 59f2: 5d 8b std Y+21, r21 ; 0x15 + 59f4: 6e 8b std Y+22, r22 ; 0x16 + 59f6: 7f 8b std Y+23, r23 ; 0x17 + CDCInterfaceInfo->State.LineEncoding.CharFormat = Endpoint_Read_8(); + 59f8: 2b db rcall .-2474 ; 0x5050 + 59fa: 88 8f std Y+24, r24 ; 0x18 + CDCInterfaceInfo->State.LineEncoding.ParityType = Endpoint_Read_8(); + 59fc: 29 db rcall .-2478 ; 0x5050 + 59fe: 89 8f std Y+25, r24 ; 0x19 + CDCInterfaceInfo->State.LineEncoding.DataBits = Endpoint_Read_8(); + 5a00: 27 db rcall .-2482 ; 0x5050 + 5a02: 8a 8f std Y+26, r24 ; 0x1a + + Endpoint_ClearOUT(); + 5a04: 16 db rcall .-2516 ; 0x5032 + Endpoint_ClearStatusStage(); + 5a06: fc dc rcall .-1544 ; 0x5400 + + EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo); + 5a08: ce 01 movw r24, r28 + EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); + } + + break; + } +} + 5a0a: df 91 pop r29 + 5a0c: cf 91 pop r28 + 5a0e: 1f 91 pop r17 + 5a10: 0f 91 pop r16 + 5a12: ff 90 pop r15 + CDCInterfaceInfo->State.LineEncoding.DataBits = Endpoint_Read_8(); + + Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); + + EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo); + 5a14: ad cf rjmp .-166 ; 0x5970 + return; + + if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber) + return; + + switch (USB_ControlRequest.bRequest) + 5a16: 82 32 cpi r24, 0x22 ; 34 + 5a18: 09 f4 brne .+2 ; 0x5a1c + 5a1a: 34 c0 rjmp .+104 ; 0x5a84 + 5a1c: 83 32 cpi r24, 0x23 ; 35 + 5a1e: 09 f0 breq .+2 ; 0x5a22 + 5a20: ba cf rjmp .-140 ; 0x5996 + EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); + } + + break; + case CDC_REQ_SendBreak: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + 5a22: 80 91 41 2b lds r24, 0x2B41 + 5a26: 81 32 cpi r24, 0x21 ; 33 + 5a28: 09 f0 breq .+2 ; 0x5a2c + 5a2a: b5 cf rjmp .-150 ; 0x5996 + { + Endpoint_ClearSETUP(); + 5a2c: 84 db rcall .-2296 ; 0x5136 + Endpoint_ClearStatusStage(); + 5a2e: e8 dc rcall .-1584 ; 0x5400 + + EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); + 5a30: 60 91 43 2b lds r22, 0x2B43 + 5a34: ce 01 movw r24, r28 + } + + break; + } +} + 5a36: df 91 pop r29 + 5a38: cf 91 pop r28 + 5a3a: 1f 91 pop r17 + 5a3c: 0f 91 pop r16 + 5a3e: ff 90 pop r15 + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); + + EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); + 5a40: 97 cf rjmp .-210 ; 0x5970 + return; + + switch (USB_ControlRequest.bRequest) + { + case CDC_REQ_GetLineEncoding: + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + 5a42: 80 91 41 2b lds r24, 0x2B41 + 5a46: 81 3a cpi r24, 0xA1 ; 161 + 5a48: 09 f0 breq .+2 ; 0x5a4c + 5a4a: a5 cf rjmp .-182 ; 0x5996 + { + Endpoint_ClearSETUP(); + 5a4c: 74 db rcall .-2328 ; 0x5136 + + while (!(Endpoint_IsINReady())); + 5a4e: d1 db rcall .-2142 ; 0x51f2 + 5a50: 88 23 and r24, r24 + 5a52: e9 f3 breq .-6 ; 0x5a4e + + Endpoint_Write_32_LE(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); + 5a54: 8c 89 ldd r24, Y+20 ; 0x14 + 5a56: fd 88 ldd r15, Y+21 ; 0x15 + 5a58: 0e 89 ldd r16, Y+22 ; 0x16 + 5a5a: 1f 89 ldd r17, Y+23 ; 0x17 + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_32_LE(const uint32_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_32_LE(const uint32_t Data) + { + Endpoint_Write_8(Data & 0xFF); + 5a5c: 08 db rcall .-2544 ; 0x506e + Endpoint_Write_8(Data >> 8); + 5a5e: 8f 2d mov r24, r15 + 5a60: 06 db rcall .-2548 ; 0x506e + Endpoint_Write_8(Data >> 16); + 5a62: 80 2f mov r24, r16 + 5a64: 04 db rcall .-2552 ; 0x506e + Endpoint_Write_8(Data >> 24); + 5a66: 81 2f mov r24, r17 + 5a68: 02 db rcall .-2556 ; 0x506e + Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.CharFormat); + 5a6a: 88 8d ldd r24, Y+24 ; 0x18 + 5a6c: 00 db rcall .-2560 ; 0x506e + Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.ParityType); + 5a6e: 89 8d ldd r24, Y+25 ; 0x19 + 5a70: fe da rcall .-2564 ; 0x506e + Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.DataBits); + 5a72: 8a 8d ldd r24, Y+26 ; 0x1a + 5a74: fc da rcall .-2568 ; 0x506e + + Endpoint_ClearIN(); + 5a76: c4 da rcall .-2680 ; 0x5000 + EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); + } + + break; + } +} + 5a78: df 91 pop r29 + 5a7a: cf 91 pop r28 + 5a7c: 1f 91 pop r17 + 5a7e: 0f 91 pop r16 + 5a80: ff 90 pop r15 + Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.CharFormat); + Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.ParityType); + Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.DataBits); + + Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); + 5a82: be cc rjmp .-1668 ; 0x5400 + EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo); + } + + break; + case CDC_REQ_SetControlLineState: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + 5a84: 80 91 41 2b lds r24, 0x2B41 + 5a88: 81 32 cpi r24, 0x21 ; 33 + 5a8a: 09 f0 breq .+2 ; 0x5a8e + 5a8c: 84 cf rjmp .-248 ; 0x5996 + { + Endpoint_ClearSETUP(); + 5a8e: 53 db rcall .-2394 ; 0x5136 + Endpoint_ClearStatusStage(); + 5a90: b7 dc rcall .-1682 ; 0x5400 + + CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue; + 5a92: 80 91 43 2b lds r24, 0x2B43 + 5a96: 90 91 44 2b lds r25, 0x2B44 + 5a9a: 88 8b std Y+16, r24 ; 0x10 + 5a9c: 99 8b std Y+17, r25 ; 0x11 + + EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); + 5a9e: ce 01 movw r24, r28 + EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); + } + + break; + } +} + 5aa0: df 91 pop r29 + 5aa2: cf 91 pop r28 + 5aa4: 1f 91 pop r17 + 5aa6: 0f 91 pop r16 + 5aa8: ff 90 pop r15 + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); + + CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue; + + EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); + 5aaa: 62 cf rjmp .-316 ; 0x5970 + +00005aac <__mulshisi3>: + 5aac: b7 ff sbrs r27, 7 + 5aae: 04 c0 rjmp .+8 ; 0x5ab8 <__muluhisi3> + +00005ab0 <__mulohisi3>: + 5ab0: 03 d0 rcall .+6 ; 0x5ab8 <__muluhisi3> + 5ab2: 82 1b sub r24, r18 + 5ab4: 93 0b sbc r25, r19 + 5ab6: 08 95 ret + +00005ab8 <__muluhisi3>: + 5ab8: 09 d0 rcall .+18 ; 0x5acc <__umulhisi3> + 5aba: a5 9f mul r26, r21 + 5abc: 90 0d add r25, r0 + 5abe: b4 9f mul r27, r20 + 5ac0: 90 0d add r25, r0 + 5ac2: a4 9f mul r26, r20 + 5ac4: 80 0d add r24, r0 + 5ac6: 91 1d adc r25, r1 + 5ac8: 11 24 eor r1, r1 + 5aca: 08 95 ret + +00005acc <__umulhisi3>: + 5acc: a2 9f mul r26, r18 + 5ace: b0 01 movw r22, r0 + 5ad0: b3 9f mul r27, r19 + 5ad2: c0 01 movw r24, r0 + 5ad4: a3 9f mul r26, r19 + 5ad6: 01 d0 rcall .+2 ; 0x5ada <__umulhisi3+0xe> + 5ad8: b2 9f mul r27, r18 + 5ada: 70 0d add r23, r0 + 5adc: 81 1d adc r24, r1 + 5ade: 11 24 eor r1, r1 + 5ae0: 91 1d adc r25, r1 + 5ae2: 08 95 ret + +00005ae4 : + 5ae4: 8f 92 push r8 + 5ae6: 9f 92 push r9 + 5ae8: af 92 push r10 + 5aea: bf 92 push r11 + 5aec: cf 92 push r12 + 5aee: df 92 push r13 + 5af0: ef 92 push r14 + 5af2: ff 92 push r15 + 5af4: cf 93 push r28 + 5af6: df 93 push r29 + 5af8: ec 01 movw r28, r24 + 5afa: 68 81 ld r22, Y + 5afc: 79 81 ldd r23, Y+1 ; 0x01 + 5afe: 8a 81 ldd r24, Y+2 ; 0x02 + 5b00: 9b 81 ldd r25, Y+3 ; 0x03 + 5b02: 61 15 cp r22, r1 + 5b04: 71 05 cpc r23, r1 + 5b06: 81 05 cpc r24, r1 + 5b08: 91 05 cpc r25, r1 + 5b0a: 21 f4 brne .+8 ; 0x5b14 + 5b0c: 64 e2 ldi r22, 0x24 ; 36 + 5b0e: 79 ed ldi r23, 0xD9 ; 217 + 5b10: 8b e5 ldi r24, 0x5B ; 91 + 5b12: 97 e0 ldi r25, 0x07 ; 7 + 5b14: 2d e1 ldi r18, 0x1D ; 29 + 5b16: 33 ef ldi r19, 0xF3 ; 243 + 5b18: 41 e0 ldi r20, 0x01 ; 1 + 5b1a: 50 e0 ldi r21, 0x00 ; 0 + 5b1c: 48 d3 rcall .+1680 ; 0x61ae <__divmodsi4> + 5b1e: 49 01 movw r8, r18 + 5b20: 5a 01 movw r10, r20 + 5b22: 9b 01 movw r18, r22 + 5b24: ac 01 movw r20, r24 + 5b26: a7 ea ldi r26, 0xA7 ; 167 + 5b28: b1 e4 ldi r27, 0x41 ; 65 + 5b2a: c6 df rcall .-116 ; 0x5ab8 <__muluhisi3> + 5b2c: 6b 01 movw r12, r22 + 5b2e: 7c 01 movw r14, r24 + 5b30: ac ee ldi r26, 0xEC ; 236 + 5b32: b4 ef ldi r27, 0xF4 ; 244 + 5b34: a5 01 movw r20, r10 + 5b36: 94 01 movw r18, r8 + 5b38: bb df rcall .-138 ; 0x5ab0 <__mulohisi3> + 5b3a: c6 0e add r12, r22 + 5b3c: d7 1e adc r13, r23 + 5b3e: e8 1e adc r14, r24 + 5b40: f9 1e adc r15, r25 + 5b42: f7 fe sbrs r15, 7 + 5b44: 06 c0 rjmp .+12 ; 0x5b52 + 5b46: 81 e0 ldi r24, 0x01 ; 1 + 5b48: c8 1a sub r12, r24 + 5b4a: d1 08 sbc r13, r1 + 5b4c: e1 08 sbc r14, r1 + 5b4e: 80 e8 ldi r24, 0x80 ; 128 + 5b50: f8 0a sbc r15, r24 + 5b52: c8 82 st Y, r12 + 5b54: d9 82 std Y+1, r13 ; 0x01 + 5b56: ea 82 std Y+2, r14 ; 0x02 + 5b58: fb 82 std Y+3, r15 ; 0x03 + 5b5a: e8 94 clt + 5b5c: d7 f8 bld r13, 7 + 5b5e: ee 24 eor r14, r14 + 5b60: ff 24 eor r15, r15 + 5b62: c6 01 movw r24, r12 + 5b64: df 91 pop r29 + 5b66: cf 91 pop r28 + 5b68: ff 90 pop r15 + 5b6a: ef 90 pop r14 + 5b6c: df 90 pop r13 + 5b6e: cf 90 pop r12 + 5b70: bf 90 pop r11 + 5b72: af 90 pop r10 + 5b74: 9f 90 pop r9 + 5b76: 8f 90 pop r8 + 5b78: 08 95 ret + +00005b7a : + 5b7a: b4 cf rjmp .-152 ; 0x5ae4 + +00005b7c : + 5b7c: 8c e1 ldi r24, 0x1C ; 28 + 5b7e: 90 e2 ldi r25, 0x20 ; 32 + 5b80: b1 cf rjmp .-158 ; 0x5ae4 + +00005b82 : + 5b82: a0 e0 ldi r26, 0x00 ; 0 + 5b84: b0 e0 ldi r27, 0x00 ; 0 + 5b86: 80 93 1c 20 sts 0x201C, r24 + 5b8a: 90 93 1d 20 sts 0x201D, r25 + 5b8e: a0 93 1e 20 sts 0x201E, r26 + 5b92: b0 93 1f 20 sts 0x201F, r27 + 5b96: 08 95 ret + +00005b98 : + 5b98: fb 01 movw r30, r22 + 5b9a: dc 01 movw r26, r24 + 5b9c: 02 c0 rjmp .+4 ; 0x5ba2 + 5b9e: 05 90 lpm r0, Z+ + 5ba0: 0d 92 st X+, r0 + 5ba2: 41 50 subi r20, 0x01 ; 1 + 5ba4: 50 40 sbci r21, 0x00 ; 0 + 5ba6: d8 f7 brcc .-10 ; 0x5b9e + 5ba8: 08 95 ret + +00005baa : + 5baa: fb 01 movw r30, r22 + 5bac: dc 01 movw r26, r24 + 5bae: 8d 91 ld r24, X+ + 5bb0: 05 90 lpm r0, Z+ + 5bb2: 80 19 sub r24, r0 + 5bb4: 01 10 cpse r0, r1 + 5bb6: d9 f3 breq .-10 ; 0x5bae + 5bb8: 99 0b sbc r25, r25 + 5bba: 08 95 ret + +00005bbc : + 5bbc: fb 01 movw r30, r22 + 5bbe: dc 01 movw r26, r24 + 5bc0: 0d 90 ld r0, X+ + 5bc2: 00 20 and r0, r0 + 5bc4: e9 f7 brne .-6 ; 0x5bc0 + 5bc6: 11 97 sbiw r26, 0x01 ; 1 + 5bc8: 41 50 subi r20, 0x01 ; 1 + 5bca: 50 40 sbci r21, 0x00 ; 0 + 5bcc: 28 f0 brcs .+10 ; 0x5bd8 + 5bce: 05 90 lpm r0, Z+ + 5bd0: 00 20 and r0, r0 + 5bd2: 0d 92 st X+, r0 + 5bd4: c9 f7 brne .-14 ; 0x5bc8 + 5bd6: 08 95 ret + 5bd8: 1c 92 st X, r1 + 5bda: 08 95 ret + +00005bdc : + 5bdc: fb 01 movw r30, r22 + 5bde: dc 01 movw r26, r24 + 5be0: 41 50 subi r20, 0x01 ; 1 + 5be2: 50 40 sbci r21, 0x00 ; 0 + 5be4: 48 f0 brcs .+18 ; 0x5bf8 + 5be6: 05 90 lpm r0, Z+ + 5be8: 0d 92 st X+, r0 + 5bea: 00 20 and r0, r0 + 5bec: c9 f7 brne .-14 ; 0x5be0 + 5bee: 01 c0 rjmp .+2 ; 0x5bf2 + 5bf0: 1d 92 st X+, r1 + 5bf2: 41 50 subi r20, 0x01 ; 1 + 5bf4: 50 40 sbci r21, 0x00 ; 0 + 5bf6: e0 f7 brcc .-8 ; 0x5bf0 + 5bf8: 08 95 ret + +00005bfa : + 5bfa: fb 01 movw r30, r22 + 5bfc: dc 01 movw r26, r24 + 5bfe: 02 c0 rjmp .+4 ; 0x5c04 + 5c00: 01 90 ld r0, Z+ + 5c02: 0d 92 st X+, r0 + 5c04: 41 50 subi r20, 0x01 ; 1 + 5c06: 50 40 sbci r21, 0x00 ; 0 + 5c08: d8 f7 brcc .-10 ; 0x5c00 + 5c0a: 08 95 ret + +00005c0c : + 5c0c: ae e0 ldi r26, 0x0E ; 14 + 5c0e: b0 e0 ldi r27, 0x00 ; 0 + 5c10: eb e0 ldi r30, 0x0B ; 11 + 5c12: fe e2 ldi r31, 0x2E ; 46 + 5c14: f5 c2 rjmp .+1514 ; 0x6200 <__prologue_saves__+0x1c> + 5c16: 0d 89 ldd r16, Y+21 ; 0x15 + 5c18: 1e 89 ldd r17, Y+22 ; 0x16 + 5c1a: 8f 89 ldd r24, Y+23 ; 0x17 + 5c1c: 98 8d ldd r25, Y+24 ; 0x18 + 5c1e: 2e e0 ldi r18, 0x0E ; 14 + 5c20: 2c 83 std Y+4, r18 ; 0x04 + 5c22: 09 83 std Y+1, r16 ; 0x01 + 5c24: 1a 83 std Y+2, r17 ; 0x02 + 5c26: 97 ff sbrs r25, 7 + 5c28: 02 c0 rjmp .+4 ; 0x5c2e + 5c2a: 80 e0 ldi r24, 0x00 ; 0 + 5c2c: 90 e8 ldi r25, 0x80 ; 128 + 5c2e: 01 97 sbiw r24, 0x01 ; 1 + 5c30: 8d 83 std Y+5, r24 ; 0x05 + 5c32: 9e 83 std Y+6, r25 ; 0x06 + 5c34: ce 01 movw r24, r28 + 5c36: 4b 96 adiw r24, 0x1b ; 27 + 5c38: ac 01 movw r20, r24 + 5c3a: 69 8d ldd r22, Y+25 ; 0x19 + 5c3c: 7a 8d ldd r23, Y+26 ; 0x1a + 5c3e: ce 01 movw r24, r28 + 5c40: 01 96 adiw r24, 0x01 ; 1 + 5c42: 11 d0 rcall .+34 ; 0x5c66 + 5c44: 4d 81 ldd r20, Y+5 ; 0x05 + 5c46: 5e 81 ldd r21, Y+6 ; 0x06 + 5c48: 57 fd sbrc r21, 7 + 5c4a: 0a c0 rjmp .+20 ; 0x5c60 + 5c4c: 2f 81 ldd r18, Y+7 ; 0x07 + 5c4e: 38 85 ldd r19, Y+8 ; 0x08 + 5c50: 42 17 cp r20, r18 + 5c52: 53 07 cpc r21, r19 + 5c54: 0c f4 brge .+2 ; 0x5c58 + 5c56: 9a 01 movw r18, r20 + 5c58: f8 01 movw r30, r16 + 5c5a: e2 0f add r30, r18 + 5c5c: f3 1f adc r31, r19 + 5c5e: 10 82 st Z, r1 + 5c60: 2e 96 adiw r28, 0x0e ; 14 + 5c62: e4 e0 ldi r30, 0x04 ; 4 + 5c64: e6 c2 rjmp .+1484 ; 0x6232 <__epilogue_restores__+0x1c> + +00005c66 : + 5c66: ac e0 ldi r26, 0x0C ; 12 + 5c68: b0 e0 ldi r27, 0x00 ; 0 + 5c6a: e8 e3 ldi r30, 0x38 ; 56 + 5c6c: fe e2 ldi r31, 0x2E ; 46 + 5c6e: ba c2 rjmp .+1396 ; 0x61e4 <__prologue_saves__> + 5c70: 7c 01 movw r14, r24 + 5c72: 6b 01 movw r12, r22 + 5c74: 8a 01 movw r16, r20 + 5c76: fc 01 movw r30, r24 + 5c78: 16 82 std Z+6, r1 ; 0x06 + 5c7a: 17 82 std Z+7, r1 ; 0x07 + 5c7c: 83 81 ldd r24, Z+3 ; 0x03 + 5c7e: 81 ff sbrs r24, 1 + 5c80: b9 c1 rjmp .+882 ; 0x5ff4 + 5c82: 88 24 eor r8, r8 + 5c84: 83 94 inc r8 + 5c86: 91 2c mov r9, r1 + 5c88: 8c 0e add r8, r28 + 5c8a: 9d 1e adc r9, r29 + 5c8c: f7 01 movw r30, r14 + 5c8e: 93 81 ldd r25, Z+3 ; 0x03 + 5c90: f6 01 movw r30, r12 + 5c92: 93 fd sbrc r25, 3 + 5c94: 85 91 lpm r24, Z+ + 5c96: 93 ff sbrs r25, 3 + 5c98: 81 91 ld r24, Z+ + 5c9a: 6f 01 movw r12, r30 + 5c9c: 88 23 and r24, r24 + 5c9e: 09 f4 brne .+2 ; 0x5ca2 + 5ca0: a5 c1 rjmp .+842 ; 0x5fec + 5ca2: 85 32 cpi r24, 0x25 ; 37 + 5ca4: 39 f4 brne .+14 ; 0x5cb4 + 5ca6: 93 fd sbrc r25, 3 + 5ca8: 85 91 lpm r24, Z+ + 5caa: 93 ff sbrs r25, 3 + 5cac: 81 91 ld r24, Z+ + 5cae: 6f 01 movw r12, r30 + 5cb0: 85 32 cpi r24, 0x25 ; 37 + 5cb2: 21 f4 brne .+8 ; 0x5cbc + 5cb4: b7 01 movw r22, r14 + 5cb6: 90 e0 ldi r25, 0x00 ; 0 + 5cb8: f0 d1 rcall .+992 ; 0x609a + 5cba: e8 cf rjmp .-48 ; 0x5c8c + 5cbc: 51 2c mov r5, r1 + 5cbe: 31 2c mov r3, r1 + 5cc0: 20 e0 ldi r18, 0x00 ; 0 + 5cc2: 20 32 cpi r18, 0x20 ; 32 + 5cc4: a8 f4 brcc .+42 ; 0x5cf0 + 5cc6: 8b 32 cpi r24, 0x2B ; 43 + 5cc8: 61 f0 breq .+24 ; 0x5ce2 + 5cca: 28 f4 brcc .+10 ; 0x5cd6 + 5ccc: 80 32 cpi r24, 0x20 ; 32 + 5cce: 51 f0 breq .+20 ; 0x5ce4 + 5cd0: 83 32 cpi r24, 0x23 ; 35 + 5cd2: 71 f4 brne .+28 ; 0x5cf0 + 5cd4: 0b c0 rjmp .+22 ; 0x5cec + 5cd6: 8d 32 cpi r24, 0x2D ; 45 + 5cd8: 39 f0 breq .+14 ; 0x5ce8 + 5cda: 80 33 cpi r24, 0x30 ; 48 + 5cdc: 49 f4 brne .+18 ; 0x5cf0 + 5cde: 21 60 ori r18, 0x01 ; 1 + 5ce0: 28 c0 rjmp .+80 ; 0x5d32 + 5ce2: 22 60 ori r18, 0x02 ; 2 + 5ce4: 24 60 ori r18, 0x04 ; 4 + 5ce6: 25 c0 rjmp .+74 ; 0x5d32 + 5ce8: 28 60 ori r18, 0x08 ; 8 + 5cea: 23 c0 rjmp .+70 ; 0x5d32 + 5cec: 20 61 ori r18, 0x10 ; 16 + 5cee: 21 c0 rjmp .+66 ; 0x5d32 + 5cf0: 27 fd sbrc r18, 7 + 5cf2: 27 c0 rjmp .+78 ; 0x5d42 + 5cf4: 38 2f mov r19, r24 + 5cf6: 30 53 subi r19, 0x30 ; 48 + 5cf8: 3a 30 cpi r19, 0x0A ; 10 + 5cfa: 78 f4 brcc .+30 ; 0x5d1a + 5cfc: 26 ff sbrs r18, 6 + 5cfe: 06 c0 rjmp .+12 ; 0x5d0c + 5d00: fa e0 ldi r31, 0x0A ; 10 + 5d02: 5f 9e mul r5, r31 + 5d04: 30 0d add r19, r0 + 5d06: 11 24 eor r1, r1 + 5d08: 53 2e mov r5, r19 + 5d0a: 13 c0 rjmp .+38 ; 0x5d32 + 5d0c: 8a e0 ldi r24, 0x0A ; 10 + 5d0e: 38 9e mul r3, r24 + 5d10: 30 0d add r19, r0 + 5d12: 11 24 eor r1, r1 + 5d14: 33 2e mov r3, r19 + 5d16: 20 62 ori r18, 0x20 ; 32 + 5d18: 0c c0 rjmp .+24 ; 0x5d32 + 5d1a: 8e 32 cpi r24, 0x2E ; 46 + 5d1c: 21 f4 brne .+8 ; 0x5d26 + 5d1e: 26 fd sbrc r18, 6 + 5d20: 65 c1 rjmp .+714 ; 0x5fec + 5d22: 20 64 ori r18, 0x40 ; 64 + 5d24: 06 c0 rjmp .+12 ; 0x5d32 + 5d26: 8c 36 cpi r24, 0x6C ; 108 + 5d28: 11 f4 brne .+4 ; 0x5d2e + 5d2a: 20 68 ori r18, 0x80 ; 128 + 5d2c: 02 c0 rjmp .+4 ; 0x5d32 + 5d2e: 88 36 cpi r24, 0x68 ; 104 + 5d30: 41 f4 brne .+16 ; 0x5d42 + 5d32: f6 01 movw r30, r12 + 5d34: 93 fd sbrc r25, 3 + 5d36: 85 91 lpm r24, Z+ + 5d38: 93 ff sbrs r25, 3 + 5d3a: 81 91 ld r24, Z+ + 5d3c: 6f 01 movw r12, r30 + 5d3e: 81 11 cpse r24, r1 + 5d40: c0 cf rjmp .-128 ; 0x5cc2 + 5d42: 98 2f mov r25, r24 + 5d44: 95 54 subi r25, 0x45 ; 69 + 5d46: 93 30 cpi r25, 0x03 ; 3 + 5d48: 18 f0 brcs .+6 ; 0x5d50 + 5d4a: 90 52 subi r25, 0x20 ; 32 + 5d4c: 93 30 cpi r25, 0x03 ; 3 + 5d4e: 28 f4 brcc .+10 ; 0x5d5a + 5d50: 0c 5f subi r16, 0xFC ; 252 + 5d52: 1f 4f sbci r17, 0xFF ; 255 + 5d54: ff e3 ldi r31, 0x3F ; 63 + 5d56: f9 83 std Y+1, r31 ; 0x01 + 5d58: 0d c0 rjmp .+26 ; 0x5d74 + 5d5a: 83 36 cpi r24, 0x63 ; 99 + 5d5c: 31 f0 breq .+12 ; 0x5d6a + 5d5e: 83 37 cpi r24, 0x73 ; 115 + 5d60: 71 f0 breq .+28 ; 0x5d7e + 5d62: 83 35 cpi r24, 0x53 ; 83 + 5d64: 09 f0 breq .+2 ; 0x5d68 + 5d66: 5a c0 rjmp .+180 ; 0x5e1c + 5d68: 22 c0 rjmp .+68 ; 0x5dae + 5d6a: f8 01 movw r30, r16 + 5d6c: 80 81 ld r24, Z + 5d6e: 89 83 std Y+1, r24 ; 0x01 + 5d70: 0e 5f subi r16, 0xFE ; 254 + 5d72: 1f 4f sbci r17, 0xFF ; 255 + 5d74: 44 24 eor r4, r4 + 5d76: 43 94 inc r4 + 5d78: 51 2c mov r5, r1 + 5d7a: 54 01 movw r10, r8 + 5d7c: 14 c0 rjmp .+40 ; 0x5da6 + 5d7e: 38 01 movw r6, r16 + 5d80: f2 e0 ldi r31, 0x02 ; 2 + 5d82: 6f 0e add r6, r31 + 5d84: 71 1c adc r7, r1 + 5d86: f8 01 movw r30, r16 + 5d88: a0 80 ld r10, Z + 5d8a: b1 80 ldd r11, Z+1 ; 0x01 + 5d8c: 26 ff sbrs r18, 6 + 5d8e: 03 c0 rjmp .+6 ; 0x5d96 + 5d90: 65 2d mov r22, r5 + 5d92: 70 e0 ldi r23, 0x00 ; 0 + 5d94: 02 c0 rjmp .+4 ; 0x5d9a + 5d96: 6f ef ldi r22, 0xFF ; 255 + 5d98: 7f ef ldi r23, 0xFF ; 255 + 5d9a: c5 01 movw r24, r10 + 5d9c: 2c 87 std Y+12, r18 ; 0x0c + 5d9e: 72 d1 rcall .+740 ; 0x6084 + 5da0: 2c 01 movw r4, r24 + 5da2: 83 01 movw r16, r6 + 5da4: 2c 85 ldd r18, Y+12 ; 0x0c + 5da6: 6f e7 ldi r22, 0x7F ; 127 + 5da8: 26 2e mov r2, r22 + 5daa: 22 22 and r2, r18 + 5dac: 17 c0 rjmp .+46 ; 0x5ddc + 5dae: 38 01 movw r6, r16 + 5db0: f2 e0 ldi r31, 0x02 ; 2 + 5db2: 6f 0e add r6, r31 + 5db4: 71 1c adc r7, r1 + 5db6: f8 01 movw r30, r16 + 5db8: a0 80 ld r10, Z + 5dba: b1 80 ldd r11, Z+1 ; 0x01 + 5dbc: 26 ff sbrs r18, 6 + 5dbe: 03 c0 rjmp .+6 ; 0x5dc6 + 5dc0: 65 2d mov r22, r5 + 5dc2: 70 e0 ldi r23, 0x00 ; 0 + 5dc4: 02 c0 rjmp .+4 ; 0x5dca + 5dc6: 6f ef ldi r22, 0xFF ; 255 + 5dc8: 7f ef ldi r23, 0xFF ; 255 + 5dca: c5 01 movw r24, r10 + 5dcc: 2c 87 std Y+12, r18 ; 0x0c + 5dce: 4f d1 rcall .+670 ; 0x606e + 5dd0: 2c 01 movw r4, r24 + 5dd2: 2c 85 ldd r18, Y+12 ; 0x0c + 5dd4: 50 e8 ldi r21, 0x80 ; 128 + 5dd6: 25 2e mov r2, r21 + 5dd8: 22 2a or r2, r18 + 5dda: 83 01 movw r16, r6 + 5ddc: 23 fc sbrc r2, 3 + 5dde: 1a c0 rjmp .+52 ; 0x5e14 + 5de0: 05 c0 rjmp .+10 ; 0x5dec + 5de2: b7 01 movw r22, r14 + 5de4: 80 e2 ldi r24, 0x20 ; 32 + 5de6: 90 e0 ldi r25, 0x00 ; 0 + 5de8: 58 d1 rcall .+688 ; 0x609a + 5dea: 3a 94 dec r3 + 5dec: 83 2d mov r24, r3 + 5dee: 90 e0 ldi r25, 0x00 ; 0 + 5df0: 48 16 cp r4, r24 + 5df2: 59 06 cpc r5, r25 + 5df4: b0 f3 brcs .-20 ; 0x5de2 + 5df6: 0e c0 rjmp .+28 ; 0x5e14 + 5df8: f5 01 movw r30, r10 + 5dfa: 27 fc sbrc r2, 7 + 5dfc: 85 91 lpm r24, Z+ + 5dfe: 27 fe sbrs r2, 7 + 5e00: 81 91 ld r24, Z+ + 5e02: 5f 01 movw r10, r30 + 5e04: b7 01 movw r22, r14 + 5e06: 90 e0 ldi r25, 0x00 ; 0 + 5e08: 48 d1 rcall .+656 ; 0x609a + 5e0a: 31 10 cpse r3, r1 + 5e0c: 3a 94 dec r3 + 5e0e: f1 e0 ldi r31, 0x01 ; 1 + 5e10: 4f 1a sub r4, r31 + 5e12: 51 08 sbc r5, r1 + 5e14: 41 14 cp r4, r1 + 5e16: 51 04 cpc r5, r1 + 5e18: 79 f7 brne .-34 ; 0x5df8 + 5e1a: e5 c0 rjmp .+458 ; 0x5fe6 + 5e1c: 84 36 cpi r24, 0x64 ; 100 + 5e1e: 11 f0 breq .+4 ; 0x5e24 + 5e20: 89 36 cpi r24, 0x69 ; 105 + 5e22: 39 f5 brne .+78 ; 0x5e72 + 5e24: f8 01 movw r30, r16 + 5e26: 27 ff sbrs r18, 7 + 5e28: 07 c0 rjmp .+14 ; 0x5e38 + 5e2a: 60 81 ld r22, Z + 5e2c: 71 81 ldd r23, Z+1 ; 0x01 + 5e2e: 82 81 ldd r24, Z+2 ; 0x02 + 5e30: 93 81 ldd r25, Z+3 ; 0x03 + 5e32: 0c 5f subi r16, 0xFC ; 252 + 5e34: 1f 4f sbci r17, 0xFF ; 255 + 5e36: 08 c0 rjmp .+16 ; 0x5e48 + 5e38: 60 81 ld r22, Z + 5e3a: 71 81 ldd r23, Z+1 ; 0x01 + 5e3c: 88 27 eor r24, r24 + 5e3e: 77 fd sbrc r23, 7 + 5e40: 80 95 com r24 + 5e42: 98 2f mov r25, r24 + 5e44: 0e 5f subi r16, 0xFE ; 254 + 5e46: 1f 4f sbci r17, 0xFF ; 255 + 5e48: 4f e6 ldi r20, 0x6F ; 111 + 5e4a: b4 2e mov r11, r20 + 5e4c: b2 22 and r11, r18 + 5e4e: 97 ff sbrs r25, 7 + 5e50: 09 c0 rjmp .+18 ; 0x5e64 + 5e52: 90 95 com r25 + 5e54: 80 95 com r24 + 5e56: 70 95 com r23 + 5e58: 61 95 neg r22 + 5e5a: 7f 4f sbci r23, 0xFF ; 255 + 5e5c: 8f 4f sbci r24, 0xFF ; 255 + 5e5e: 9f 4f sbci r25, 0xFF ; 255 + 5e60: f0 e8 ldi r31, 0x80 ; 128 + 5e62: bf 2a or r11, r31 + 5e64: 2a e0 ldi r18, 0x0A ; 10 + 5e66: 30 e0 ldi r19, 0x00 ; 0 + 5e68: a4 01 movw r20, r8 + 5e6a: 43 d1 rcall .+646 ; 0x60f2 <__ultoa_invert> + 5e6c: a8 2e mov r10, r24 + 5e6e: a8 18 sub r10, r8 + 5e70: 42 c0 rjmp .+132 ; 0x5ef6 + 5e72: 85 37 cpi r24, 0x75 ; 117 + 5e74: 31 f4 brne .+12 ; 0x5e82 + 5e76: 3f ee ldi r19, 0xEF ; 239 + 5e78: b3 2e mov r11, r19 + 5e7a: b2 22 and r11, r18 + 5e7c: 2a e0 ldi r18, 0x0A ; 10 + 5e7e: 30 e0 ldi r19, 0x00 ; 0 + 5e80: 24 c0 rjmp .+72 ; 0x5eca + 5e82: 99 ef ldi r25, 0xF9 ; 249 + 5e84: b9 2e mov r11, r25 + 5e86: b2 22 and r11, r18 + 5e88: 8f 36 cpi r24, 0x6F ; 111 + 5e8a: b9 f0 breq .+46 ; 0x5eba + 5e8c: 20 f4 brcc .+8 ; 0x5e96 + 5e8e: 88 35 cpi r24, 0x58 ; 88 + 5e90: 09 f0 breq .+2 ; 0x5e94 + 5e92: ac c0 rjmp .+344 ; 0x5fec + 5e94: 0d c0 rjmp .+26 ; 0x5eb0 + 5e96: 80 37 cpi r24, 0x70 ; 112 + 5e98: 21 f0 breq .+8 ; 0x5ea2 + 5e9a: 88 37 cpi r24, 0x78 ; 120 + 5e9c: 09 f0 breq .+2 ; 0x5ea0 + 5e9e: a6 c0 rjmp .+332 ; 0x5fec + 5ea0: 02 c0 rjmp .+4 ; 0x5ea6 + 5ea2: 20 e1 ldi r18, 0x10 ; 16 + 5ea4: b2 2a or r11, r18 + 5ea6: b4 fe sbrs r11, 4 + 5ea8: 0b c0 rjmp .+22 ; 0x5ec0 + 5eaa: 84 e0 ldi r24, 0x04 ; 4 + 5eac: b8 2a or r11, r24 + 5eae: 08 c0 rjmp .+16 ; 0x5ec0 + 5eb0: 24 ff sbrs r18, 4 + 5eb2: 09 c0 rjmp .+18 ; 0x5ec6 + 5eb4: e6 e0 ldi r30, 0x06 ; 6 + 5eb6: be 2a or r11, r30 + 5eb8: 06 c0 rjmp .+12 ; 0x5ec6 + 5eba: 28 e0 ldi r18, 0x08 ; 8 + 5ebc: 30 e0 ldi r19, 0x00 ; 0 + 5ebe: 05 c0 rjmp .+10 ; 0x5eca + 5ec0: 20 e1 ldi r18, 0x10 ; 16 + 5ec2: 30 e0 ldi r19, 0x00 ; 0 + 5ec4: 02 c0 rjmp .+4 ; 0x5eca + 5ec6: 20 e1 ldi r18, 0x10 ; 16 + 5ec8: 32 e0 ldi r19, 0x02 ; 2 + 5eca: f8 01 movw r30, r16 + 5ecc: b7 fe sbrs r11, 7 + 5ece: 07 c0 rjmp .+14 ; 0x5ede + 5ed0: 60 81 ld r22, Z + 5ed2: 71 81 ldd r23, Z+1 ; 0x01 + 5ed4: 82 81 ldd r24, Z+2 ; 0x02 + 5ed6: 93 81 ldd r25, Z+3 ; 0x03 + 5ed8: 0c 5f subi r16, 0xFC ; 252 + 5eda: 1f 4f sbci r17, 0xFF ; 255 + 5edc: 06 c0 rjmp .+12 ; 0x5eea + 5ede: 60 81 ld r22, Z + 5ee0: 71 81 ldd r23, Z+1 ; 0x01 + 5ee2: 80 e0 ldi r24, 0x00 ; 0 + 5ee4: 90 e0 ldi r25, 0x00 ; 0 + 5ee6: 0e 5f subi r16, 0xFE ; 254 + 5ee8: 1f 4f sbci r17, 0xFF ; 255 + 5eea: a4 01 movw r20, r8 + 5eec: 02 d1 rcall .+516 ; 0x60f2 <__ultoa_invert> + 5eee: a8 2e mov r10, r24 + 5ef0: a8 18 sub r10, r8 + 5ef2: ff e7 ldi r31, 0x7F ; 127 + 5ef4: bf 22 and r11, r31 + 5ef6: b6 fe sbrs r11, 6 + 5ef8: 0b c0 rjmp .+22 ; 0x5f10 + 5efa: 2b 2d mov r18, r11 + 5efc: 2e 7f andi r18, 0xFE ; 254 + 5efe: a5 14 cp r10, r5 + 5f00: 50 f4 brcc .+20 ; 0x5f16 + 5f02: b4 fe sbrs r11, 4 + 5f04: 0a c0 rjmp .+20 ; 0x5f1a + 5f06: b2 fc sbrc r11, 2 + 5f08: 08 c0 rjmp .+16 ; 0x5f1a + 5f0a: 2b 2d mov r18, r11 + 5f0c: 2e 7e andi r18, 0xEE ; 238 + 5f0e: 05 c0 rjmp .+10 ; 0x5f1a + 5f10: 7a 2c mov r7, r10 + 5f12: 2b 2d mov r18, r11 + 5f14: 03 c0 rjmp .+6 ; 0x5f1c + 5f16: 7a 2c mov r7, r10 + 5f18: 01 c0 rjmp .+2 ; 0x5f1c + 5f1a: 75 2c mov r7, r5 + 5f1c: 24 ff sbrs r18, 4 + 5f1e: 0d c0 rjmp .+26 ; 0x5f3a + 5f20: fe 01 movw r30, r28 + 5f22: ea 0d add r30, r10 + 5f24: f1 1d adc r31, r1 + 5f26: 80 81 ld r24, Z + 5f28: 80 33 cpi r24, 0x30 ; 48 + 5f2a: 11 f4 brne .+4 ; 0x5f30 + 5f2c: 29 7e andi r18, 0xE9 ; 233 + 5f2e: 09 c0 rjmp .+18 ; 0x5f42 + 5f30: 22 ff sbrs r18, 2 + 5f32: 06 c0 rjmp .+12 ; 0x5f40 + 5f34: 73 94 inc r7 + 5f36: 73 94 inc r7 + 5f38: 04 c0 rjmp .+8 ; 0x5f42 + 5f3a: 82 2f mov r24, r18 + 5f3c: 86 78 andi r24, 0x86 ; 134 + 5f3e: 09 f0 breq .+2 ; 0x5f42 + 5f40: 73 94 inc r7 + 5f42: 23 fd sbrc r18, 3 + 5f44: 13 c0 rjmp .+38 ; 0x5f6c + 5f46: 20 ff sbrs r18, 0 + 5f48: 0e c0 rjmp .+28 ; 0x5f66 + 5f4a: 5a 2c mov r5, r10 + 5f4c: 73 14 cp r7, r3 + 5f4e: 58 f4 brcc .+22 ; 0x5f66 + 5f50: 53 0c add r5, r3 + 5f52: 57 18 sub r5, r7 + 5f54: 73 2c mov r7, r3 + 5f56: 07 c0 rjmp .+14 ; 0x5f66 + 5f58: b7 01 movw r22, r14 + 5f5a: 80 e2 ldi r24, 0x20 ; 32 + 5f5c: 90 e0 ldi r25, 0x00 ; 0 + 5f5e: 2c 87 std Y+12, r18 ; 0x0c + 5f60: 9c d0 rcall .+312 ; 0x609a + 5f62: 73 94 inc r7 + 5f64: 2c 85 ldd r18, Y+12 ; 0x0c + 5f66: 73 14 cp r7, r3 + 5f68: b8 f3 brcs .-18 ; 0x5f58 + 5f6a: 04 c0 rjmp .+8 ; 0x5f74 + 5f6c: 73 14 cp r7, r3 + 5f6e: 10 f4 brcc .+4 ; 0x5f74 + 5f70: 37 18 sub r3, r7 + 5f72: 01 c0 rjmp .+2 ; 0x5f76 + 5f74: 31 2c mov r3, r1 + 5f76: 24 ff sbrs r18, 4 + 5f78: 11 c0 rjmp .+34 ; 0x5f9c + 5f7a: b7 01 movw r22, r14 + 5f7c: 80 e3 ldi r24, 0x30 ; 48 + 5f7e: 90 e0 ldi r25, 0x00 ; 0 + 5f80: 2c 87 std Y+12, r18 ; 0x0c + 5f82: 8b d0 rcall .+278 ; 0x609a + 5f84: 2c 85 ldd r18, Y+12 ; 0x0c + 5f86: 22 ff sbrs r18, 2 + 5f88: 1c c0 rjmp .+56 ; 0x5fc2 + 5f8a: 21 ff sbrs r18, 1 + 5f8c: 03 c0 rjmp .+6 ; 0x5f94 + 5f8e: 88 e5 ldi r24, 0x58 ; 88 + 5f90: 90 e0 ldi r25, 0x00 ; 0 + 5f92: 02 c0 rjmp .+4 ; 0x5f98 + 5f94: 88 e7 ldi r24, 0x78 ; 120 + 5f96: 90 e0 ldi r25, 0x00 ; 0 + 5f98: b7 01 movw r22, r14 + 5f9a: 0c c0 rjmp .+24 ; 0x5fb4 + 5f9c: 82 2f mov r24, r18 + 5f9e: 86 78 andi r24, 0x86 ; 134 + 5fa0: 81 f0 breq .+32 ; 0x5fc2 + 5fa2: 21 fd sbrc r18, 1 + 5fa4: 02 c0 rjmp .+4 ; 0x5faa + 5fa6: 80 e2 ldi r24, 0x20 ; 32 + 5fa8: 01 c0 rjmp .+2 ; 0x5fac + 5faa: 8b e2 ldi r24, 0x2B ; 43 + 5fac: 27 fd sbrc r18, 7 + 5fae: 8d e2 ldi r24, 0x2D ; 45 + 5fb0: b7 01 movw r22, r14 + 5fb2: 90 e0 ldi r25, 0x00 ; 0 + 5fb4: 72 d0 rcall .+228 ; 0x609a + 5fb6: 05 c0 rjmp .+10 ; 0x5fc2 + 5fb8: b7 01 movw r22, r14 + 5fba: 80 e3 ldi r24, 0x30 ; 48 + 5fbc: 90 e0 ldi r25, 0x00 ; 0 + 5fbe: 6d d0 rcall .+218 ; 0x609a + 5fc0: 5a 94 dec r5 + 5fc2: a5 14 cp r10, r5 + 5fc4: c8 f3 brcs .-14 ; 0x5fb8 + 5fc6: aa 94 dec r10 + 5fc8: f4 01 movw r30, r8 + 5fca: ea 0d add r30, r10 + 5fcc: f1 1d adc r31, r1 + 5fce: b7 01 movw r22, r14 + 5fd0: 80 81 ld r24, Z + 5fd2: 90 e0 ldi r25, 0x00 ; 0 + 5fd4: 62 d0 rcall .+196 ; 0x609a + 5fd6: a1 10 cpse r10, r1 + 5fd8: f6 cf rjmp .-20 ; 0x5fc6 + 5fda: 05 c0 rjmp .+10 ; 0x5fe6 + 5fdc: b7 01 movw r22, r14 + 5fde: 80 e2 ldi r24, 0x20 ; 32 + 5fe0: 90 e0 ldi r25, 0x00 ; 0 + 5fe2: 5b d0 rcall .+182 ; 0x609a + 5fe4: 3a 94 dec r3 + 5fe6: 31 10 cpse r3, r1 + 5fe8: f9 cf rjmp .-14 ; 0x5fdc + 5fea: 50 ce rjmp .-864 ; 0x5c8c + 5fec: f7 01 movw r30, r14 + 5fee: 26 81 ldd r18, Z+6 ; 0x06 + 5ff0: 37 81 ldd r19, Z+7 ; 0x07 + 5ff2: 02 c0 rjmp .+4 ; 0x5ff8 + 5ff4: 2f ef ldi r18, 0xFF ; 255 + 5ff6: 3f ef ldi r19, 0xFF ; 255 + 5ff8: c9 01 movw r24, r18 + 5ffa: 2c 96 adiw r28, 0x0c ; 12 + 5ffc: e2 e1 ldi r30, 0x12 ; 18 + 5ffe: 0b c1 rjmp .+534 ; 0x6216 <__epilogue_restores__> + +00006000 <__eerd_block_x32a4u>: + 6000: e0 ec ldi r30, 0xC0 ; 192 + 6002: f1 e0 ldi r31, 0x01 ; 1 + 6004: a7 85 ldd r26, Z+15 ; 0x0f + 6006: a7 fd sbrc r26, 7 + 6008: fd cf rjmp .-6 ; 0x6004 <__eerd_block_x32a4u+0x4> + 600a: a4 85 ldd r26, Z+12 ; 0x0c + 600c: a8 60 ori r26, 0x08 ; 8 + 600e: a4 87 std Z+12, r26 ; 0x0c + 6010: 60 50 subi r22, 0x00 ; 0 + 6012: 70 4f sbci r23, 0xF0 ; 240 + 6014: f2 cd rjmp .-1052 ; 0x5bfa + +00006016 <__eewr_block_x32a4u>: + 6016: dc 01 movw r26, r24 + 6018: cb 01 movw r24, r22 + 601a: 02 c0 rjmp .+4 ; 0x6020 <__eewr_block_x32a4u+0xa> + 601c: 2d 91 ld r18, X+ + 601e: 05 d0 rcall .+10 ; 0x602a <__eewr_r18_x32a4u> + 6020: 41 50 subi r20, 0x01 ; 1 + 6022: 50 40 sbci r21, 0x00 ; 0 + 6024: d8 f7 brcc .-10 ; 0x601c <__eewr_block_x32a4u+0x6> + 6026: 08 95 ret + +00006028 <__eewr_byte_x32a4u>: + 6028: 26 2f mov r18, r22 + +0000602a <__eewr_r18_x32a4u>: + 602a: e0 ec ldi r30, 0xC0 ; 192 + 602c: f1 e0 ldi r31, 0x01 ; 1 + 602e: 37 85 ldd r19, Z+15 ; 0x0f + 6030: 37 fd sbrc r19, 7 + 6032: fd cf rjmp .-6 ; 0x602e <__eewr_r18_x32a4u+0x4> + 6034: 34 85 ldd r19, Z+12 ; 0x0c + 6036: 37 7f andi r19, 0xF7 ; 247 + 6038: 34 87 std Z+12, r19 ; 0x0c + 603a: 37 85 ldd r19, Z+15 ; 0x0f + 603c: 31 ff sbrs r19, 1 + 603e: 09 c0 rjmp .+18 ; 0x6052 <__eewr_r18_x32a4u+0x28> + 6040: 36 e3 ldi r19, 0x36 ; 54 + 6042: 32 87 std Z+10, r19 ; 0x0a + 6044: 38 ed ldi r19, 0xD8 ; 216 + 6046: 34 bf out 0x34, r19 ; 52 + 6048: 31 e0 ldi r19, 0x01 ; 1 + 604a: 33 87 std Z+11, r19 ; 0x0b + 604c: 37 85 ldd r19, Z+15 ; 0x0f + 604e: 37 fd sbrc r19, 7 + 6050: fd cf rjmp .-6 ; 0x604c <__eewr_r18_x32a4u+0x22> + 6052: 33 e3 ldi r19, 0x33 ; 51 + 6054: 32 87 std Z+10, r19 ; 0x0a + 6056: 80 83 st Z, r24 + 6058: 91 83 std Z+1, r25 ; 0x01 + 605a: 12 82 std Z+2, r1 ; 0x02 + 605c: 24 83 std Z+4, r18 ; 0x04 + 605e: 25 e3 ldi r18, 0x35 ; 53 + 6060: 22 87 std Z+10, r18 ; 0x0a + 6062: 28 ed ldi r18, 0xD8 ; 216 + 6064: 31 e0 ldi r19, 0x01 ; 1 + 6066: 24 bf out 0x34, r18 ; 52 + 6068: 33 87 std Z+11, r19 ; 0x0b + 606a: 01 96 adiw r24, 0x01 ; 1 + 606c: 08 95 ret + +0000606e : + 606e: fc 01 movw r30, r24 + 6070: 05 90 lpm r0, Z+ + 6072: 61 50 subi r22, 0x01 ; 1 + 6074: 70 40 sbci r23, 0x00 ; 0 + 6076: 01 10 cpse r0, r1 + 6078: d8 f7 brcc .-10 ; 0x6070 + 607a: 80 95 com r24 + 607c: 90 95 com r25 + 607e: 8e 0f add r24, r30 + 6080: 9f 1f adc r25, r31 + 6082: 08 95 ret + +00006084 : + 6084: fc 01 movw r30, r24 + 6086: 61 50 subi r22, 0x01 ; 1 + 6088: 70 40 sbci r23, 0x00 ; 0 + 608a: 01 90 ld r0, Z+ + 608c: 01 10 cpse r0, r1 + 608e: d8 f7 brcc .-10 ; 0x6086 + 6090: 80 95 com r24 + 6092: 90 95 com r25 + 6094: 8e 0f add r24, r30 + 6096: 9f 1f adc r25, r31 + 6098: 08 95 ret + +0000609a : + 609a: 0f 93 push r16 + 609c: 1f 93 push r17 + 609e: cf 93 push r28 + 60a0: df 93 push r29 + 60a2: 8c 01 movw r16, r24 + 60a4: eb 01 movw r28, r22 + 60a6: 8b 81 ldd r24, Y+3 ; 0x03 + 60a8: 81 fd sbrc r24, 1 + 60aa: 03 c0 rjmp .+6 ; 0x60b2 + 60ac: 0f ef ldi r16, 0xFF ; 255 + 60ae: 1f ef ldi r17, 0xFF ; 255 + 60b0: 1a c0 rjmp .+52 ; 0x60e6 + 60b2: 82 ff sbrs r24, 2 + 60b4: 0d c0 rjmp .+26 ; 0x60d0 + 60b6: 2e 81 ldd r18, Y+6 ; 0x06 + 60b8: 3f 81 ldd r19, Y+7 ; 0x07 + 60ba: 8c 81 ldd r24, Y+4 ; 0x04 + 60bc: 9d 81 ldd r25, Y+5 ; 0x05 + 60be: 28 17 cp r18, r24 + 60c0: 39 07 cpc r19, r25 + 60c2: 64 f4 brge .+24 ; 0x60dc + 60c4: e8 81 ld r30, Y + 60c6: f9 81 ldd r31, Y+1 ; 0x01 + 60c8: 01 93 st Z+, r16 + 60ca: e8 83 st Y, r30 + 60cc: f9 83 std Y+1, r31 ; 0x01 + 60ce: 06 c0 rjmp .+12 ; 0x60dc + 60d0: e8 85 ldd r30, Y+8 ; 0x08 + 60d2: f9 85 ldd r31, Y+9 ; 0x09 + 60d4: 80 2f mov r24, r16 + 60d6: 09 95 icall + 60d8: 89 2b or r24, r25 + 60da: 41 f7 brne .-48 ; 0x60ac + 60dc: 8e 81 ldd r24, Y+6 ; 0x06 + 60de: 9f 81 ldd r25, Y+7 ; 0x07 + 60e0: 01 96 adiw r24, 0x01 ; 1 + 60e2: 8e 83 std Y+6, r24 ; 0x06 + 60e4: 9f 83 std Y+7, r25 ; 0x07 + 60e6: c8 01 movw r24, r16 + 60e8: df 91 pop r29 + 60ea: cf 91 pop r28 + 60ec: 1f 91 pop r17 + 60ee: 0f 91 pop r16 + 60f0: 08 95 ret + +000060f2 <__ultoa_invert>: + 60f2: fa 01 movw r30, r20 + 60f4: aa 27 eor r26, r26 + 60f6: 28 30 cpi r18, 0x08 ; 8 + 60f8: 51 f1 breq .+84 ; 0x614e <__ultoa_invert+0x5c> + 60fa: 20 31 cpi r18, 0x10 ; 16 + 60fc: 81 f1 breq .+96 ; 0x615e <__ultoa_invert+0x6c> + 60fe: e8 94 clt + 6100: 6f 93 push r22 + 6102: 6e 7f andi r22, 0xFE ; 254 + 6104: 6e 5f subi r22, 0xFE ; 254 + 6106: 7f 4f sbci r23, 0xFF ; 255 + 6108: 8f 4f sbci r24, 0xFF ; 255 + 610a: 9f 4f sbci r25, 0xFF ; 255 + 610c: af 4f sbci r26, 0xFF ; 255 + 610e: b1 e0 ldi r27, 0x01 ; 1 + 6110: 3e d0 rcall .+124 ; 0x618e <__ultoa_invert+0x9c> + 6112: b4 e0 ldi r27, 0x04 ; 4 + 6114: 3c d0 rcall .+120 ; 0x618e <__ultoa_invert+0x9c> + 6116: 67 0f add r22, r23 + 6118: 78 1f adc r23, r24 + 611a: 89 1f adc r24, r25 + 611c: 9a 1f adc r25, r26 + 611e: a1 1d adc r26, r1 + 6120: 68 0f add r22, r24 + 6122: 79 1f adc r23, r25 + 6124: 8a 1f adc r24, r26 + 6126: 91 1d adc r25, r1 + 6128: a1 1d adc r26, r1 + 612a: 6a 0f add r22, r26 + 612c: 71 1d adc r23, r1 + 612e: 81 1d adc r24, r1 + 6130: 91 1d adc r25, r1 + 6132: a1 1d adc r26, r1 + 6134: 20 d0 rcall .+64 ; 0x6176 <__ultoa_invert+0x84> + 6136: 09 f4 brne .+2 ; 0x613a <__ultoa_invert+0x48> + 6138: 68 94 set + 613a: 3f 91 pop r19 + 613c: 2a e0 ldi r18, 0x0A ; 10 + 613e: 26 9f mul r18, r22 + 6140: 11 24 eor r1, r1 + 6142: 30 19 sub r19, r0 + 6144: 30 5d subi r19, 0xD0 ; 208 + 6146: 31 93 st Z+, r19 + 6148: de f6 brtc .-74 ; 0x6100 <__ultoa_invert+0xe> + 614a: cf 01 movw r24, r30 + 614c: 08 95 ret + 614e: 46 2f mov r20, r22 + 6150: 47 70 andi r20, 0x07 ; 7 + 6152: 40 5d subi r20, 0xD0 ; 208 + 6154: 41 93 st Z+, r20 + 6156: b3 e0 ldi r27, 0x03 ; 3 + 6158: 0f d0 rcall .+30 ; 0x6178 <__ultoa_invert+0x86> + 615a: c9 f7 brne .-14 ; 0x614e <__ultoa_invert+0x5c> + 615c: f6 cf rjmp .-20 ; 0x614a <__ultoa_invert+0x58> + 615e: 46 2f mov r20, r22 + 6160: 4f 70 andi r20, 0x0F ; 15 + 6162: 40 5d subi r20, 0xD0 ; 208 + 6164: 4a 33 cpi r20, 0x3A ; 58 + 6166: 18 f0 brcs .+6 ; 0x616e <__ultoa_invert+0x7c> + 6168: 49 5d subi r20, 0xD9 ; 217 + 616a: 31 fd sbrc r19, 1 + 616c: 40 52 subi r20, 0x20 ; 32 + 616e: 41 93 st Z+, r20 + 6170: 02 d0 rcall .+4 ; 0x6176 <__ultoa_invert+0x84> + 6172: a9 f7 brne .-22 ; 0x615e <__ultoa_invert+0x6c> + 6174: ea cf rjmp .-44 ; 0x614a <__ultoa_invert+0x58> + 6176: b4 e0 ldi r27, 0x04 ; 4 + 6178: a6 95 lsr r26 + 617a: 97 95 ror r25 + 617c: 87 95 ror r24 + 617e: 77 95 ror r23 + 6180: 67 95 ror r22 + 6182: ba 95 dec r27 + 6184: c9 f7 brne .-14 ; 0x6178 <__ultoa_invert+0x86> + 6186: 00 97 sbiw r24, 0x00 ; 0 + 6188: 61 05 cpc r22, r1 + 618a: 71 05 cpc r23, r1 + 618c: 08 95 ret + 618e: 9b 01 movw r18, r22 + 6190: ac 01 movw r20, r24 + 6192: 0a 2e mov r0, r26 + 6194: 06 94 lsr r0 + 6196: 57 95 ror r21 + 6198: 47 95 ror r20 + 619a: 37 95 ror r19 + 619c: 27 95 ror r18 + 619e: ba 95 dec r27 + 61a0: c9 f7 brne .-14 ; 0x6194 <__ultoa_invert+0xa2> + 61a2: 62 0f add r22, r18 + 61a4: 73 1f adc r23, r19 + 61a6: 84 1f adc r24, r20 + 61a8: 95 1f adc r25, r21 + 61aa: a0 1d adc r26, r0 + 61ac: 08 95 ret + +000061ae <__divmodsi4>: + 61ae: 05 2e mov r0, r21 + 61b0: 97 fb bst r25, 7 + 61b2: 16 f4 brtc .+4 ; 0x61b8 <__divmodsi4+0xa> + 61b4: 00 94 com r0 + 61b6: 06 d0 rcall .+12 ; 0x61c4 <__divmodsi4_neg1> + 61b8: 57 fd sbrc r21, 7 + 61ba: 0c d0 rcall .+24 ; 0x61d4 <__divmodsi4_neg2> + 61bc: 44 d0 rcall .+136 ; 0x6246 <__udivmodsi4> + 61be: 07 fc sbrc r0, 7 + 61c0: 09 d0 rcall .+18 ; 0x61d4 <__divmodsi4_neg2> + 61c2: 7e f4 brtc .+30 ; 0x61e2 <__divmodsi4_exit> + +000061c4 <__divmodsi4_neg1>: + 61c4: 90 95 com r25 + 61c6: 80 95 com r24 + 61c8: 70 95 com r23 + 61ca: 61 95 neg r22 + 61cc: 7f 4f sbci r23, 0xFF ; 255 + 61ce: 8f 4f sbci r24, 0xFF ; 255 + 61d0: 9f 4f sbci r25, 0xFF ; 255 + 61d2: 08 95 ret + +000061d4 <__divmodsi4_neg2>: + 61d4: 50 95 com r21 + 61d6: 40 95 com r20 + 61d8: 30 95 com r19 + 61da: 21 95 neg r18 + 61dc: 3f 4f sbci r19, 0xFF ; 255 + 61de: 4f 4f sbci r20, 0xFF ; 255 + 61e0: 5f 4f sbci r21, 0xFF ; 255 + +000061e2 <__divmodsi4_exit>: + 61e2: 08 95 ret + +000061e4 <__prologue_saves__>: + 61e4: 2f 92 push r2 + 61e6: 3f 92 push r3 + 61e8: 4f 92 push r4 + 61ea: 5f 92 push r5 + 61ec: 6f 92 push r6 + 61ee: 7f 92 push r7 + 61f0: 8f 92 push r8 + 61f2: 9f 92 push r9 + 61f4: af 92 push r10 + 61f6: bf 92 push r11 + 61f8: cf 92 push r12 + 61fa: df 92 push r13 + 61fc: ef 92 push r14 + 61fe: ff 92 push r15 + 6200: 0f 93 push r16 + 6202: 1f 93 push r17 + 6204: cf 93 push r28 + 6206: df 93 push r29 + 6208: cd b7 in r28, 0x3d ; 61 + 620a: de b7 in r29, 0x3e ; 62 + 620c: ca 1b sub r28, r26 + 620e: db 0b sbc r29, r27 + 6210: cd bf out 0x3d, r28 ; 61 + 6212: de bf out 0x3e, r29 ; 62 + 6214: 09 94 ijmp + +00006216 <__epilogue_restores__>: + 6216: 2a 88 ldd r2, Y+18 ; 0x12 + 6218: 39 88 ldd r3, Y+17 ; 0x11 + 621a: 48 88 ldd r4, Y+16 ; 0x10 + 621c: 5f 84 ldd r5, Y+15 ; 0x0f + 621e: 6e 84 ldd r6, Y+14 ; 0x0e + 6220: 7d 84 ldd r7, Y+13 ; 0x0d + 6222: 8c 84 ldd r8, Y+12 ; 0x0c + 6224: 9b 84 ldd r9, Y+11 ; 0x0b + 6226: aa 84 ldd r10, Y+10 ; 0x0a + 6228: b9 84 ldd r11, Y+9 ; 0x09 + 622a: c8 84 ldd r12, Y+8 ; 0x08 + 622c: df 80 ldd r13, Y+7 ; 0x07 + 622e: ee 80 ldd r14, Y+6 ; 0x06 + 6230: fd 80 ldd r15, Y+5 ; 0x05 + 6232: 0c 81 ldd r16, Y+4 ; 0x04 + 6234: 1b 81 ldd r17, Y+3 ; 0x03 + 6236: aa 81 ldd r26, Y+2 ; 0x02 + 6238: b9 81 ldd r27, Y+1 ; 0x01 + 623a: ce 0f add r28, r30 + 623c: d1 1d adc r29, r1 + 623e: cd bf out 0x3d, r28 ; 61 + 6240: de bf out 0x3e, r29 ; 62 + 6242: ed 01 movw r28, r26 + 6244: 08 95 ret + +00006246 <__udivmodsi4>: + 6246: a1 e2 ldi r26, 0x21 ; 33 + 6248: 1a 2e mov r1, r26 + 624a: aa 1b sub r26, r26 + 624c: bb 1b sub r27, r27 + 624e: fd 01 movw r30, r26 + 6250: 0d c0 rjmp .+26 ; 0x626c <__udivmodsi4_ep> + +00006252 <__udivmodsi4_loop>: + 6252: aa 1f adc r26, r26 + 6254: bb 1f adc r27, r27 + 6256: ee 1f adc r30, r30 + 6258: ff 1f adc r31, r31 + 625a: a2 17 cp r26, r18 + 625c: b3 07 cpc r27, r19 + 625e: e4 07 cpc r30, r20 + 6260: f5 07 cpc r31, r21 + 6262: 20 f0 brcs .+8 ; 0x626c <__udivmodsi4_ep> + 6264: a2 1b sub r26, r18 + 6266: b3 0b sbc r27, r19 + 6268: e4 0b sbc r30, r20 + 626a: f5 0b sbc r31, r21 + +0000626c <__udivmodsi4_ep>: + 626c: 66 1f adc r22, r22 + 626e: 77 1f adc r23, r23 + 6270: 88 1f adc r24, r24 + 6272: 99 1f adc r25, r25 + 6274: 1a 94 dec r1 + 6276: 69 f7 brne .-38 ; 0x6252 <__udivmodsi4_loop> + 6278: 60 95 com r22 + 627a: 70 95 com r23 + 627c: 80 95 com r24 + 627e: 90 95 com r25 + 6280: 9b 01 movw r18, r22 + 6282: ac 01 movw r20, r24 + 6284: bd 01 movw r22, r26 + 6286: cf 01 movw r24, r30 + 6288: 08 95 ret + +0000628a <_exit>: + 628a: f8 94 cli + +0000628c <__stop_program>: + 628c: ff cf rjmp .-2 ; 0x628c <__stop_program> diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.map b/Firmware/Chameleon-Mini/Chameleon-Mini.map index 729541b..b6d89ab 100644 --- a/Firmware/Chameleon-Mini/Chameleon-Mini.map +++ b/Firmware/Chameleon-Mini/Chameleon-Mini.map @@ -1,2936 +1,3206 @@ -Archive member included because of file (symbol) - -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o (exit) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) - Bin/XModem.o (__tablejump2__) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - Bin/Terminal.o (__do_copy_data) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - Bin/Configuration.o (__do_clear_bss) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - Bin/Commands.o (__mulshisi3) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) (__muluhisi3) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_umulhisi3.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) (__umulhisi3) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) - Bin/Random.o (rand) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcpy_P.o) - Bin/Configuration.o (memcpy_P) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strcmp_P.o) - Bin/Button.o (strcmp_P) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strncpy_P.o) - Bin/Button.o (strncpy_P) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcmp.o) - Bin/HIDClassDevice.o (memcmp) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcpy.o) - Bin/HIDClassDevice.o (memcpy) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memset.o) - Bin/HIDClassDevice.o (memset) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) - Bin/Commands.o (snprintf_P) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) (vfprintf) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_block_atxmega32a4u.o) - Bin/Settings.o (__eerd_block_x32a4u) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_byte_atxmega32a4u.o) - Bin/EndpointStream_XMEGA.o (__eerd_byte_x32a4u) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eeupd_byte_atxmega32a4u.o) - Bin/EndpointStream_XMEGA.o (__eeupd_byte_x32a4u) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_block_atxmega32a4u.o) - Bin/Settings.o (__eewr_block_x32a4u) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_byte_atxmega32a4u.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eeupd_byte_atxmega32a4u.o) (__eewr_r18_x32a4u) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strnlen_P.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) (strnlen_P) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strnlen.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) (strnlen) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(fputc.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) (fputc) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(ultoa_invert.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) (__ultoa_invert) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) (__divmodsi4) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_negsi2.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) (__negsi2) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_prologue.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) (__prologue_saves__) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_epilogue.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) (__epilogue_restores__) -/home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_udivmodsi4.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) (__udivmodsi4) - -Allocating common symbols -Common symbol size file - -USB_IsInitialized 0x1 Bin/USBTask.o -USB_EndpointTable 0x63 Bin/USBController_XMEGA.o -TerminalBuffer 0x100 Bin/Terminal.o -USB_Endpoint_SelectedFIFO - 0x2 Bin/Endpoint_XMEGA.o -ActiveConfiguration - 0x25 Bin/Configuration.o -USB_DeviceState 0x1 Bin/USBTask.o -USB_Device_ConfigurationNumber - 0x1 Bin/DeviceStandardReq.o -USB_Endpoint_SelectedHandle - 0x2 Bin/Endpoint_XMEGA.o -USB_Device_CurrentlySelfPowered - 0x1 Bin/DeviceStandardReq.o -CodecBuffer 0x100 Bin/Codec.o -GlobalSettings 0x13 Bin/Settings.o -USB_Endpoint_SelectedEndpoint - 0x1 Bin/Endpoint_XMEGA.o -USB_ControlRequest 0x8 Bin/USBTask.o -USB_Endpoint_FIFOs 0x318 Bin/Endpoint_XMEGA.o -USB_Device_RemoteWakeupEnabled - 0x1 Bin/DeviceStandardReq.o - -Discarded input sections - - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o - .text 0x00000000 0x0 Bin/Chameleon-Mini.o - .bss 0x00000000 0x0 Bin/Chameleon-Mini.o - .text 0x00000000 0x0 Bin/LUFADescriptors.o - .bss 0x00000000 0x0 Bin/LUFADescriptors.o - .text 0x00000000 0x0 Bin/System.o - .bss 0x00000000 0x0 Bin/System.o - .text 0x00000000 0x0 Bin/Configuration.o - .bss 0x00000000 0x0 Bin/Configuration.o - .text 0x00000000 0x0 Bin/Random.o - .bss 0x00000000 0x0 Bin/Random.o - .text 0x00000000 0x0 Bin/Common.o - .bss 0x00000000 0x0 Bin/Common.o - .text 0x00000000 0x0 Bin/Memory.o - .text 0x00000000 0x0 Bin/Button.o - .text.ButtonSetActionById - 0x00000000 0xc Bin/Button.o - .text 0x00000000 0x0 Bin/Settings.o - .bss 0x00000000 0x0 Bin/Settings.o - .text.SettingsGetActiveById - 0x00000000 0x6 Bin/Settings.o - .text 0x00000000 0x0 Bin/LED.o - .text 0x00000000 0x0 Bin/Terminal.o - .text 0x00000000 0x0 Bin/Commands.o - .bss 0x00000000 0x0 Bin/Commands.o - .text 0x00000000 0x0 Bin/XModem.o - .text 0x00000000 0x0 Bin/CommandLine.o - .text.CommandLineInit - 0x00000000 0xa Bin/CommandLine.o - .text 0x00000000 0x0 Bin/Codec.o - .bss 0x00000000 0x0 Bin/Codec.o - .text 0x00000000 0x0 Bin/ISO14443-2A.o - .text 0x00000000 0x0 Bin/MifareClassic.o - .text 0x00000000 0x0 Bin/ISO14443-3A.o - .bss 0x00000000 0x0 Bin/ISO14443-3A.o - .text 0x00000000 0x0 Bin/Crypto1.o - .text 0x00000000 0x0 Bin/HIDParser.o - .bss 0x00000000 0x0 Bin/HIDParser.o - .text.USB_ProcessHIDReport - 0x00000000 0x99a Bin/HIDParser.o - .progmem.gcc_sw_table.USB_ProcessHIDReport - 0x00000000 0x17a Bin/HIDParser.o - .text.USB_GetHIDReportItemInfo - 0x00000000 0xc6 Bin/HIDParser.o - .text.USB_SetHIDReportItemInfo - 0x00000000 0x110 Bin/HIDParser.o - .text.USB_GetHIDReportSize - 0x00000000 0x11c Bin/HIDParser.o - .text 0x00000000 0x0 Bin/ConfigDescriptors.o - .bss 0x00000000 0x0 Bin/ConfigDescriptors.o - .text.USB_GetNextDescriptorOfType - 0x00000000 0x52 Bin/ConfigDescriptors.o - .text.USB_GetNextDescriptorOfTypeBefore - 0x00000000 0x7c Bin/ConfigDescriptors.o - .text.USB_GetNextDescriptorOfTypeAfter - 0x00000000 0x3e Bin/ConfigDescriptors.o - .text.USB_GetNextDescriptorComp - 0x00000000 0x8e Bin/ConfigDescriptors.o - .text 0x00000000 0x0 Bin/DeviceStandardReq.o - .bss 0x00000000 0x0 Bin/DeviceStandardReq.o - .text 0x00000000 0x0 Bin/Events.o - .bss 0x00000000 0x0 Bin/Events.o - .text 0x00000000 0x0 Bin/HostStandardReq.o - .bss 0x00000000 0x0 Bin/HostStandardReq.o - .text 0x00000000 0x0 Bin/USBTask.o - .bss 0x00000000 0x0 Bin/USBTask.o - .text 0x00000000 0x0 Bin/Device_XMEGA.o - .bss 0x00000000 0x0 Bin/Device_XMEGA.o - .text.USB_Device_SendRemoteWakeup - 0x00000000 0xc Bin/Device_XMEGA.o - .text 0x00000000 0x0 Bin/EndpointStream_XMEGA.o - .bss 0x00000000 0x0 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Discard_Stream - 0x00000000 0xc8 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Null_Stream - 0x00000000 0xc2 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Write_Stream_BE - 0x00000000 0xe8 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Read_Stream_LE - 0x00000000 0xd8 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Read_Stream_BE - 0x00000000 0xe8 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Write_PStream_LE - 0x00000000 0xe0 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Write_PStream_BE - 0x00000000 0xea Bin/EndpointStream_XMEGA.o - .text.Endpoint_Write_EStream_LE - 0x00000000 0xe0 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Write_EStream_BE - 0x00000000 0xea Bin/EndpointStream_XMEGA.o - .text.Endpoint_Read_EStream_LE - 0x00000000 0xee Bin/EndpointStream_XMEGA.o - .text.Endpoint_Read_EStream_BE - 0x00000000 0xf8 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Write_Control_Stream_BE - 0x00000000 0x170 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Read_Control_Stream_LE - 0x00000000 0xe2 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Read_Control_Stream_BE - 0x00000000 0xd4 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Write_Control_PStream_BE - 0x00000000 0x170 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Write_Control_EStream_LE - 0x00000000 0x170 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Write_Control_EStream_BE - 0x00000000 0x172 Bin/EndpointStream_XMEGA.o - .text.Endpoint_Read_Control_EStream_LE - 0x00000000 0xec Bin/EndpointStream_XMEGA.o - .text.Endpoint_Read_Control_EStream_BE - 0x00000000 0xd8 Bin/EndpointStream_XMEGA.o - .text 0x00000000 0x0 Bin/Endpoint_XMEGA.o - .bss 0x00000000 0x0 Bin/Endpoint_XMEGA.o - .text 0x00000000 0x0 Bin/Host_XMEGA.o - .bss 0x00000000 0x0 Bin/Host_XMEGA.o - .text 0x00000000 0x0 Bin/PipeStream_XMEGA.o - .bss 0x00000000 0x0 Bin/PipeStream_XMEGA.o - .text 0x00000000 0x0 Bin/Pipe_XMEGA.o - .bss 0x00000000 0x0 Bin/Pipe_XMEGA.o - .text 0x00000000 0x0 Bin/USBController_XMEGA.o - .bss 0x00000000 0x0 Bin/USBController_XMEGA.o - .text 0x00000000 0x0 Bin/USBInterrupt_XMEGA.o - .bss 0x00000000 0x0 Bin/USBInterrupt_XMEGA.o - .text 0x00000000 0x0 Bin/AudioClassDevice.o - .bss 0x00000000 0x0 Bin/AudioClassDevice.o - .text.Audio_Device_ConfigureEndpoints - 0x00000000 0x32 Bin/AudioClassDevice.o - .text.Audio_Device_Event_Stub - 0x00000000 0x2 Bin/AudioClassDevice.o - .text.Audio_Device_ProcessControlRequest - 0x00000000 0x29e Bin/AudioClassDevice.o - .text 0x00000000 0x0 Bin/CDCClassDevice.o - .bss 0x00000000 0x0 Bin/CDCClassDevice.o - .text.CDC_Device_putchar - 0x00000000 0x22 Bin/CDCClassDevice.o - .text.CDC_Device_BytesReceived - 0x00000000 0xa4 Bin/CDCClassDevice.o - .text.CDC_Device_getchar - 0x00000000 0x14 Bin/CDCClassDevice.o - .text.CDC_Device_getchar_Blocking - 0x00000000 0x38 Bin/CDCClassDevice.o - .rodata 0x00000000 0x8 Bin/CDCClassDevice.o - .text.CDC_Device_SendControlLineStateChange - 0x00000000 0x7c Bin/CDCClassDevice.o - .text.CDC_Device_CreateStream - 0x00000000 0x26 Bin/CDCClassDevice.o - .text.CDC_Device_CreateBlockingStream - 0x00000000 0x26 Bin/CDCClassDevice.o - .text 0x00000000 0x0 Bin/HIDClassDevice.o - .bss 0x00000000 0x0 Bin/HIDClassDevice.o - .text.HID_Device_ProcessControlRequest - 0x00000000 0x240 Bin/HIDClassDevice.o - .text.HID_Device_ConfigureEndpoints - 0x00000000 0x28 Bin/HIDClassDevice.o - .text.HID_Device_USBTask - 0x00000000 0x1a8 Bin/HIDClassDevice.o - .text 0x00000000 0x0 Bin/MassStorageClassDevice.o - .bss 0x00000000 0x0 Bin/MassStorageClassDevice.o - .text.MS_Device_ProcessControlRequest - 0x00000000 0x70 Bin/MassStorageClassDevice.o - .text.MS_Device_ConfigureEndpoints - 0x00000000 0x3e Bin/MassStorageClassDevice.o - .text.MS_Device_USBTask - 0x00000000 0x2c2 Bin/MassStorageClassDevice.o - .text 0x00000000 0x0 Bin/MIDIClassDevice.o - .bss 0x00000000 0x0 Bin/MIDIClassDevice.o - .text.MIDI_Device_ConfigureEndpoints - 0x00000000 0x32 Bin/MIDIClassDevice.o - .text.MIDI_Device_SendEventPacket - 0x00000000 0x54 Bin/MIDIClassDevice.o - .text.MIDI_Device_Flush - 0x00000000 0x58 Bin/MIDIClassDevice.o - .text.MIDI_Device_USBTask - 0x00000000 0x2c Bin/MIDIClassDevice.o - .text.MIDI_Device_ReceiveEventPacket - 0x00000000 0x68 Bin/MIDIClassDevice.o - .text 0x00000000 0x0 Bin/PrinterClassDevice.o - .bss 0x00000000 0x0 Bin/PrinterClassDevice.o - .text.PRNT_Device_ConfigureEndpoints - 0x00000000 0x38 Bin/PrinterClassDevice.o - .text.PRNT_Device_SendString - 0x00000000 0x3e Bin/PrinterClassDevice.o - .text.PRNT_Device_SendData - 0x00000000 0x3c Bin/PrinterClassDevice.o - .text.PRNT_Device_SendByte - 0x00000000 0x5a Bin/PrinterClassDevice.o - .text.PRNT_Device_putchar - 0x00000000 0x22 Bin/PrinterClassDevice.o - .text.PRNT_Device_Flush - 0x00000000 0x74 Bin/PrinterClassDevice.o - .text.PRNT_Device_USBTask - 0x00000000 0xcc Bin/PrinterClassDevice.o - .text.PRNT_Device_BytesReceived - 0x00000000 0x94 Bin/PrinterClassDevice.o - .text.PRNT_Device_ReceiveByte - 0x00000000 0xb0 Bin/PrinterClassDevice.o - .text.PRNT_Device_getchar - 0x00000000 0x14 Bin/PrinterClassDevice.o - .text.PRNT_Device_getchar_Blocking - 0x00000000 0x38 Bin/PrinterClassDevice.o - .text.PRNT_Device_CreateStream - 0x00000000 0x26 Bin/PrinterClassDevice.o - .text.PRNT_Device_CreateBlockingStream - 0x00000000 0x26 Bin/PrinterClassDevice.o - .text.PRNT_Device_Event_Stub - 0x00000000 0x2 Bin/PrinterClassDevice.o - .text.PRNT_Device_ProcessControlRequest - 0x00000000 0xda Bin/PrinterClassDevice.o - .text 0x00000000 0x0 Bin/RNDISClassDevice.o - .bss 0x00000000 0x0 Bin/RNDISClassDevice.o - .text.RNDIS_Device_ProcessControlRequest - 0x00000000 0x52e Bin/RNDISClassDevice.o - .text.RNDIS_Device_ConfigureEndpoints - 0x00000000 0x50 Bin/RNDISClassDevice.o - .rodata 0x00000000 0x8 Bin/RNDISClassDevice.o - .text.RNDIS_Device_USBTask - 0x00000000 0x74 Bin/RNDISClassDevice.o - .text.RNDIS_Device_IsPacketReceived - 0x00000000 0x24 Bin/RNDISClassDevice.o - .text.RNDIS_Device_ReadPacket - 0x00000000 0xa2 Bin/RNDISClassDevice.o - .text.RNDIS_Device_SendPacket - 0x00000000 0xca Bin/RNDISClassDevice.o - .progmem.data 0x00000000 0x6c Bin/RNDISClassDevice.o - .text 0x00000000 0x0 Bin/AndroidAccessoryClassHost.o - .bss 0x00000000 0x0 Bin/AndroidAccessoryClassHost.o - .text 0x00000000 0x0 Bin/AudioClassHost.o - .bss 0x00000000 0x0 Bin/AudioClassHost.o - .text 0x00000000 0x0 Bin/CDCClassHost.o - .bss 0x00000000 0x0 Bin/CDCClassHost.o - .text 0x00000000 0x0 Bin/HIDClassHost.o - .bss 0x00000000 0x0 Bin/HIDClassHost.o - .text 0x00000000 0x0 Bin/MassStorageClassHost.o - .bss 0x00000000 0x0 Bin/MassStorageClassHost.o - .text 0x00000000 0x0 Bin/MIDIClassHost.o - .bss 0x00000000 0x0 Bin/MIDIClassHost.o - .text 0x00000000 0x0 Bin/PrinterClassHost.o - .bss 0x00000000 0x0 Bin/PrinterClassHost.o - .text 0x00000000 0x0 Bin/RNDISClassHost.o - .bss 0x00000000 0x0 Bin/RNDISClassHost.o - .text 0x00000000 0x0 Bin/StillImageClassHost.o - .bss 0x00000000 0x0 Bin/StillImageClassHost.o - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - .text.libgcc.mul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - .text.libgcc.div - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - .text.libgcc 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - .text.libgcc.prologue - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - .text.libgcc.builtins - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - .text.libgcc.fmul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - .text.libgcc.fixed - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) - .text.libgcc.mul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) - .text.libgcc.div - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) - .text.libgcc.prologue - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) - .text.libgcc.builtins - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) - .text.libgcc.fmul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) - .text.libgcc.fixed - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - .text.libgcc.mul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - .text.libgcc.div - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - .text.libgcc 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - .text.libgcc.prologue - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - .text.libgcc.builtins - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - .text.libgcc.fmul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - .text.libgcc.fixed - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - .text.libgcc.mul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - .text.libgcc.div - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - .text.libgcc 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - .text.libgcc.prologue - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - .text.libgcc.builtins - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - .text.libgcc.fmul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - .text.libgcc.fixed - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - .text.libgcc.div - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - .text.libgcc 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - .text.libgcc.prologue - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - .text.libgcc.builtins - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - .text.libgcc.fmul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - .text.libgcc.fixed - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) - .text.libgcc.div - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) - .text.libgcc 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) - .text.libgcc.prologue - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) - .text.libgcc.builtins - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) - .text.libgcc.fmul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) - .text.libgcc.fixed - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_umulhisi3.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_umulhisi3.o) - .text.libgcc.div - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_umulhisi3.o) - .text.libgcc 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_umulhisi3.o) - .text.libgcc.prologue - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_umulhisi3.o) - .text.libgcc.builtins - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_umulhisi3.o) - .text.libgcc.fmul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_umulhisi3.o) - .text.libgcc.fixed - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_umulhisi3.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcpy_P.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcpy_P.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strcmp_P.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strcmp_P.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strncpy_P.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strncpy_P.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcmp.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcmp.o) - .text.avr-libc - 0x00000000 0x1a /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcmp.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcpy.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcpy.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memset.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memset.o) - .text.avr-libc - 0x00000000 0xe /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memset.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_block_atxmega32a4u.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_block_atxmega32a4u.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_byte_atxmega32a4u.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_byte_atxmega32a4u.o) - .text.avr-libc - 0x00000000 0x20 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_byte_atxmega32a4u.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eeupd_byte_atxmega32a4u.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eeupd_byte_atxmega32a4u.o) - .text.avr-libc - 0x00000000 0x16 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eeupd_byte_atxmega32a4u.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_block_atxmega32a4u.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_block_atxmega32a4u.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_byte_atxmega32a4u.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_byte_atxmega32a4u.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strnlen_P.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strnlen_P.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strnlen.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strnlen.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(fputc.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(fputc.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(ultoa_invert.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(ultoa_invert.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) - .text.libgcc.mul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) - .text.libgcc 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) - .text.libgcc.prologue - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) - .text.libgcc.builtins - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) - .text.libgcc.fmul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) - .text.libgcc.fixed - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_negsi2.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_negsi2.o) - .text.libgcc.mul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_negsi2.o) - .text.libgcc 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_negsi2.o) - .text.libgcc.prologue - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_negsi2.o) - .text.libgcc.builtins - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_negsi2.o) - .text.libgcc.fmul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_negsi2.o) - .text.libgcc.fixed - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_negsi2.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_prologue.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_prologue.o) - .text.libgcc.mul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_prologue.o) - .text.libgcc.div - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_prologue.o) - .text.libgcc 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_prologue.o) - .text.libgcc.builtins - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_prologue.o) - .text.libgcc.fmul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_prologue.o) - .text.libgcc.fixed - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_prologue.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_epilogue.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_epilogue.o) - .text.libgcc.mul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_epilogue.o) - .text.libgcc.div - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_epilogue.o) - .text.libgcc 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_epilogue.o) - .text.libgcc.builtins - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_epilogue.o) - .text.libgcc.fmul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_epilogue.o) - .text.libgcc.fixed - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_epilogue.o) - .text 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_udivmodsi4.o) - .bss 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_udivmodsi4.o) - .text.libgcc.mul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_udivmodsi4.o) - .text.libgcc 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_udivmodsi4.o) - .text.libgcc.prologue - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_udivmodsi4.o) - .text.libgcc.builtins - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_udivmodsi4.o) - .text.libgcc.fmul - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_udivmodsi4.o) - .text.libgcc.fixed - 0x00000000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_udivmodsi4.o) - -Memory Configuration - -Name Origin Length Attributes -text 0x00000000 0x00100000 xr -data 0x00802000 0x0000ffa0 rw !x -eeprom 0x00810000 0x00010000 rw !x -fuse 0x00820000 0x00000400 rw !x -lock 0x00830000 0x00000400 rw !x -signature 0x00840000 0x00000400 rw !x -user_signatures 0x00850000 0x00000400 rw !x -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -LOAD Bin/Chameleon-Mini.o -LOAD Bin/LUFADescriptors.o -LOAD Bin/System.o -LOAD Bin/Configuration.o -LOAD Bin/Random.o -LOAD Bin/Common.o -LOAD Bin/Memory.o -LOAD Bin/Button.o -LOAD Bin/Settings.o -LOAD Bin/LED.o -LOAD Bin/Terminal.o -LOAD Bin/Commands.o -LOAD Bin/XModem.o -LOAD Bin/CommandLine.o -LOAD Bin/Codec.o -LOAD Bin/ISO14443-2A.o -LOAD Bin/MifareClassic.o -LOAD Bin/ISO14443-3A.o -LOAD Bin/Crypto1.o -LOAD Bin/HIDParser.o -LOAD Bin/ConfigDescriptors.o -LOAD Bin/DeviceStandardReq.o -LOAD Bin/Events.o -LOAD Bin/HostStandardReq.o -LOAD Bin/USBTask.o -LOAD Bin/Device_XMEGA.o -LOAD Bin/EndpointStream_XMEGA.o -LOAD Bin/Endpoint_XMEGA.o -LOAD Bin/Host_XMEGA.o -LOAD Bin/PipeStream_XMEGA.o -LOAD Bin/Pipe_XMEGA.o -LOAD Bin/USBController_XMEGA.o -LOAD Bin/USBInterrupt_XMEGA.o -LOAD Bin/AudioClassDevice.o -LOAD Bin/CDCClassDevice.o -LOAD Bin/HIDClassDevice.o -LOAD Bin/MassStorageClassDevice.o -LOAD Bin/MIDIClassDevice.o -LOAD Bin/PrinterClassDevice.o -LOAD Bin/RNDISClassDevice.o -LOAD Bin/AndroidAccessoryClassHost.o -LOAD Bin/AudioClassHost.o -LOAD Bin/CDCClassHost.o -LOAD Bin/HIDClassHost.o -LOAD Bin/MassStorageClassHost.o -LOAD Bin/MIDIClassHost.o -LOAD Bin/PrinterClassHost.o -LOAD Bin/RNDISClassHost.o -LOAD Bin/StillImageClassHost.o -LOAD /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libm.a -START GROUP -LOAD /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a -LOAD /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libm.a -LOAD /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a -END GROUP - -.hash - *(.hash) - -.dynsym - *(.dynsym) - -.dynstr - *(.dynstr) - -.gnu.version - *(.gnu.version) - -.gnu.version_d - *(.gnu.version_d) - -.gnu.version_r - *(.gnu.version_r) - -.rel.init - *(.rel.init) - -.rela.init - *(.rela.init) - -.rel.text - *(.rel.text) - *(.rel.text.*) - *(.rel.gnu.linkonce.t*) - -.rela.text - *(.rela.text) - *(.rela.text.*) - *(.rela.gnu.linkonce.t*) - -.rel.fini - *(.rel.fini) - -.rela.fini - *(.rela.fini) - -.rel.rodata - *(.rel.rodata) - *(.rel.rodata.*) - *(.rel.gnu.linkonce.r*) - -.rela.rodata - *(.rela.rodata) - *(.rela.rodata.*) - *(.rela.gnu.linkonce.r*) - -.rel.data - *(.rel.data) - *(.rel.data.*) - *(.rel.gnu.linkonce.d*) - -.rela.data - *(.rela.data) - *(.rela.data.*) - *(.rela.gnu.linkonce.d*) - -.rel.ctors - *(.rel.ctors) - -.rela.ctors - *(.rela.ctors) - -.rel.dtors - *(.rel.dtors) - -.rela.dtors - *(.rela.dtors) - -.rel.got - *(.rel.got) - -.rela.got - *(.rela.got) - -.rel.bss - *(.rel.bss) - -.rela.bss - *(.rela.bss) - -.rel.plt - *(.rel.plt) - -.rela.plt - *(.rela.plt) - -.text 0x00000000 0x4e9a - *(.vectors) - .vectors 0x00000000 0x1fc /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o - 0x00000000 __vectors - *(.vectors) - *(.progmem.gcc*) - .progmem.gcc_sw_table.XModemProcessByte - 0x000001fc 0x12 Bin/XModem.o - .progmem.gcc_sw_table.__vector_83 - 0x0000020e 0x16 Bin/ISO14443-2A.o - .progmem.gcc_sw_table.MifareClassicAppProcess - 0x00000224 0x14 Bin/MifareClassic.o - .progmem.gcc_sw_table.USB_Device_ProcessControlRequest - 0x00000238 0x14 Bin/DeviceStandardReq.o - 0x0000024c . = ALIGN (0x2) - 0x0000024c __trampolines_start = . - *(.trampolines) - .trampolines 0x0000024c 0x0 linker stubs - *(.trampolines*) - 0x0000024c __trampolines_end = . - *(.progmem*) - .progmem.data 0x0000024c 0x8c Bin/LUFADescriptors.o - 0x0000024c ProductString - 0x0000026a ManufacturerString - 0x00000284 LanguageString - 0x00000288 ConfigurationDescriptor - 0x000002c6 DeviceDescriptor - .progmem.data 0x000002d8 0x6f Bin/Configuration.o - .progmem.data 0x00000347 0x120 Bin/Button.o - .progmem.data 0x00000467 0x64 Bin/Commands.o - .progmem.data 0x000004cb 0x22c Bin/CommandLine.o - 0x00000597 CommandTable - 0x000006f8 . = ALIGN (0x2) - *fill* 0x000006f7 0x1 - *(.jumptables) - *(.jumptables*) - *(.lowtext) - *(.lowtext*) - 0x000006f8 __ctors_start = . - *(.ctors) - 0x000006f8 __ctors_end = . - 0x000006f8 __dtors_start = . - *(.dtors) - 0x000006f8 __dtors_end = . - SORT(*)(.ctors) - SORT(*)(.dtors) - *(.init0) - .init0 0x000006f8 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o - 0x000006f8 __init - *(.init0) - *(.init1) - *(.init1) - *(.init2) - .init2 0x000006f8 0xc /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o - *(.init2) - *(.init3) - *(.init3) - *(.init4) - .init4 0x00000704 0x16 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - 0x00000704 __do_copy_data - .init4 0x0000071a 0x10 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - 0x0000071a __do_clear_bss - *(.init4) - *(.init5) - *(.init5) - *(.init6) - *(.init6) - *(.init7) - *(.init7) - *(.init8) - *(.init8) - *(.init9) - .init9 0x0000072a 0x6 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o - *(.init9) - *(.text) - .text 0x00000730 0x2 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o - 0x00000730 __vector_38 - 0x00000730 __vector_104 - 0x00000730 __vector_63 - 0x00000730 __vector_28 - 0x00000730 __vector_67 - 0x00000730 __vector_1 - 0x00000730 __vector_119 - 0x00000730 __vector_32 - 0x00000730 __vector_75 - 0x00000730 __vector_71 - 0x00000730 __vector_91 - 0x00000730 __vector_62 - 0x00000730 __vector_77 - 0x00000730 __vector_102 - 0x00000730 __vector_24 - 0x00000730 __vector_12 - 0x00000730 __vector_55 - 0x00000730 __vector_69 - 0x00000730 __vector_81 - 0x00000730 __vector_90 - 0x00000730 __vector_46 - 0x00000730 __bad_interrupt - 0x00000730 __vector_122 - 0x00000730 __vector_72 - 0x00000730 __vector_114 - 0x00000730 __vector_6 - 0x00000730 __vector_110 - 0x00000730 __vector_31 - 0x00000730 __vector_92 - 0x00000730 __vector_35 - 0x00000730 __vector_78 - 0x00000730 __vector_74 - 0x00000730 __vector_117 - 0x00000730 __vector_39 - 0x00000730 __vector_107 - 0x00000730 __vector_3 - 0x00000730 __vector_105 - 0x00000730 __vector_98 - 0x00000730 __vector_23 - 0x00000730 __vector_68 - 0x00000730 __vector_30 - 0x00000730 __vector_73 - 0x00000730 __vector_45 - 0x00000730 __vector_25 - 0x00000730 __vector_93 - 0x00000730 __vector_61 - 0x00000730 __vector_11 - 0x00000730 __vector_54 - 0x00000730 __vector_99 - 0x00000730 __vector_13 - 0x00000730 __vector_17 - 0x00000730 __vector_19 - 0x00000730 __vector_56 - 0x00000730 __vector_7 - 0x00000730 __vector_49 - 0x00000730 __vector_123 - 0x00000730 __vector_41 - 0x00000730 __vector_86 - 0x00000730 __vector_100 - 0x00000730 __vector_101 - 0x00000730 __vector_64 - 0x00000730 __vector_88 - 0x00000730 __vector_109 - 0x00000730 __vector_43 - 0x00000730 __vector_27 - 0x00000730 __vector_5 - 0x00000730 __vector_113 - 0x00000730 __vector_33 - 0x00000730 __vector_76 - 0x00000730 __vector_115 - 0x00000730 __vector_47 - 0x00000730 __vector_52 - 0x00000730 __vector_37 - 0x00000730 __vector_95 - 0x00000730 __vector_103 - 0x00000730 __vector_96 - 0x00000730 __vector_89 - 0x00000730 __vector_108 - 0x00000730 __vector_4 - 0x00000730 __vector_44 - 0x00000730 __vector_82 - 0x00000730 __vector_106 - 0x00000730 __vector_118 - 0x00000730 __vector_51 - 0x00000730 __vector_9 - 0x00000730 __vector_2 - 0x00000730 __vector_21 - 0x00000730 __vector_15 - 0x00000730 __vector_66 - 0x00000730 __vector_36 - 0x00000730 __vector_79 - 0x00000730 __vector_58 - 0x00000730 __vector_70 - 0x00000730 __vector_29 - 0x00000730 __vector_60 - 0x00000730 __vector_121 - 0x00000730 __vector_40 - 0x00000730 __vector_85 - 0x00000730 __vector_94 - 0x00000730 __vector_126 - 0x00000730 __vector_8 - 0x00000730 __vector_26 - 0x00000730 __vector_48 - 0x00000730 __vector_124 - 0x00000730 __vector_116 - 0x00000730 __vector_112 - 0x00000730 __vector_111 - 0x00000730 __vector_80 - 0x00000730 __vector_14 - 0x00000730 __vector_84 - 0x00000730 __vector_57 - 0x00000730 __vector_53 - 0x00000730 __vector_10 - 0x00000730 __vector_50 - 0x00000730 __vector_16 - 0x00000730 __vector_59 - 0x00000730 __vector_18 - 0x00000730 __vector_97 - 0x00000730 __vector_20 - 0x00000730 __vector_42 - 0x00000730 __vector_87 - 0x00000730 __vector_65 - 0x00000730 __vector_120 - 0x00000732 . = ALIGN (0x2) - *(.text.*) - .text.startup.main - 0x00000732 0x76 Bin/Chameleon-Mini.o - 0x00000732 main - .text.CALLBACK_USB_GetDescriptor - 0x000007a8 0x7c Bin/LUFADescriptors.o - 0x000007a8 CALLBACK_USB_GetDescriptor - .text.__vector_default - 0x00000824 0xc Bin/System.o - 0x00000824 __vector_default - .text.SystemInit - 0x00000830 0x6e Bin/System.o - 0x00000830 SystemInit - .text.SystemReset - 0x0000089e 0xe Bin/System.o - 0x0000089e SystemReset - .text.SystemEnterBootloader - 0x000008ac 0xc Bin/System.o - 0x000008ac SystemEnterBootloader - .text.SystemStartUSBClock - 0x000008b8 0x32 Bin/System.o - 0x000008b8 SystemStartUSBClock - .text.SystemStopUSBClock - 0x000008ea 0x1c Bin/System.o - 0x000008ea SystemStopUSBClock - .text.SystemInterruptInit - 0x00000906 0xc Bin/System.o - 0x00000906 SystemInterruptInit - .text.CodecInitDummy - 0x00000912 0x2 Bin/Configuration.o - .text.CodecTaskDummy - 0x00000914 0x2 Bin/Configuration.o - .text.ApplicationInitDummy - 0x00000916 0x2 Bin/Configuration.o - .text.ApplicationResetDummy - 0x00000918 0x2 Bin/Configuration.o - .text.ApplicationTaskDummy - 0x0000091a 0x2 Bin/Configuration.o - .text.ApplicationProcessDummy - 0x0000091c 0x6 Bin/Configuration.o - .text.ApplicationGetUidDummy - 0x00000922 0x2 Bin/Configuration.o - .text.ApplicationSetUidDummy - 0x00000924 0x2 Bin/Configuration.o - .text.ConfigurationSetById - 0x00000926 0x36 Bin/Configuration.o - 0x00000926 ConfigurationSetById - .text.ConfigurationInit - 0x0000095c 0xc Bin/Configuration.o - 0x0000095c ConfigurationInit - .text.ConfigurationSetByName - 0x00000968 0x7a Bin/Configuration.o - 0x00000968 ConfigurationSetByName - .text.ConfigurationGetList - 0x000009e2 0x74 Bin/Configuration.o - 0x000009e2 ConfigurationGetList - .text.RandomInit - 0x00000a56 0x2 Bin/Random.o - 0x00000a56 RandomInit - .text.RandomGetByte - 0x00000a58 0x6 Bin/Random.o - 0x00000a58 RandomGetByte - .text.RandomGetBuffer - 0x00000a5e 0x20 Bin/Random.o - 0x00000a5e RandomGetBuffer - .text.RandomTick - 0x00000a7e 0x10 Bin/Random.o - 0x00000a7e RandomTick - .text.BufferToHexString - 0x00000a8e 0x86 Bin/Common.o - 0x00000a8e BufferToHexString - .text.HexStringToBuffer - 0x00000b14 0x94 Bin/Common.o - 0x00000b14 HexStringToBuffer - .text.MemoryReadBlock - 0x00000ba8 0x30 Bin/Memory.o - 0x00000ba8 MemoryReadBlock - .text.MemoryWriteBlock - 0x00000bd8 0x2e Bin/Memory.o - 0x00000bd8 MemoryWriteBlock - .text.MemoryClear - 0x00000c06 0x16 Bin/Memory.o - 0x00000c06 MemoryClear - .text.MemoryRecall - 0x00000c1c 0xec Bin/Memory.o - 0x00000c1c MemoryRecall - .text.MemoryInit - 0x00000d08 0xfc Bin/Memory.o - 0x00000d08 MemoryInit - .text.MemoryStore - 0x00000e04 0x27a Bin/Memory.o - 0x00000e04 MemoryStore - .text.MemoryUploadBlock - 0x0000107e 0x392 Bin/Memory.o - 0x0000107e MemoryUploadBlock - .text.MemoryDownloadBlock - 0x00001410 0x7a Bin/Memory.o - 0x00001410 MemoryDownloadBlock - .text.ButtonInit - 0x0000148a 0xe Bin/Button.o - 0x0000148a ButtonInit - .text.ButtonTick - 0x00001498 0x1ba Bin/Button.o - 0x00001498 ButtonTick - .text.ButtonGetActionList - 0x00001652 0x72 Bin/Button.o - 0x00001652 ButtonGetActionList - .text.ButtonGetActionByName - 0x000016c4 0x1c Bin/Button.o - 0x000016c4 ButtonGetActionByName - .text.ButtonSetActionByName - 0x000016e0 0xc0 Bin/Button.o - 0x000016e0 ButtonSetActionByName - .text.SettingsLoad - 0x000017a0 0x10 Bin/Settings.o - 0x000017a0 SettingsLoad - .text.SettingsSave - 0x000017b0 0x10 Bin/Settings.o - 0x000017b0 SettingsSave - .text.SettingsSetActiveById - 0x000017c0 0x3c Bin/Settings.o - 0x000017c0 SettingsSetActiveById - .text.SettingsCycle - 0x000017fc 0xda Bin/Settings.o - 0x000017fc SettingsCycle - .text.SettingsGetActiveByName - 0x000018d6 0xe Bin/Settings.o - 0x000018d6 SettingsGetActiveByName - .text.SettingsSetActiveByName - 0x000018e4 0x1a Bin/Settings.o - 0x000018e4 SettingsSetActiveByName - .text.TerminalSendString - 0x000018fe 0xa Bin/Terminal.o - 0x000018fe TerminalSendString - .text.TerminalSendStringP - 0x00001908 0x28 Bin/Terminal.o - 0x00001908 TerminalSendStringP - .text.TerminalSendBlock - 0x00001930 0xc Bin/Terminal.o - 0x00001930 TerminalSendBlock - .text.TerminalInit - 0x0000193c 0xa Bin/Terminal.o - 0x0000193c TerminalInit - .text.TerminalTask - 0x00001946 0x3e Bin/Terminal.o - 0x00001946 TerminalTask - .text.TerminalTick - 0x00001984 0x80 Bin/Terminal.o - 0x00001984 TerminalTick - .text.EVENT_USB_Device_Connect - 0x00001a04 0xa Bin/Terminal.o - 0x00001a04 EVENT_USB_Device_Connect - .text.EVENT_USB_Device_Disconnect - 0x00001a0e 0xa Bin/Terminal.o - 0x00001a0e EVENT_USB_Device_Disconnect - .text.EVENT_USB_Device_ConfigurationChanged - 0x00001a18 0x8 Bin/Terminal.o - 0x00001a18 EVENT_USB_Device_ConfigurationChanged - .text.EVENT_USB_Device_ControlRequest - 0x00001a20 0x8 Bin/Terminal.o - 0x00001a20 EVENT_USB_Device_ControlRequest - .text.CommandGetVersion - 0x00001a28 0x3c Bin/Commands.o - 0x00001a28 CommandGetVersion - .text.CommandGetConfig - 0x00001a64 0x2c Bin/Commands.o - 0x00001a64 CommandGetConfig - .text.CommandSetConfig - 0x00001a90 0x12 Bin/Commands.o - 0x00001a90 CommandSetConfig - .text.CommandExecConfig - 0x00001aa2 0xc Bin/Commands.o - 0x00001aa2 CommandExecConfig - .text.CommandGetUid - 0x00001aae 0x54 Bin/Commands.o - 0x00001aae CommandGetUid - .text.CommandSetUid - 0x00001b02 0xa4 Bin/Commands.o - 0x00001b02 CommandSetUid - .text.CommandGetReadOnly - 0x00001ba6 0x24 Bin/Commands.o - 0x00001ba6 CommandGetReadOnly - .text.CommandSetReadOnly - 0x00001bca 0x28 Bin/Commands.o - 0x00001bca CommandSetReadOnly - .text.CommandExecUpload - 0x00001bf2 0xa Bin/Commands.o - 0x00001bf2 CommandExecUpload - .text.CommandExecDownload - 0x00001bfc 0xa Bin/Commands.o - 0x00001bfc CommandExecDownload - .text.CommandExecReset - 0x00001c06 0x16 Bin/Commands.o - 0x00001c06 CommandExecReset - .text.CommandExecUpgrade - 0x00001c1c 0x16 Bin/Commands.o - 0x00001c1c CommandExecUpgrade - .text.CommandGetMemSize - 0x00001c32 0x30 Bin/Commands.o - 0x00001c32 CommandGetMemSize - .text.CommandGetUidSize - 0x00001c62 0x2c Bin/Commands.o - 0x00001c62 CommandGetUidSize - .text.CommandExecButton - 0x00001c8e 0xa Bin/Commands.o - 0x00001c8e CommandExecButton - .text.CommandGetButton - 0x00001c98 0xa Bin/Commands.o - 0x00001c98 CommandGetButton - .text.CommandSetButton - 0x00001ca2 0x10 Bin/Commands.o - 0x00001ca2 CommandSetButton - .text.CommandGetSetting - 0x00001cb2 0xa Bin/Commands.o - 0x00001cb2 CommandGetSetting - .text.CommandSetSetting - 0x00001cbc 0x10 Bin/Commands.o - 0x00001cbc CommandSetSetting - .text.CommandExecClear - 0x00001ccc 0x8 Bin/Commands.o - 0x00001ccc CommandExecClear - .text.CommandExecHelp - 0x00001cd4 0x94 Bin/Commands.o - 0x00001cd4 CommandExecHelp - .text.CommandGetRssi - 0x00001d68 0x68 Bin/Commands.o - 0x00001d68 CommandGetRssi - .text.XModemReceive - 0x00001dd0 0x30 Bin/XModem.o - 0x00001dd0 XModemReceive - .text.XModemSend - 0x00001e00 0x26 Bin/XModem.o - 0x00001e00 XModemSend - .text.XModemProcessByte - 0x00001e26 0x2c2 Bin/XModem.o - 0x00001e26 XModemProcessByte - .text.XModemTick - 0x000020e8 0x5c Bin/XModem.o - 0x000020e8 XModemTick - .text.CommandLineProcessByte - 0x00002144 0x34c Bin/CommandLine.o - 0x00002144 CommandLineProcessByte - .text.CommandLineTick - 0x00002490 0x2 Bin/CommandLine.o - 0x00002490 CommandLineTick - .text.StartDemod - 0x00002492 0x3c Bin/ISO14443-2A.o - .text.__vector_34 - 0x000024ce 0x88 Bin/ISO14443-2A.o - 0x000024ce __vector_34 - .text.__vector_22 - 0x00002556 0x174 Bin/ISO14443-2A.o - 0x00002556 __vector_22 - .text.__vector_83 - 0x000026ca 0x1bc Bin/ISO14443-2A.o - 0x000026ca __vector_83 - .text.ISO14443ACodecInit - 0x00002886 0x6e Bin/ISO14443-2A.o - 0x00002886 ISO14443ACodecInit - .text.ISO14443ACodecTask - 0x000028f4 0xf6 Bin/ISO14443-2A.o - 0x000028f4 ISO14443ACodecTask - .text.MifareClassicAppInit1K - 0x000029ea 0x1a Bin/MifareClassic.o - 0x000029ea MifareClassicAppInit1K - .text.MifareClassicAppInit4K - 0x00002a04 0x1a Bin/MifareClassic.o - 0x00002a04 MifareClassicAppInit4K - .text.MifareClassicAppReset - 0x00002a1e 0x8 Bin/MifareClassic.o - 0x00002a1e MifareClassicAppReset - .text.MifareClassicAppTask - 0x00002a26 0x2 Bin/MifareClassic.o - 0x00002a26 MifareClassicAppTask - .text.MifareClassicAppProcess - 0x00002a28 0x7a6 Bin/MifareClassic.o - 0x00002a28 MifareClassicAppProcess - .text.MifareClassicGetUid - 0x000031ce 0xc Bin/MifareClassic.o - 0x000031ce MifareClassicGetUid - .text.MifareClassicSetUid - 0x000031da 0x40 Bin/MifareClassic.o - 0x000031da MifareClassicSetUid - .text.ISO14443AAppendCRCA - 0x0000321a 0x5c Bin/ISO14443-3A.o - 0x0000321a ISO14443AAppendCRCA - .text.ISO14443ACheckCRCA - 0x00003276 0x7c Bin/ISO14443-3A.o - 0x00003276 ISO14443ACheckCRCA - .text.Crypto1LFSR - 0x000032f2 0x8c Bin/Crypto1.o - .text.Crypto1FilterOutput - 0x0000337e 0x64 Bin/Crypto1.o - 0x0000337e Crypto1FilterOutput - .text.Crypto1Setup - 0x000033e2 0x19a Bin/Crypto1.o - 0x000033e2 Crypto1Setup - .text.Crypto1Auth - 0x0000357c 0x4a Bin/Crypto1.o - 0x0000357c Crypto1Auth - .text.Crypto1Byte - 0x000035c6 0x26 Bin/Crypto1.o - 0x000035c6 Crypto1Byte - .text.Crypto1Nibble - 0x000035ec 0x26 Bin/Crypto1.o - 0x000035ec Crypto1Nibble - .text.Crypto1PRNG - 0x00003612 0xa0 Bin/Crypto1.o - 0x00003612 Crypto1PRNG - .text.USB_Device_ProcessControlRequest - 0x000036b2 0x240 Bin/DeviceStandardReq.o - 0x000036b2 USB_Device_ProcessControlRequest - .text.USB_Event_Stub - 0x000038f2 0x2 Bin/Events.o - 0x000038f2 EVENT_USB_Device_WakeUp - 0x000038f2 USB_Event_Stub - 0x000038f2 EVENT_USB_Device_Suspend - 0x000038f2 EVENT_USB_Device_StartOfFrame - 0x000038f2 EVENT_USB_Device_Reset - .text.USB_USBTask - 0x000038f4 0x2a Bin/USBTask.o - 0x000038f4 USB_USBTask - .text.Endpoint_Write_Stream_LE - 0x0000391e 0xc8 Bin/EndpointStream_XMEGA.o - 0x0000391e Endpoint_Write_Stream_LE - .text.Endpoint_Write_Control_Stream_LE - 0x000039e6 0x12a Bin/EndpointStream_XMEGA.o - 0x000039e6 Endpoint_Write_Control_Stream_LE - .text.Endpoint_Write_Control_PStream_LE - 0x00003b10 0x158 Bin/EndpointStream_XMEGA.o - 0x00003b10 Endpoint_Write_Control_PStream_LE - .text.Endpoint_ClearIN - 0x00003c68 0x32 Bin/Endpoint_XMEGA.o - 0x00003c68 Endpoint_ClearIN - .text.Endpoint_ClearOUT - 0x00003c9a 0x1e Bin/Endpoint_XMEGA.o - 0x00003c9a Endpoint_ClearOUT - .text.Endpoint_Read_8 - 0x00003cb8 0x20 Bin/Endpoint_XMEGA.o - 0x00003cb8 Endpoint_Read_8 - .text.Endpoint_Write_8 - 0x00003cd8 0x20 Bin/Endpoint_XMEGA.o - 0x00003cd8 Endpoint_Write_8 - .text.Endpoint_SelectEndpoint - 0x00003cf8 0x72 Bin/Endpoint_XMEGA.o - 0x00003cf8 Endpoint_SelectEndpoint - .text.Endpoint_IsINReady - 0x00003d6a 0x18 Bin/Endpoint_XMEGA.o - 0x00003d6a Endpoint_IsINReady - .text.Endpoint_IsOUTReceived - 0x00003d82 0x32 Bin/Endpoint_XMEGA.o - 0x00003d82 Endpoint_IsOUTReceived - .text.Endpoint_IsSETUPReceived - 0x00003db4 0x32 Bin/Endpoint_XMEGA.o - 0x00003db4 Endpoint_IsSETUPReceived - .text.Endpoint_ClearSETUP - 0x00003de6 0x58 Bin/Endpoint_XMEGA.o - 0x00003de6 Endpoint_ClearSETUP - .text.Endpoint_StallTransaction - 0x00003e3e 0x38 Bin/Endpoint_XMEGA.o - 0x00003e3e Endpoint_StallTransaction - .text.Endpoint_ConfigureEndpoint_PRV - 0x00003e76 0x96 Bin/Endpoint_XMEGA.o - 0x00003e76 Endpoint_ConfigureEndpoint_PRV - .text.Endpoint_ConfigureEndpointTable - 0x00003f0c 0xd8 Bin/Endpoint_XMEGA.o - 0x00003f0c Endpoint_ConfigureEndpointTable - .text.Endpoint_ClearEndpoints - 0x00003fe4 0x70 Bin/Endpoint_XMEGA.o - 0x00003fe4 Endpoint_ClearEndpoints - .text.Endpoint_ClearStatusStage - 0x00004054 0x2c Bin/Endpoint_XMEGA.o - 0x00004054 Endpoint_ClearStatusStage - .text.Endpoint_WaitUntilReady - 0x00004080 0xa6 Bin/Endpoint_XMEGA.o - 0x00004080 Endpoint_WaitUntilReady - .text.USB_Disable - 0x00004126 0x1a Bin/USBController_XMEGA.o - 0x00004126 USB_Disable - .text.USB_ResetInterface - 0x00004140 0x5c Bin/USBController_XMEGA.o - 0x00004140 USB_ResetInterface - .text.USB_Init - 0x0000419c 0x50 Bin/USBController_XMEGA.o - 0x0000419c USB_Init - .text.USB_INT_DisableAllInterrupts - 0x000041ec 0xe Bin/USBInterrupt_XMEGA.o - 0x000041ec USB_INT_DisableAllInterrupts - .text.USB_INT_ClearAllInterrupts - 0x000041fa 0xc Bin/USBInterrupt_XMEGA.o - 0x000041fa USB_INT_ClearAllInterrupts - .text.__vector_125 - 0x00004206 0xda Bin/USBInterrupt_XMEGA.o - 0x00004206 __vector_125 - .text.CDC_Device_ConfigureEndpoints - 0x000042e0 0x4a Bin/CDCClassDevice.o - 0x000042e0 CDC_Device_ConfigureEndpoints - .text.CDC_Device_SendString - 0x0000432a 0x4a Bin/CDCClassDevice.o - 0x0000432a CDC_Device_SendString - .text.CDC_Device_SendData - 0x00004374 0x54 Bin/CDCClassDevice.o - 0x00004374 CDC_Device_SendData - .text.CDC_Device_SendByte - 0x000043c8 0x6a Bin/CDCClassDevice.o - 0x000043c8 CDC_Device_SendByte - .text.CDC_Device_Flush - 0x00004432 0x7c Bin/CDCClassDevice.o - 0x00004432 CDC_Device_Flush - .text.CDC_Device_USBTask - 0x000044ae 0x36 Bin/CDCClassDevice.o - 0x000044ae CDC_Device_USBTask - .text.CDC_Device_ReceiveByte - 0x000044e4 0xb8 Bin/CDCClassDevice.o - 0x000044e4 CDC_Device_ReceiveByte - .text.CDC_Device_Event_Stub - 0x0000459c 0x2 Bin/CDCClassDevice.o - 0x0000459c EVENT_CDC_Device_LineEncodingChanged - 0x0000459c EVENT_CDC_Device_ControLineStateChanged - 0x0000459c EVENT_CDC_Device_BreakSent - 0x0000459c CDC_Device_Event_Stub - .text.CDC_Device_ProcessControlRequest - 0x0000459e 0x134 Bin/CDCClassDevice.o - 0x0000459e CDC_Device_ProcessControlRequest - .text.libgcc 0x000046d2 0xc /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) - 0x000046d2 __tablejump2__ - 0x000046d6 __tablejump__ - .text.libgcc.mul - 0x000046de 0xc /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - 0x000046de __mulshisi3 - 0x000046e2 __mulohisi3 - .text.libgcc.mul - 0x000046ea 0x14 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) - 0x000046ea __muluhisi3 - .text.libgcc.mul - 0x000046fe 0x1e /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_umulhisi3.o) - 0x000046fe __umulhisi3 - .text.avr-libc - 0x0000471c 0xae /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) - 0x000047ac rand_r - 0x000047ae rand - 0x000047b4 srand - .text.avr-libc - 0x000047ca 0x12 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcpy_P.o) - 0x000047ca memcpy_P - .text.avr-libc - 0x000047dc 0x12 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strcmp_P.o) - 0x000047dc strcmp_P - .text.avr-libc - 0x000047ee 0x1e /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strncpy_P.o) - 0x000047ee strncpy_P - .text.avr-libc - 0x0000480c 0x12 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcpy.o) - 0x0000480c memcpy - .text.avr-libc - 0x0000481e 0x5a /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) - 0x0000481e snprintf_P - .text.avr-libc - 0x00004878 0x386 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) - 0x00004878 vfprintf - .text.avr-libc - 0x00004bfe 0x16 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_block_atxmega32a4u.o) - 0x00004bfe __eerd_block_x32a4u - .text.avr-libc - 0x00004c14 0x12 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_block_atxmega32a4u.o) - 0x00004c14 __eewr_block_x32a4u - .text.avr-libc - 0x00004c26 0x46 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_byte_atxmega32a4u.o) - 0x00004c26 __eewr_byte_x32a4u - 0x00004c28 __eewr_r18_x32a4u - .text.avr-libc - 0x00004c6c 0x16 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strnlen_P.o) - 0x00004c6c strnlen_P - .text.avr-libc - 0x00004c82 0x16 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strnlen.o) - 0x00004c82 strnlen - .text.avr-libc - 0x00004c98 0x64 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(fputc.o) - 0x00004c98 fputc - .text.avr-libc - 0x00004cfc 0xbc /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(ultoa_invert.o) - 0x00004cfc __ultoa_invert - .text.libgcc.div - 0x00004db8 0x28 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) - 0x00004db8 __divmodsi4 - .text.libgcc.div - 0x00004de0 0x10 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_negsi2.o) - 0x00004de0 __negsi2 - .text.libgcc.prologue - 0x00004df0 0x32 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_prologue.o) - 0x00004df0 __prologue_saves__ - .text.libgcc.prologue - 0x00004e22 0x30 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_epilogue.o) - 0x00004e22 __epilogue_restores__ - .text.libgcc.div - 0x00004e52 0x44 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_udivmodsi4.o) - 0x00004e52 __udivmodsi4 - 0x00004e96 . = ALIGN (0x2) - *(.fini9) - .fini9 0x00004e96 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - 0x00004e96 exit - 0x00004e96 _exit - *(.fini9) - *(.fini8) - *(.fini8) - *(.fini7) - *(.fini7) - *(.fini6) - *(.fini6) - *(.fini5) - *(.fini5) - *(.fini4) - *(.fini4) - *(.fini3) - *(.fini3) - *(.fini2) - *(.fini2) - *(.fini1) - *(.fini1) - *(.fini0) - .fini0 0x00004e96 0x4 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - *(.fini0) - 0x00004e9a _etext = . - -.data 0x00802000 0x92 load address 0x00004e9a - 0x00802000 PROVIDE (__data_start, .) - *(.data) - .data 0x00802000 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o - .data 0x00802000 0x0 Bin/Chameleon-Mini.o - .data 0x00802000 0x0 Bin/LUFADescriptors.o - .data 0x00802000 0x0 Bin/System.o - .data 0x00802000 0x0 Bin/Configuration.o - .data 0x00802000 0x0 Bin/Random.o - .data 0x00802000 0x0 Bin/Common.o - .data 0x00802000 0x0 Bin/Memory.o - .data 0x00802000 0x0 Bin/Button.o - .data 0x00802000 0x0 Bin/Settings.o - .data 0x00802000 0x0 Bin/LED.o - .data 0x00802000 0x1c Bin/Terminal.o - 0x00802001 TerminalHandle - .data 0x0080201c 0x0 Bin/Commands.o - .data 0x0080201c 0x0 Bin/XModem.o - .data 0x0080201c 0x0 Bin/CommandLine.o - .data 0x0080201c 0x0 Bin/Codec.o - .data 0x0080201c 0x0 Bin/ISO14443-2A.o - .data 0x0080201c 0x0 Bin/MifareClassic.o - .data 0x0080201c 0x0 Bin/ISO14443-3A.o - .data 0x0080201c 0x0 Bin/Crypto1.o - .data 0x0080201c 0x0 Bin/HIDParser.o - .data 0x0080201c 0x0 Bin/ConfigDescriptors.o - .data 0x0080201c 0x0 Bin/DeviceStandardReq.o - .data 0x0080201c 0x0 Bin/Events.o - .data 0x0080201c 0x0 Bin/HostStandardReq.o - .data 0x0080201c 0x0 Bin/USBTask.o - .data 0x0080201c 0x0 Bin/Device_XMEGA.o - .data 0x0080201c 0x0 Bin/EndpointStream_XMEGA.o - .data 0x0080201c 0x0 Bin/Endpoint_XMEGA.o - .data 0x0080201c 0x0 Bin/Host_XMEGA.o - .data 0x0080201c 0x0 Bin/PipeStream_XMEGA.o - .data 0x0080201c 0x0 Bin/Pipe_XMEGA.o - .data 0x0080201c 0x0 Bin/USBController_XMEGA.o - .data 0x0080201c 0x0 Bin/USBInterrupt_XMEGA.o - .data 0x0080201c 0x0 Bin/AudioClassDevice.o - .data 0x0080201c 0x0 Bin/CDCClassDevice.o - .data 0x0080201c 0x0 Bin/HIDClassDevice.o - .data 0x0080201c 0x0 Bin/MassStorageClassDevice.o - .data 0x0080201c 0x0 Bin/MIDIClassDevice.o - .data 0x0080201c 0x0 Bin/PrinterClassDevice.o - .data 0x0080201c 0x0 Bin/RNDISClassDevice.o - .data 0x0080201c 0x0 Bin/AndroidAccessoryClassHost.o - .data 0x0080201c 0x0 Bin/AudioClassHost.o - .data 0x0080201c 0x0 Bin/CDCClassHost.o - .data 0x0080201c 0x0 Bin/HIDClassHost.o - .data 0x0080201c 0x0 Bin/MassStorageClassHost.o - .data 0x0080201c 0x0 Bin/MIDIClassHost.o - .data 0x0080201c 0x0 Bin/PrinterClassHost.o - .data 0x0080201c 0x0 Bin/RNDISClassHost.o - .data 0x0080201c 0x0 Bin/StillImageClassHost.o - .data 0x0080201c 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - .data 0x0080201c 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) - .data 0x0080201c 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - .data 0x0080201c 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - .data 0x0080201c 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - .data 0x0080201c 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) - .data 0x0080201c 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_umulhisi3.o) - .data 0x0080201c 0x4 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcpy_P.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strcmp_P.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strncpy_P.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcmp.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcpy.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memset.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_block_atxmega32a4u.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_byte_atxmega32a4u.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eeupd_byte_atxmega32a4u.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_block_atxmega32a4u.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_byte_atxmega32a4u.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strnlen_P.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strnlen.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(fputc.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(ultoa_invert.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_negsi2.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_prologue.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_epilogue.o) - .data 0x00802020 0x0 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_udivmodsi4.o) - *(.data*) - *(.rodata) - .rodata 0x00802020 0x70 Bin/Crypto1.o - *(.rodata*) - .rodata.str1.1 - 0x00802090 0x1 Bin/Commands.o - *(.gnu.linkonce.d*) - 0x00802092 . = ALIGN (0x2) - *fill* 0x00802091 0x1 - 0x00802092 _edata = . - 0x00802092 PROVIDE (__data_end, .) - -.bss 0x00802092 0xa0b - 0x00802092 PROVIDE (__bss_start, .) - *(.bss) - .bss 0x00802092 0x400 Bin/Memory.o - .bss 0x00802492 0x1 Bin/Button.o - .bss 0x00802493 0x1 Bin/LED.o - 0x00802493 LEDPulseMask - .bss 0x00802494 0x1 Bin/Terminal.o - 0x00802494 TerminalState - .bss 0x00802495 0xe Bin/XModem.o - .bss 0x008024a3 0x2 Bin/CommandLine.o - .bss 0x008024a5 0x10 Bin/ISO14443-2A.o - .bss 0x008024b5 0x1d Bin/MifareClassic.o - .bss 0x008024d2 0x6 Bin/Crypto1.o - *(.bss*) - *(COMMON) - COMMON 0x008024d8 0x25 Bin/Configuration.o - 0x008024d8 ActiveConfiguration - COMMON 0x008024fd 0x13 Bin/Settings.o - 0x008024fd GlobalSettings - COMMON 0x00802510 0x100 Bin/Terminal.o - 0x00802510 TerminalBuffer - COMMON 0x00802610 0x100 Bin/Codec.o - 0x00802610 CodecBuffer - COMMON 0x00802710 0x3 Bin/DeviceStandardReq.o - 0x00802710 USB_Device_ConfigurationNumber - 0x00802711 USB_Device_CurrentlySelfPowered - 0x00802712 USB_Device_RemoteWakeupEnabled - COMMON 0x00802713 0xa Bin/USBTask.o - 0x00802713 USB_IsInitialized - 0x00802714 USB_DeviceState - 0x00802715 USB_ControlRequest - COMMON 0x0080271d 0x31d Bin/Endpoint_XMEGA.o - 0x0080271d USB_Endpoint_SelectedFIFO - 0x0080271f USB_Endpoint_SelectedHandle - 0x00802721 USB_Endpoint_SelectedEndpoint - 0x00802722 USB_Endpoint_FIFOs - COMMON 0x00802a3a 0x63 Bin/USBController_XMEGA.o - 0x00802a3a USB_EndpointTable - 0x00802a9d PROVIDE (__bss_end, .) - 0x00004e9a __data_load_start = LOADADDR (.data) - 0x00004f2c __data_load_end = (__data_load_start + SIZEOF (.data)) - -.noinit 0x00802a9d 0x0 - 0x00802a9d PROVIDE (__noinit_start, .) - *(.noinit*) - 0x00802a9d PROVIDE (__noinit_end, .) - 0x00802a9d _end = . - 0x00802a9d PROVIDE (__heap_start, .) - -.eeprom 0x00810000 0x13 - *(.eeprom*) - .eeprom 0x00810000 0x13 Bin/Settings.o - 0x00810000 StoredSettings - 0x00810013 __eeprom_end = . - -.fuse - *(.fuse) - *(.lfuse) - *(.hfuse) - *(.efuse) - -.lock - *(.lock*) - -.signature - *(.signature*) - -.user_signatures - *(.user_signatures*) - -.stab - *(.stab) - -.stabstr - *(.stabstr) - -.stab.excl - *(.stab.excl) - -.stab.exclstr - *(.stab.exclstr) - -.stab.index - *(.stab.index) - -.stab.indexstr - *(.stab.indexstr) - -.comment 0x00000000 0x5c - *(.comment) - .comment 0x00000000 0x30 Bin/Chameleon-Mini.o - 0x31 (size before relaxing) - .comment 0x00000000 0x31 Bin/LUFADescriptors.o - .comment 0x00000000 0x31 Bin/System.o - .comment 0x00000000 0x31 Bin/Configuration.o - .comment 0x00000000 0x31 Bin/Random.o - .comment 0x00000000 0x31 Bin/Common.o - .comment 0x00000000 0x31 Bin/Memory.o - .comment 0x00000000 0x31 Bin/Button.o - .comment 0x00000000 0x31 Bin/Settings.o - .comment 0x00000000 0x31 Bin/LED.o - .comment 0x00000000 0x31 Bin/Terminal.o - .comment 0x00000000 0x31 Bin/Commands.o - .comment 0x00000000 0x31 Bin/XModem.o - .comment 0x00000000 0x31 Bin/CommandLine.o - .comment 0x00000000 0x31 Bin/Codec.o - .comment 0x00000000 0x31 Bin/ISO14443-2A.o - .comment 0x00000000 0x31 Bin/MifareClassic.o - .comment 0x00000000 0x31 Bin/ISO14443-3A.o - .comment 0x00000000 0x31 Bin/Crypto1.o - .comment 0x00000000 0x31 Bin/HIDParser.o - .comment 0x00000000 0x31 Bin/ConfigDescriptors.o - .comment 0x00000000 0x31 Bin/DeviceStandardReq.o - .comment 0x00000000 0x31 Bin/Events.o - .comment 0x00000000 0x31 Bin/HostStandardReq.o - .comment 0x00000000 0x31 Bin/USBTask.o - .comment 0x00000000 0x31 Bin/Device_XMEGA.o - .comment 0x00000000 0x31 Bin/EndpointStream_XMEGA.o - .comment 0x00000000 0x31 Bin/Endpoint_XMEGA.o - .comment 0x00000000 0x31 Bin/Host_XMEGA.o - .comment 0x00000000 0x31 Bin/PipeStream_XMEGA.o - .comment 0x00000000 0x31 Bin/Pipe_XMEGA.o - .comment 0x00000000 0x31 Bin/USBController_XMEGA.o - .comment 0x00000000 0x31 Bin/USBInterrupt_XMEGA.o - .comment 0x00000000 0x31 Bin/AudioClassDevice.o - .comment 0x00000000 0x31 Bin/CDCClassDevice.o - .comment 0x00000000 0x31 Bin/HIDClassDevice.o - .comment 0x00000000 0x31 Bin/MassStorageClassDevice.o - .comment 0x00000000 0x31 Bin/MIDIClassDevice.o - .comment 0x00000000 0x31 Bin/PrinterClassDevice.o - .comment 0x00000000 0x31 Bin/RNDISClassDevice.o - .comment 0x00000000 0x31 Bin/AndroidAccessoryClassHost.o - .comment 0x00000000 0x31 Bin/AudioClassHost.o - .comment 0x00000000 0x31 Bin/CDCClassHost.o - .comment 0x00000000 0x31 Bin/HIDClassHost.o - .comment 0x00000000 0x31 Bin/MassStorageClassHost.o - .comment 0x00000000 0x31 Bin/MIDIClassHost.o - .comment 0x00000000 0x31 Bin/PrinterClassHost.o - .comment 0x00000000 0x31 Bin/RNDISClassHost.o - .comment 0x00000000 0x31 Bin/StillImageClassHost.o - .comment 0x00000000 0x31 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) - .comment 0x00000000 0x31 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) - .comment 0x00000030 0x2c /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) - 0x2d (size before relaxing) - .comment 0x00000000 0x31 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(fputc.o) - -.note.gnu.build-id - *(.note.gnu.build-id) - -.debug - *(.debug) - -.line - *(.line) - -.debug_srcinfo - *(.debug_srcinfo) - -.debug_sfnames - *(.debug_sfnames) - -.debug_aranges 0x00000000 0xb50 - *(.debug_aranges) - .debug_aranges - 0x00000000 0x20 Bin/Chameleon-Mini.o - .debug_aranges - 0x00000020 0x20 Bin/LUFADescriptors.o - .debug_aranges - 0x00000040 0x50 Bin/System.o - .debug_aranges - 0x00000090 0x78 Bin/Configuration.o - .debug_aranges - 0x00000108 0x38 Bin/Random.o - .debug_aranges - 0x00000140 0x28 Bin/Common.o - .debug_aranges - 0x00000168 0x58 Bin/Memory.o - .debug_aranges - 0x000001c0 0x48 Bin/Button.o - .debug_aranges - 0x00000208 0x50 Bin/Settings.o - .debug_aranges - 0x00000258 0x18 Bin/LED.o - .debug_aranges - 0x00000270 0x68 Bin/Terminal.o - .debug_aranges - 0x000002d8 0xc8 Bin/Commands.o - .debug_aranges - 0x000003a0 0x38 Bin/XModem.o - .debug_aranges - 0x000003d8 0x30 Bin/CommandLine.o - .debug_aranges - 0x00000408 0x18 Bin/Codec.o - .debug_aranges - 0x00000420 0x48 Bin/ISO14443-2A.o - .debug_aranges - 0x00000468 0x50 Bin/MifareClassic.o - .debug_aranges - 0x000004b8 0x28 Bin/ISO14443-3A.o - .debug_aranges - 0x000004e0 0x50 Bin/Crypto1.o - .debug_aranges - 0x00000530 0x38 Bin/HIDParser.o - .debug_aranges - 0x00000568 0x38 Bin/ConfigDescriptors.o - .debug_aranges - 0x000005a0 0x20 Bin/DeviceStandardReq.o - .debug_aranges - 0x000005c0 0x20 Bin/Events.o - .debug_aranges - 0x000005e0 0x18 Bin/HostStandardReq.o - .debug_aranges - 0x000005f8 0x20 Bin/USBTask.o - .debug_aranges - 0x00000618 0x20 Bin/Device_XMEGA.o - .debug_aranges - 0x00000638 0xc8 Bin/EndpointStream_XMEGA.o - .debug_aranges - 0x00000700 0x90 Bin/Endpoint_XMEGA.o - .debug_aranges - 0x00000790 0x18 Bin/Host_XMEGA.o - .debug_aranges - 0x000007a8 0x18 Bin/PipeStream_XMEGA.o - .debug_aranges - 0x000007c0 0x18 Bin/Pipe_XMEGA.o - .debug_aranges - 0x000007d8 0x30 Bin/USBController_XMEGA.o - .debug_aranges - 0x00000808 0x30 Bin/USBInterrupt_XMEGA.o - .debug_aranges - 0x00000838 0x30 Bin/AudioClassDevice.o - .debug_aranges - 0x00000868 0x98 Bin/CDCClassDevice.o - .debug_aranges - 0x00000900 0x30 Bin/HIDClassDevice.o - .debug_aranges - 0x00000930 0x30 Bin/MassStorageClassDevice.o - .debug_aranges - 0x00000960 0x40 Bin/MIDIClassDevice.o - .debug_aranges - 0x000009a0 0x90 Bin/PrinterClassDevice.o - .debug_aranges - 0x00000a30 0x48 Bin/RNDISClassDevice.o - .debug_aranges - 0x00000a78 0x18 Bin/AndroidAccessoryClassHost.o - .debug_aranges - 0x00000a90 0x18 Bin/AudioClassHost.o - .debug_aranges - 0x00000aa8 0x18 Bin/CDCClassHost.o - .debug_aranges - 0x00000ac0 0x18 Bin/HIDClassHost.o - .debug_aranges - 0x00000ad8 0x18 Bin/MassStorageClassHost.o - .debug_aranges - 0x00000af0 0x18 Bin/MIDIClassHost.o - .debug_aranges - 0x00000b08 0x18 Bin/PrinterClassHost.o - .debug_aranges - 0x00000b20 0x18 Bin/RNDISClassHost.o - .debug_aranges - 0x00000b38 0x18 Bin/StillImageClassHost.o - -.debug_pubnames - *(.debug_pubnames) - -.debug_info 0x00000000 0x189de - *(.debug_info .gnu.linkonce.wi.*) - .debug_info 0x00000000 0x1381 Bin/Chameleon-Mini.o - .debug_info 0x00001381 0x962 Bin/LUFADescriptors.o - .debug_info 0x00001ce3 0xea8 Bin/System.o - .debug_info 0x00002b8b 0x657 Bin/Configuration.o - .debug_info 0x000031e2 0x177 Bin/Random.o - .debug_info 0x00003359 0x1b3 Bin/Common.o - .debug_info 0x0000350c 0x1264 Bin/Memory.o - .debug_info 0x00004770 0xa98 Bin/Button.o - .debug_info 0x00005208 0x514 Bin/Settings.o - .debug_info 0x0000571c 0x7a Bin/LED.o - .debug_info 0x00005796 0xb73 Bin/Terminal.o - .debug_info 0x00006309 0x1806 Bin/Commands.o - .debug_info 0x00007b0f 0xa2b Bin/XModem.o - .debug_info 0x0000853a 0xb77 Bin/CommandLine.o - .debug_info 0x000090b1 0x1f1 Bin/Codec.o - .debug_info 0x000092a2 0x187e Bin/ISO14443-2A.o - .debug_info 0x0000ab20 0xee1 Bin/MifareClassic.o - .debug_info 0x0000ba01 0x179 Bin/ISO14443-3A.o - .debug_info 0x0000bb7a 0x42a Bin/Crypto1.o - .debug_info 0x0000bfa4 0x73c Bin/HIDParser.o - .debug_info 0x0000c6e0 0x5ed Bin/ConfigDescriptors.o - .debug_info 0x0000cccd 0x119b Bin/DeviceStandardReq.o - .debug_info 0x0000de68 0x7f Bin/Events.o - .debug_info 0x0000dee7 0x5d Bin/HostStandardReq.o - .debug_info 0x0000df44 0x433 Bin/USBTask.o - .debug_info 0x0000e377 0x670 Bin/Device_XMEGA.o - .debug_info 0x0000e9e7 0x198f Bin/EndpointStream_XMEGA.o - .debug_info 0x00010376 0xd09 Bin/Endpoint_XMEGA.o - .debug_info 0x0001107f 0x5d Bin/Host_XMEGA.o - .debug_info 0x000110dc 0x5d Bin/PipeStream_XMEGA.o - .debug_info 0x00011139 0x5d Bin/Pipe_XMEGA.o - .debug_info 0x00011196 0xd3e Bin/USBController_XMEGA.o - .debug_info 0x00011ed4 0xa7b Bin/USBInterrupt_XMEGA.o - .debug_info 0x0001294f 0xab1 Bin/AudioClassDevice.o - .debug_info 0x00013400 0xf9f Bin/CDCClassDevice.o - .debug_info 0x0001439f 0xf94 Bin/HIDClassDevice.o - .debug_info 0x00015333 0xa9e Bin/MassStorageClassDevice.o - .debug_info 0x00015dd1 0x7c4 Bin/MIDIClassDevice.o - .debug_info 0x00016595 0xded Bin/PrinterClassDevice.o - .debug_info 0x00017382 0x1317 Bin/RNDISClassDevice.o - .debug_info 0x00018699 0x5d Bin/AndroidAccessoryClassHost.o - .debug_info 0x000186f6 0x5d Bin/AudioClassHost.o - .debug_info 0x00018753 0x5d Bin/CDCClassHost.o - .debug_info 0x000187b0 0x5d Bin/HIDClassHost.o - .debug_info 0x0001880d 0x5d Bin/MassStorageClassHost.o - .debug_info 0x0001886a 0x5d Bin/MIDIClassHost.o - .debug_info 0x000188c7 0x5d Bin/PrinterClassHost.o - .debug_info 0x00018924 0x5d Bin/RNDISClassHost.o - .debug_info 0x00018981 0x5d Bin/StillImageClassHost.o - -.debug_abbrev 0x00000000 0x553d - *(.debug_abbrev) - .debug_abbrev 0x00000000 0x1d2 Bin/Chameleon-Mini.o - .debug_abbrev 0x000001d2 0x1bb Bin/LUFADescriptors.o - .debug_abbrev 0x0000038d 0x144 Bin/System.o - .debug_abbrev 0x000004d1 0x250 Bin/Configuration.o - .debug_abbrev 0x00000721 0x113 Bin/Random.o - .debug_abbrev 0x00000834 0xb2 Bin/Common.o - .debug_abbrev 0x000008e6 0x331 Bin/Memory.o - .debug_abbrev 0x00000c17 0x2ea Bin/Button.o - .debug_abbrev 0x00000f01 0x1e1 Bin/Settings.o - .debug_abbrev 0x000010e2 0x44 Bin/LED.o - .debug_abbrev 0x00001126 0x33a Bin/Terminal.o - .debug_abbrev 0x00001460 0x397 Bin/Commands.o - .debug_abbrev 0x000017f7 0x2ce Bin/XModem.o - .debug_abbrev 0x00001ac5 0x2d2 Bin/CommandLine.o - .debug_abbrev 0x00001d97 0xc4 Bin/Codec.o - .debug_abbrev 0x00001e5b 0x2db Bin/ISO14443-2A.o - .debug_abbrev 0x00002136 0x314 Bin/MifareClassic.o - .debug_abbrev 0x0000244a 0xa6 Bin/ISO14443-3A.o - .debug_abbrev 0x000024f0 0x1a9 Bin/Crypto1.o - .debug_abbrev 0x00002699 0x22d Bin/HIDParser.o - .debug_abbrev 0x000028c6 0x248 Bin/ConfigDescriptors.o - .debug_abbrev 0x00002b0e 0x38d Bin/DeviceStandardReq.o - .debug_abbrev 0x00002e9b 0x44 Bin/Events.o - .debug_abbrev 0x00002edf 0x26 Bin/HostStandardReq.o - .debug_abbrev 0x00002f05 0x21b Bin/USBTask.o - .debug_abbrev 0x00003120 0x11e Bin/Device_XMEGA.o - .debug_abbrev 0x0000323e 0x252 Bin/EndpointStream_XMEGA.o - .debug_abbrev 0x00003490 0x300 Bin/Endpoint_XMEGA.o - .debug_abbrev 0x00003790 0x26 Bin/Host_XMEGA.o - .debug_abbrev 0x000037b6 0x26 Bin/PipeStream_XMEGA.o - .debug_abbrev 0x000037dc 0x26 Bin/Pipe_XMEGA.o - .debug_abbrev 0x00003802 0x2f7 Bin/USBController_XMEGA.o - .debug_abbrev 0x00003af9 0x266 Bin/USBInterrupt_XMEGA.o - .debug_abbrev 0x00003d5f 0x280 Bin/AudioClassDevice.o - .debug_abbrev 0x00003fdf 0x41d Bin/CDCClassDevice.o - .debug_abbrev 0x000043fc 0x2d1 Bin/HIDClassDevice.o - .debug_abbrev 0x000046cd 0x338 Bin/MassStorageClassDevice.o - .debug_abbrev 0x00004a05 0x285 Bin/MIDIClassDevice.o - .debug_abbrev 0x00004c8a 0x3c7 Bin/PrinterClassDevice.o - .debug_abbrev 0x00005051 0x396 Bin/RNDISClassDevice.o - .debug_abbrev 0x000053e7 0x26 Bin/AndroidAccessoryClassHost.o - .debug_abbrev 0x0000540d 0x26 Bin/AudioClassHost.o - .debug_abbrev 0x00005433 0x26 Bin/CDCClassHost.o - .debug_abbrev 0x00005459 0x26 Bin/HIDClassHost.o - .debug_abbrev 0x0000547f 0x26 Bin/MassStorageClassHost.o - .debug_abbrev 0x000054a5 0x26 Bin/MIDIClassHost.o - .debug_abbrev 0x000054cb 0x26 Bin/PrinterClassHost.o - .debug_abbrev 0x000054f1 0x26 Bin/RNDISClassHost.o - .debug_abbrev 0x00005517 0x26 Bin/StillImageClassHost.o - -.debug_line 0x00000000 0xa17f - *(.debug_line .debug_line.* .debug_line_end) - .debug_line 0x00000000 0x33c Bin/Chameleon-Mini.o - .debug_line 0x0000033c 0x2aa Bin/LUFADescriptors.o - .debug_line 0x000005e6 0x1fd Bin/System.o - .debug_line 0x000007e3 0x338 Bin/Configuration.o - .debug_line 0x00000b1b 0xef Bin/Random.o - .debug_line 0x00000c0a 0x1fb Bin/Common.o - .debug_line 0x00000e05 0x932 Bin/Memory.o - .debug_line 0x00001737 0x3f4 Bin/Button.o - .debug_line 0x00001b2b 0x2a5 Bin/Settings.o - .debug_line 0x00001dd0 0x61 Bin/LED.o - .debug_line 0x00001e31 0x403 Bin/Terminal.o - .debug_line 0x00002234 0x787 Bin/Commands.o - .debug_line 0x000029bb 0x4a8 Bin/XModem.o - .debug_line 0x00002e63 0x36d Bin/CommandLine.o - .debug_line 0x000031d0 0x85 Bin/Codec.o - .debug_line 0x00003255 0x5f6 Bin/ISO14443-2A.o - .debug_line 0x0000384b 0x6d0 Bin/MifareClassic.o - .debug_line 0x00003f1b 0x152 Bin/ISO14443-3A.o - .debug_line 0x0000406d 0x444 Bin/Crypto1.o - .debug_line 0x000044b1 0x6d1 Bin/HIDParser.o - .debug_line 0x00004b82 0x289 Bin/ConfigDescriptors.o - .debug_line 0x00004e0b 0x469 Bin/DeviceStandardReq.o - .debug_line 0x00005274 0x4f Bin/Events.o - .debug_line 0x000052c3 0x1a Bin/HostStandardReq.o - .debug_line 0x000052dd 0x1b5 Bin/USBTask.o - .debug_line 0x00005492 0x131 Bin/Device_XMEGA.o - .debug_line 0x000055c3 0x153a Bin/EndpointStream_XMEGA.o - .debug_line 0x00006afd 0x69a Bin/Endpoint_XMEGA.o - .debug_line 0x00007197 0x1a Bin/Host_XMEGA.o - .debug_line 0x000071b1 0x1a Bin/PipeStream_XMEGA.o - .debug_line 0x000071cb 0x1a Bin/Pipe_XMEGA.o - .debug_line 0x000071e5 0x357 Bin/USBController_XMEGA.o - .debug_line 0x0000753c 0x35c Bin/USBInterrupt_XMEGA.o - .debug_line 0x00007898 0x401 Bin/AudioClassDevice.o - .debug_line 0x00007c99 0x826 Bin/CDCClassDevice.o - .debug_line 0x000084bf 0x538 Bin/HIDClassDevice.o - .debug_line 0x000089f7 0x4b5 Bin/MassStorageClassDevice.o - .debug_line 0x00008eac 0x3ba Bin/MIDIClassDevice.o - .debug_line 0x00009266 0x763 Bin/PrinterClassDevice.o - .debug_line 0x000099c9 0x6cc Bin/RNDISClassDevice.o - .debug_line 0x0000a095 0x1a Bin/AndroidAccessoryClassHost.o - .debug_line 0x0000a0af 0x1a Bin/AudioClassHost.o - .debug_line 0x0000a0c9 0x1a Bin/CDCClassHost.o - .debug_line 0x0000a0e3 0x1a Bin/HIDClassHost.o - .debug_line 0x0000a0fd 0x1a Bin/MassStorageClassHost.o - .debug_line 0x0000a117 0x1a Bin/MIDIClassHost.o - .debug_line 0x0000a131 0x1a Bin/PrinterClassHost.o - .debug_line 0x0000a14b 0x1a Bin/RNDISClassHost.o - .debug_line 0x0000a165 0x1a Bin/StillImageClassHost.o - -.debug_frame 0x00000000 0x1d28 - *(.debug_frame) - .debug_frame 0x00000000 0x24 Bin/Chameleon-Mini.o - .debug_frame 0x00000024 0x24 Bin/LUFADescriptors.o - .debug_frame 0x00000048 0x90 Bin/System.o - .debug_frame 0x000000d8 0xfc Bin/Configuration.o - .debug_frame 0x000001d4 0x64 Bin/Random.o - .debug_frame 0x00000238 0x40 Bin/Common.o - .debug_frame 0x00000278 0x170 Bin/Memory.o - .debug_frame 0x000003e8 0xb4 Bin/Button.o - .debug_frame 0x0000049c 0x94 Bin/Settings.o - .debug_frame 0x00000530 0xcc Bin/Terminal.o - .debug_frame 0x000005fc 0x288 Bin/Commands.o - .debug_frame 0x00000884 0x5c Bin/XModem.o - .debug_frame 0x000008e0 0x54 Bin/CommandLine.o - .debug_frame 0x00000934 0x110 Bin/ISO14443-2A.o - .debug_frame 0x00000a44 0xdc Bin/MifareClassic.o - .debug_frame 0x00000b20 0x34 Bin/ISO14443-3A.o - .debug_frame 0x00000b54 0x13c Bin/Crypto1.o - .debug_frame 0x00000c90 0x11c Bin/HIDParser.o - .debug_frame 0x00000dac 0xd0 Bin/ConfigDescriptors.o - .debug_frame 0x00000e7c 0x40 Bin/DeviceStandardReq.o - .debug_frame 0x00000ebc 0x24 Bin/Events.o - .debug_frame 0x00000ee0 0x2c Bin/USBTask.o - .debug_frame 0x00000f0c 0x24 Bin/Device_XMEGA.o - .debug_frame 0x00000f30 0x4a0 Bin/EndpointStream_XMEGA.o - .debug_frame 0x000013d0 0x15c Bin/Endpoint_XMEGA.o - .debug_frame 0x0000152c 0x50 Bin/USBController_XMEGA.o - .debug_frame 0x0000157c 0x8c Bin/USBInterrupt_XMEGA.o - .debug_frame 0x00001608 0xa4 Bin/AudioClassDevice.o - .debug_frame 0x000016ac 0x1e0 Bin/CDCClassDevice.o - .debug_frame 0x0000188c 0xf0 Bin/HIDClassDevice.o - .debug_frame 0x0000197c 0x80 Bin/MassStorageClassDevice.o - .debug_frame 0x000019fc 0x94 Bin/MIDIClassDevice.o - .debug_frame 0x00001a90 0x194 Bin/PrinterClassDevice.o - .debug_frame 0x00001c24 0x104 Bin/RNDISClassDevice.o - -.debug_str 0x00000000 0x76e1 - *(.debug_str) - .debug_str 0x00000000 0xd8c Bin/Chameleon-Mini.o - 0xe51 (size before relaxing) - .debug_str 0x00000d8c 0x8cc Bin/LUFADescriptors.o - 0xbd9 (size before relaxing) - .debug_str 0x00001658 0x764 Bin/System.o - 0xc54 (size before relaxing) - .debug_str 0x00001dbc 0x2ff Bin/Configuration.o - 0x629 (size before relaxing) - .debug_str 0x000020bb 0x2c Bin/Random.o - 0x1d3 (size before relaxing) - .debug_str 0x000020e7 0x56 Bin/Common.o - 0x1f6 (size before relaxing) - .debug_str 0x0000213d 0x22d Bin/Memory.o - 0x7de (size before relaxing) - .debug_str 0x0000236a 0x1d2 Bin/Button.o - 0x788 (size before relaxing) - .debug_str 0x0000253c 0xc0 Bin/Settings.o - 0x590 (size before relaxing) - .debug_str 0x000025fc 0x6 Bin/LED.o - 0x184 (size before relaxing) - .debug_str 0x00002602 0x295 Bin/Terminal.o - 0x7e8 (size before relaxing) - .debug_str 0x00002897 0x3f0 Bin/Commands.o - 0xd8e (size before relaxing) - .debug_str 0x00002c87 0x149 Bin/XModem.o - 0x5ef (size before relaxing) - .debug_str 0x00002dd0 0xc1 Bin/CommandLine.o - 0x5cc (size before relaxing) - .debug_str 0x00002e91 0x1a Bin/Codec.o - 0x2f4 (size before relaxing) - .debug_str 0x00002eab 0x12b9 Bin/ISO14443-2A.o - 0x1adc (size before relaxing) - .debug_str 0x00004164 0x2b0 Bin/MifareClassic.o - 0x601 (size before relaxing) - .debug_str 0x00004414 0x1a Bin/ISO14443-3A.o - 0x1ed (size before relaxing) - .debug_str 0x0000442e 0x95 Bin/Crypto1.o - 0x27b (size before relaxing) - .debug_str 0x000044c3 0x492 Bin/HIDParser.o - 0x6af (size before relaxing) - .debug_str 0x00004955 0x22e Bin/ConfigDescriptors.o - 0x4ed (size before relaxing) - .debug_str 0x00004b83 0xa04 Bin/DeviceStandardReq.o - 0x11eb (size before relaxing) - .debug_str 0x00005587 0x31 Bin/Events.o - 0x19a (size before relaxing) - .debug_str 0x000055b8 0x2b Bin/HostStandardReq.o - 0x194 (size before relaxing) - .debug_str 0x000055e3 0x6d Bin/USBTask.o - 0x466 (size before relaxing) - .debug_str 0x00005650 0x4a Bin/Device_XMEGA.o - 0x5da (size before relaxing) - .debug_str 0x0000569a 0x4d9 Bin/EndpointStream_XMEGA.o - 0x97e (size before relaxing) - .debug_str 0x00005b73 0x2aa Bin/Endpoint_XMEGA.o - 0xaec (size before relaxing) - .debug_str 0x00005e1d 0x2c Bin/Host_XMEGA.o - 0x195 (size before relaxing) - .debug_str 0x00005e49 0x32 Bin/PipeStream_XMEGA.o - 0x19b (size before relaxing) - .debug_str 0x00005e7b 0x2c Bin/Pipe_XMEGA.o - 0x195 (size before relaxing) - .debug_str 0x00005ea7 0x1bb Bin/USBController_XMEGA.o - 0xe7c (size before relaxing) - .debug_str 0x00006062 0xaa Bin/USBInterrupt_XMEGA.o - 0x94d (size before relaxing) - .debug_str 0x0000610c 0x280 Bin/AudioClassDevice.o - 0x7c1 (size before relaxing) - .debug_str 0x0000638c 0x286 Bin/CDCClassDevice.o - 0xb16 (size before relaxing) - .debug_str 0x00006612 0x248 Bin/HIDClassDevice.o - 0xb31 (size before relaxing) - .debug_str 0x0000685a 0x261 Bin/MassStorageClassDevice.o - 0x914 (size before relaxing) - .debug_str 0x00006abb 0x115 Bin/MIDIClassDevice.o - 0x76b (size before relaxing) - .debug_str 0x00006bd0 0x269 Bin/PrinterClassDevice.o - 0xa3f (size before relaxing) - .debug_str 0x00006e39 0x6e5 Bin/RNDISClassDevice.o - 0xe74 (size before relaxing) - .debug_str 0x0000751e 0x3b Bin/AndroidAccessoryClassHost.o - 0x1a4 (size before relaxing) - .debug_str 0x00007559 0x30 Bin/AudioClassHost.o - 0x199 (size before relaxing) - .debug_str 0x00007589 0x2e Bin/CDCClassHost.o - 0x197 (size before relaxing) - .debug_str 0x000075b7 0x2e Bin/HIDClassHost.o - 0x197 (size before relaxing) - .debug_str 0x000075e5 0x36 Bin/MassStorageClassHost.o - 0x19f (size before relaxing) - .debug_str 0x0000761b 0x2f Bin/MIDIClassHost.o - 0x198 (size before relaxing) - .debug_str 0x0000764a 0x32 Bin/PrinterClassHost.o - 0x19b (size before relaxing) - .debug_str 0x0000767c 0x30 Bin/RNDISClassHost.o - 0x199 (size before relaxing) - .debug_str 0x000076ac 0x35 Bin/StillImageClassHost.o - 0x19e (size before relaxing) - -.debug_loc 0x00000000 0xc84e - *(.debug_loc) - .debug_loc 0x00000000 0x253 Bin/LUFADescriptors.o - .debug_loc 0x00000253 0x2f Bin/System.o - .debug_loc 0x00000282 0x4e7 Bin/Configuration.o - .debug_loc 0x00000769 0xde Bin/Random.o - .debug_loc 0x00000847 0x34b Bin/Common.o - .debug_loc 0x00000b92 0xcbd Bin/Memory.o - .debug_loc 0x0000184f 0x810 Bin/Button.o - .debug_loc 0x0000205f 0x1a6 Bin/Settings.o - .debug_loc 0x00002205 0x214 Bin/Terminal.o - .debug_loc 0x00002419 0xa5a Bin/Commands.o - .debug_loc 0x00002e73 0x390 Bin/XModem.o - .debug_loc 0x00003203 0x670 Bin/CommandLine.o - .debug_loc 0x00003873 0x4a4 Bin/ISO14443-2A.o - .debug_loc 0x00003d17 0x972 Bin/MifareClassic.o - .debug_loc 0x00004689 0x317 Bin/ISO14443-3A.o - .debug_loc 0x000049a0 0x7ad Bin/Crypto1.o - .debug_loc 0x0000514d 0xf2d Bin/HIDParser.o - .debug_loc 0x0000607a 0x592 Bin/ConfigDescriptors.o - .debug_loc 0x0000660c 0x2d8 Bin/DeviceStandardReq.o - .debug_loc 0x000068e4 0x22 Bin/USBTask.o - .debug_loc 0x00006906 0x2acb Bin/EndpointStream_XMEGA.o - .debug_loc 0x000093d1 0x58b Bin/Endpoint_XMEGA.o - .debug_loc 0x0000995c 0x80 Bin/USBController_XMEGA.o - .debug_loc 0x000099dc 0x200 Bin/USBInterrupt_XMEGA.o - .debug_loc 0x00009bdc 0x37f Bin/AudioClassDevice.o - .debug_loc 0x00009f5b 0xa0b Bin/CDCClassDevice.o - .debug_loc 0x0000a966 0x3e7 Bin/HIDClassDevice.o - .debug_loc 0x0000ad4d 0x29f Bin/MassStorageClassDevice.o - .debug_loc 0x0000afec 0x33c Bin/MIDIClassDevice.o - .debug_loc 0x0000b328 0x8cd Bin/PrinterClassDevice.o - .debug_loc 0x0000bbf5 0xc59 Bin/RNDISClassDevice.o - -.debug_macinfo - *(.debug_macinfo) - -.debug_weaknames - *(.debug_weaknames) - -.debug_funcnames - *(.debug_funcnames) - -.debug_typenames - *(.debug_typenames) - -.debug_varnames - *(.debug_varnames) - -.debug_pubtypes - *(.debug_pubtypes) - -.debug_ranges 0x00000000 0x16c8 - *(.debug_ranges) - .debug_ranges 0x00000000 0x28 Bin/Chameleon-Mini.o - .debug_ranges 0x00000028 0x10 Bin/LUFADescriptors.o - .debug_ranges 0x00000038 0x40 Bin/System.o - .debug_ranges 0x00000078 0xb8 Bin/Configuration.o - .debug_ranges 0x00000130 0x28 Bin/Random.o - .debug_ranges 0x00000158 0x48 Bin/Common.o - .debug_ranges 0x000001a0 0x298 Bin/Memory.o - .debug_ranges 0x00000438 0xa0 Bin/Button.o - .debug_ranges 0x000004d8 0x40 Bin/Settings.o - .debug_ranges 0x00000518 0xb8 Bin/Terminal.o - .debug_ranges 0x000005d0 0xf0 Bin/Commands.o - .debug_ranges 0x000006c0 0x40 Bin/XModem.o - .debug_ranges 0x00000700 0xc0 Bin/CommandLine.o - .debug_ranges 0x000007c0 0xc0 Bin/ISO14443-2A.o - .debug_ranges 0x00000880 0x158 Bin/MifareClassic.o - .debug_ranges 0x000009d8 0x18 Bin/ISO14443-3A.o - .debug_ranges 0x000009f0 0x40 Bin/Crypto1.o - .debug_ranges 0x00000a30 0x108 Bin/HIDParser.o - .debug_ranges 0x00000b38 0x40 Bin/ConfigDescriptors.o - .debug_ranges 0x00000b78 0xf0 Bin/DeviceStandardReq.o - .debug_ranges 0x00000c68 0x10 Bin/Events.o - .debug_ranges 0x00000c78 0x38 Bin/USBTask.o - .debug_ranges 0x00000cb0 0x10 Bin/Device_XMEGA.o - .debug_ranges 0x00000cc0 0x4f0 Bin/EndpointStream_XMEGA.o - .debug_ranges 0x000011b0 0xf8 Bin/Endpoint_XMEGA.o - .debug_ranges 0x000012a8 0x20 Bin/USBController_XMEGA.o - .debug_ranges 0x000012c8 0x20 Bin/USBInterrupt_XMEGA.o - .debug_ranges 0x000012e8 0x38 Bin/AudioClassDevice.o - .debug_ranges 0x00001320 0x100 Bin/CDCClassDevice.o - .debug_ranges 0x00001420 0x20 Bin/HIDClassDevice.o - .debug_ranges 0x00001440 0x80 Bin/MassStorageClassDevice.o - .debug_ranges 0x000014c0 0x48 Bin/MIDIClassDevice.o - .debug_ranges 0x00001508 0x128 Bin/PrinterClassDevice.o - .debug_ranges 0x00001630 0x98 Bin/RNDISClassDevice.o - -.debug_macro - *(.debug_macro) -OUTPUT(Chameleon-Mini.elf elf32-avr) -LOAD linker stubs - -Cross Reference Table - -Symbol File -ActiveConfiguration Bin/Configuration.o - Bin/MifareClassic.o - Bin/ISO14443-2A.o - Bin/Commands.o - Bin/Button.o - Bin/Chameleon-Mini.o -Audio_Device_ConfigureEndpoints Bin/AudioClassDevice.o -Audio_Device_Event_Stub Bin/AudioClassDevice.o -Audio_Device_ProcessControlRequest Bin/AudioClassDevice.o -BufferToHexString Bin/Common.o - Bin/Commands.o -ButtonGetActionByName Bin/Button.o - Bin/Commands.o -ButtonGetActionList Bin/Button.o - Bin/Commands.o -ButtonInit Bin/Button.o - Bin/Chameleon-Mini.o -ButtonSetActionById Bin/Button.o -ButtonSetActionByName Bin/Button.o - Bin/Commands.o -ButtonTick Bin/Button.o - Bin/Chameleon-Mini.o -CALLBACK_Audio_Device_GetSetEndpointProperty Bin/AudioClassDevice.o -CALLBACK_Audio_Device_GetSetInterfaceProperty Bin/AudioClassDevice.o -CALLBACK_HIDParser_FilterHIDReportItem Bin/HIDParser.o -CALLBACK_HID_Device_CreateHIDReport Bin/HIDClassDevice.o -CALLBACK_HID_Device_ProcessHIDReport Bin/HIDClassDevice.o -CALLBACK_MS_Device_SCSICommandReceived Bin/MassStorageClassDevice.o -CALLBACK_USB_GetDescriptor Bin/LUFADescriptors.o - Bin/DeviceStandardReq.o -CDC_Device_BytesReceived Bin/CDCClassDevice.o -CDC_Device_ConfigureEndpoints Bin/CDCClassDevice.o - Bin/Terminal.o -CDC_Device_CreateBlockingStream Bin/CDCClassDevice.o -CDC_Device_CreateStream Bin/CDCClassDevice.o -CDC_Device_Event_Stub Bin/CDCClassDevice.o -CDC_Device_Flush Bin/CDCClassDevice.o -CDC_Device_ProcessControlRequest Bin/CDCClassDevice.o - Bin/Terminal.o -CDC_Device_ReceiveByte Bin/CDCClassDevice.o - Bin/Terminal.o -CDC_Device_SendByte Bin/CDCClassDevice.o - Bin/XModem.o - Bin/Terminal.o -CDC_Device_SendControlLineStateChange Bin/CDCClassDevice.o -CDC_Device_SendData Bin/CDCClassDevice.o - Bin/Terminal.o -CDC_Device_SendString Bin/CDCClassDevice.o - Bin/Terminal.o -CDC_Device_USBTask Bin/CDCClassDevice.o - Bin/Terminal.o -CodecBuffer Bin/Codec.o - Bin/ISO14443-2A.o -CommandExecButton Bin/Commands.o - Bin/CommandLine.o -CommandExecClear Bin/Commands.o - Bin/CommandLine.o -CommandExecConfig Bin/Commands.o - Bin/CommandLine.o -CommandExecDownload Bin/Commands.o - Bin/CommandLine.o -CommandExecHelp Bin/Commands.o - Bin/CommandLine.o -CommandExecReset Bin/Commands.o - Bin/CommandLine.o -CommandExecUpgrade Bin/Commands.o - Bin/CommandLine.o -CommandExecUpload Bin/Commands.o - Bin/CommandLine.o -CommandGetButton Bin/Commands.o - Bin/CommandLine.o -CommandGetConfig Bin/Commands.o - Bin/CommandLine.o -CommandGetMemSize Bin/Commands.o - Bin/CommandLine.o -CommandGetReadOnly Bin/Commands.o - Bin/CommandLine.o -CommandGetRssi Bin/Commands.o - Bin/CommandLine.o -CommandGetSetting Bin/Commands.o - Bin/CommandLine.o -CommandGetUid Bin/Commands.o - Bin/CommandLine.o -CommandGetUidSize Bin/Commands.o - Bin/CommandLine.o -CommandGetVersion Bin/Commands.o - Bin/CommandLine.o -CommandLineInit Bin/CommandLine.o -CommandLineProcessByte Bin/CommandLine.o - Bin/Terminal.o -CommandLineTick Bin/CommandLine.o - Bin/Terminal.o -CommandSetButton Bin/Commands.o - Bin/CommandLine.o -CommandSetConfig Bin/Commands.o - Bin/CommandLine.o -CommandSetReadOnly Bin/Commands.o - Bin/CommandLine.o -CommandSetSetting Bin/Commands.o - Bin/CommandLine.o -CommandSetUid Bin/Commands.o - Bin/CommandLine.o -CommandTable Bin/CommandLine.o - Bin/Commands.o -ConfigurationDescriptor Bin/LUFADescriptors.o -ConfigurationGetList Bin/Configuration.o - Bin/Commands.o -ConfigurationInit Bin/Configuration.o - Bin/Settings.o - Bin/Chameleon-Mini.o -ConfigurationSetById Bin/Configuration.o -ConfigurationSetByName Bin/Configuration.o - Bin/Commands.o -Crypto1Auth Bin/Crypto1.o - Bin/MifareClassic.o -Crypto1Byte Bin/Crypto1.o - Bin/MifareClassic.o -Crypto1FilterOutput Bin/Crypto1.o - Bin/MifareClassic.o -Crypto1Nibble Bin/Crypto1.o - Bin/MifareClassic.o -Crypto1PRNG Bin/Crypto1.o - Bin/MifareClassic.o -Crypto1Setup Bin/Crypto1.o - Bin/MifareClassic.o -DeviceDescriptor Bin/LUFADescriptors.o -EVENT_Audio_Device_StreamStartStop Bin/AudioClassDevice.o -EVENT_CDC_Device_BreakSent Bin/CDCClassDevice.o -EVENT_CDC_Device_ControLineStateChanged Bin/CDCClassDevice.o -EVENT_CDC_Device_LineEncodingChanged Bin/CDCClassDevice.o -EVENT_PRNT_Device_SoftReset Bin/PrinterClassDevice.o -EVENT_USB_Device_ConfigurationChanged Bin/Terminal.o - Bin/DeviceStandardReq.o -EVENT_USB_Device_Connect Bin/Terminal.o - Bin/USBInterrupt_XMEGA.o -EVENT_USB_Device_ControlRequest Bin/Terminal.o - Bin/DeviceStandardReq.o -EVENT_USB_Device_Disconnect Bin/Terminal.o - Bin/USBInterrupt_XMEGA.o -EVENT_USB_Device_Reset Bin/Events.o - Bin/USBInterrupt_XMEGA.o -EVENT_USB_Device_StartOfFrame Bin/Events.o - Bin/USBInterrupt_XMEGA.o -EVENT_USB_Device_Suspend Bin/Events.o -EVENT_USB_Device_WakeUp Bin/Events.o -Endpoint_ClearEndpoints Bin/Endpoint_XMEGA.o - Bin/USBInterrupt_XMEGA.o -Endpoint_ClearIN Bin/Endpoint_XMEGA.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/MIDIClassDevice.o - Bin/MassStorageClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o - Bin/AudioClassDevice.o - Bin/EndpointStream_XMEGA.o - Bin/DeviceStandardReq.o -Endpoint_ClearOUT Bin/Endpoint_XMEGA.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/MIDIClassDevice.o - Bin/MassStorageClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o - Bin/AudioClassDevice.o - Bin/EndpointStream_XMEGA.o - Bin/DeviceStandardReq.o -Endpoint_ClearSETUP Bin/Endpoint_XMEGA.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/MassStorageClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o - Bin/AudioClassDevice.o - Bin/DeviceStandardReq.o -Endpoint_ClearStatusStage Bin/Endpoint_XMEGA.o - Bin/PrinterClassDevice.o - Bin/MassStorageClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o - Bin/AudioClassDevice.o - Bin/DeviceStandardReq.o -Endpoint_ConfigureEndpointTable Bin/Endpoint_XMEGA.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/MIDIClassDevice.o - Bin/MassStorageClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o - Bin/AudioClassDevice.o -Endpoint_ConfigureEndpoint_PRV Bin/Endpoint_XMEGA.o - Bin/USBInterrupt_XMEGA.o - Bin/USBController_XMEGA.o -Endpoint_Discard_Stream Bin/EndpointStream_XMEGA.o -Endpoint_IsINReady Bin/Endpoint_XMEGA.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/MIDIClassDevice.o - Bin/MassStorageClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o - Bin/EndpointStream_XMEGA.o - Bin/DeviceStandardReq.o -Endpoint_IsOUTReceived Bin/Endpoint_XMEGA.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/MassStorageClassDevice.o - Bin/CDCClassDevice.o - Bin/EndpointStream_XMEGA.o -Endpoint_IsSETUPReceived Bin/Endpoint_XMEGA.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/MassStorageClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o - Bin/AudioClassDevice.o - Bin/EndpointStream_XMEGA.o - Bin/USBTask.o - Bin/DeviceStandardReq.o -Endpoint_Null_Stream Bin/EndpointStream_XMEGA.o -Endpoint_Read_8 Bin/Endpoint_XMEGA.o - Bin/PrinterClassDevice.o - Bin/CDCClassDevice.o - Bin/EndpointStream_XMEGA.o - Bin/DeviceStandardReq.o -Endpoint_Read_Control_EStream_BE Bin/EndpointStream_XMEGA.o -Endpoint_Read_Control_EStream_LE Bin/EndpointStream_XMEGA.o -Endpoint_Read_Control_Stream_BE Bin/EndpointStream_XMEGA.o -Endpoint_Read_Control_Stream_LE Bin/EndpointStream_XMEGA.o - Bin/RNDISClassDevice.o - Bin/HIDClassDevice.o - Bin/AudioClassDevice.o -Endpoint_Read_EStream_BE Bin/EndpointStream_XMEGA.o -Endpoint_Read_EStream_LE Bin/EndpointStream_XMEGA.o -Endpoint_Read_Stream_BE Bin/EndpointStream_XMEGA.o -Endpoint_Read_Stream_LE Bin/EndpointStream_XMEGA.o - Bin/RNDISClassDevice.o - Bin/MIDIClassDevice.o - Bin/MassStorageClassDevice.o -Endpoint_SelectEndpoint Bin/Endpoint_XMEGA.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/MIDIClassDevice.o - Bin/MassStorageClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o - Bin/EndpointStream_XMEGA.o - Bin/USBTask.o - Bin/DeviceStandardReq.o -Endpoint_StallTransaction Bin/Endpoint_XMEGA.o - Bin/RNDISClassDevice.o - Bin/MassStorageClassDevice.o - Bin/DeviceStandardReq.o -Endpoint_WaitUntilReady Bin/Endpoint_XMEGA.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/MIDIClassDevice.o - Bin/CDCClassDevice.o - Bin/EndpointStream_XMEGA.o -Endpoint_Write_8 Bin/Endpoint_XMEGA.o - Bin/PrinterClassDevice.o - Bin/MassStorageClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o - Bin/EndpointStream_XMEGA.o - Bin/DeviceStandardReq.o -Endpoint_Write_Control_EStream_BE Bin/EndpointStream_XMEGA.o -Endpoint_Write_Control_EStream_LE Bin/EndpointStream_XMEGA.o -Endpoint_Write_Control_PStream_BE Bin/EndpointStream_XMEGA.o -Endpoint_Write_Control_PStream_LE Bin/EndpointStream_XMEGA.o - Bin/DeviceStandardReq.o -Endpoint_Write_Control_Stream_BE Bin/EndpointStream_XMEGA.o -Endpoint_Write_Control_Stream_LE Bin/EndpointStream_XMEGA.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/HIDClassDevice.o - Bin/AudioClassDevice.o - Bin/DeviceStandardReq.o -Endpoint_Write_EStream_BE Bin/EndpointStream_XMEGA.o -Endpoint_Write_EStream_LE Bin/EndpointStream_XMEGA.o -Endpoint_Write_PStream_BE Bin/EndpointStream_XMEGA.o -Endpoint_Write_PStream_LE Bin/EndpointStream_XMEGA.o -Endpoint_Write_Stream_BE Bin/EndpointStream_XMEGA.o -Endpoint_Write_Stream_LE Bin/EndpointStream_XMEGA.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/MIDIClassDevice.o - Bin/MassStorageClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o -GlobalSettings Bin/Settings.o - Bin/Button.o - Bin/Memory.o - Bin/Configuration.o -HID_Device_ConfigureEndpoints Bin/HIDClassDevice.o -HID_Device_ProcessControlRequest Bin/HIDClassDevice.o -HID_Device_USBTask Bin/HIDClassDevice.o -HexStringToBuffer Bin/Common.o - Bin/Commands.o -ISO14443AAppendCRCA Bin/ISO14443-3A.o - Bin/MifareClassic.o -ISO14443ACheckCRCA Bin/ISO14443-3A.o - Bin/MifareClassic.o -ISO14443ACodecInit Bin/ISO14443-2A.o - Bin/Configuration.o -ISO14443ACodecTask Bin/ISO14443-2A.o - Bin/Configuration.o -LEDPulseMask Bin/LED.o - Bin/Terminal.o - Bin/Chameleon-Mini.o -LanguageString Bin/LUFADescriptors.o -MIDI_Device_ConfigureEndpoints Bin/MIDIClassDevice.o -MIDI_Device_Flush Bin/MIDIClassDevice.o -MIDI_Device_ReceiveEventPacket Bin/MIDIClassDevice.o -MIDI_Device_SendEventPacket Bin/MIDIClassDevice.o -MIDI_Device_USBTask Bin/MIDIClassDevice.o -MS_Device_ConfigureEndpoints Bin/MassStorageClassDevice.o -MS_Device_ProcessControlRequest Bin/MassStorageClassDevice.o -MS_Device_USBTask Bin/MassStorageClassDevice.o -ManufacturerString Bin/LUFADescriptors.o -MemoryClear Bin/Memory.o - Bin/Commands.o -MemoryDownloadBlock Bin/Memory.o - Bin/Commands.o -MemoryInit Bin/Memory.o - Bin/Chameleon-Mini.o -MemoryReadBlock Bin/Memory.o - Bin/MifareClassic.o -MemoryRecall Bin/Memory.o - Bin/Settings.o - Bin/Button.o -MemoryStore Bin/Memory.o - Bin/Settings.o - Bin/Button.o -MemoryUploadBlock Bin/Memory.o - Bin/Commands.o -MemoryWriteBlock Bin/Memory.o - Bin/MifareClassic.o -MifareClassicAppInit1K Bin/MifareClassic.o - Bin/Configuration.o -MifareClassicAppInit4K Bin/MifareClassic.o - Bin/Configuration.o -MifareClassicAppProcess Bin/MifareClassic.o - Bin/Configuration.o -MifareClassicAppReset Bin/MifareClassic.o - Bin/Configuration.o -MifareClassicAppTask Bin/MifareClassic.o - Bin/Configuration.o -MifareClassicGetUid Bin/MifareClassic.o - Bin/Configuration.o -MifareClassicSetUid Bin/MifareClassic.o - Bin/Configuration.o -PRNT_Device_BytesReceived Bin/PrinterClassDevice.o -PRNT_Device_ConfigureEndpoints Bin/PrinterClassDevice.o -PRNT_Device_CreateBlockingStream Bin/PrinterClassDevice.o -PRNT_Device_CreateStream Bin/PrinterClassDevice.o -PRNT_Device_Event_Stub Bin/PrinterClassDevice.o -PRNT_Device_Flush Bin/PrinterClassDevice.o -PRNT_Device_ProcessControlRequest Bin/PrinterClassDevice.o -PRNT_Device_ReceiveByte Bin/PrinterClassDevice.o -PRNT_Device_SendByte Bin/PrinterClassDevice.o -PRNT_Device_SendData Bin/PrinterClassDevice.o -PRNT_Device_SendString Bin/PrinterClassDevice.o -PRNT_Device_USBTask Bin/PrinterClassDevice.o -ProductString Bin/LUFADescriptors.o -RNDIS_Device_ConfigureEndpoints Bin/RNDISClassDevice.o -RNDIS_Device_IsPacketReceived Bin/RNDISClassDevice.o -RNDIS_Device_ProcessControlRequest Bin/RNDISClassDevice.o -RNDIS_Device_ReadPacket Bin/RNDISClassDevice.o -RNDIS_Device_SendPacket Bin/RNDISClassDevice.o -RNDIS_Device_USBTask Bin/RNDISClassDevice.o -RandomGetBuffer Bin/Random.o - Bin/MifareClassic.o -RandomGetByte Bin/Random.o - Bin/Commands.o - Bin/Button.o -RandomInit Bin/Random.o - Bin/Chameleon-Mini.o -RandomTick Bin/Random.o - Bin/Chameleon-Mini.o -SettingsCycle Bin/Settings.o - Bin/Button.o -SettingsGetActiveById Bin/Settings.o -SettingsGetActiveByName Bin/Settings.o - Bin/Commands.o -SettingsLoad Bin/Settings.o - Bin/Chameleon-Mini.o -SettingsSave Bin/Settings.o - Bin/Commands.o -SettingsSetActiveById Bin/Settings.o -SettingsSetActiveByName Bin/Settings.o - Bin/Commands.o -StoredSettings Bin/Settings.o -SystemEnterBootloader Bin/System.o - Bin/Commands.o -SystemInit Bin/System.o - Bin/Chameleon-Mini.o -SystemInterruptInit Bin/System.o - Bin/Chameleon-Mini.o -SystemReset Bin/System.o - Bin/Commands.o -SystemStartUSBClock Bin/System.o - Bin/Terminal.o -SystemStopUSBClock Bin/System.o - Bin/Terminal.o -TerminalBuffer Bin/Terminal.o - Bin/CommandLine.o - Bin/XModem.o -TerminalHandle Bin/Terminal.o - Bin/XModem.o -TerminalInit Bin/Terminal.o - Bin/Chameleon-Mini.o -TerminalSendBlock Bin/Terminal.o - Bin/XModem.o -TerminalSendString Bin/Terminal.o - Bin/CommandLine.o -TerminalSendStringP Bin/Terminal.o - Bin/CommandLine.o -TerminalState Bin/Terminal.o -TerminalTask Bin/Terminal.o - Bin/Chameleon-Mini.o -TerminalTick Bin/Terminal.o - Bin/Chameleon-Mini.o -USB_ControlRequest Bin/USBTask.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/MassStorageClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o - Bin/AudioClassDevice.o - Bin/Endpoint_XMEGA.o - Bin/EndpointStream_XMEGA.o - Bin/DeviceStandardReq.o -USB_DeviceState Bin/USBTask.o - Bin/RNDISClassDevice.o - Bin/PrinterClassDevice.o - Bin/MIDIClassDevice.o - Bin/MassStorageClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o - Bin/USBInterrupt_XMEGA.o - Bin/USBController_XMEGA.o - Bin/Endpoint_XMEGA.o - Bin/EndpointStream_XMEGA.o - Bin/DeviceStandardReq.o -USB_Device_ConfigurationNumber Bin/DeviceStandardReq.o - Bin/USBInterrupt_XMEGA.o - Bin/USBController_XMEGA.o -USB_Device_CurrentlySelfPowered Bin/DeviceStandardReq.o - Bin/USBController_XMEGA.o -USB_Device_ProcessControlRequest Bin/DeviceStandardReq.o - Bin/USBTask.o -USB_Device_RemoteWakeupEnabled Bin/DeviceStandardReq.o - Bin/USBController_XMEGA.o -USB_Device_SendRemoteWakeup Bin/Device_XMEGA.o -USB_Disable Bin/USBController_XMEGA.o - Bin/Commands.o - Bin/Terminal.o -USB_EndpointTable Bin/USBController_XMEGA.o -USB_Endpoint_FIFOs Bin/Endpoint_XMEGA.o - Bin/PrinterClassDevice.o - Bin/MassStorageClassDevice.o - Bin/DeviceStandardReq.o -USB_Endpoint_SelectedEndpoint Bin/Endpoint_XMEGA.o - Bin/PrinterClassDevice.o - Bin/MIDIClassDevice.o - Bin/CDCClassDevice.o - Bin/EndpointStream_XMEGA.o - Bin/USBTask.o -USB_Endpoint_SelectedFIFO Bin/Endpoint_XMEGA.o - Bin/PrinterClassDevice.o - Bin/MIDIClassDevice.o - Bin/HIDClassDevice.o - Bin/CDCClassDevice.o - Bin/EndpointStream_XMEGA.o -USB_Endpoint_SelectedHandle Bin/Endpoint_XMEGA.o - Bin/PrinterClassDevice.o - Bin/MassStorageClassDevice.o - Bin/DeviceStandardReq.o -USB_Event_Stub Bin/Events.o -USB_GetHIDReportItemInfo Bin/HIDParser.o -USB_GetHIDReportSize Bin/HIDParser.o -USB_GetNextDescriptorComp Bin/ConfigDescriptors.o -USB_GetNextDescriptorOfType Bin/ConfigDescriptors.o -USB_GetNextDescriptorOfTypeAfter Bin/ConfigDescriptors.o -USB_GetNextDescriptorOfTypeBefore Bin/ConfigDescriptors.o -USB_INT_ClearAllInterrupts Bin/USBInterrupt_XMEGA.o - Bin/USBController_XMEGA.o -USB_INT_DisableAllInterrupts Bin/USBInterrupt_XMEGA.o - Bin/USBController_XMEGA.o -USB_Init Bin/USBController_XMEGA.o - Bin/Terminal.o -USB_IsInitialized Bin/USBTask.o - Bin/USBController_XMEGA.o -USB_ProcessHIDReport Bin/HIDParser.o -USB_ResetInterface Bin/USBController_XMEGA.o -USB_SetHIDReportItemInfo Bin/HIDParser.o -USB_USBTask Bin/USBTask.o - Bin/PrinterClassDevice.o - Bin/MassStorageClassDevice.o - Bin/CDCClassDevice.o - Bin/EndpointStream_XMEGA.o - Bin/Terminal.o -XModemProcessByte Bin/XModem.o - Bin/Terminal.o -XModemReceive Bin/XModem.o - Bin/Commands.o -XModemSend Bin/XModem.o - Bin/Commands.o -XModemTick Bin/XModem.o - Bin/Terminal.o -__bad_interrupt /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__bss_end /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) -__bss_start /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) -__data_end /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) -__data_load_start /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) -__data_start /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) -__divmodsi4 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) -__do_clear_bss /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_clear_bss.o) - Bin/USBController_XMEGA.o - Bin/Endpoint_XMEGA.o - Bin/USBTask.o - Bin/DeviceStandardReq.o - Bin/Crypto1.o - Bin/MifareClassic.o - Bin/ISO14443-2A.o - Bin/Codec.o - Bin/CommandLine.o - Bin/XModem.o - Bin/Terminal.o - Bin/LED.o - Bin/Settings.o - Bin/Button.o - Bin/Memory.o - Bin/Configuration.o -__do_copy_data /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_copy_data.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) - Bin/RNDISClassDevice.o - Bin/CDCClassDevice.o - Bin/Crypto1.o - Bin/Commands.o - Bin/Terminal.o -__eerd_block_x32a4u /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_block_atxmega32a4u.o) - Bin/Settings.o -__eerd_byte_x32a4u /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_byte_atxmega32a4u.o) - Bin/EndpointStream_XMEGA.o -__eeupd_byte_x32a4u /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eeupd_byte_atxmega32a4u.o) - Bin/EndpointStream_XMEGA.o -__eeupd_r18_x32a4u /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eeupd_byte_atxmega32a4u.o) -__eewr_block_x32a4u /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_block_atxmega32a4u.o) - Bin/Settings.o -__eewr_byte_x32a4u /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_byte_atxmega32a4u.o) -__eewr_r18_x32a4u /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_byte_atxmega32a4u.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eewr_block_atxmega32a4u.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eeupd_byte_atxmega32a4u.o) -__epilogue_restores__ /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_epilogue.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) -__heap_end /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__init /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__mulohisi3 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) -__mulshisi3 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) - Bin/Commands.o -__muluhisi3 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_mulshisi3.o) -__negsi2 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_negsi2.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) -__prologue_saves__ /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_prologue.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) -__stack /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__tablejump2__ /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) - Bin/DeviceStandardReq.o - Bin/HIDParser.o - Bin/MifareClassic.o - Bin/ISO14443-2A.o - Bin/XModem.o -__tablejump__ /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_tablejump.o) -__udivmodsi4 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_udivmodsi4.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_divmodsi4.o) -__ultoa_invert /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(ultoa_invert.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) -__umulhisi3 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_umulhisi3.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_muluhisi3.o) -__vector_1 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_10 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_100 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_101 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_102 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_103 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_104 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_105 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_106 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_107 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_108 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_109 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_11 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_110 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_111 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_112 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_113 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_114 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_115 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_116 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_117 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_118 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_119 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_12 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_120 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_121 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_122 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_123 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_124 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_125 Bin/USBInterrupt_XMEGA.o - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_126 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_13 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_14 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_15 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_16 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_17 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_18 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_19 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_2 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_20 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_21 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_22 Bin/ISO14443-2A.o - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_23 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_24 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_25 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_26 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_27 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_28 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_29 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_3 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_30 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_31 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_32 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_33 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_34 Bin/ISO14443-2A.o - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_35 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_36 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_37 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_38 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_39 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_4 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_40 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_41 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_42 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_43 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_44 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_45 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_46 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_47 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_48 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_49 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_5 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_50 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_51 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_52 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_53 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_54 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_55 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_56 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_57 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_58 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_59 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_6 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_60 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_61 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_62 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_63 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_64 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_65 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_66 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_67 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_68 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_69 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_7 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_70 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_71 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_72 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_73 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_74 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_75 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_76 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_77 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_78 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_79 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_8 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_80 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_81 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_82 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_83 Bin/ISO14443-2A.o - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_84 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_85 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_86 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_87 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_88 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_89 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_9 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_90 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_91 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_92 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_93 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_94 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_95 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_96 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_97 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_98 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_99 /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vector_default Bin/System.o - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -__vectors /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -_exit /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) -eeprom_mapen /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_byte_atxmega32a4u.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eeupd_byte_atxmega32a4u.o) -exit /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/avrxmega2/libgcc.a(_exit.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -fputc /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(fputc.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) -main Bin/Chameleon-Mini.o - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/crtx32a4u.o -memcmp /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcmp.o) - Bin/HIDClassDevice.o -memcpy /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcpy.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(eerd_block_atxmega32a4u.o) - Bin/RNDISClassDevice.o - Bin/HIDClassDevice.o -memcpy_P /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memcpy_P.o) - Bin/RNDISClassDevice.o - Bin/Configuration.o -memset /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(memset.o) - Bin/HIDClassDevice.o -rand /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) - Bin/Random.o -rand_r /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) -snprintf_P /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) - Bin/Commands.o -srand /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(rand.o) -strcmp_P /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strcmp_P.o) - Bin/CommandLine.o - Bin/Commands.o - Bin/Button.o -strncpy_P /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strncpy_P.o) - Bin/Button.o -strnlen /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strnlen.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) -strnlen_P /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(strnlen_P.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) -vfprintf /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(vfprintf_std.o) - /home/sk/avr8-gnu-toolchain-linux_x86/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avrxmega2/libc.a(snprintf_p.o) +Archive member included because of file (symbol) + +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o (exit) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_tablejump.o) + Bin/HIDParser.o (__tablejump2__) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) + Bin/Terminal.o (__do_copy_data) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) + Bin/Configuration.o (__do_clear_bss) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) + Bin/Commands.o (__mulshisi3) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) (__muluhisi3) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_umulhisi3.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) (__umulhisi3) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + Bin/Random.o (rand) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + Bin/Configuration.o (memcpy_P) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + Bin/Button.o (strcmp_P) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncat_P.o) + Bin/Log.o (strncat_P) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + Bin/Button.o (strncpy_P) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + Bin/HIDClassDevice.o (memcmp) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + Bin/HIDClassDevice.o (memcpy) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + Bin/HIDClassDevice.o (memset) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + Bin/Commands.o (snprintf_P) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) (vfprintf) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + Bin/Settings.o (__eerd_block_x32a4u) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + Bin/EndpointStream_XMEGA.o (__eerd_byte_x32a4u) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + Bin/EndpointStream_XMEGA.o (__eeupd_byte_x32a4u) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + Bin/Settings.o (__eewr_block_x32a4u) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) (__eewr_r18_x32a4u) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) (strnlen_P) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) (strnlen) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) (fputc) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) (__ultoa_invert) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) (__divmodsi4) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_prologue.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) (__prologue_saves__) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_epilogue.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) (__epilogue_restores__) +c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_udivmodsi4.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) (__udivmodsi4) + +Allocating common symbols +Common symbol size file + +USB_IsInitialized 0x1 Bin/USBTask.o +USB_EndpointTable 0x63 Bin/USBController_XMEGA.o +TerminalBuffer 0x100 Bin/Terminal.o +USB_Endpoint_SelectedFIFO + 0x2 Bin/Endpoint_XMEGA.o +ActiveConfiguration + 0x25 Bin/Configuration.o +USB_DeviceState 0x1 Bin/USBTask.o +USB_Device_ConfigurationNumber + 0x1 Bin/DeviceStandardReq.o +USB_Endpoint_SelectedHandle + 0x2 Bin/Endpoint_XMEGA.o +USB_Device_CurrentlySelfPowered + 0x1 Bin/DeviceStandardReq.o +CodecBuffer 0x100 Bin/Codec.o +GlobalSettings 0x33 Bin/Settings.o +USB_Endpoint_SelectedEndpoint + 0x1 Bin/Endpoint_XMEGA.o +USB_ControlRequest 0x8 Bin/USBTask.o +USB_Endpoint_FIFOs 0x318 Bin/Endpoint_XMEGA.o +LogFunc 0x2 Bin/Log.o +USB_Device_RemoteWakeupEnabled + 0x1 Bin/DeviceStandardReq.o + +Discarded input sections + + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + .text 0x00000000 0x0 Bin/Chameleon-Mini.o + .bss 0x00000000 0x0 Bin/Chameleon-Mini.o + .text 0x00000000 0x0 Bin/LUFADescriptors.o + .bss 0x00000000 0x0 Bin/LUFADescriptors.o + .text 0x00000000 0x0 Bin/System.o + .bss 0x00000000 0x0 Bin/System.o + .text 0x00000000 0x0 Bin/Configuration.o + .bss 0x00000000 0x0 Bin/Configuration.o + .text 0x00000000 0x0 Bin/Random.o + .bss 0x00000000 0x0 Bin/Random.o + .text 0x00000000 0x0 Bin/Common.o + .bss 0x00000000 0x0 Bin/Common.o + .text 0x00000000 0x0 Bin/Memory.o + .text 0x00000000 0x0 Bin/Button.o + .text 0x00000000 0x0 Bin/Log.o + .text 0x00000000 0x0 Bin/Settings.o + .bss 0x00000000 0x0 Bin/Settings.o + .text 0x00000000 0x0 Bin/LED.o + .text 0x00000000 0x0 Bin/Terminal.o + .text 0x00000000 0x0 Bin/Commands.o + .bss 0x00000000 0x0 Bin/Commands.o + .text 0x00000000 0x0 Bin/XModem.o + .text 0x00000000 0x0 Bin/CommandLine.o + .text.CommandLineInit + 0x00000000 0xa Bin/CommandLine.o + .text 0x00000000 0x0 Bin/Codec.o + .bss 0x00000000 0x0 Bin/Codec.o + .text 0x00000000 0x0 Bin/ISO14443-2A.o + .text 0x00000000 0x0 Bin/MifareUltralight.o + .text 0x00000000 0x0 Bin/MifareClassic.o + .text 0x00000000 0x0 Bin/ISO14443-3A.o + .bss 0x00000000 0x0 Bin/ISO14443-3A.o + .text 0x00000000 0x0 Bin/Crypto1.o + .text 0x00000000 0x0 Bin/HIDParser.o + .bss 0x00000000 0x0 Bin/HIDParser.o + .text.USB_ProcessHIDReport + 0x00000000 0x850 Bin/HIDParser.o + .progmem.gcc_sw_table.USB_ProcessHIDReport + 0x00000000 0x17a Bin/HIDParser.o + .text.USB_GetHIDReportItemInfo + 0x00000000 0xc6 Bin/HIDParser.o + .text.USB_SetHIDReportItemInfo + 0x00000000 0xee Bin/HIDParser.o + .text.USB_GetHIDReportSize + 0x00000000 0x158 Bin/HIDParser.o + .text 0x00000000 0x0 Bin/ConfigDescriptors.o + .bss 0x00000000 0x0 Bin/ConfigDescriptors.o + .text.USB_GetNextDescriptorOfType + 0x00000000 0x50 Bin/ConfigDescriptors.o + .text.USB_GetNextDescriptorOfTypeBefore + 0x00000000 0x6c Bin/ConfigDescriptors.o + .text.USB_GetNextDescriptorOfTypeAfter + 0x00000000 0x3e Bin/ConfigDescriptors.o + .text.USB_GetNextDescriptorComp + 0x00000000 0x8e Bin/ConfigDescriptors.o + .text 0x00000000 0x0 Bin/DeviceStandardReq.o + .bss 0x00000000 0x0 Bin/DeviceStandardReq.o + .text 0x00000000 0x0 Bin/Events.o + .bss 0x00000000 0x0 Bin/Events.o + .text 0x00000000 0x0 Bin/HostStandardReq.o + .bss 0x00000000 0x0 Bin/HostStandardReq.o + .text 0x00000000 0x0 Bin/USBTask.o + .bss 0x00000000 0x0 Bin/USBTask.o + .text 0x00000000 0x0 Bin/Device_XMEGA.o + .bss 0x00000000 0x0 Bin/Device_XMEGA.o + .text.USB_Device_SendRemoteWakeup + 0x00000000 0xc Bin/Device_XMEGA.o + .text 0x00000000 0x0 Bin/EndpointStream_XMEGA.o + .bss 0x00000000 0x0 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Discard_Stream + 0x00000000 0xc4 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Null_Stream + 0x00000000 0xc8 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_Stream_BE + 0x00000000 0xf8 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_Stream_LE + 0x00000000 0xe8 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_Stream_BE + 0x00000000 0xf8 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_PStream_LE + 0x00000000 0xec Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_PStream_BE + 0x00000000 0xf6 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_EStream_LE + 0x00000000 0xf0 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_EStream_BE + 0x00000000 0xfa Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_EStream_LE + 0x00000000 0xfe Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_EStream_BE + 0x00000000 0x108 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_Control_Stream_BE + 0x00000000 0x170 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_Control_Stream_LE + 0x00000000 0xf0 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_Control_Stream_BE + 0x00000000 0xde Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_Control_PStream_BE + 0x00000000 0x170 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_Control_EStream_LE + 0x00000000 0x156 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_Control_EStream_BE + 0x00000000 0x172 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_Control_EStream_LE + 0x00000000 0xf6 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_Control_EStream_BE + 0x00000000 0xe2 Bin/EndpointStream_XMEGA.o + .text 0x00000000 0x0 Bin/Endpoint_XMEGA.o + .bss 0x00000000 0x0 Bin/Endpoint_XMEGA.o + .text 0x00000000 0x0 Bin/Host_XMEGA.o + .bss 0x00000000 0x0 Bin/Host_XMEGA.o + .text 0x00000000 0x0 Bin/PipeStream_XMEGA.o + .bss 0x00000000 0x0 Bin/PipeStream_XMEGA.o + .text 0x00000000 0x0 Bin/Pipe_XMEGA.o + .bss 0x00000000 0x0 Bin/Pipe_XMEGA.o + .text 0x00000000 0x0 Bin/USBController_XMEGA.o + .bss 0x00000000 0x0 Bin/USBController_XMEGA.o + .text 0x00000000 0x0 Bin/USBInterrupt_XMEGA.o + .bss 0x00000000 0x0 Bin/USBInterrupt_XMEGA.o + .text 0x00000000 0x0 Bin/AudioClassDevice.o + .bss 0x00000000 0x0 Bin/AudioClassDevice.o + .text.Audio_Device_ConfigureEndpoints + 0x00000000 0x32 Bin/AudioClassDevice.o + .text.Audio_Device_Event_Stub + 0x00000000 0x2 Bin/AudioClassDevice.o + .text.Audio_Device_ProcessControlRequest + 0x00000000 0x29e Bin/AudioClassDevice.o + .text 0x00000000 0x0 Bin/CDCClassDevice.o + .bss 0x00000000 0x0 Bin/CDCClassDevice.o + .text.CDC_Device_putchar + 0x00000000 0x1e Bin/CDCClassDevice.o + .text.CDC_Device_BytesReceived + 0x00000000 0x8a Bin/CDCClassDevice.o + .text.CDC_Device_getchar_Blocking + 0x00000000 0x3e Bin/CDCClassDevice.o + .text.CDC_Device_getchar + 0x00000000 0x1a Bin/CDCClassDevice.o + .rodata 0x00000000 0x8 Bin/CDCClassDevice.o + .text.CDC_Device_SendControlLineStateChange + 0x00000000 0x7c Bin/CDCClassDevice.o + .text.CDC_Device_CreateStream + 0x00000000 0x26 Bin/CDCClassDevice.o + .text.CDC_Device_CreateBlockingStream + 0x00000000 0x26 Bin/CDCClassDevice.o + .text 0x00000000 0x0 Bin/HIDClassDevice.o + .bss 0x00000000 0x0 Bin/HIDClassDevice.o + .text.HID_Device_ProcessControlRequest + 0x00000000 0x254 Bin/HIDClassDevice.o + .text.HID_Device_ConfigureEndpoints + 0x00000000 0x2c Bin/HIDClassDevice.o + .text.HID_Device_USBTask + 0x00000000 0x1b2 Bin/HIDClassDevice.o + .text 0x00000000 0x0 Bin/MassStorageClassDevice.o + .bss 0x00000000 0x0 Bin/MassStorageClassDevice.o + .text.MS_Device_ProcessControlRequest + 0x00000000 0x70 Bin/MassStorageClassDevice.o + .text.MS_Device_ConfigureEndpoints + 0x00000000 0x3e Bin/MassStorageClassDevice.o + .text.MS_Device_USBTask + 0x00000000 0x2ca Bin/MassStorageClassDevice.o + .text 0x00000000 0x0 Bin/MIDIClassDevice.o + .bss 0x00000000 0x0 Bin/MIDIClassDevice.o + .text.MIDI_Device_ConfigureEndpoints + 0x00000000 0x32 Bin/MIDIClassDevice.o + .text.MIDI_Device_SendEventPacket + 0x00000000 0x66 Bin/MIDIClassDevice.o + .text.MIDI_Device_Flush + 0x00000000 0x5c Bin/MIDIClassDevice.o + .text.MIDI_Device_USBTask + 0x00000000 0x2c Bin/MIDIClassDevice.o + .text.MIDI_Device_ReceiveEventPacket + 0x00000000 0x70 Bin/MIDIClassDevice.o + .text 0x00000000 0x0 Bin/PrinterClassDevice.o + .bss 0x00000000 0x0 Bin/PrinterClassDevice.o + .text.PRNT_Device_ConfigureEndpoints + 0x00000000 0x38 Bin/PrinterClassDevice.o + .text.PRNT_Device_SendString + 0x00000000 0x46 Bin/PrinterClassDevice.o + .text.PRNT_Device_SendData + 0x00000000 0x3c Bin/PrinterClassDevice.o + .text.PRNT_Device_SendByte + 0x00000000 0x5e Bin/PrinterClassDevice.o + .text.PRNT_Device_putchar + 0x00000000 0x1e Bin/PrinterClassDevice.o + .text.PRNT_Device_Flush + 0x00000000 0x88 Bin/PrinterClassDevice.o + .text.PRNT_Device_USBTask + 0x00000000 0xcc Bin/PrinterClassDevice.o + .text.PRNT_Device_BytesReceived + 0x00000000 0x7a Bin/PrinterClassDevice.o + .text.PRNT_Device_ReceiveByte + 0x00000000 0xb6 Bin/PrinterClassDevice.o + .text.PRNT_Device_getchar_Blocking + 0x00000000 0x3e Bin/PrinterClassDevice.o + .text.PRNT_Device_getchar + 0x00000000 0x1a Bin/PrinterClassDevice.o + .text.PRNT_Device_CreateStream + 0x00000000 0x26 Bin/PrinterClassDevice.o + .text.PRNT_Device_CreateBlockingStream + 0x00000000 0x26 Bin/PrinterClassDevice.o + .text.PRNT_Device_Event_Stub + 0x00000000 0x2 Bin/PrinterClassDevice.o + .text.PRNT_Device_ProcessControlRequest + 0x00000000 0xe2 Bin/PrinterClassDevice.o + .text 0x00000000 0x0 Bin/RNDISClassDevice.o + .bss 0x00000000 0x0 Bin/RNDISClassDevice.o + .text.RNDIS_Device_ProcessControlRequest + 0x00000000 0x53c Bin/RNDISClassDevice.o + .text.RNDIS_Device_ConfigureEndpoints + 0x00000000 0x50 Bin/RNDISClassDevice.o + .rodata 0x00000000 0x8 Bin/RNDISClassDevice.o + .text.RNDIS_Device_USBTask + 0x00000000 0x74 Bin/RNDISClassDevice.o + .text.RNDIS_Device_IsPacketReceived + 0x00000000 0x24 Bin/RNDISClassDevice.o + .text.RNDIS_Device_ReadPacket + 0x00000000 0xa2 Bin/RNDISClassDevice.o + .text.RNDIS_Device_SendPacket + 0x00000000 0xca Bin/RNDISClassDevice.o + .progmem.data 0x00000000 0x6c Bin/RNDISClassDevice.o + .text 0x00000000 0x0 Bin/AndroidAccessoryClassHost.o + .bss 0x00000000 0x0 Bin/AndroidAccessoryClassHost.o + .text 0x00000000 0x0 Bin/AudioClassHost.o + .bss 0x00000000 0x0 Bin/AudioClassHost.o + .text 0x00000000 0x0 Bin/CDCClassHost.o + .bss 0x00000000 0x0 Bin/CDCClassHost.o + .text 0x00000000 0x0 Bin/HIDClassHost.o + .bss 0x00000000 0x0 Bin/HIDClassHost.o + .text 0x00000000 0x0 Bin/MassStorageClassHost.o + .bss 0x00000000 0x0 Bin/MassStorageClassHost.o + .text 0x00000000 0x0 Bin/MIDIClassHost.o + .bss 0x00000000 0x0 Bin/MIDIClassHost.o + .text 0x00000000 0x0 Bin/PrinterClassHost.o + .bss 0x00000000 0x0 Bin/PrinterClassHost.o + .text 0x00000000 0x0 Bin/RNDISClassHost.o + .bss 0x00000000 0x0 Bin/RNDISClassHost.o + .text 0x00000000 0x0 Bin/StillImageClassHost.o + .bss 0x00000000 0x0 Bin/StillImageClassHost.o + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + .text.libgcc.mul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + .text.libgcc.div + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + .text.libgcc.prologue + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_tablejump.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_tablejump.o) + .text.libgcc.mul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_tablejump.o) + .text.libgcc.div + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_tablejump.o) + .text.libgcc 0x00000000 0xc c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_tablejump.o) + .text.libgcc.prologue + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_tablejump.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_tablejump.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_tablejump.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) + .text.libgcc.mul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) + .text.libgcc.div + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) + .text.libgcc.prologue + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) + .text.libgcc.mul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) + .text.libgcc.div + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) + .text.libgcc.prologue + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) + .text.libgcc.div + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) + .text.libgcc.prologue + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) + .text.libgcc.div + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) + .text.libgcc.prologue + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_umulhisi3.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_umulhisi3.o) + .text.libgcc.div + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_umulhisi3.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_umulhisi3.o) + .text.libgcc.prologue + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_umulhisi3.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_umulhisi3.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_umulhisi3.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncat_P.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncat_P.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + .text.avr-libc + 0x00000000 0x1a c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + .text.avr-libc + 0x00000000 0xe c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + .text.avr-libc + 0x00000000 0x20 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + .text.avr-libc + 0x00000000 0x16 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) + .text.libgcc.mul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) + .text.libgcc.prologue + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_prologue.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_prologue.o) + .text.libgcc.mul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_prologue.o) + .text.libgcc.div + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_prologue.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_prologue.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_prologue.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_prologue.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_epilogue.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_epilogue.o) + .text.libgcc.mul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_epilogue.o) + .text.libgcc.div + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_epilogue.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_epilogue.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_epilogue.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_epilogue.o) + .text 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_udivmodsi4.o) + .bss 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_udivmodsi4.o) + .text.libgcc.mul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_udivmodsi4.o) + .text.libgcc 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_udivmodsi4.o) + .text.libgcc.prologue + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_udivmodsi4.o) + .text.libgcc.builtins + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_udivmodsi4.o) + .text.libgcc.fmul + 0x00000000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_udivmodsi4.o) + +Memory Configuration + +Name Origin Length Attributes +text 0x00000000 0x00100000 xr +data 0x00802000 0x0000ffa0 rw !x +eeprom 0x00810000 0x00010000 rw !x +fuse 0x00820000 0x00000400 rw !x +lock 0x00830000 0x00000400 rw !x +signature 0x00840000 0x00000400 rw !x +user_signatures 0x00850000 0x00000400 rw !x +*default* 0x00000000 0xffffffff + +Linker script and memory map + +LOAD c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +LOAD Bin/Chameleon-Mini.o +LOAD Bin/LUFADescriptors.o +LOAD Bin/System.o +LOAD Bin/Configuration.o +LOAD Bin/Random.o +LOAD Bin/Common.o +LOAD Bin/Memory.o +LOAD Bin/Button.o +LOAD Bin/Log.o +LOAD Bin/Settings.o +LOAD Bin/LED.o +LOAD Bin/Terminal.o +LOAD Bin/Commands.o +LOAD Bin/XModem.o +LOAD Bin/CommandLine.o +LOAD Bin/Codec.o +LOAD Bin/ISO14443-2A.o +LOAD Bin/MifareUltralight.o +LOAD Bin/MifareClassic.o +LOAD Bin/ISO14443-3A.o +LOAD Bin/Crypto1.o +LOAD Bin/HIDParser.o +LOAD Bin/ConfigDescriptors.o +LOAD Bin/DeviceStandardReq.o +LOAD Bin/Events.o +LOAD Bin/HostStandardReq.o +LOAD Bin/USBTask.o +LOAD Bin/Device_XMEGA.o +LOAD Bin/EndpointStream_XMEGA.o +LOAD Bin/Endpoint_XMEGA.o +LOAD Bin/Host_XMEGA.o +LOAD Bin/PipeStream_XMEGA.o +LOAD Bin/Pipe_XMEGA.o +LOAD Bin/USBController_XMEGA.o +LOAD Bin/USBInterrupt_XMEGA.o +LOAD Bin/AudioClassDevice.o +LOAD Bin/CDCClassDevice.o +LOAD Bin/HIDClassDevice.o +LOAD Bin/MassStorageClassDevice.o +LOAD Bin/MIDIClassDevice.o +LOAD Bin/PrinterClassDevice.o +LOAD Bin/RNDISClassDevice.o +LOAD Bin/AndroidAccessoryClassHost.o +LOAD Bin/AudioClassHost.o +LOAD Bin/CDCClassHost.o +LOAD Bin/HIDClassHost.o +LOAD Bin/MassStorageClassHost.o +LOAD Bin/MIDIClassHost.o +LOAD Bin/PrinterClassHost.o +LOAD Bin/RNDISClassHost.o +LOAD Bin/StillImageClassHost.o +LOAD c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libm.a +LOAD c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a +LOAD c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a +LOAD c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a + +.hash + *(.hash) + +.dynsym + *(.dynsym) + +.dynstr + *(.dynstr) + +.gnu.version + *(.gnu.version) + +.gnu.version_d + *(.gnu.version_d) + +.gnu.version_r + *(.gnu.version_r) + +.rel.init + *(.rel.init) + +.rela.init + *(.rela.init) + +.rel.text + *(.rel.text) + *(.rel.text.*) + *(.rel.gnu.linkonce.t*) + +.rela.text + *(.rela.text) + *(.rela.text.*) + *(.rela.gnu.linkonce.t*) + +.rel.fini + *(.rel.fini) + +.rela.fini + *(.rela.fini) + +.rel.rodata + *(.rel.rodata) + *(.rel.rodata.*) + *(.rel.gnu.linkonce.r*) + +.rela.rodata + *(.rela.rodata) + *(.rela.rodata.*) + *(.rela.gnu.linkonce.r*) + +.rel.data + *(.rel.data) + *(.rel.data.*) + *(.rel.gnu.linkonce.d*) + +.rela.data + *(.rela.data) + *(.rela.data.*) + *(.rela.gnu.linkonce.d*) + +.rel.ctors + *(.rel.ctors) + +.rela.ctors + *(.rela.ctors) + +.rel.dtors + *(.rel.dtors) + +.rela.dtors + *(.rela.dtors) + +.rel.got + *(.rel.got) + +.rela.got + *(.rela.got) + +.rel.bss + *(.rel.bss) + +.rela.bss + *(.rela.bss) + +.rel.plt + *(.rel.plt) + +.rela.plt + *(.rela.plt) + +.text 0x00000000 0x628e + *(.vectors) + .vectors 0x00000000 0x1fc c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + 0x00000000 __vectors + *(.vectors) + *(.progmem.gcc*) + *(.progmem*) + .progmem.data 0x000001fc 0x8c Bin/LUFADescriptors.o + 0x000001fc ProductString + 0x0000021a ManufacturerString + 0x00000234 LanguageString + 0x00000238 ConfigurationDescriptor + 0x00000276 DeviceDescriptor + .progmem.data 0x00000288 0xde Bin/Configuration.o + .progmem.data 0x00000366 0x120 Bin/Button.o + .progmem.data 0x00000486 0x32 Bin/Log.o + .progmem.data 0x000004b8 0x100 Bin/LED.o + .progmem.data 0x000005b8 0x89 Bin/Commands.o + .progmem.data 0x00000641 0x29a Bin/CommandLine.o + 0x00000641 CommandTable + 0x000008dc . = ALIGN (0x2) + *fill* 0x000008db 0x1 + 0x000008dc __trampolines_start = . + *(.trampolines) + .trampolines 0x000008dc 0x0 linker stubs + *(.trampolines*) + 0x000008dc __trampolines_end = . + *(.jumptables) + *(.jumptables*) + *(.lowtext) + *(.lowtext*) + 0x000008dc __ctors_start = . + *(.ctors) + 0x000008dc __ctors_end = . + 0x000008dc __dtors_start = . + *(.dtors) + 0x000008dc __dtors_end = . + SORT(*)(.ctors) + SORT(*)(.dtors) + *(.init0) + .init0 0x000008dc 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + 0x000008dc __init + *(.init0) + *(.init1) + *(.init1) + *(.init2) + .init2 0x000008dc 0xc c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + *(.init2) + *(.init3) + *(.init3) + *(.init4) + .init4 0x000008e8 0x16 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) + 0x000008e8 __do_copy_data + .init4 0x000008fe 0x10 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) + 0x000008fe __do_clear_bss + *(.init4) + *(.init5) + *(.init5) + *(.init6) + *(.init6) + *(.init7) + *(.init7) + *(.init8) + *(.init8) + *(.init9) + .init9 0x0000090e 0x6 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + *(.init9) + *(.text) + .text 0x00000914 0x2 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + 0x00000914 __vector_38 + 0x00000914 __vector_104 + 0x00000914 __vector_63 + 0x00000914 __vector_28 + 0x00000914 __vector_67 + 0x00000914 __vector_1 + 0x00000914 __vector_119 + 0x00000914 __vector_32 + 0x00000914 __vector_75 + 0x00000914 __vector_71 + 0x00000914 __vector_91 + 0x00000914 __vector_62 + 0x00000914 __vector_77 + 0x00000914 __vector_102 + 0x00000914 __vector_24 + 0x00000914 __vector_12 + 0x00000914 __vector_55 + 0x00000914 __vector_69 + 0x00000914 __vector_81 + 0x00000914 __vector_90 + 0x00000914 __vector_46 + 0x00000914 __bad_interrupt + 0x00000914 __vector_122 + 0x00000914 __vector_72 + 0x00000914 __vector_114 + 0x00000914 __vector_6 + 0x00000914 __vector_110 + 0x00000914 __vector_31 + 0x00000914 __vector_92 + 0x00000914 __vector_35 + 0x00000914 __vector_78 + 0x00000914 __vector_74 + 0x00000914 __vector_117 + 0x00000914 __vector_39 + 0x00000914 __vector_107 + 0x00000914 __vector_3 + 0x00000914 __vector_105 + 0x00000914 __vector_98 + 0x00000914 __vector_23 + 0x00000914 __vector_68 + 0x00000914 __vector_30 + 0x00000914 __vector_73 + 0x00000914 __vector_45 + 0x00000914 __vector_25 + 0x00000914 __vector_93 + 0x00000914 __vector_61 + 0x00000914 __vector_11 + 0x00000914 __vector_54 + 0x00000914 __vector_99 + 0x00000914 __vector_13 + 0x00000914 __vector_17 + 0x00000914 __vector_19 + 0x00000914 __vector_56 + 0x00000914 __vector_7 + 0x00000914 __vector_49 + 0x00000914 __vector_123 + 0x00000914 __vector_41 + 0x00000914 __vector_86 + 0x00000914 __vector_100 + 0x00000914 __vector_101 + 0x00000914 __vector_64 + 0x00000914 __vector_88 + 0x00000914 __vector_109 + 0x00000914 __vector_43 + 0x00000914 __vector_27 + 0x00000914 __vector_5 + 0x00000914 __vector_113 + 0x00000914 __vector_33 + 0x00000914 __vector_76 + 0x00000914 __vector_115 + 0x00000914 __vector_47 + 0x00000914 __vector_52 + 0x00000914 __vector_37 + 0x00000914 __vector_95 + 0x00000914 __vector_103 + 0x00000914 __vector_96 + 0x00000914 __vector_89 + 0x00000914 __vector_108 + 0x00000914 __vector_4 + 0x00000914 __vector_44 + 0x00000914 __vector_82 + 0x00000914 __vector_106 + 0x00000914 __vector_118 + 0x00000914 __vector_51 + 0x00000914 __vector_9 + 0x00000914 __vector_2 + 0x00000914 __vector_21 + 0x00000914 __vector_15 + 0x00000914 __vector_66 + 0x00000914 __vector_36 + 0x00000914 __vector_79 + 0x00000914 __vector_58 + 0x00000914 __vector_70 + 0x00000914 __vector_29 + 0x00000914 __vector_60 + 0x00000914 __vector_121 + 0x00000914 __vector_40 + 0x00000914 __vector_85 + 0x00000914 __vector_94 + 0x00000914 __vector_126 + 0x00000914 __vector_8 + 0x00000914 __vector_26 + 0x00000914 __vector_48 + 0x00000914 __vector_124 + 0x00000914 __vector_116 + 0x00000914 __vector_112 + 0x00000914 __vector_111 + 0x00000914 __vector_80 + 0x00000914 __vector_14 + 0x00000914 __vector_84 + 0x00000914 __vector_57 + 0x00000914 __vector_53 + 0x00000914 __vector_50 + 0x00000914 __vector_16 + 0x00000914 __vector_59 + 0x00000914 __vector_18 + 0x00000914 __vector_97 + 0x00000914 __vector_20 + 0x00000914 __vector_42 + 0x00000914 __vector_87 + 0x00000914 __vector_65 + 0x00000914 __vector_120 + 0x00000916 . = ALIGN (0x2) + *(.text.*) + .text.startup.main + 0x00000916 0x8c Bin/Chameleon-Mini.o + 0x00000916 main + .text.CALLBACK_USB_GetDescriptor + 0x000009a2 0x82 Bin/LUFADescriptors.o + 0x000009a2 CALLBACK_USB_GetDescriptor + .text.__vector_default + 0x00000a24 0xc Bin/System.o + 0x00000a24 __vector_default + .text.__vector_10 + 0x00000a30 0x2 Bin/System.o + 0x00000a30 __vector_10 + .text.SystemInit + 0x00000a32 0x86 Bin/System.o + 0x00000a32 SystemInit + .text.SystemReset + 0x00000ab8 0xe Bin/System.o + 0x00000ab8 SystemReset + .text.SystemEnterBootloader + 0x00000ac6 0xc Bin/System.o + 0x00000ac6 SystemEnterBootloader + .text.SystemStartUSBClock + 0x00000ad2 0x3c Bin/System.o + 0x00000ad2 SystemStartUSBClock + .text.SystemStopUSBClock + 0x00000b0e 0x26 Bin/System.o + 0x00000b0e SystemStopUSBClock + .text.SystemInterruptInit + 0x00000b34 0xc Bin/System.o + 0x00000b34 SystemInterruptInit + .text.CodecInitDummy + 0x00000b40 0x2 Bin/Configuration.o + .text.CodecTaskDummy + 0x00000b42 0x2 Bin/Configuration.o + .text.ApplicationInitDummy + 0x00000b44 0x2 Bin/Configuration.o + .text.ApplicationResetDummy + 0x00000b46 0x2 Bin/Configuration.o + .text.ApplicationTaskDummy + 0x00000b48 0x2 Bin/Configuration.o + .text.ApplicationProcessDummy + 0x00000b4a 0x6 Bin/Configuration.o + .text.ApplicationGetUidDummy + 0x00000b50 0x2 Bin/Configuration.o + .text.ApplicationSetUidDummy + 0x00000b52 0x2 Bin/Configuration.o + .text.ConfigurationSetById + 0x00000b54 0x36 Bin/Configuration.o + 0x00000b54 ConfigurationSetById + .text.ConfigurationInit + 0x00000b8a 0xc Bin/Configuration.o + 0x00000b8a ConfigurationInit + .text.ConfigurationSetByName + 0x00000b96 0x82 Bin/Configuration.o + 0x00000b96 ConfigurationSetByName + .text.ConfigurationGetList + 0x00000c18 0x5e Bin/Configuration.o + 0x00000c18 ConfigurationGetList + .text.RandomInit + 0x00000c76 0x2 Bin/Random.o + 0x00000c76 RandomInit + .text.RandomGetByte + 0x00000c78 0x6 Bin/Random.o + 0x00000c78 RandomGetByte + .text.RandomGetBuffer + 0x00000c7e 0x1e Bin/Random.o + 0x00000c7e RandomGetBuffer + .text.RandomTick + 0x00000c9c 0x10 Bin/Random.o + 0x00000c9c RandomTick + .text.BufferToHexString + 0x00000cac 0x84 Bin/Common.o + 0x00000cac BufferToHexString + .text.HexStringToBuffer + 0x00000d30 0x8c Bin/Common.o + 0x00000d30 HexStringToBuffer + .text.MemoryReadBlock + 0x00000dbc 0x30 Bin/Memory.o + 0x00000dbc MemoryReadBlock + .text.MemoryWriteBlock + 0x00000dec 0x38 Bin/Memory.o + 0x00000dec MemoryWriteBlock + .text.MemoryClear + 0x00000e24 0x10 Bin/Memory.o + 0x00000e24 MemoryClear + .text.MemoryRecall + 0x00000e34 0xec Bin/Memory.o + 0x00000e34 MemoryRecall + .text.MemoryInit + 0x00000f20 0xfe Bin/Memory.o + 0x00000f20 MemoryInit + .text.MemoryStore + 0x0000101e 0x28e Bin/Memory.o + 0x0000101e MemoryStore + .text.MemoryUploadBlock + 0x000012ac 0x38a Bin/Memory.o + 0x000012ac MemoryUploadBlock + .text.MemoryDownloadBlock + 0x00001636 0x7a Bin/Memory.o + 0x00001636 MemoryDownloadBlock + .text.ExecuteButtonAction + 0x000016b0 0x1aa Bin/Button.o + .text.ButtonInit + 0x0000185a 0xe Bin/Button.o + 0x0000185a ButtonInit + .text.ButtonTick + 0x00001868 0x4a Bin/Button.o + 0x00001868 ButtonTick + .text.ButtonGetActionList + 0x000018b2 0x64 Bin/Button.o + 0x000018b2 ButtonGetActionList + .text.ButtonSetActionById + 0x00001916 0x4e Bin/Button.o + 0x00001916 ButtonSetActionById + .text.ButtonGetActionByName + 0x00001964 0x38 Bin/Button.o + 0x00001964 ButtonGetActionByName + .text.ButtonSetActionByName + 0x0000199c 0xc4 Bin/Button.o + 0x0000199c ButtonSetActionByName + .text.LogFuncOff + 0x00001a60 0x2 Bin/Log.o + .text.LogFuncTerminal + 0x00001a62 0x2c Bin/Log.o + .text.LogTick 0x00001a8e 0x2 Bin/Log.o + 0x00001a8e LogTick + .text.LogTask 0x00001a90 0x2 Bin/Log.o + 0x00001a90 LogTask + .text.LogMemLoadBlock + 0x00001a92 0x30 Bin/Log.o + 0x00001a92 LogMemLoadBlock + .text.LogMemClear + 0x00001ac2 0x2a Bin/Log.o + 0x00001ac2 LogMemClear + .text.LogMemFree + 0x00001aec 0xa Bin/Log.o + 0x00001aec LogMemFree + .text.LogSetModeById + 0x00001af6 0x40 Bin/Log.o + 0x00001af6 LogSetModeById + .text.LogFuncMemory + 0x00001b36 0x6e Bin/Log.o + .text.LogInit 0x00001ba4 0xe Bin/Log.o + 0x00001ba4 LogInit + .text.LogSetModeByName + 0x00001bb2 0x4a Bin/Log.o + 0x00001bb2 LogSetModeByName + .text.LogGetModeByName + 0x00001bfc 0x1c Bin/Log.o + 0x00001bfc LogGetModeByName + .text.LogGetModeList + 0x00001c18 0x50 Bin/Log.o + 0x00001c18 LogGetModeList + .text.SettingsLoad + 0x00001c68 0x10 Bin/Settings.o + 0x00001c68 SettingsLoad + .text.SettingsSave + 0x00001c78 0x10 Bin/Settings.o + 0x00001c78 SettingsSave + .text.SettingsSetActiveById + 0x00001c88 0x64 Bin/Settings.o + 0x00001c88 SettingsSetActiveById + .text.SettingsCycle + 0x00001cec 0x120 Bin/Settings.o + 0x00001cec SettingsCycle + .text.SettingsGetActiveById + 0x00001e0c 0x8 Bin/Settings.o + 0x00001e0c SettingsGetActiveById + .text.SettingsGetActiveByName + 0x00001e14 0x14 Bin/Settings.o + 0x00001e14 SettingsGetActiveByName + .text.SettingsSetActiveByName + 0x00001e28 0x12 Bin/Settings.o + 0x00001e28 SettingsSetActiveByName + .text.LEDInit 0x00001e3a 0xa Bin/LED.o + 0x00001e3a LEDInit + .text.LEDTick 0x00001e44 0x11a Bin/LED.o + 0x00001e44 LEDTick + .text.LEDTrigger + 0x00001f5e 0x20 Bin/LED.o + 0x00001f5e LEDTrigger + .text.LEDGetFuncList + 0x00001f7e 0x64 Bin/LED.o + 0x00001f7e LEDGetFuncList + .text.LEDSetFuncById + 0x00001fe2 0xac Bin/LED.o + 0x00001fe2 LEDSetFuncById + .text.LEDGetFuncByName + 0x0000208e 0x3a Bin/LED.o + 0x0000208e LEDGetFuncByName + .text.LEDSetFuncByName + 0x000020c8 0xb0 Bin/LED.o + 0x000020c8 LEDSetFuncByName + .text.TerminalSendString + 0x00002178 0xa Bin/Terminal.o + 0x00002178 TerminalSendString + .text.TerminalSendStringP + 0x00002182 0x28 Bin/Terminal.o + 0x00002182 TerminalSendStringP + .text.TerminalSendBlock + 0x000021aa 0xc Bin/Terminal.o + 0x000021aa TerminalSendBlock + .text.TerminalInit + 0x000021b6 0xa Bin/Terminal.o + 0x000021b6 TerminalInit + .text.TerminalTask + 0x000021c0 0x42 Bin/Terminal.o + 0x000021c0 TerminalTask + .text.TerminalTick + 0x00002202 0x80 Bin/Terminal.o + 0x00002202 TerminalTick + .text.EVENT_USB_Device_Connect + 0x00002282 0x6 Bin/Terminal.o + 0x00002282 EVENT_USB_Device_Connect + .text.EVENT_USB_Device_Disconnect + 0x00002288 0x6 Bin/Terminal.o + 0x00002288 EVENT_USB_Device_Disconnect + .text.EVENT_USB_Device_ConfigurationChanged + 0x0000228e 0x8 Bin/Terminal.o + 0x0000228e EVENT_USB_Device_ConfigurationChanged + .text.EVENT_USB_Device_ControlRequest + 0x00002296 0x8 Bin/Terminal.o + 0x00002296 EVENT_USB_Device_ControlRequest + .text.CommandGetVersion + 0x0000229e 0x3c Bin/Commands.o + 0x0000229e CommandGetVersion + .text.CommandGetConfig + 0x000022da 0x2c Bin/Commands.o + 0x000022da CommandGetConfig + .text.CommandSetConfig + 0x00002306 0x12 Bin/Commands.o + 0x00002306 CommandSetConfig + .text.CommandExecConfig + 0x00002318 0xc Bin/Commands.o + 0x00002318 CommandExecConfig + .text.CommandGetUid + 0x00002324 0x4e Bin/Commands.o + 0x00002324 CommandGetUid + .text.CommandSetUid + 0x00002372 0xb2 Bin/Commands.o + 0x00002372 CommandSetUid + .text.CommandGetReadOnly + 0x00002424 0x24 Bin/Commands.o + 0x00002424 CommandGetReadOnly + .text.CommandSetReadOnly + 0x00002448 0x28 Bin/Commands.o + 0x00002448 CommandSetReadOnly + .text.CommandExecUpload + 0x00002470 0xa Bin/Commands.o + 0x00002470 CommandExecUpload + .text.CommandExecDownload + 0x0000247a 0xa Bin/Commands.o + 0x0000247a CommandExecDownload + .text.CommandExecReset + 0x00002484 0x16 Bin/Commands.o + 0x00002484 CommandExecReset + .text.CommandExecUpgrade + 0x0000249a 0x16 Bin/Commands.o + 0x0000249a CommandExecUpgrade + .text.CommandGetMemSize + 0x000024b0 0x30 Bin/Commands.o + 0x000024b0 CommandGetMemSize + .text.CommandGetUidSize + 0x000024e0 0x2c Bin/Commands.o + 0x000024e0 CommandGetUidSize + .text.CommandExecButton + 0x0000250c 0xa Bin/Commands.o + 0x0000250c CommandExecButton + .text.CommandGetButton + 0x00002516 0xe Bin/Commands.o + 0x00002516 CommandGetButton + .text.CommandSetButton + 0x00002524 0x14 Bin/Commands.o + 0x00002524 CommandSetButton + .text.CommandExecButtonLong + 0x00002538 0xa Bin/Commands.o + 0x00002538 CommandExecButtonLong + .text.CommandGetButtonLong + 0x00002542 0xe Bin/Commands.o + 0x00002542 CommandGetButtonLong + .text.CommandSetButtonLong + 0x00002550 0x14 Bin/Commands.o + 0x00002550 CommandSetButtonLong + .text.CommandExecLedGreen + 0x00002564 0xa Bin/Commands.o + 0x00002564 CommandExecLedGreen + .text.CommandGetLedGreen + 0x0000256e 0xe Bin/Commands.o + 0x0000256e CommandGetLedGreen + .text.CommandSetLedGreen + 0x0000257c 0x14 Bin/Commands.o + 0x0000257c CommandSetLedGreen + .text.CommandExecLedRed + 0x00002590 0xa Bin/Commands.o + 0x00002590 CommandExecLedRed + .text.CommandGetLedRed + 0x0000259a 0xe Bin/Commands.o + 0x0000259a CommandGetLedRed + .text.CommandSetLedRed + 0x000025a8 0x14 Bin/Commands.o + 0x000025a8 CommandSetLedRed + .text.CommandExecLogMode + 0x000025bc 0xa Bin/Commands.o + 0x000025bc CommandExecLogMode + .text.CommandGetLogMode + 0x000025c6 0xa Bin/Commands.o + 0x000025c6 CommandGetLogMode + .text.CommandSetLogMode + 0x000025d0 0x10 Bin/Commands.o + 0x000025d0 CommandSetLogMode + .text.CommandExecLogMem + 0x000025e0 0x34 Bin/Commands.o + 0x000025e0 CommandExecLogMem + .text.CommandGetLogMem + 0x00002614 0x34 Bin/Commands.o + 0x00002614 CommandGetLogMem + .text.CommandSetLogMem + 0x00002648 0x40 Bin/Commands.o + 0x00002648 CommandSetLogMem + .text.CommandGetSetting + 0x00002688 0xa Bin/Commands.o + 0x00002688 CommandGetSetting + .text.CommandSetSetting + 0x00002692 0x10 Bin/Commands.o + 0x00002692 CommandSetSetting + .text.CommandExecClear + 0x000026a2 0x8 Bin/Commands.o + 0x000026a2 CommandExecClear + .text.CommandExecHelp + 0x000026aa 0x98 Bin/Commands.o + 0x000026aa CommandExecHelp + .text.CommandGetRssi + 0x00002742 0x68 Bin/Commands.o + 0x00002742 CommandGetRssi + .text.CalcChecksum.constprop.0 + 0x000027aa 0x14 Bin/XModem.o + .text.XModemReceive + 0x000027be 0x36 Bin/XModem.o + 0x000027be XModemReceive + .text.XModemSend + 0x000027f4 0x2c Bin/XModem.o + 0x000027f4 XModemSend + .text.XModemProcessByte + 0x00002820 0x296 Bin/XModem.o + 0x00002820 XModemProcessByte + .text.XModemTick + 0x00002ab6 0x76 Bin/XModem.o + 0x00002ab6 XModemTick + .text.CommandLineProcessByte + 0x00002b2c 0x20e Bin/CommandLine.o + 0x00002b2c CommandLineProcessByte + .text.CommandLineTick + 0x00002d3a 0x2 Bin/CommandLine.o + 0x00002d3a CommandLineTick + .text.StartDemod + 0x00002d3c 0x7a Bin/ISO14443-2A.o + .text.__vector_34 + 0x00002db6 0x62 Bin/ISO14443-2A.o + 0x00002db6 __vector_34 + .text.__vector_22 + 0x00002e18 0x148 Bin/ISO14443-2A.o + 0x00002e18 __vector_22 + .text.__vector_83 + 0x00002f60 0x1e2 Bin/ISO14443-2A.o + 0x00002f60 __vector_83 + .text.ISO14443ACodecInit + 0x00003142 0x6e Bin/ISO14443-2A.o + 0x00003142 ISO14443ACodecInit + .text.ISO14443ACodecTask + 0x000031b0 0x162 Bin/ISO14443-2A.o + 0x000031b0 ISO14443ACodecTask + .text.MifareUltralightAppInit + 0x00003312 0x8 Bin/MifareUltralight.o + 0x00003312 MifareUltralightAppInit + .text.MifareUltralightAppReset + 0x0000331a 0x8 Bin/MifareUltralight.o + 0x0000331a MifareUltralightAppReset + .text.MifareUltralightAppTask + 0x00003322 0x2 Bin/MifareUltralight.o + 0x00003322 MifareUltralightAppTask + .text.MifareUltralightAppProcess + 0x00003324 0x2a4 Bin/MifareUltralight.o + 0x00003324 MifareUltralightAppProcess + .text.MifareUltralightGetUid + 0x000035c8 0x26 Bin/MifareUltralight.o + 0x000035c8 MifareUltralightGetUid + .text.MifareUltralightSetUid + 0x000035ee 0x7e Bin/MifareUltralight.o + 0x000035ee MifareUltralightSetUid + .text.MifareClassicAppInit1K + 0x0000366c 0x1e Bin/MifareClassic.o + 0x0000366c MifareClassicAppInit1K + .text.MifarePlus1kAppInit_7B + 0x0000368a 0x2a Bin/MifareClassic.o + 0x0000368a MifarePlus1kAppInit_7B + .text.MifareClassicAppInit4K + 0x000036b4 0x1e Bin/MifareClassic.o + 0x000036b4 MifareClassicAppInit4K + .text.MifareClassicAppReset + 0x000036d2 0x8 Bin/MifareClassic.o + 0x000036d2 MifareClassicAppReset + .text.MifareClassicAppTask + 0x000036da 0x2 Bin/MifareClassic.o + 0x000036da MifareClassicAppTask + .text.MifareClassicAppProcess + 0x000036dc 0xb88 Bin/MifareClassic.o + 0x000036dc MifareClassicAppProcess + .text.MifareClassicGetUid + 0x00004264 0x42 Bin/MifareClassic.o + 0x00004264 MifareClassicGetUid + .text.MifareClassicSetUid + 0x000042a6 0x5e Bin/MifareClassic.o + 0x000042a6 MifareClassicSetUid + .text.ISO14443AAppendCRCA + 0x00004304 0x5e Bin/ISO14443-3A.o + 0x00004304 ISO14443AAppendCRCA + .text.ISO14443ACheckCRCA + 0x00004362 0x7e Bin/ISO14443-3A.o + 0x00004362 ISO14443ACheckCRCA + .text.Crypto1LFSR + 0x000043e0 0x8c Bin/Crypto1.o + .text.Crypto1FilterOutput + 0x0000446c 0x68 Bin/Crypto1.o + 0x0000446c Crypto1FilterOutput + .text.Crypto1Setup + 0x000044d4 0x340 Bin/Crypto1.o + 0x000044d4 Crypto1Setup + .text.Crypto1Auth + 0x00004814 0x52 Bin/Crypto1.o + 0x00004814 Crypto1Auth + .text.Crypto1Byte + 0x00004866 0x82 Bin/Crypto1.o + 0x00004866 Crypto1Byte + .text.Crypto1Nibble + 0x000048e8 0x48 Bin/Crypto1.o + 0x000048e8 Crypto1Nibble + .text.Crypto1PRNG + 0x00004930 0xb6 Bin/Crypto1.o + 0x00004930 Crypto1PRNG + .text.USB_Device_ProcessControlRequest + 0x000049e6 0x296 Bin/DeviceStandardReq.o + 0x000049e6 USB_Device_ProcessControlRequest + .text.USB_Event_Stub + 0x00004c7c 0x2 Bin/Events.o + 0x00004c7c USB_Event_Stub + 0x00004c7c EVENT_USB_Device_Suspend + 0x00004c7c EVENT_USB_Device_StartOfFrame + 0x00004c7c EVENT_USB_Device_Reset + 0x00004c7c EVENT_USB_Device_WakeUp + .text.USB_USBTask + 0x00004c7e 0x2a Bin/USBTask.o + 0x00004c7e USB_USBTask + .text.Endpoint_Write_Stream_LE + 0x00004ca8 0xd8 Bin/EndpointStream_XMEGA.o + 0x00004ca8 Endpoint_Write_Stream_LE + .text.Endpoint_Write_Control_Stream_LE + 0x00004d80 0x142 Bin/EndpointStream_XMEGA.o + 0x00004d80 Endpoint_Write_Control_Stream_LE + .text.Endpoint_Write_Control_PStream_LE + 0x00004ec2 0x13e Bin/EndpointStream_XMEGA.o + 0x00004ec2 Endpoint_Write_Control_PStream_LE + .text.Endpoint_ClearIN + 0x00005000 0x32 Bin/Endpoint_XMEGA.o + 0x00005000 Endpoint_ClearIN + .text.Endpoint_ClearOUT + 0x00005032 0x1e Bin/Endpoint_XMEGA.o + 0x00005032 Endpoint_ClearOUT + .text.Endpoint_Read_8 + 0x00005050 0x1e Bin/Endpoint_XMEGA.o + 0x00005050 Endpoint_Read_8 + .text.Endpoint_Write_8 + 0x0000506e 0x1e Bin/Endpoint_XMEGA.o + 0x0000506e Endpoint_Write_8 + .text.Endpoint_SelectEndpoint + 0x0000508c 0x72 Bin/Endpoint_XMEGA.o + 0x0000508c Endpoint_SelectEndpoint + .text.Endpoint_StallTransaction + 0x000050fe 0x38 Bin/Endpoint_XMEGA.o + 0x000050fe Endpoint_StallTransaction + .text.Endpoint_ClearSETUP + 0x00005136 0x58 Bin/Endpoint_XMEGA.o + 0x00005136 Endpoint_ClearSETUP + .text.Endpoint_IsSETUPReceived + 0x0000518e 0x32 Bin/Endpoint_XMEGA.o + 0x0000518e Endpoint_IsSETUPReceived + .text.Endpoint_IsOUTReceived + 0x000051c0 0x32 Bin/Endpoint_XMEGA.o + 0x000051c0 Endpoint_IsOUTReceived + .text.Endpoint_IsINReady + 0x000051f2 0x18 Bin/Endpoint_XMEGA.o + 0x000051f2 Endpoint_IsINReady + .text.Endpoint_ConfigureEndpoint_PRV + 0x0000520a 0x9a Bin/Endpoint_XMEGA.o + 0x0000520a Endpoint_ConfigureEndpoint_PRV + .text.Endpoint_ConfigureEndpointTable + 0x000052a4 0xec Bin/Endpoint_XMEGA.o + 0x000052a4 Endpoint_ConfigureEndpointTable + .text.Endpoint_ClearEndpoints + 0x00005390 0x70 Bin/Endpoint_XMEGA.o + 0x00005390 Endpoint_ClearEndpoints + .text.Endpoint_ClearStatusStage + 0x00005400 0x2c Bin/Endpoint_XMEGA.o + 0x00005400 Endpoint_ClearStatusStage + .text.Endpoint_WaitUntilReady + 0x0000542c 0xa6 Bin/Endpoint_XMEGA.o + 0x0000542c Endpoint_WaitUntilReady + .text.USB_Disable + 0x000054d2 0x1a Bin/USBController_XMEGA.o + 0x000054d2 USB_Disable + .text.USB_ResetInterface + 0x000054ec 0x5c Bin/USBController_XMEGA.o + 0x000054ec USB_ResetInterface + .text.USB_Init + 0x00005548 0x52 Bin/USBController_XMEGA.o + 0x00005548 USB_Init + .text.USB_INT_DisableAllInterrupts + 0x0000559a 0xe Bin/USBInterrupt_XMEGA.o + 0x0000559a USB_INT_DisableAllInterrupts + .text.USB_INT_ClearAllInterrupts + 0x000055a8 0xc Bin/USBInterrupt_XMEGA.o + 0x000055a8 USB_INT_ClearAllInterrupts + .text.__vector_125 + 0x000055b4 0xda Bin/USBInterrupt_XMEGA.o + 0x000055b4 __vector_125 + .text.CDC_Device_ConfigureEndpoints + 0x0000568e 0x4a Bin/CDCClassDevice.o + 0x0000568e CDC_Device_ConfigureEndpoints + .text.CDC_Device_SendString + 0x000056d8 0x52 Bin/CDCClassDevice.o + 0x000056d8 CDC_Device_SendString + .text.CDC_Device_SendData + 0x0000572a 0x54 Bin/CDCClassDevice.o + 0x0000572a CDC_Device_SendData + .text.CDC_Device_SendByte + 0x0000577e 0x6e Bin/CDCClassDevice.o + 0x0000577e CDC_Device_SendByte + .text.CDC_Device_Flush + 0x000057ec 0x90 Bin/CDCClassDevice.o + 0x000057ec CDC_Device_Flush + .text.CDC_Device_USBTask + 0x0000587c 0x36 Bin/CDCClassDevice.o + 0x0000587c CDC_Device_USBTask + .text.CDC_Device_ReceiveByte + 0x000058b2 0xbe Bin/CDCClassDevice.o + 0x000058b2 CDC_Device_ReceiveByte + .text.CDC_Device_Event_Stub + 0x00005970 0x2 Bin/CDCClassDevice.o + 0x00005970 EVENT_CDC_Device_ControLineStateChanged + 0x00005970 EVENT_CDC_Device_BreakSent + 0x00005970 CDC_Device_Event_Stub + 0x00005970 EVENT_CDC_Device_LineEncodingChanged + .text.CDC_Device_ProcessControlRequest + 0x00005972 0x13a Bin/CDCClassDevice.o + 0x00005972 CDC_Device_ProcessControlRequest + .text.libgcc.mul + 0x00005aac 0xc c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) + 0x00005aac __mulshisi3 + 0x00005ab0 __mulohisi3 + .text.libgcc.mul + 0x00005ab8 0x14 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) + 0x00005ab8 __muluhisi3 + .text.libgcc.mul + 0x00005acc 0x18 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_umulhisi3.o) + 0x00005acc __umulhisi3 + .text.avr-libc + 0x00005ae4 0xb4 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + 0x00005b7a rand_r + 0x00005b7c rand + 0x00005b82 srand + .text.avr-libc + 0x00005b98 0x12 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + 0x00005b98 memcpy_P + .text.avr-libc + 0x00005baa 0x12 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + 0x00005baa strcmp_P + .text.avr-libc + 0x00005bbc 0x20 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncat_P.o) + 0x00005bbc strncat_P + .text.avr-libc + 0x00005bdc 0x1e c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + 0x00005bdc strncpy_P + .text.avr-libc + 0x00005bfa 0x12 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + 0x00005bfa memcpy + .text.avr-libc + 0x00005c0c 0x5a c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + 0x00005c0c snprintf_P + .text.avr-libc + 0x00005c66 0x39a c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + 0x00005c66 vfprintf + .text.avr-libc + 0x00006000 0x16 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + 0x00006000 __eerd_block_x32a4u + .text.avr-libc + 0x00006016 0x12 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + 0x00006016 __eewr_block_x32a4u + .text.avr-libc + 0x00006028 0x46 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + 0x00006028 __eewr_byte_x32a4u + 0x0000602a __eewr_r18_x32a4u + .text.avr-libc + 0x0000606e 0x16 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + 0x0000606e strnlen_P + .text.avr-libc + 0x00006084 0x16 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + 0x00006084 strnlen + .text.avr-libc + 0x0000609a 0x58 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + 0x0000609a fputc + .text.avr-libc + 0x000060f2 0xbc c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + 0x000060f2 __ultoa_invert + .text.libgcc.div + 0x000061ae 0x36 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) + 0x000061ae __divmodsi4 + .text.libgcc.prologue + 0x000061e4 0x32 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_prologue.o) + 0x000061e4 __prologue_saves__ + .text.libgcc.prologue + 0x00006216 0x30 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_epilogue.o) + 0x00006216 __epilogue_restores__ + .text.libgcc.div + 0x00006246 0x44 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_udivmodsi4.o) + 0x00006246 __udivmodsi4 + 0x0000628a . = ALIGN (0x2) + *(.fini9) + .fini9 0x0000628a 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + 0x0000628a _exit + 0x0000628a exit + *(.fini9) + *(.fini8) + *(.fini8) + *(.fini7) + *(.fini7) + *(.fini6) + *(.fini6) + *(.fini5) + *(.fini5) + *(.fini4) + *(.fini4) + *(.fini3) + *(.fini3) + *(.fini2) + *(.fini2) + *(.fini1) + *(.fini1) + *(.fini0) + .fini0 0x0000628a 0x4 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + *(.fini0) + 0x0000628e _etext = . + +.data 0x00802000 0x92 load address 0x0000628e + 0x00802000 PROVIDE (__data_start, .) + *(.data) + .data 0x00802000 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + .data 0x00802000 0x0 Bin/Chameleon-Mini.o + .data 0x00802000 0x0 Bin/LUFADescriptors.o + .data 0x00802000 0x0 Bin/System.o + .data 0x00802000 0x0 Bin/Configuration.o + .data 0x00802000 0x0 Bin/Random.o + .data 0x00802000 0x0 Bin/Common.o + .data 0x00802000 0x0 Bin/Memory.o + .data 0x00802000 0x0 Bin/Button.o + .data 0x00802000 0x0 Bin/Log.o + .data 0x00802000 0x0 Bin/Settings.o + .data 0x00802000 0x0 Bin/LED.o + .data 0x00802000 0x1c Bin/Terminal.o + 0x00802000 TerminalHandle + .data 0x0080201c 0x0 Bin/Commands.o + .data 0x0080201c 0x0 Bin/XModem.o + .data 0x0080201c 0x0 Bin/CommandLine.o + .data 0x0080201c 0x0 Bin/Codec.o + .data 0x0080201c 0x0 Bin/ISO14443-2A.o + .data 0x0080201c 0x0 Bin/MifareUltralight.o + .data 0x0080201c 0x0 Bin/MifareClassic.o + .data 0x0080201c 0x0 Bin/ISO14443-3A.o + .data 0x0080201c 0x0 Bin/Crypto1.o + .data 0x0080201c 0x0 Bin/HIDParser.o + .data 0x0080201c 0x0 Bin/ConfigDescriptors.o + .data 0x0080201c 0x0 Bin/DeviceStandardReq.o + .data 0x0080201c 0x0 Bin/Events.o + .data 0x0080201c 0x0 Bin/HostStandardReq.o + .data 0x0080201c 0x0 Bin/USBTask.o + .data 0x0080201c 0x0 Bin/Device_XMEGA.o + .data 0x0080201c 0x0 Bin/EndpointStream_XMEGA.o + .data 0x0080201c 0x0 Bin/Endpoint_XMEGA.o + .data 0x0080201c 0x0 Bin/Host_XMEGA.o + .data 0x0080201c 0x0 Bin/PipeStream_XMEGA.o + .data 0x0080201c 0x0 Bin/Pipe_XMEGA.o + .data 0x0080201c 0x0 Bin/USBController_XMEGA.o + .data 0x0080201c 0x0 Bin/USBInterrupt_XMEGA.o + .data 0x0080201c 0x0 Bin/AudioClassDevice.o + .data 0x0080201c 0x0 Bin/CDCClassDevice.o + .data 0x0080201c 0x0 Bin/HIDClassDevice.o + .data 0x0080201c 0x0 Bin/MassStorageClassDevice.o + .data 0x0080201c 0x0 Bin/MIDIClassDevice.o + .data 0x0080201c 0x0 Bin/PrinterClassDevice.o + .data 0x0080201c 0x0 Bin/RNDISClassDevice.o + .data 0x0080201c 0x0 Bin/AndroidAccessoryClassHost.o + .data 0x0080201c 0x0 Bin/AudioClassHost.o + .data 0x0080201c 0x0 Bin/CDCClassHost.o + .data 0x0080201c 0x0 Bin/HIDClassHost.o + .data 0x0080201c 0x0 Bin/MassStorageClassHost.o + .data 0x0080201c 0x0 Bin/MIDIClassHost.o + .data 0x0080201c 0x0 Bin/PrinterClassHost.o + .data 0x0080201c 0x0 Bin/RNDISClassHost.o + .data 0x0080201c 0x0 Bin/StillImageClassHost.o + .data 0x0080201c 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + .data 0x0080201c 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_tablejump.o) + .data 0x0080201c 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) + .data 0x0080201c 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) + .data 0x0080201c 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) + .data 0x0080201c 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) + .data 0x0080201c 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_umulhisi3.o) + .data 0x0080201c 0x4 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncat_P.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_prologue.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_epilogue.o) + .data 0x00802020 0x0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_udivmodsi4.o) + *(.data*) + *(.rodata) + .rodata 0x00802020 0x70 Bin/Crypto1.o + *(.rodata*) + .rodata.str1.1 + 0x00802090 0x1 Bin/Commands.o + *(.gnu.linkonce.d*) + 0x00802092 . = ALIGN (0x2) + *fill* 0x00802091 0x1 + 0x00802092 _edata = . + 0x00802092 PROVIDE (__data_end, .) + +.bss 0x00802092 0xe37 + 0x00802092 PROVIDE (__bss_start, .) + *(.bss) + .bss 0x00802092 0x400 Bin/Memory.o + .bss 0x00802492 0x1 Bin/Button.o + .bss 0x00802493 0x404 Bin/Log.o + .bss 0x00802897 0x3 Bin/LED.o + 0x00802897 LEDRedAction + 0x00802898 LEDGreenAction + .bss 0x0080289a 0x1 Bin/Terminal.o + 0x0080289a TerminalState + .bss 0x0080289b 0xf Bin/XModem.o + .bss 0x008028aa 0x2 Bin/CommandLine.o + .bss 0x008028ac 0x10 Bin/ISO14443-2A.o + .bss 0x008028bc 0x2 Bin/MifareUltralight.o + .bss 0x008028be 0x1e Bin/MifareClassic.o + .bss 0x008028dc 0x6 Bin/Crypto1.o + *(.bss*) + *(COMMON) + COMMON 0x008028e2 0x25 Bin/Configuration.o + 0x008028e2 ActiveConfiguration + COMMON 0x00802907 0x2 Bin/Log.o + 0x00802907 LogFunc + COMMON 0x00802909 0x33 Bin/Settings.o + 0x00802909 GlobalSettings + COMMON 0x0080293c 0x100 Bin/Terminal.o + 0x0080293c TerminalBuffer + COMMON 0x00802a3c 0x100 Bin/Codec.o + 0x00802a3c CodecBuffer + COMMON 0x00802b3c 0x3 Bin/DeviceStandardReq.o + 0x00802b3c USB_Device_ConfigurationNumber + 0x00802b3d USB_Device_CurrentlySelfPowered + 0x00802b3e USB_Device_RemoteWakeupEnabled + COMMON 0x00802b3f 0xa Bin/USBTask.o + 0x00802b3f USB_IsInitialized + 0x00802b40 USB_DeviceState + 0x00802b41 USB_ControlRequest + COMMON 0x00802b49 0x31d Bin/Endpoint_XMEGA.o + 0x00802b49 USB_Endpoint_SelectedFIFO + 0x00802b4b USB_Endpoint_SelectedHandle + 0x00802b4d USB_Endpoint_SelectedEndpoint + 0x00802b4e USB_Endpoint_FIFOs + COMMON 0x00802e66 0x63 Bin/USBController_XMEGA.o + 0x00802e66 USB_EndpointTable + 0x00802ec9 PROVIDE (__bss_end, .) + 0x0000628e __data_load_start = LOADADDR (.data) + 0x00006320 __data_load_end = (__data_load_start + SIZEOF (.data)) + +.noinit 0x00802ec9 0x0 + 0x00802ec9 PROVIDE (__noinit_start, .) + *(.noinit*) + 0x00802ec9 PROVIDE (__noinit_end, .) + 0x00802ec9 _end = . + 0x00802ec9 PROVIDE (__heap_start, .) + +.eeprom 0x00810000 0x33 + *(.eeprom*) + .eeprom 0x00810000 0x33 Bin/Settings.o + 0x00810000 StoredSettings + 0x00810033 __eeprom_end = . + +.fuse + *(.fuse) + *(.lfuse) + *(.hfuse) + *(.efuse) + +.lock + *(.lock*) + +.signature + *(.signature*) + +.user_signatures + *(.user_signatures*) + +.stab 0x00000000 0x15a8 + *(.stab) + .stab 0x00000000 0x6cc c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + .stab 0x000006cc 0x84 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + 0x90 (size before relaxing) + .stab 0x00000750 0x84 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + 0x90 (size before relaxing) + .stab 0x000007d4 0xd8 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncat_P.o) + 0xe4 (size before relaxing) + .stab 0x000008ac 0xcc c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + 0xd8 (size before relaxing) + .stab 0x00000978 0xb4 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + 0xc0 (size before relaxing) + .stab 0x00000a2c 0x84 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + 0x90 (size before relaxing) + .stab 0x00000ab0 0x6c c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + 0x78 (size before relaxing) + .stab 0x00000b1c 0xb4 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + 0xc0 (size before relaxing) + .stab 0x00000bd0 0xfc c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + 0x108 (size before relaxing) + .stab 0x00000ccc 0xa8 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + 0xb4 (size before relaxing) + .stab 0x00000d74 0x9c c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + 0xa8 (size before relaxing) + .stab 0x00000e10 0x1e0 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + 0x1ec (size before relaxing) + .stab 0x00000ff0 0x9c c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + 0xa8 (size before relaxing) + .stab 0x0000108c 0x9c c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + 0xa8 (size before relaxing) + .stab 0x00001128 0x480 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + 0x48c (size before relaxing) + +.stabstr 0x00000000 0x788 + *(.stabstr) + .stabstr 0x00000000 0x788 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + +.stab.excl + *(.stab.excl) + +.stab.exclstr + *(.stab.exclstr) + +.stab.index + *(.stab.index) + +.stab.indexstr + *(.stab.indexstr) + +.comment 0x00000000 0x2f + *(.comment) + .comment 0x00000000 0x2f Bin/Chameleon-Mini.o + 0x30 (size before relaxing) + .comment 0x00000000 0x30 Bin/LUFADescriptors.o + .comment 0x00000000 0x30 Bin/System.o + .comment 0x00000000 0x30 Bin/Configuration.o + .comment 0x00000000 0x30 Bin/Random.o + .comment 0x00000000 0x30 Bin/Common.o + .comment 0x00000000 0x30 Bin/Memory.o + .comment 0x00000000 0x30 Bin/Button.o + .comment 0x00000000 0x30 Bin/Log.o + .comment 0x00000000 0x30 Bin/Settings.o + .comment 0x00000000 0x30 Bin/LED.o + .comment 0x00000000 0x30 Bin/Terminal.o + .comment 0x00000000 0x30 Bin/Commands.o + .comment 0x00000000 0x30 Bin/XModem.o + .comment 0x00000000 0x30 Bin/CommandLine.o + .comment 0x00000000 0x30 Bin/Codec.o + .comment 0x00000000 0x30 Bin/ISO14443-2A.o + .comment 0x00000000 0x30 Bin/MifareUltralight.o + .comment 0x00000000 0x30 Bin/MifareClassic.o + .comment 0x00000000 0x30 Bin/ISO14443-3A.o + .comment 0x00000000 0x30 Bin/Crypto1.o + .comment 0x00000000 0x30 Bin/HIDParser.o + .comment 0x00000000 0x30 Bin/ConfigDescriptors.o + .comment 0x00000000 0x30 Bin/DeviceStandardReq.o + .comment 0x00000000 0x30 Bin/Events.o + .comment 0x00000000 0x30 Bin/HostStandardReq.o + .comment 0x00000000 0x30 Bin/USBTask.o + .comment 0x00000000 0x30 Bin/Device_XMEGA.o + .comment 0x00000000 0x30 Bin/EndpointStream_XMEGA.o + .comment 0x00000000 0x30 Bin/Endpoint_XMEGA.o + .comment 0x00000000 0x30 Bin/Host_XMEGA.o + .comment 0x00000000 0x30 Bin/PipeStream_XMEGA.o + .comment 0x00000000 0x30 Bin/Pipe_XMEGA.o + .comment 0x00000000 0x30 Bin/USBController_XMEGA.o + .comment 0x00000000 0x30 Bin/USBInterrupt_XMEGA.o + .comment 0x00000000 0x30 Bin/AudioClassDevice.o + .comment 0x00000000 0x30 Bin/CDCClassDevice.o + .comment 0x00000000 0x30 Bin/HIDClassDevice.o + .comment 0x00000000 0x30 Bin/MassStorageClassDevice.o + .comment 0x00000000 0x30 Bin/MIDIClassDevice.o + .comment 0x00000000 0x30 Bin/PrinterClassDevice.o + .comment 0x00000000 0x30 Bin/RNDISClassDevice.o + .comment 0x00000000 0x30 Bin/AndroidAccessoryClassHost.o + .comment 0x00000000 0x30 Bin/AudioClassHost.o + .comment 0x00000000 0x30 Bin/CDCClassHost.o + .comment 0x00000000 0x30 Bin/HIDClassHost.o + .comment 0x00000000 0x30 Bin/MassStorageClassHost.o + .comment 0x00000000 0x30 Bin/MIDIClassHost.o + .comment 0x00000000 0x30 Bin/PrinterClassHost.o + .comment 0x00000000 0x30 Bin/RNDISClassHost.o + .comment 0x00000000 0x30 Bin/StillImageClassHost.o + .comment 0x00000000 0x30 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .comment 0x00000000 0x30 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .comment 0x00000000 0x30 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .comment 0x00000000 0x30 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + +.debug + *(.debug) + +.line + *(.line) + +.debug_srcinfo + *(.debug_srcinfo) + +.debug_sfnames + *(.debug_sfnames) + +.debug_aranges 0x00000000 0xd80 + *(.debug_aranges) + .debug_aranges + 0x00000000 0x20 Bin/Chameleon-Mini.o + .debug_aranges + 0x00000020 0x20 Bin/LUFADescriptors.o + .debug_aranges + 0x00000040 0x58 Bin/System.o + .debug_aranges + 0x00000098 0x78 Bin/Configuration.o + .debug_aranges + 0x00000110 0x38 Bin/Random.o + .debug_aranges + 0x00000148 0x28 Bin/Common.o + .debug_aranges + 0x00000170 0x58 Bin/Memory.o + .debug_aranges + 0x000001c8 0x50 Bin/Button.o + .debug_aranges + 0x00000218 0x80 Bin/Log.o + .debug_aranges + 0x00000298 0x50 Bin/Settings.o + .debug_aranges + 0x000002e8 0x50 Bin/LED.o + .debug_aranges + 0x00000338 0x68 Bin/Terminal.o + .debug_aranges + 0x000003a0 0x140 Bin/Commands.o + .debug_aranges + 0x000004e0 0x40 Bin/XModem.o + .debug_aranges + 0x00000520 0x30 Bin/CommandLine.o + .debug_aranges + 0x00000550 0x18 Bin/Codec.o + .debug_aranges + 0x00000568 0x48 Bin/ISO14443-2A.o + .debug_aranges + 0x000005b0 0x48 Bin/MifareUltralight.o + .debug_aranges + 0x000005f8 0x58 Bin/MifareClassic.o + .debug_aranges + 0x00000650 0x28 Bin/ISO14443-3A.o + .debug_aranges + 0x00000678 0x50 Bin/Crypto1.o + .debug_aranges + 0x000006c8 0x38 Bin/HIDParser.o + .debug_aranges + 0x00000700 0x38 Bin/ConfigDescriptors.o + .debug_aranges + 0x00000738 0x20 Bin/DeviceStandardReq.o + .debug_aranges + 0x00000758 0x20 Bin/Events.o + .debug_aranges + 0x00000778 0x18 Bin/HostStandardReq.o + .debug_aranges + 0x00000790 0x20 Bin/USBTask.o + .debug_aranges + 0x000007b0 0x20 Bin/Device_XMEGA.o + .debug_aranges + 0x000007d0 0xc8 Bin/EndpointStream_XMEGA.o + .debug_aranges + 0x00000898 0x90 Bin/Endpoint_XMEGA.o + .debug_aranges + 0x00000928 0x18 Bin/Host_XMEGA.o + .debug_aranges + 0x00000940 0x18 Bin/PipeStream_XMEGA.o + .debug_aranges + 0x00000958 0x18 Bin/Pipe_XMEGA.o + .debug_aranges + 0x00000970 0x30 Bin/USBController_XMEGA.o + .debug_aranges + 0x000009a0 0x30 Bin/USBInterrupt_XMEGA.o + .debug_aranges + 0x000009d0 0x30 Bin/AudioClassDevice.o + .debug_aranges + 0x00000a00 0x98 Bin/CDCClassDevice.o + .debug_aranges + 0x00000a98 0x30 Bin/HIDClassDevice.o + .debug_aranges + 0x00000ac8 0x30 Bin/MassStorageClassDevice.o + .debug_aranges + 0x00000af8 0x40 Bin/MIDIClassDevice.o + .debug_aranges + 0x00000b38 0x90 Bin/PrinterClassDevice.o + .debug_aranges + 0x00000bc8 0x48 Bin/RNDISClassDevice.o + .debug_aranges + 0x00000c10 0x18 Bin/AndroidAccessoryClassHost.o + .debug_aranges + 0x00000c28 0x18 Bin/AudioClassHost.o + .debug_aranges + 0x00000c40 0x18 Bin/CDCClassHost.o + .debug_aranges + 0x00000c58 0x18 Bin/HIDClassHost.o + .debug_aranges + 0x00000c70 0x18 Bin/MassStorageClassHost.o + .debug_aranges + 0x00000c88 0x18 Bin/MIDIClassHost.o + .debug_aranges + 0x00000ca0 0x18 Bin/PrinterClassHost.o + .debug_aranges + 0x00000cb8 0x18 Bin/RNDISClassHost.o + .debug_aranges + 0x00000cd0 0x18 Bin/StillImageClassHost.o + .debug_aranges + 0x00000ce8 0x38 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_aranges + 0x00000d20 0x20 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_aranges + 0x00000d40 0x20 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_aranges + 0x00000d60 0x20 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + +.debug_pubnames + *(.debug_pubnames) + +.debug_info 0x00000000 0x1c598 + *(.debug_info) + .debug_info 0x00000000 0xe9a Bin/Chameleon-Mini.o + .debug_info 0x00000e9a 0x962 Bin/LUFADescriptors.o + .debug_info 0x000017fc 0xf3a Bin/System.o + .debug_info 0x00002736 0x78d Bin/Configuration.o + .debug_info 0x00002ec3 0x161 Bin/Random.o + .debug_info 0x00003024 0x1b3 Bin/Common.o + .debug_info 0x000031d7 0x144f Bin/Memory.o + .debug_info 0x00004626 0xc37 Bin/Button.o + .debug_info 0x0000525d 0xdd0 Bin/Log.o + .debug_info 0x0000602d 0x70e Bin/Settings.o + .debug_info 0x0000673b 0xa62 Bin/LED.o + .debug_info 0x0000719d 0xbc1 Bin/Terminal.o + .debug_info 0x00007d5e 0x1e54 Bin/Commands.o + .debug_info 0x00009bb2 0x99e Bin/XModem.o + .debug_info 0x0000a550 0x9bc Bin/CommandLine.o + .debug_info 0x0000af0c 0x203 Bin/Codec.o + .debug_info 0x0000b10f 0x1b56 Bin/ISO14443-2A.o + .debug_info 0x0000cc65 0x9dc Bin/MifareUltralight.o + .debug_info 0x0000d641 0x1423 Bin/MifareClassic.o + .debug_info 0x0000ea64 0x179 Bin/ISO14443-3A.o + .debug_info 0x0000ebdd 0x530 Bin/Crypto1.o + .debug_info 0x0000f10d 0x72e Bin/HIDParser.o + .debug_info 0x0000f83b 0x5ed Bin/ConfigDescriptors.o + .debug_info 0x0000fe28 0x11d6 Bin/DeviceStandardReq.o + .debug_info 0x00010ffe 0x7f Bin/Events.o + .debug_info 0x0001107d 0x5d Bin/HostStandardReq.o + .debug_info 0x000110da 0x435 Bin/USBTask.o + .debug_info 0x0001150f 0x670 Bin/Device_XMEGA.o + .debug_info 0x00011b7f 0x19be Bin/EndpointStream_XMEGA.o + .debug_info 0x0001353d 0xcff Bin/Endpoint_XMEGA.o + .debug_info 0x0001423c 0x5d Bin/Host_XMEGA.o + .debug_info 0x00014299 0x5d Bin/PipeStream_XMEGA.o + .debug_info 0x000142f6 0x5d Bin/Pipe_XMEGA.o + .debug_info 0x00014353 0xd40 Bin/USBController_XMEGA.o + .debug_info 0x00015093 0xa7b Bin/USBInterrupt_XMEGA.o + .debug_info 0x00015b0e 0xa9d Bin/AudioClassDevice.o + .debug_info 0x000165ab 0xf93 Bin/CDCClassDevice.o + .debug_info 0x0001753e 0xf91 Bin/HIDClassDevice.o + .debug_info 0x000184cf 0xaa0 Bin/MassStorageClassDevice.o + .debug_info 0x00018f6f 0x7c6 Bin/MIDIClassDevice.o + .debug_info 0x00019735 0xddd Bin/PrinterClassDevice.o + .debug_info 0x0001a512 0x1311 Bin/RNDISClassDevice.o + .debug_info 0x0001b823 0x5d Bin/AndroidAccessoryClassHost.o + .debug_info 0x0001b880 0x5d Bin/AudioClassHost.o + .debug_info 0x0001b8dd 0x5d Bin/CDCClassHost.o + .debug_info 0x0001b93a 0x5d Bin/HIDClassHost.o + .debug_info 0x0001b997 0x5d Bin/MassStorageClassHost.o + .debug_info 0x0001b9f4 0x5d Bin/MIDIClassHost.o + .debug_info 0x0001ba51 0x5d Bin/PrinterClassHost.o + .debug_info 0x0001baae 0x5d Bin/RNDISClassHost.o + .debug_info 0x0001bb0b 0x5d Bin/StillImageClassHost.o + .debug_info 0x0001bb68 0x157 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_info 0x0001bcbf 0x21c c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_info 0x0001bedb 0x549 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_info 0x0001c424 0x174 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + *(.gnu.linkonce.wi.*) + +.debug_abbrev 0x00000000 0x6309 + *(.debug_abbrev) + .debug_abbrev 0x00000000 0x1d9 Bin/Chameleon-Mini.o + .debug_abbrev 0x000001d9 0x1bb Bin/LUFADescriptors.o + .debug_abbrev 0x00000394 0x16b Bin/System.o + .debug_abbrev 0x000004ff 0x26e Bin/Configuration.o + .debug_abbrev 0x0000076d 0xfb Bin/Random.o + .debug_abbrev 0x00000868 0xb2 Bin/Common.o + .debug_abbrev 0x0000091a 0x348 Bin/Memory.o + .debug_abbrev 0x00000c62 0x2f9 Bin/Button.o + .debug_abbrev 0x00000f5b 0x373 Bin/Log.o + .debug_abbrev 0x000012ce 0x21b Bin/Settings.o + .debug_abbrev 0x000014e9 0x2c1 Bin/LED.o + .debug_abbrev 0x000017aa 0x322 Bin/Terminal.o + .debug_abbrev 0x00001acc 0x38e Bin/Commands.o + .debug_abbrev 0x00001e5a 0x2bd Bin/XModem.o + .debug_abbrev 0x00002117 0x2ce Bin/CommandLine.o + .debug_abbrev 0x000023e5 0xc4 Bin/Codec.o + .debug_abbrev 0x000024a9 0x328 Bin/ISO14443-2A.o + .debug_abbrev 0x000027d1 0x260 Bin/MifareUltralight.o + .debug_abbrev 0x00002a31 0x2f5 Bin/MifareClassic.o + .debug_abbrev 0x00002d26 0xa6 Bin/ISO14443-3A.o + .debug_abbrev 0x00002dcc 0x1bd Bin/Crypto1.o + .debug_abbrev 0x00002f89 0x20a Bin/HIDParser.o + .debug_abbrev 0x00003193 0x248 Bin/ConfigDescriptors.o + .debug_abbrev 0x000033db 0x37e Bin/DeviceStandardReq.o + .debug_abbrev 0x00003759 0x44 Bin/Events.o + .debug_abbrev 0x0000379d 0x26 Bin/HostStandardReq.o + .debug_abbrev 0x000037c3 0x21d Bin/USBTask.o + .debug_abbrev 0x000039e0 0x11e Bin/Device_XMEGA.o + .debug_abbrev 0x00003afe 0x252 Bin/EndpointStream_XMEGA.o + .debug_abbrev 0x00003d50 0x300 Bin/Endpoint_XMEGA.o + .debug_abbrev 0x00004050 0x26 Bin/Host_XMEGA.o + .debug_abbrev 0x00004076 0x26 Bin/PipeStream_XMEGA.o + .debug_abbrev 0x0000409c 0x26 Bin/Pipe_XMEGA.o + .debug_abbrev 0x000040c2 0x306 Bin/USBController_XMEGA.o + .debug_abbrev 0x000043c8 0x266 Bin/USBInterrupt_XMEGA.o + .debug_abbrev 0x0000462e 0x28b Bin/AudioClassDevice.o + .debug_abbrev 0x000048b9 0x439 Bin/CDCClassDevice.o + .debug_abbrev 0x00004cf2 0x2de Bin/HIDClassDevice.o + .debug_abbrev 0x00004fd0 0x338 Bin/MassStorageClassDevice.o + .debug_abbrev 0x00005308 0x287 Bin/MIDIClassDevice.o + .debug_abbrev 0x0000558f 0x3e1 Bin/PrinterClassDevice.o + .debug_abbrev 0x00005970 0x36d Bin/RNDISClassDevice.o + .debug_abbrev 0x00005cdd 0x26 Bin/AndroidAccessoryClassHost.o + .debug_abbrev 0x00005d03 0x26 Bin/AudioClassHost.o + .debug_abbrev 0x00005d29 0x26 Bin/CDCClassHost.o + .debug_abbrev 0x00005d4f 0x26 Bin/HIDClassHost.o + .debug_abbrev 0x00005d75 0x26 Bin/MassStorageClassHost.o + .debug_abbrev 0x00005d9b 0x26 Bin/MIDIClassHost.o + .debug_abbrev 0x00005dc1 0x26 Bin/PrinterClassHost.o + .debug_abbrev 0x00005de7 0x26 Bin/RNDISClassHost.o + .debug_abbrev 0x00005e0d 0x26 Bin/StillImageClassHost.o + .debug_abbrev 0x00005e33 0xd6 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_abbrev 0x00005f09 0x139 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_abbrev 0x00006042 0x1d6 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_abbrev 0x00006218 0xf1 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + +.debug_line 0x00000000 0xd67b + *(.debug_line) + .debug_line 0x00000000 0x41a Bin/Chameleon-Mini.o + .debug_line 0x0000041a 0x39a Bin/LUFADescriptors.o + .debug_line 0x000007b4 0x2ee Bin/System.o + .debug_line 0x00000aa2 0x448 Bin/Configuration.o + .debug_line 0x00000eea 0x144 Bin/Random.o + .debug_line 0x0000102e 0x246 Bin/Common.o + .debug_line 0x00001274 0xaa3 Bin/Memory.o + .debug_line 0x00001d17 0x535 Bin/Button.o + .debug_line 0x0000224c 0x5a5 Bin/Log.o + .debug_line 0x000027f1 0x3a7 Bin/Settings.o + .debug_line 0x00002b98 0x4e9 Bin/LED.o + .debug_line 0x00003081 0x498 Bin/Terminal.o + .debug_line 0x00003519 0xab5 Bin/Commands.o + .debug_line 0x00003fce 0x588 Bin/XModem.o + .debug_line 0x00004556 0x42e Bin/CommandLine.o + .debug_line 0x00004984 0xdf Bin/Codec.o + .debug_line 0x00004a63 0x70e Bin/ISO14443-2A.o + .debug_line 0x00005171 0x3fa Bin/MifareUltralight.o + .debug_line 0x0000556b 0x98b Bin/MifareClassic.o + .debug_line 0x00005ef6 0x1d7 Bin/ISO14443-3A.o + .debug_line 0x000060cd 0x75c Bin/Crypto1.o + .debug_line 0x00006829 0x668 Bin/HIDParser.o + .debug_line 0x00006e91 0x325 Bin/ConfigDescriptors.o + .debug_line 0x000071b6 0x532 Bin/DeviceStandardReq.o + .debug_line 0x000076e8 0x4f Bin/Events.o + .debug_line 0x00007737 0x1a Bin/HostStandardReq.o + .debug_line 0x00007751 0x269 Bin/USBTask.o + .debug_line 0x000079ba 0x1e5 Bin/Device_XMEGA.o + .debug_line 0x00007b9f 0x16b5 Bin/EndpointStream_XMEGA.o + .debug_line 0x00009254 0x75d Bin/Endpoint_XMEGA.o + .debug_line 0x000099b1 0x1a Bin/Host_XMEGA.o + .debug_line 0x000099cb 0x1a Bin/PipeStream_XMEGA.o + .debug_line 0x000099e5 0x1a Bin/Pipe_XMEGA.o + .debug_line 0x000099ff 0x411 Bin/USBController_XMEGA.o + .debug_line 0x00009e10 0x410 Bin/USBInterrupt_XMEGA.o + .debug_line 0x0000a220 0x4b3 Bin/AudioClassDevice.o + .debug_line 0x0000a6d3 0x892 Bin/CDCClassDevice.o + .debug_line 0x0000af65 0x628 Bin/HIDClassDevice.o + .debug_line 0x0000b58d 0x56f Bin/MassStorageClassDevice.o + .debug_line 0x0000bafc 0x462 Bin/MIDIClassDevice.o + .debug_line 0x0000bf5e 0x7d5 Bin/PrinterClassDevice.o + .debug_line 0x0000c733 0x7ba Bin/RNDISClassDevice.o + .debug_line 0x0000ceed 0x1a Bin/AndroidAccessoryClassHost.o + .debug_line 0x0000cf07 0x1a Bin/AudioClassHost.o + .debug_line 0x0000cf21 0x1a Bin/CDCClassHost.o + .debug_line 0x0000cf3b 0x1a Bin/HIDClassHost.o + .debug_line 0x0000cf55 0x1a Bin/MassStorageClassHost.o + .debug_line 0x0000cf6f 0x1a Bin/MIDIClassHost.o + .debug_line 0x0000cf89 0x1a Bin/PrinterClassHost.o + .debug_line 0x0000cfa3 0x1a Bin/RNDISClassHost.o + .debug_line 0x0000cfbd 0x1a Bin/StillImageClassHost.o + .debug_line 0x0000cfd7 0xa1 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_line 0x0000d078 0x1a6 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_line 0x0000d21e 0x359 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_line 0x0000d577 0x104 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + +.debug_frame 0x00000000 0x2304 + *(.debug_frame) + .debug_frame 0x00000000 0x24 Bin/Chameleon-Mini.o + .debug_frame 0x00000024 0x24 Bin/LUFADescriptors.o + .debug_frame 0x00000048 0xa0 Bin/System.o + .debug_frame 0x000000e8 0xf4 Bin/Configuration.o + .debug_frame 0x000001dc 0x64 Bin/Random.o + .debug_frame 0x00000240 0x40 Bin/Common.o + .debug_frame 0x00000280 0x174 Bin/Memory.o + .debug_frame 0x000003f4 0xc0 Bin/Button.o + .debug_frame 0x000004b4 0x114 Bin/Log.o + .debug_frame 0x000005c8 0xa8 Bin/Settings.o + .debug_frame 0x00000670 0xa0 Bin/LED.o + .debug_frame 0x00000710 0xcc Bin/Terminal.o + .debug_frame 0x000007dc 0x3d4 Bin/Commands.o + .debug_frame 0x00000bb0 0x6c Bin/XModem.o + .debug_frame 0x00000c1c 0x78 Bin/CommandLine.o + .debug_frame 0x00000c94 0x100 Bin/ISO14443-2A.o + .debug_frame 0x00000d94 0xbc Bin/MifareUltralight.o + .debug_frame 0x00000e50 0xfc Bin/MifareClassic.o + .debug_frame 0x00000f4c 0x34 Bin/ISO14443-3A.o + .debug_frame 0x00000f80 0x13c Bin/Crypto1.o + .debug_frame 0x000010bc 0x11c Bin/HIDParser.o + .debug_frame 0x000011d8 0xd0 Bin/ConfigDescriptors.o + .debug_frame 0x000012a8 0x40 Bin/DeviceStandardReq.o + .debug_frame 0x000012e8 0x24 Bin/Events.o + .debug_frame 0x0000130c 0x2c Bin/USBTask.o + .debug_frame 0x00001338 0x24 Bin/Device_XMEGA.o + .debug_frame 0x0000135c 0x4f8 Bin/EndpointStream_XMEGA.o + .debug_frame 0x00001854 0x160 Bin/Endpoint_XMEGA.o + .debug_frame 0x000019b4 0x5c Bin/USBController_XMEGA.o + .debug_frame 0x00001a10 0x8c Bin/USBInterrupt_XMEGA.o + .debug_frame 0x00001a9c 0xa4 Bin/AudioClassDevice.o + .debug_frame 0x00001b40 0x1e0 Bin/CDCClassDevice.o + .debug_frame 0x00001d20 0xf0 Bin/HIDClassDevice.o + .debug_frame 0x00001e10 0x80 Bin/MassStorageClassDevice.o + .debug_frame 0x00001e90 0xa4 Bin/MIDIClassDevice.o + .debug_frame 0x00001f34 0x194 Bin/PrinterClassDevice.o + .debug_frame 0x000020c8 0x100 Bin/RNDISClassDevice.o + .debug_frame 0x000021c8 0x88 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_frame 0x00002250 0x30 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_frame 0x00002280 0x4c c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_frame 0x000022cc 0x38 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + +.debug_str 0x00000000 0x7fb5 + *(.debug_str) + .debug_str 0x00000000 0xb76 Bin/Chameleon-Mini.o + 0xc3b (size before relaxing) + .debug_str 0x00000b76 0x8cc Bin/LUFADescriptors.o + 0xb22 (size before relaxing) + .debug_str 0x00001442 0x9d2 Bin/System.o + 0xc3b (size before relaxing) + .debug_str 0x00001e14 0x402 Bin/Configuration.o + 0x783 (size before relaxing) + .debug_str 0x00002216 0x27 Bin/Random.o + 0x11c (size before relaxing) + .debug_str 0x0000223d 0x56 Bin/Common.o + 0x13f (size before relaxing) + .debug_str 0x00002293 0x37b Bin/Memory.o + 0x9f5 (size before relaxing) + .debug_str 0x0000260e 0x1fa Bin/Button.o + 0x90f (size before relaxing) + .debug_str 0x00002808 0x101 Bin/Log.o + 0x9a7 (size before relaxing) + .debug_str 0x00002909 0xc0 Bin/Settings.o + 0x7ba (size before relaxing) + .debug_str 0x000029c9 0x8f Bin/LED.o + 0x851 (size before relaxing) + .debug_str 0x00002a58 0x253 Bin/Terminal.o + 0x861 (size before relaxing) + .debug_str 0x00002cab 0x509 Bin/Commands.o + 0xf89 (size before relaxing) + .debug_str 0x000031b4 0x130 Bin/XModem.o + 0x538 (size before relaxing) + .debug_str 0x000032e4 0xc1 Bin/CommandLine.o + 0x515 (size before relaxing) + .debug_str 0x000033a5 0x1a Bin/Codec.o + 0x27d (size before relaxing) + .debug_str 0x000033bf 0x12f9 Bin/ISO14443-2A.o + 0x1d48 (size before relaxing) + .debug_str 0x000046b8 0x17d Bin/MifareUltralight.o + 0x4f7 (size before relaxing) + .debug_str 0x00004835 0x272 Bin/MifareClassic.o + 0x69d (size before relaxing) + .debug_str 0x00004aa7 0x1a Bin/ISO14443-3A.o + 0x136 (size before relaxing) + .debug_str 0x00004ac1 0x95 Bin/Crypto1.o + 0x1c4 (size before relaxing) + .debug_str 0x00004b56 0x492 Bin/HIDParser.o + 0x5f8 (size before relaxing) + .debug_str 0x00004fe8 0x22e Bin/ConfigDescriptors.o + 0x436 (size before relaxing) + .debug_str 0x00005216 0xa04 Bin/DeviceStandardReq.o + 0x1134 (size before relaxing) + .debug_str 0x00005c1a 0x31 Bin/Events.o + 0xe3 (size before relaxing) + .debug_str 0x00005c4b 0x2b Bin/HostStandardReq.o + 0xdd (size before relaxing) + .debug_str 0x00005c76 0x6d Bin/USBTask.o + 0x3af (size before relaxing) + .debug_str 0x00005ce3 0x4a Bin/Device_XMEGA.o + 0x523 (size before relaxing) + .debug_str 0x00005d2d 0x4d9 Bin/EndpointStream_XMEGA.o + 0x8c7 (size before relaxing) + .debug_str 0x00006206 0x2aa Bin/Endpoint_XMEGA.o + 0xa35 (size before relaxing) + .debug_str 0x000064b0 0x2c Bin/Host_XMEGA.o + 0xde (size before relaxing) + .debug_str 0x000064dc 0x32 Bin/PipeStream_XMEGA.o + 0xe4 (size before relaxing) + .debug_str 0x0000650e 0x2c Bin/Pipe_XMEGA.o + 0xde (size before relaxing) + .debug_str 0x0000653a 0x1bb Bin/USBController_XMEGA.o + 0xdc5 (size before relaxing) + .debug_str 0x000066f5 0xaa Bin/USBInterrupt_XMEGA.o + 0x896 (size before relaxing) + .debug_str 0x0000679f 0x280 Bin/AudioClassDevice.o + 0x70a (size before relaxing) + .debug_str 0x00006a1f 0x286 Bin/CDCClassDevice.o + 0xa5f (size before relaxing) + .debug_str 0x00006ca5 0x248 Bin/HIDClassDevice.o + 0xa7a (size before relaxing) + .debug_str 0x00006eed 0x261 Bin/MassStorageClassDevice.o + 0x85d (size before relaxing) + .debug_str 0x0000714e 0x115 Bin/MIDIClassDevice.o + 0x6b4 (size before relaxing) + .debug_str 0x00007263 0x269 Bin/PrinterClassDevice.o + 0x988 (size before relaxing) + .debug_str 0x000074cc 0x6e5 Bin/RNDISClassDevice.o + 0xdbd (size before relaxing) + .debug_str 0x00007bb1 0x3b Bin/AndroidAccessoryClassHost.o + 0xed (size before relaxing) + .debug_str 0x00007bec 0x30 Bin/AudioClassHost.o + 0xe2 (size before relaxing) + .debug_str 0x00007c1c 0x2e Bin/CDCClassHost.o + 0xe0 (size before relaxing) + .debug_str 0x00007c4a 0x2e Bin/HIDClassHost.o + 0xe0 (size before relaxing) + .debug_str 0x00007c78 0x36 Bin/MassStorageClassHost.o + 0xe8 (size before relaxing) + .debug_str 0x00007cae 0x2f Bin/MIDIClassHost.o + 0xe1 (size before relaxing) + .debug_str 0x00007cdd 0x32 Bin/PrinterClassHost.o + 0xe4 (size before relaxing) + .debug_str 0x00007d0f 0x30 Bin/RNDISClassHost.o + 0xe2 (size before relaxing) + .debug_str 0x00007d3f 0x35 Bin/StillImageClassHost.o + 0xe7 (size before relaxing) + .debug_str 0x00007d74 0x81 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + 0xba (size before relaxing) + .debug_str 0x00007df5 0x91 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + 0x149 (size before relaxing) + .debug_str 0x00007e86 0xcd c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + 0x1ad (size before relaxing) + .debug_str 0x00007f53 0x62 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + 0x10d (size before relaxing) + +.debug_loc 0x00000000 0xeb2a + *(.debug_loc) + .debug_loc 0x00000000 0x277 Bin/LUFADescriptors.o + .debug_loc 0x00000277 0x2f Bin/System.o + .debug_loc 0x000002a6 0x3cf Bin/Configuration.o + .debug_loc 0x00000675 0xaa Bin/Random.o + .debug_loc 0x0000071f 0x319 Bin/Common.o + .debug_loc 0x00000a38 0xc2f Bin/Memory.o + .debug_loc 0x00001667 0x75a Bin/Button.o + .debug_loc 0x00001dc1 0x5d9 Bin/Log.o + .debug_loc 0x0000239a 0x2bb Bin/Settings.o + .debug_loc 0x00002655 0x555 Bin/LED.o + .debug_loc 0x00002baa 0x1c9 Bin/Terminal.o + .debug_loc 0x00002d73 0xe44 Bin/Commands.o + .debug_loc 0x00003bb7 0x2e3 Bin/XModem.o + .debug_loc 0x00003e9a 0x4f4 Bin/CommandLine.o + .debug_loc 0x0000438e 0x515 Bin/ISO14443-2A.o + .debug_loc 0x000048a3 0x679 Bin/MifareUltralight.o + .debug_loc 0x00004f1c 0x101d Bin/MifareClassic.o + .debug_loc 0x00005f39 0x231 Bin/ISO14443-3A.o + .debug_loc 0x0000616a 0xa3a Bin/Crypto1.o + .debug_loc 0x00006ba4 0xc34 Bin/HIDParser.o + .debug_loc 0x000077d8 0x536 Bin/ConfigDescriptors.o + .debug_loc 0x00007d0e 0x2d9 Bin/DeviceStandardReq.o + .debug_loc 0x00007fe7 0x22 Bin/USBTask.o + .debug_loc 0x00008009 0x2bf0 Bin/EndpointStream_XMEGA.o + .debug_loc 0x0000abf9 0x581 Bin/Endpoint_XMEGA.o + .debug_loc 0x0000b17a 0xa3 Bin/USBController_XMEGA.o + .debug_loc 0x0000b21d 0x200 Bin/USBInterrupt_XMEGA.o + .debug_loc 0x0000b41d 0x3ad Bin/AudioClassDevice.o + .debug_loc 0x0000b7ca 0x9f6 Bin/CDCClassDevice.o + .debug_loc 0x0000c1c0 0x473 Bin/HIDClassDevice.o + .debug_loc 0x0000c633 0x303 Bin/MassStorageClassDevice.o + .debug_loc 0x0000c936 0x35f Bin/MIDIClassDevice.o + .debug_loc 0x0000cc95 0x8b8 Bin/PrinterClassDevice.o + .debug_loc 0x0000d54d 0xd71 Bin/RNDISClassDevice.o + .debug_loc 0x0000e2be 0x1e8 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_loc 0x0000e4a6 0x74 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_loc 0x0000e51a 0x51d c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_loc 0x0000ea37 0xf3 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + +.debug_macinfo + *(.debug_macinfo) + +.debug_pubtypes + *(.debug_pubtypes) + +.debug_ranges 0x00000000 0x1de0 + *(.debug_ranges) + .debug_ranges 0x00000000 0x28 Bin/Chameleon-Mini.o + .debug_ranges 0x00000028 0x10 Bin/LUFADescriptors.o + .debug_ranges 0x00000038 0x48 Bin/System.o + .debug_ranges 0x00000080 0xb0 Bin/Configuration.o + .debug_ranges 0x00000130 0x28 Bin/Random.o + .debug_ranges 0x00000158 0x48 Bin/Common.o + .debug_ranges 0x000001a0 0x320 Bin/Memory.o + .debug_ranges 0x000004c0 0xe8 Bin/Button.o + .debug_ranges 0x000005a8 0x88 Bin/Log.o + .debug_ranges 0x00000630 0x40 Bin/Settings.o + .debug_ranges 0x00000670 0x138 Bin/LED.o + .debug_ranges 0x000007a8 0xc0 Bin/Terminal.o + .debug_ranges 0x00000868 0x190 Bin/Commands.o + .debug_ranges 0x000009f8 0x48 Bin/XModem.o + .debug_ranges 0x00000a40 0x120 Bin/CommandLine.o + .debug_ranges 0x00000b60 0xc0 Bin/ISO14443-2A.o + .debug_ranges 0x00000c20 0xc8 Bin/MifareUltralight.o + .debug_ranges 0x00000ce8 0x230 Bin/MifareClassic.o + .debug_ranges 0x00000f18 0x18 Bin/ISO14443-3A.o + .debug_ranges 0x00000f30 0x70 Bin/Crypto1.o + .debug_ranges 0x00000fa0 0x150 Bin/HIDParser.o + .debug_ranges 0x000010f0 0x40 Bin/ConfigDescriptors.o + .debug_ranges 0x00001130 0x138 Bin/DeviceStandardReq.o + .debug_ranges 0x00001268 0x10 Bin/Events.o + .debug_ranges 0x00001278 0x60 Bin/USBTask.o + .debug_ranges 0x000012d8 0x10 Bin/Device_XMEGA.o + .debug_ranges 0x000012e8 0x4a8 Bin/EndpointStream_XMEGA.o + .debug_ranges 0x00001790 0x188 Bin/Endpoint_XMEGA.o + .debug_ranges 0x00001918 0x20 Bin/USBController_XMEGA.o + .debug_ranges 0x00001938 0x20 Bin/USBInterrupt_XMEGA.o + .debug_ranges 0x00001958 0x38 Bin/AudioClassDevice.o + .debug_ranges 0x00001990 0x100 Bin/CDCClassDevice.o + .debug_ranges 0x00001a90 0x20 Bin/HIDClassDevice.o + .debug_ranges 0x00001ab0 0xa0 Bin/MassStorageClassDevice.o + .debug_ranges 0x00001b50 0x48 Bin/MIDIClassDevice.o + .debug_ranges 0x00001b98 0x128 Bin/PrinterClassDevice.o + .debug_ranges 0x00001cc0 0xc8 Bin/RNDISClassDevice.o + .debug_ranges 0x00001d88 0x28 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_ranges 0x00001db0 0x10 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_ranges 0x00001dc0 0x10 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_ranges 0x00001dd0 0x10 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + +.debug_macro + *(.debug_macro) +OUTPUT(Chameleon-Mini.elf elf32-avr) +LOAD linker stubs + +Cross Reference Table + +Symbol File +ActiveConfiguration Bin/MifareClassic.o + Bin/MifareUltralight.o + Bin/ISO14443-2A.o + Bin/Commands.o + Bin/Button.o + Bin/Configuration.o + Bin/Chameleon-Mini.o +Audio_Device_ConfigureEndpoints Bin/AudioClassDevice.o +Audio_Device_Event_Stub Bin/AudioClassDevice.o +Audio_Device_ProcessControlRequest Bin/AudioClassDevice.o +BufferToHexString Bin/Common.o + Bin/Commands.o +ButtonGetActionByName Bin/Button.o + Bin/Commands.o +ButtonGetActionList Bin/Button.o + Bin/Commands.o +ButtonInit Bin/Button.o + Bin/Chameleon-Mini.o +ButtonSetActionById Bin/Button.o +ButtonSetActionByName Bin/Button.o + Bin/Commands.o +ButtonTick Bin/Button.o + Bin/Chameleon-Mini.o +CALLBACK_Audio_Device_GetSetEndpointProperty Bin/AudioClassDevice.o +CALLBACK_Audio_Device_GetSetInterfaceProperty Bin/AudioClassDevice.o +CALLBACK_HIDParser_FilterHIDReportItem Bin/HIDParser.o +CALLBACK_HID_Device_CreateHIDReport Bin/HIDClassDevice.o +CALLBACK_HID_Device_ProcessHIDReport Bin/HIDClassDevice.o +CALLBACK_MS_Device_SCSICommandReceived Bin/MassStorageClassDevice.o +CALLBACK_USB_GetDescriptor Bin/LUFADescriptors.o + Bin/DeviceStandardReq.o +CDC_Device_BytesReceived Bin/CDCClassDevice.o +CDC_Device_ConfigureEndpoints Bin/CDCClassDevice.o + Bin/Terminal.o +CDC_Device_CreateBlockingStream Bin/CDCClassDevice.o +CDC_Device_CreateStream Bin/CDCClassDevice.o +CDC_Device_Event_Stub Bin/CDCClassDevice.o +CDC_Device_Flush Bin/CDCClassDevice.o +CDC_Device_ProcessControlRequest Bin/CDCClassDevice.o + Bin/Terminal.o +CDC_Device_ReceiveByte Bin/CDCClassDevice.o + Bin/Terminal.o +CDC_Device_SendByte Bin/CDCClassDevice.o + Bin/XModem.o + Bin/Terminal.o + Bin/Log.o +CDC_Device_SendControlLineStateChange Bin/CDCClassDevice.o +CDC_Device_SendData Bin/CDCClassDevice.o + Bin/Terminal.o +CDC_Device_SendString Bin/CDCClassDevice.o + Bin/Terminal.o +CDC_Device_USBTask Bin/CDCClassDevice.o + Bin/Terminal.o +CodecBuffer Bin/ISO14443-2A.o + Bin/Codec.o +CommandExecButton Bin/Commands.o + Bin/CommandLine.o +CommandExecButtonLong Bin/Commands.o + Bin/CommandLine.o +CommandExecClear Bin/Commands.o + Bin/CommandLine.o +CommandExecConfig Bin/Commands.o + Bin/CommandLine.o +CommandExecDownload Bin/Commands.o + Bin/CommandLine.o +CommandExecHelp Bin/Commands.o + Bin/CommandLine.o +CommandExecLedGreen Bin/Commands.o + Bin/CommandLine.o +CommandExecLedRed Bin/Commands.o + Bin/CommandLine.o +CommandExecLogMem Bin/Commands.o + Bin/CommandLine.o +CommandExecLogMode Bin/Commands.o + Bin/CommandLine.o +CommandExecReset Bin/Commands.o + Bin/CommandLine.o +CommandExecUpgrade Bin/Commands.o + Bin/CommandLine.o +CommandExecUpload Bin/Commands.o + Bin/CommandLine.o +CommandGetButton Bin/Commands.o + Bin/CommandLine.o +CommandGetButtonLong Bin/Commands.o + Bin/CommandLine.o +CommandGetConfig Bin/Commands.o + Bin/CommandLine.o +CommandGetLedGreen Bin/Commands.o + Bin/CommandLine.o +CommandGetLedRed Bin/Commands.o + Bin/CommandLine.o +CommandGetLogMem Bin/Commands.o + Bin/CommandLine.o +CommandGetLogMode Bin/Commands.o + Bin/CommandLine.o +CommandGetMemSize Bin/Commands.o + Bin/CommandLine.o +CommandGetReadOnly Bin/Commands.o + Bin/CommandLine.o +CommandGetRssi Bin/Commands.o + Bin/CommandLine.o +CommandGetSetting Bin/Commands.o + Bin/CommandLine.o +CommandGetUid Bin/Commands.o + Bin/CommandLine.o +CommandGetUidSize Bin/Commands.o + Bin/CommandLine.o +CommandGetVersion Bin/Commands.o + Bin/CommandLine.o +CommandLineInit Bin/CommandLine.o +CommandLineProcessByte Bin/CommandLine.o + Bin/Terminal.o +CommandLineTick Bin/CommandLine.o + Bin/Terminal.o +CommandSetButton Bin/Commands.o + Bin/CommandLine.o +CommandSetButtonLong Bin/Commands.o + Bin/CommandLine.o +CommandSetConfig Bin/Commands.o + Bin/CommandLine.o +CommandSetLedGreen Bin/Commands.o + Bin/CommandLine.o +CommandSetLedRed Bin/Commands.o + Bin/CommandLine.o +CommandSetLogMem Bin/Commands.o + Bin/CommandLine.o +CommandSetLogMode Bin/Commands.o + Bin/CommandLine.o +CommandSetReadOnly Bin/Commands.o + Bin/CommandLine.o +CommandSetSetting Bin/Commands.o + Bin/CommandLine.o +CommandSetUid Bin/Commands.o + Bin/CommandLine.o +CommandTable Bin/CommandLine.o + Bin/Commands.o +ConfigurationDescriptor Bin/LUFADescriptors.o +ConfigurationGetList Bin/Configuration.o + Bin/Commands.o +ConfigurationInit Bin/Configuration.o + Bin/Settings.o + Bin/Chameleon-Mini.o +ConfigurationSetById Bin/Configuration.o +ConfigurationSetByName Bin/Configuration.o + Bin/Commands.o +Crypto1Auth Bin/Crypto1.o + Bin/MifareClassic.o +Crypto1Byte Bin/Crypto1.o + Bin/MifareClassic.o +Crypto1FilterOutput Bin/Crypto1.o + Bin/MifareClassic.o +Crypto1Nibble Bin/Crypto1.o + Bin/MifareClassic.o +Crypto1PRNG Bin/Crypto1.o + Bin/MifareClassic.o +Crypto1Setup Bin/Crypto1.o + Bin/MifareClassic.o +DeviceDescriptor Bin/LUFADescriptors.o +EVENT_Audio_Device_StreamStartStop Bin/AudioClassDevice.o +EVENT_CDC_Device_BreakSent Bin/CDCClassDevice.o +EVENT_CDC_Device_ControLineStateChanged Bin/CDCClassDevice.o +EVENT_CDC_Device_LineEncodingChanged Bin/CDCClassDevice.o +EVENT_PRNT_Device_SoftReset Bin/PrinterClassDevice.o +EVENT_USB_Device_ConfigurationChanged Bin/Terminal.o + Bin/DeviceStandardReq.o +EVENT_USB_Device_Connect Bin/Terminal.o + Bin/USBInterrupt_XMEGA.o +EVENT_USB_Device_ControlRequest Bin/Terminal.o + Bin/DeviceStandardReq.o +EVENT_USB_Device_Disconnect Bin/Terminal.o + Bin/USBInterrupt_XMEGA.o +EVENT_USB_Device_Reset Bin/Events.o + Bin/USBInterrupt_XMEGA.o +EVENT_USB_Device_StartOfFrame Bin/Events.o + Bin/USBInterrupt_XMEGA.o +EVENT_USB_Device_Suspend Bin/Events.o +EVENT_USB_Device_WakeUp Bin/Events.o +Endpoint_ClearEndpoints Bin/Endpoint_XMEGA.o + Bin/USBInterrupt_XMEGA.o +Endpoint_ClearIN Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/DeviceStandardReq.o +Endpoint_ClearOUT Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/DeviceStandardReq.o +Endpoint_ClearSETUP Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/DeviceStandardReq.o +Endpoint_ClearStatusStage Bin/Endpoint_XMEGA.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/DeviceStandardReq.o +Endpoint_ConfigureEndpointTable Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o +Endpoint_ConfigureEndpoint_PRV Bin/Endpoint_XMEGA.o + Bin/USBInterrupt_XMEGA.o + Bin/USBController_XMEGA.o +Endpoint_Discard_Stream Bin/EndpointStream_XMEGA.o +Endpoint_IsINReady Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/DeviceStandardReq.o +Endpoint_IsOUTReceived Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o +Endpoint_IsSETUPReceived Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/USBTask.o + Bin/DeviceStandardReq.o +Endpoint_Null_Stream Bin/EndpointStream_XMEGA.o +Endpoint_Read_8 Bin/Endpoint_XMEGA.o + Bin/PrinterClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/DeviceStandardReq.o +Endpoint_Read_Control_EStream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Read_Control_EStream_LE Bin/EndpointStream_XMEGA.o +Endpoint_Read_Control_Stream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Read_Control_Stream_LE Bin/EndpointStream_XMEGA.o + Bin/RNDISClassDevice.o + Bin/HIDClassDevice.o + Bin/AudioClassDevice.o +Endpoint_Read_EStream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Read_EStream_LE Bin/EndpointStream_XMEGA.o +Endpoint_Read_Stream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Read_Stream_LE Bin/EndpointStream_XMEGA.o + Bin/RNDISClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o +Endpoint_SelectEndpoint Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/USBTask.o + Bin/DeviceStandardReq.o +Endpoint_StallTransaction Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/MassStorageClassDevice.o + Bin/DeviceStandardReq.o +Endpoint_WaitUntilReady Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o +Endpoint_Write_8 Bin/Endpoint_XMEGA.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/DeviceStandardReq.o +Endpoint_Write_Control_EStream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Write_Control_EStream_LE Bin/EndpointStream_XMEGA.o +Endpoint_Write_Control_PStream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Write_Control_PStream_LE Bin/EndpointStream_XMEGA.o + Bin/DeviceStandardReq.o +Endpoint_Write_Control_Stream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Write_Control_Stream_LE Bin/EndpointStream_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/HIDClassDevice.o + Bin/AudioClassDevice.o + Bin/DeviceStandardReq.o +Endpoint_Write_EStream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Write_EStream_LE Bin/EndpointStream_XMEGA.o +Endpoint_Write_PStream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Write_PStream_LE Bin/EndpointStream_XMEGA.o +Endpoint_Write_Stream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Write_Stream_LE Bin/EndpointStream_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o +GlobalSettings Bin/LED.o + Bin/Settings.o + Bin/Log.o + Bin/Button.o + Bin/Memory.o + Bin/Configuration.o +HID_Device_ConfigureEndpoints Bin/HIDClassDevice.o +HID_Device_ProcessControlRequest Bin/HIDClassDevice.o +HID_Device_USBTask Bin/HIDClassDevice.o +HexStringToBuffer Bin/Common.o + Bin/Commands.o +ISO14443AAppendCRCA Bin/ISO14443-3A.o + Bin/MifareClassic.o + Bin/MifareUltralight.o +ISO14443ACheckCRCA Bin/ISO14443-3A.o + Bin/MifareClassic.o + Bin/MifareUltralight.o +ISO14443ACodecInit Bin/ISO14443-2A.o + Bin/Configuration.o +ISO14443ACodecTask Bin/ISO14443-2A.o + Bin/Configuration.o +LEDGetFuncByName Bin/LED.o + Bin/Commands.o +LEDGetFuncList Bin/LED.o + Bin/Commands.o +LEDGreenAction Bin/LED.o +LEDInit Bin/LED.o + Bin/Chameleon-Mini.o +LEDRedAction Bin/LED.o +LEDSetFuncById Bin/LED.o +LEDSetFuncByName Bin/LED.o + Bin/Commands.o +LEDTick Bin/LED.o + Bin/Chameleon-Mini.o +LEDTrigger Bin/LED.o + Bin/ISO14443-2A.o + Bin/Terminal.o + Bin/Settings.o + Bin/Memory.o +LanguageString Bin/LUFADescriptors.o +LogFunc Bin/ISO14443-2A.o + Bin/Log.o +LogGetModeByName Bin/Log.o + Bin/Commands.o +LogGetModeList Bin/Log.o + Bin/Commands.o +LogInit Bin/Log.o + Bin/Settings.o + Bin/Chameleon-Mini.o +LogMemClear Bin/Log.o + Bin/Commands.o +LogMemFree Bin/Log.o + Bin/Commands.o +LogMemLoadBlock Bin/Log.o + Bin/Commands.o +LogSetModeById Bin/Log.o +LogSetModeByName Bin/Log.o + Bin/Commands.o +LogTask Bin/Log.o + Bin/Chameleon-Mini.o +LogTick Bin/Log.o + Bin/Chameleon-Mini.o +MIDI_Device_ConfigureEndpoints Bin/MIDIClassDevice.o +MIDI_Device_Flush Bin/MIDIClassDevice.o +MIDI_Device_ReceiveEventPacket Bin/MIDIClassDevice.o +MIDI_Device_SendEventPacket Bin/MIDIClassDevice.o +MIDI_Device_USBTask Bin/MIDIClassDevice.o +MS_Device_ConfigureEndpoints Bin/MassStorageClassDevice.o +MS_Device_ProcessControlRequest Bin/MassStorageClassDevice.o +MS_Device_USBTask Bin/MassStorageClassDevice.o +ManufacturerString Bin/LUFADescriptors.o +MemoryClear Bin/Memory.o + Bin/Commands.o +MemoryDownloadBlock Bin/Memory.o + Bin/Commands.o +MemoryInit Bin/Memory.o + Bin/Chameleon-Mini.o +MemoryReadBlock Bin/Memory.o + Bin/MifareClassic.o + Bin/MifareUltralight.o +MemoryRecall Bin/Memory.o + Bin/Settings.o + Bin/Button.o +MemoryStore Bin/Memory.o + Bin/Settings.o + Bin/Button.o +MemoryUploadBlock Bin/Memory.o + Bin/Commands.o +MemoryWriteBlock Bin/Memory.o + Bin/MifareClassic.o + Bin/MifareUltralight.o +MifareClassicAppInit1K Bin/MifareClassic.o + Bin/Configuration.o +MifareClassicAppInit4K Bin/MifareClassic.o + Bin/Configuration.o +MifareClassicAppProcess Bin/MifareClassic.o + Bin/Configuration.o +MifareClassicAppReset Bin/MifareClassic.o + Bin/Configuration.o +MifareClassicAppTask Bin/MifareClassic.o + Bin/Configuration.o +MifareClassicGetUid Bin/MifareClassic.o + Bin/Configuration.o +MifareClassicSetUid Bin/MifareClassic.o + Bin/Configuration.o +MifarePlus1kAppInit_7B Bin/MifareClassic.o + Bin/Configuration.o +MifareUltralightAppInit Bin/MifareUltralight.o + Bin/Configuration.o +MifareUltralightAppProcess Bin/MifareUltralight.o + Bin/Configuration.o +MifareUltralightAppReset Bin/MifareUltralight.o + Bin/Configuration.o +MifareUltralightAppTask Bin/MifareUltralight.o + Bin/Configuration.o +MifareUltralightGetUid Bin/MifareUltralight.o + Bin/Configuration.o +MifareUltralightSetUid Bin/MifareUltralight.o + Bin/Configuration.o +PRNT_Device_BytesReceived Bin/PrinterClassDevice.o +PRNT_Device_ConfigureEndpoints Bin/PrinterClassDevice.o +PRNT_Device_CreateBlockingStream Bin/PrinterClassDevice.o +PRNT_Device_CreateStream Bin/PrinterClassDevice.o +PRNT_Device_Event_Stub Bin/PrinterClassDevice.o +PRNT_Device_Flush Bin/PrinterClassDevice.o +PRNT_Device_ProcessControlRequest Bin/PrinterClassDevice.o +PRNT_Device_ReceiveByte Bin/PrinterClassDevice.o +PRNT_Device_SendByte Bin/PrinterClassDevice.o +PRNT_Device_SendData Bin/PrinterClassDevice.o +PRNT_Device_SendString Bin/PrinterClassDevice.o +PRNT_Device_USBTask Bin/PrinterClassDevice.o +ProductString Bin/LUFADescriptors.o +RNDIS_Device_ConfigureEndpoints Bin/RNDISClassDevice.o +RNDIS_Device_IsPacketReceived Bin/RNDISClassDevice.o +RNDIS_Device_ProcessControlRequest Bin/RNDISClassDevice.o +RNDIS_Device_ReadPacket Bin/RNDISClassDevice.o +RNDIS_Device_SendPacket Bin/RNDISClassDevice.o +RNDIS_Device_USBTask Bin/RNDISClassDevice.o +RandomGetBuffer Bin/Random.o + Bin/MifareClassic.o +RandomGetByte Bin/Random.o + Bin/Commands.o + Bin/Button.o +RandomInit Bin/Random.o + Bin/Chameleon-Mini.o +RandomTick Bin/Random.o + Bin/Chameleon-Mini.o +SettingsCycle Bin/Settings.o + Bin/Button.o +SettingsGetActiveById Bin/Settings.o +SettingsGetActiveByName Bin/Settings.o + Bin/Commands.o +SettingsLoad Bin/Settings.o + Bin/Chameleon-Mini.o +SettingsSave Bin/Settings.o + Bin/Commands.o +SettingsSetActiveById Bin/Settings.o +SettingsSetActiveByName Bin/Settings.o + Bin/Commands.o +StoredSettings Bin/Settings.o +SystemEnterBootloader Bin/System.o + Bin/Commands.o +SystemInit Bin/System.o + Bin/Chameleon-Mini.o +SystemInterruptInit Bin/System.o + Bin/Chameleon-Mini.o +SystemReset Bin/System.o + Bin/Commands.o +SystemStartUSBClock Bin/System.o + Bin/Terminal.o +SystemStopUSBClock Bin/System.o + Bin/Terminal.o +TerminalBuffer Bin/CommandLine.o + Bin/XModem.o + Bin/Terminal.o +TerminalHandle Bin/Terminal.o + Bin/XModem.o + Bin/Log.o +TerminalInit Bin/Terminal.o + Bin/Chameleon-Mini.o +TerminalSendBlock Bin/Terminal.o + Bin/XModem.o + Bin/Log.o +TerminalSendString Bin/Terminal.o + Bin/CommandLine.o +TerminalSendStringP Bin/Terminal.o + Bin/CommandLine.o +TerminalState Bin/Terminal.o +TerminalTask Bin/Terminal.o + Bin/Chameleon-Mini.o +TerminalTick Bin/Terminal.o + Bin/Chameleon-Mini.o +USB_ControlRequest Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/Endpoint_XMEGA.o + Bin/EndpointStream_XMEGA.o + Bin/USBTask.o + Bin/DeviceStandardReq.o +USB_DeviceState Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/USBInterrupt_XMEGA.o + Bin/USBController_XMEGA.o + Bin/Endpoint_XMEGA.o + Bin/EndpointStream_XMEGA.o + Bin/USBTask.o + Bin/DeviceStandardReq.o +USB_Device_ConfigurationNumber Bin/USBInterrupt_XMEGA.o + Bin/USBController_XMEGA.o + Bin/DeviceStandardReq.o +USB_Device_CurrentlySelfPowered Bin/USBController_XMEGA.o + Bin/DeviceStandardReq.o +USB_Device_ProcessControlRequest Bin/DeviceStandardReq.o + Bin/USBTask.o +USB_Device_RemoteWakeupEnabled Bin/USBController_XMEGA.o + Bin/DeviceStandardReq.o +USB_Device_SendRemoteWakeup Bin/Device_XMEGA.o +USB_Disable Bin/USBController_XMEGA.o + Bin/Commands.o + Bin/Terminal.o +USB_EndpointTable Bin/USBController_XMEGA.o +USB_Endpoint_FIFOs Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/Endpoint_XMEGA.o + Bin/DeviceStandardReq.o +USB_Endpoint_SelectedEndpoint Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/CDCClassDevice.o + Bin/Endpoint_XMEGA.o + Bin/EndpointStream_XMEGA.o + Bin/USBTask.o +USB_Endpoint_SelectedFIFO Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/Endpoint_XMEGA.o + Bin/EndpointStream_XMEGA.o +USB_Endpoint_SelectedHandle Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/Endpoint_XMEGA.o + Bin/DeviceStandardReq.o +USB_Event_Stub Bin/Events.o +USB_GetHIDReportItemInfo Bin/HIDParser.o +USB_GetHIDReportSize Bin/HIDParser.o +USB_GetNextDescriptorComp Bin/ConfigDescriptors.o +USB_GetNextDescriptorOfType Bin/ConfigDescriptors.o +USB_GetNextDescriptorOfTypeAfter Bin/ConfigDescriptors.o +USB_GetNextDescriptorOfTypeBefore Bin/ConfigDescriptors.o +USB_INT_ClearAllInterrupts Bin/USBInterrupt_XMEGA.o + Bin/USBController_XMEGA.o +USB_INT_DisableAllInterrupts Bin/USBInterrupt_XMEGA.o + Bin/USBController_XMEGA.o +USB_Init Bin/USBController_XMEGA.o + Bin/Terminal.o +USB_IsInitialized Bin/USBController_XMEGA.o + Bin/USBTask.o +USB_ProcessHIDReport Bin/HIDParser.o +USB_ResetInterface Bin/USBController_XMEGA.o +USB_SetHIDReportItemInfo Bin/HIDParser.o +USB_USBTask Bin/USBTask.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/Terminal.o +XModemProcessByte Bin/XModem.o + Bin/Terminal.o +XModemReceive Bin/XModem.o + Bin/Commands.o +XModemSend Bin/XModem.o + Bin/Commands.o +XModemTick Bin/XModem.o + Bin/Terminal.o +__bad_interrupt c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__bss_end c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) +__bss_start c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) +__data_end c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) +__data_load_start c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) +__data_start c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) +__divmodsi4 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) +__do_clear_bss c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_clear_bss.o) + Bin/USBController_XMEGA.o + Bin/Endpoint_XMEGA.o + Bin/USBTask.o + Bin/DeviceStandardReq.o + Bin/Crypto1.o + Bin/MifareClassic.o + Bin/MifareUltralight.o + Bin/ISO14443-2A.o + Bin/Codec.o + Bin/CommandLine.o + Bin/XModem.o + Bin/Terminal.o + Bin/LED.o + Bin/Settings.o + Bin/Log.o + Bin/Button.o + Bin/Memory.o + Bin/Configuration.o +__do_copy_data c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_copy_data.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + Bin/RNDISClassDevice.o + Bin/CDCClassDevice.o + Bin/Crypto1.o + Bin/Commands.o + Bin/Terminal.o +__eerd_block_x32a4u c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + Bin/Settings.o +__eerd_byte_x32a4u c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + Bin/EndpointStream_XMEGA.o +__eeupd_byte_x32a4u c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + Bin/EndpointStream_XMEGA.o +__eeupd_r18_x32a4u c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) +__eewr_block_x32a4u c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + Bin/Settings.o +__eewr_byte_x32a4u c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) +__eewr_r18_x32a4u c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) +__epilogue_restores__ c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_epilogue.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) +__heap_end c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__init c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__mulohisi3 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) +__mulshisi3 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) + Bin/Commands.o +__muluhisi3 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_mulshisi3.o) +__prologue_saves__ c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_prologue.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) +__stack c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__tablejump2__ c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_tablejump.o) + Bin/HIDParser.o +__tablejump__ c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_tablejump.o) +__udivmodsi4 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_udivmodsi4.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_divmodsi4.o) +__ultoa_invert c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) +__umulhisi3 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_umulhisi3.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_muluhisi3.o) +__vector_1 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_10 Bin/System.o + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_100 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_101 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_102 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_103 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_104 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_105 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_106 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_107 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_108 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_109 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_11 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_110 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_111 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_112 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_113 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_114 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_115 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_116 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_117 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_118 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_119 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_12 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_120 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_121 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_122 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_123 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_124 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_125 Bin/USBInterrupt_XMEGA.o + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_126 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_13 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_14 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_15 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_16 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_17 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_18 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_19 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_2 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_20 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_21 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_22 Bin/ISO14443-2A.o + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_23 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_24 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_25 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_26 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_27 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_28 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_29 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_3 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_30 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_31 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_32 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_33 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_34 Bin/ISO14443-2A.o + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_35 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_36 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_37 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_38 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_39 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_4 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_40 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_41 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_42 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_43 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_44 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_45 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_46 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_47 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_48 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_49 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_5 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_50 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_51 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_52 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_53 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_54 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_55 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_56 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_57 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_58 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_59 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_6 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_60 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_61 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_62 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_63 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_64 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_65 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_66 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_67 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_68 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_69 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_7 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_70 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_71 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_72 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_73 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_74 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_75 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_76 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_77 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_78 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_79 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_8 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_80 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_81 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_82 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_83 Bin/ISO14443-2A.o + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_84 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_85 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_86 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_87 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_88 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_89 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_9 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_90 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_91 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_92 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_93 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_94 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_95 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_96 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_97 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_98 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_99 c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_default Bin/System.o + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vectors c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +_exit c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) +eeprom_mapen c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) +exit c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/avrxmega2\libgcc.a(_exit.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +fputc c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) +main Bin/Chameleon-Mini.o + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +memcmp c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + Bin/HIDClassDevice.o +memcpy c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + Bin/RNDISClassDevice.o + Bin/HIDClassDevice.o +memcpy_P c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + Bin/RNDISClassDevice.o + Bin/Configuration.o +memset c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + Bin/HIDClassDevice.o +rand c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + Bin/Random.o +rand_r c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) +snprintf_P c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + Bin/Commands.o +srand c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) +strcmp_P c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + Bin/CommandLine.o + Bin/Commands.o + Bin/LED.o + Bin/Log.o + Bin/Button.o +strncat_P c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncat_P.o) + Bin/Log.o +strncpy_P c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + Bin/LED.o + Bin/Log.o + Bin/Button.o +strnlen c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) +strnlen_P c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) +vfprintf c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + c:/program files (x86)/atmel/atmel toolchain/avr8 gcc/native/3.4.2.1002/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.7.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.sym b/Firmware/Chameleon-Mini/Chameleon-Mini.sym index 0f11987..47e8088 100644 --- a/Firmware/Chameleon-Mini/Chameleon-Mini.sym +++ b/Firmware/Chameleon-Mini/Chameleon-Mini.sym @@ -1,731 +1,806 @@ - U CALLBACK_Audio_Device_GetSetEndpointProperty - U CALLBACK_Audio_Device_GetSetInterfaceProperty - U CALLBACK_HID_Device_CreateHIDReport - U CALLBACK_HID_Device_ProcessHIDReport - U CALLBACK_HIDParser_FilterHIDReportItem - U CALLBACK_MS_Device_SCSICommandReceived -00000000 W __heap_end -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 a __tmp_reg__ -00000000 T __vectors -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000001 a __zero_reg__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -00000034 a __CCP__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003d a __SP_L__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003e a __SP_H__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000003f a __SREG__ -0000024c T ProductString -0000024c T __trampolines_end -0000024c T __trampolines_start -0000026a T ManufacturerString -00000284 T LanguageString -00000288 T ConfigurationDescriptor -000002c6 T DeviceDescriptor -000002d8 t ConfigurationTable -00000347 t ButtonActionTable -00000467 t __c.6505 -0000046e t __c.6466 -00000471 t __c.6461 -00000474 t __c.6434 -0000047b t __c.6416 -0000047e t __c.6405 -000004b7 t __c.6407 -000004be t __c.6409 -000004c5 t __c.6411 -000004cb t __c.6197 -000004ce t __c.6195 -000004d1 t StatusTable -00000597 T CommandTable -000006f8 T __ctors_end -000006f8 T __ctors_start -000006f8 T __dtors_end -000006f8 T __dtors_start -000006f8 W __init -00000704 T __do_copy_data -0000071a T __do_clear_bss -00000722 t .do_clear_bss_loop -00000724 t .do_clear_bss_start -00000730 T __bad_interrupt -00000730 W __vector_1 -00000730 W __vector_10 -00000730 W __vector_100 -00000730 W __vector_101 -00000730 W __vector_102 -00000730 W __vector_103 -00000730 W __vector_104 -00000730 W __vector_105 -00000730 W __vector_106 -00000730 W __vector_107 -00000730 W __vector_108 -00000730 W __vector_109 -00000730 W __vector_11 -00000730 W __vector_110 -00000730 W __vector_111 -00000730 W __vector_112 -00000730 W __vector_113 -00000730 W __vector_114 -00000730 W __vector_115 -00000730 W __vector_116 -00000730 W __vector_117 -00000730 W __vector_118 -00000730 W __vector_119 -00000730 W __vector_12 -00000730 W __vector_120 -00000730 W __vector_121 -00000730 W __vector_122 -00000730 W __vector_123 -00000730 W __vector_124 -00000730 W __vector_126 -00000730 W __vector_13 -00000730 W __vector_14 -00000730 W __vector_15 -00000730 W __vector_16 -00000730 W __vector_17 -00000730 W __vector_18 -00000730 W __vector_19 -00000730 W __vector_2 -00000730 W __vector_20 -00000730 W __vector_21 -00000730 W __vector_23 -00000730 W __vector_24 -00000730 W __vector_25 -00000730 W __vector_26 -00000730 W __vector_27 -00000730 W __vector_28 -00000730 W __vector_29 -00000730 W __vector_3 -00000730 W __vector_30 -00000730 W __vector_31 -00000730 W __vector_32 -00000730 W __vector_33 -00000730 W __vector_35 -00000730 W __vector_36 -00000730 W __vector_37 -00000730 W __vector_38 -00000730 W __vector_39 -00000730 W __vector_4 -00000730 W __vector_40 -00000730 W __vector_41 -00000730 W __vector_42 -00000730 W __vector_43 -00000730 W __vector_44 -00000730 W __vector_45 -00000730 W __vector_46 -00000730 W __vector_47 -00000730 W __vector_48 -00000730 W __vector_49 -00000730 W __vector_5 -00000730 W __vector_50 -00000730 W __vector_51 -00000730 W __vector_52 -00000730 W __vector_53 -00000730 W __vector_54 -00000730 W __vector_55 -00000730 W __vector_56 -00000730 W __vector_57 -00000730 W __vector_58 -00000730 W __vector_59 -00000730 W __vector_6 -00000730 W __vector_60 -00000730 W __vector_61 -00000730 W __vector_62 -00000730 W __vector_63 -00000730 W __vector_64 -00000730 W __vector_65 -00000730 W __vector_66 -00000730 W __vector_67 -00000730 W __vector_68 -00000730 W __vector_69 -00000730 W __vector_7 -00000730 W __vector_70 -00000730 W __vector_71 -00000730 W __vector_72 -00000730 W __vector_73 -00000730 W __vector_74 -00000730 W __vector_75 -00000730 W __vector_76 -00000730 W __vector_77 -00000730 W __vector_78 -00000730 W __vector_79 -00000730 W __vector_8 -00000730 W __vector_80 -00000730 W __vector_81 -00000730 W __vector_82 -00000730 W __vector_84 -00000730 W __vector_85 -00000730 W __vector_86 -00000730 W __vector_87 -00000730 W __vector_88 -00000730 W __vector_89 -00000730 W __vector_9 -00000730 W __vector_90 -00000730 W __vector_91 -00000730 W __vector_92 -00000730 W __vector_93 -00000730 W __vector_94 -00000730 W __vector_95 -00000730 W __vector_96 -00000730 W __vector_97 -00000730 W __vector_98 -00000730 W __vector_99 -00000732 T main -000007a8 T CALLBACK_USB_GetDescriptor -00000824 T __vector_default -00000830 T SystemInit -0000089e T SystemReset -000008ac T SystemEnterBootloader -000008b8 T SystemStartUSBClock -000008ea T SystemStopUSBClock -00000906 T SystemInterruptInit -00000912 t CodecInitDummy -00000914 t CodecTaskDummy -00000916 t ApplicationInitDummy -00000918 t ApplicationResetDummy -0000091a t ApplicationTaskDummy -0000091c t ApplicationProcessDummy -00000922 t ApplicationGetUidDummy -00000924 t ApplicationSetUidDummy -00000926 T ConfigurationSetById -0000095c T ConfigurationInit -00000968 T ConfigurationSetByName -000009e2 T ConfigurationGetList -00000a56 T RandomInit -00000a58 T RandomGetByte -00000a5e T RandomGetBuffer -00000a7e T RandomTick -00000a8e T BufferToHexString -00000b14 T HexStringToBuffer -00000ba8 T MemoryReadBlock -00000bd8 T MemoryWriteBlock -00000c06 T MemoryClear -00000c1c T MemoryRecall -00000d08 T MemoryInit -00000e04 T MemoryStore -0000107e T MemoryUploadBlock -00001410 T MemoryDownloadBlock -0000148a T ButtonInit -00001498 T ButtonTick -00001652 T ButtonGetActionList -000016c4 T ButtonGetActionByName -000016e0 T ButtonSetActionByName -000017a0 T SettingsLoad -000017b0 T SettingsSave -000017c0 T SettingsSetActiveById -000017fc T SettingsCycle -000018d6 T SettingsGetActiveByName -000018e4 T SettingsSetActiveByName -000018fe T TerminalSendString -00001908 T TerminalSendStringP -00001930 T TerminalSendBlock -0000193c T TerminalInit -00001946 T TerminalTask -00001984 T TerminalTick -00001a04 T EVENT_USB_Device_Connect -00001a0e T EVENT_USB_Device_Disconnect -00001a18 T EVENT_USB_Device_ConfigurationChanged -00001a20 T EVENT_USB_Device_ControlRequest -00001a28 T CommandGetVersion -00001a64 T CommandGetConfig -00001a90 T CommandSetConfig -00001aa2 T CommandExecConfig -00001aae T CommandGetUid -00001b02 T CommandSetUid -00001ba6 T CommandGetReadOnly -00001bca T CommandSetReadOnly -00001bf2 T CommandExecUpload -00001bfc T CommandExecDownload -00001c06 T CommandExecReset -00001c1c T CommandExecUpgrade -00001c32 T CommandGetMemSize -00001c62 T CommandGetUidSize -00001c8e T CommandExecButton -00001c98 T CommandGetButton -00001ca2 T CommandSetButton -00001cb2 T CommandGetSetting -00001cbc T CommandSetSetting -00001ccc T CommandExecClear -00001cd4 T CommandExecHelp -00001d68 T CommandGetRssi -00001dd0 T XModemReceive -00001e00 T XModemSend -00001e26 T XModemProcessByte -000020e8 T XModemTick -00002144 T CommandLineProcessByte -00002490 T CommandLineTick -00002492 t StartDemod -000024ce T __vector_34 -00002556 T __vector_22 -000026ca T __vector_83 -00002886 T ISO14443ACodecInit -000028f4 T ISO14443ACodecTask -000029ea T MifareClassicAppInit1K -00002a04 T MifareClassicAppInit4K -00002a1e T MifareClassicAppReset -00002a26 T MifareClassicAppTask -00002a28 T MifareClassicAppProcess -00002fff W __stack -000031ce T MifareClassicGetUid -000031da T MifareClassicSetUid -0000321a T ISO14443AAppendCRCA -00003276 T ISO14443ACheckCRCA -000032f2 t Crypto1LFSR -0000337e T Crypto1FilterOutput -000033e2 T Crypto1Setup -0000357c T Crypto1Auth -000035c6 T Crypto1Byte -000035ec T Crypto1Nibble -00003612 T Crypto1PRNG -000036b2 T USB_Device_ProcessControlRequest -000038f2 W EVENT_USB_Device_Reset -000038f2 W EVENT_USB_Device_StartOfFrame -000038f2 W EVENT_USB_Device_Suspend -000038f2 W EVENT_USB_Device_WakeUp -000038f2 T USB_Event_Stub -000038f4 T USB_USBTask -0000391e T Endpoint_Write_Stream_LE -000039e6 T Endpoint_Write_Control_Stream_LE -00003b10 T Endpoint_Write_Control_PStream_LE -00003c68 T Endpoint_ClearIN -00003c9a T Endpoint_ClearOUT -00003cb8 T Endpoint_Read_8 -00003cd8 T Endpoint_Write_8 -00003cf8 T Endpoint_SelectEndpoint -00003d6a T Endpoint_IsINReady -00003d82 T Endpoint_IsOUTReceived -00003db4 T Endpoint_IsSETUPReceived -00003de6 T Endpoint_ClearSETUP -00003e3e T Endpoint_StallTransaction -00003e76 T Endpoint_ConfigureEndpoint_PRV -00003f0c T Endpoint_ConfigureEndpointTable -00003fe4 T Endpoint_ClearEndpoints -00004054 T Endpoint_ClearStatusStage -00004080 T Endpoint_WaitUntilReady -00004126 T USB_Disable -00004140 T USB_ResetInterface -0000419c T USB_Init -000041ec T USB_INT_DisableAllInterrupts -000041fa T USB_INT_ClearAllInterrupts -00004206 T __vector_125 -000042e0 T CDC_Device_ConfigureEndpoints -0000432a T CDC_Device_SendString -00004374 T CDC_Device_SendData -000043c8 T CDC_Device_SendByte -00004432 T CDC_Device_Flush -000044ae T CDC_Device_USBTask -000044e4 T CDC_Device_ReceiveByte -0000459c T CDC_Device_Event_Stub -0000459c W EVENT_CDC_Device_BreakSent -0000459c W EVENT_CDC_Device_ControLineStateChanged -0000459c W EVENT_CDC_Device_LineEncodingChanged -0000459e T CDC_Device_ProcessControlRequest -000046d2 T __tablejump2__ -000046d6 T __tablejump__ -000046de T __mulshisi3 -000046e2 T __mulohisi3 -000046ea T __muluhisi3 -000046fe T __umulhisi3 -0000471c t do_rand -000047ac T rand_r -000047ae T rand -000047b4 T srand -000047ca T memcpy_P -000047dc T strcmp_P -000047ee T strncpy_P -0000480c T memcpy -0000481e T snprintf_P -00004878 T vfprintf -00004bfe T __eerd_block_x32a4u -00004c14 T __eewr_block_x32a4u -00004c26 T __eewr_byte_x32a4u -00004c28 T __eewr_r18_x32a4u -00004c6c T strnlen_P -00004c82 T strnlen -00004c98 T fputc -00004cfc T __ultoa_invert -00004db8 T __divmodsi4 -00004dd0 t __divmodsi4_neg2 -00004dde t __divmodsi4_exit -00004de0 T __negsi2 -00004df0 T __prologue_saves__ -00004e22 T __epilogue_restores__ -00004e52 T __udivmodsi4 -00004e5e t __udivmodsi4_loop -00004e78 t __udivmodsi4_ep -00004e96 W exit -00004e96 T _exit -00004e98 t __stop_program -00004e9a A __data_load_start -00004e9a T _etext -00004f2c A __data_load_end -00802000 D __data_start -00802000 d TerminalInitDelay -00802001 D TerminalHandle -0080201c d next -00802020 d TableC -00802040 d TableAB -00802092 B __bss_start -00802092 D __data_end -00802092 D _edata -00802092 b Memory -00802492 b LastButtonState.4250 -00802493 B LEDPulseMask -00802494 B TerminalState -00802495 b CallbackFunc -00802497 b BlockAddress -0080249b b BufferIdx -0080249d b RetryTimeout -0080249e b RetryCount -0080249f b Checksum -008024a0 b ReceivedFrameNumber -008024a1 b CurrentFrameNumber -008024a2 b State -008024a3 b BufferIdx -008024a5 b SamplePosition -008024a6 b LoadModState -008024a7 b LastBit -008024a8 b IsParityBit -008024a9 b SampleRegister -008024aa b DataRegister -008024ab b BitSent -008024ad b BitCount -008024af b ParityBufferPtr -008024b1 b CodecBufferPtr -008024b3 b Flags -008024b5 b CardSAKValue -008024b6 b CardATQAValue -008024b8 b BlockBuffer -008024c8 b CurrentAddress -008024c9 b ReaderResponse -008024cd b CardResponse -008024d1 b State -008024d2 b StateOdd -008024d5 b StateEven -008024d8 B ActiveConfiguration -008024fd B GlobalSettings -00802510 B TerminalBuffer -00802610 B CodecBuffer -00802710 B USB_Device_ConfigurationNumber -00802711 B USB_Device_CurrentlySelfPowered -00802712 B USB_Device_RemoteWakeupEnabled -00802713 B USB_IsInitialized -00802714 B USB_DeviceState -00802715 B USB_ControlRequest -0080271d B USB_Endpoint_SelectedFIFO -0080271f B USB_Endpoint_SelectedHandle -00802721 B USB_Endpoint_SelectedEndpoint -00802722 B USB_Endpoint_FIFOs -00802a3a B USB_EndpointTable -00802a9d B __bss_end -00802a9d B _end -00810000 D StoredSettings -00810013 D __eeprom_end + U CALLBACK_Audio_Device_GetSetEndpointProperty + U CALLBACK_Audio_Device_GetSetInterfaceProperty + U CALLBACK_HID_Device_CreateHIDReport + U CALLBACK_HID_Device_ProcessHIDReport + U CALLBACK_HIDParser_FilterHIDReportItem + U CALLBACK_MS_Device_SCSICommandReceived +00000000 W __heap_end +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 T __vectors +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +000001fc T ProductString +0000021a T ManufacturerString +00000234 T LanguageString +00000238 T ConfigurationDescriptor +00000276 T DeviceDescriptor +00000288 t ConfigurationTable +00000366 t ButtonActionTable +00000486 t LogModeTable +000004b6 t __c.6349 +000004b8 t LEDFuncTable +000005b8 t __c.6462 +000005f1 t __c.6464 +000005f8 t __c.6466 +000005ff t __c.6468 +00000605 t __c.6473 +00000608 t __c.6491 +0000060f t __c.6518 +00000612 t __c.6523 +00000615 t __c.6573 +0000061b t __c.6575 +00000623 t __c.6577 +00000629 t __c.6582 +0000062c t __c.6587 +00000634 t __c.6589 +0000063a t __c.6619 +00000641 T CommandTable +0000080f t __c.6126 +00000812 t __c.6128 +00000815 t StatusTable +000008dc T __ctors_end +000008dc T __ctors_start +000008dc T __dtors_end +000008dc T __dtors_start +000008dc W __init +000008dc T __trampolines_end +000008dc T __trampolines_start +000008e8 T __do_copy_data +000008fe T __do_clear_bss +00000906 t .do_clear_bss_loop +00000908 t .do_clear_bss_start +00000914 T __bad_interrupt +00000914 W __vector_1 +00000914 W __vector_100 +00000914 W __vector_101 +00000914 W __vector_102 +00000914 W __vector_103 +00000914 W __vector_104 +00000914 W __vector_105 +00000914 W __vector_106 +00000914 W __vector_107 +00000914 W __vector_108 +00000914 W __vector_109 +00000914 W __vector_11 +00000914 W __vector_110 +00000914 W __vector_111 +00000914 W __vector_112 +00000914 W __vector_113 +00000914 W __vector_114 +00000914 W __vector_115 +00000914 W __vector_116 +00000914 W __vector_117 +00000914 W __vector_118 +00000914 W __vector_119 +00000914 W __vector_12 +00000914 W __vector_120 +00000914 W __vector_121 +00000914 W __vector_122 +00000914 W __vector_123 +00000914 W __vector_124 +00000914 W __vector_126 +00000914 W __vector_13 +00000914 W __vector_14 +00000914 W __vector_15 +00000914 W __vector_16 +00000914 W __vector_17 +00000914 W __vector_18 +00000914 W __vector_19 +00000914 W __vector_2 +00000914 W __vector_20 +00000914 W __vector_21 +00000914 W __vector_23 +00000914 W __vector_24 +00000914 W __vector_25 +00000914 W __vector_26 +00000914 W __vector_27 +00000914 W __vector_28 +00000914 W __vector_29 +00000914 W __vector_3 +00000914 W __vector_30 +00000914 W __vector_31 +00000914 W __vector_32 +00000914 W __vector_33 +00000914 W __vector_35 +00000914 W __vector_36 +00000914 W __vector_37 +00000914 W __vector_38 +00000914 W __vector_39 +00000914 W __vector_4 +00000914 W __vector_40 +00000914 W __vector_41 +00000914 W __vector_42 +00000914 W __vector_43 +00000914 W __vector_44 +00000914 W __vector_45 +00000914 W __vector_46 +00000914 W __vector_47 +00000914 W __vector_48 +00000914 W __vector_49 +00000914 W __vector_5 +00000914 W __vector_50 +00000914 W __vector_51 +00000914 W __vector_52 +00000914 W __vector_53 +00000914 W __vector_54 +00000914 W __vector_55 +00000914 W __vector_56 +00000914 W __vector_57 +00000914 W __vector_58 +00000914 W __vector_59 +00000914 W __vector_6 +00000914 W __vector_60 +00000914 W __vector_61 +00000914 W __vector_62 +00000914 W __vector_63 +00000914 W __vector_64 +00000914 W __vector_65 +00000914 W __vector_66 +00000914 W __vector_67 +00000914 W __vector_68 +00000914 W __vector_69 +00000914 W __vector_7 +00000914 W __vector_70 +00000914 W __vector_71 +00000914 W __vector_72 +00000914 W __vector_73 +00000914 W __vector_74 +00000914 W __vector_75 +00000914 W __vector_76 +00000914 W __vector_77 +00000914 W __vector_78 +00000914 W __vector_79 +00000914 W __vector_8 +00000914 W __vector_80 +00000914 W __vector_81 +00000914 W __vector_82 +00000914 W __vector_84 +00000914 W __vector_85 +00000914 W __vector_86 +00000914 W __vector_87 +00000914 W __vector_88 +00000914 W __vector_89 +00000914 W __vector_9 +00000914 W __vector_90 +00000914 W __vector_91 +00000914 W __vector_92 +00000914 W __vector_93 +00000914 W __vector_94 +00000914 W __vector_95 +00000914 W __vector_96 +00000914 W __vector_97 +00000914 W __vector_98 +00000914 W __vector_99 +00000916 T main +000009a2 T CALLBACK_USB_GetDescriptor +00000a24 T __vector_default +00000a30 T __vector_10 +00000a32 T SystemInit +00000ab8 T SystemReset +00000ac6 T SystemEnterBootloader +00000ad2 T SystemStartUSBClock +00000b0e T SystemStopUSBClock +00000b34 T SystemInterruptInit +00000b40 t CodecInitDummy +00000b42 t CodecTaskDummy +00000b44 t ApplicationInitDummy +00000b46 t ApplicationResetDummy +00000b48 t ApplicationTaskDummy +00000b4a t ApplicationProcessDummy +00000b50 t ApplicationGetUidDummy +00000b52 t ApplicationSetUidDummy +00000b54 T ConfigurationSetById +00000b8a T ConfigurationInit +00000b96 T ConfigurationSetByName +00000c18 T ConfigurationGetList +00000c76 T RandomInit +00000c78 T RandomGetByte +00000c7e T RandomGetBuffer +00000c9c T RandomTick +00000cac T BufferToHexString +00000d30 T HexStringToBuffer +00000dbc T MemoryReadBlock +00000dec T MemoryWriteBlock +00000e24 T MemoryClear +00000e34 T MemoryRecall +00000f20 T MemoryInit +0000101e T MemoryStore +000012ac T MemoryUploadBlock +00001636 T MemoryDownloadBlock +000016b0 t ExecuteButtonAction +0000185a T ButtonInit +00001868 T ButtonTick +000018b2 T ButtonGetActionList +00001916 T ButtonSetActionById +00001964 T ButtonGetActionByName +0000199c T ButtonSetActionByName +00001a60 t LogFuncOff +00001a62 t LogFuncTerminal +00001a8e T LogTick +00001a90 T LogTask +00001a92 T LogMemLoadBlock +00001ac2 T LogMemClear +00001aec T LogMemFree +00001af6 T LogSetModeById +00001b36 t LogFuncMemory +00001ba4 T LogInit +00001bb2 T LogSetModeByName +00001bfc T LogGetModeByName +00001c18 T LogGetModeList +00001c68 T SettingsLoad +00001c78 T SettingsSave +00001c88 T SettingsSetActiveById +00001cec T SettingsCycle +00001e0c T SettingsGetActiveById +00001e14 T SettingsGetActiveByName +00001e28 T SettingsSetActiveByName +00001e3a T LEDInit +00001e44 T LEDTick +00001f5e T LEDTrigger +00001f7e T LEDGetFuncList +00001fe2 T LEDSetFuncById +0000208e T LEDGetFuncByName +000020c8 T LEDSetFuncByName +00002178 T TerminalSendString +00002182 T TerminalSendStringP +000021aa T TerminalSendBlock +000021b6 T TerminalInit +000021c0 T TerminalTask +00002202 T TerminalTick +00002282 T EVENT_USB_Device_Connect +00002288 T EVENT_USB_Device_Disconnect +0000228e T EVENT_USB_Device_ConfigurationChanged +00002296 T EVENT_USB_Device_ControlRequest +0000229e T CommandGetVersion +000022da T CommandGetConfig +00002306 T CommandSetConfig +00002318 T CommandExecConfig +00002324 T CommandGetUid +00002372 T CommandSetUid +00002424 T CommandGetReadOnly +00002448 T CommandSetReadOnly +00002470 T CommandExecUpload +0000247a T CommandExecDownload +00002484 T CommandExecReset +0000249a T CommandExecUpgrade +000024b0 T CommandGetMemSize +000024e0 T CommandGetUidSize +0000250c T CommandExecButton +00002516 T CommandGetButton +00002524 T CommandSetButton +00002538 T CommandExecButtonLong +00002542 T CommandGetButtonLong +00002550 T CommandSetButtonLong +00002564 T CommandExecLedGreen +0000256e T CommandGetLedGreen +0000257c T CommandSetLedGreen +00002590 T CommandExecLedRed +0000259a T CommandGetLedRed +000025a8 T CommandSetLedRed +000025bc T CommandExecLogMode +000025c6 T CommandGetLogMode +000025d0 T CommandSetLogMode +000025e0 T CommandExecLogMem +00002614 T CommandGetLogMem +00002648 T CommandSetLogMem +00002688 T CommandGetSetting +00002692 T CommandSetSetting +000026a2 T CommandExecClear +000026aa T CommandExecHelp +00002742 T CommandGetRssi +000027aa t CalcChecksum.constprop.0 +000027be T XModemReceive +000027f4 T XModemSend +00002820 T XModemProcessByte +00002ab6 T XModemTick +00002b2c T CommandLineProcessByte +00002d3a T CommandLineTick +00002d3c t StartDemod +00002db6 T __vector_34 +00002e18 T __vector_22 +00002f60 T __vector_83 +00002fff W __stack +00003142 T ISO14443ACodecInit +000031b0 T ISO14443ACodecTask +00003312 T MifareUltralightAppInit +0000331a T MifareUltralightAppReset +00003322 T MifareUltralightAppTask +00003324 T MifareUltralightAppProcess +000035c8 T MifareUltralightGetUid +000035ee T MifareUltralightSetUid +0000366c T MifareClassicAppInit1K +0000368a T MifarePlus1kAppInit_7B +000036b4 T MifareClassicAppInit4K +000036d2 T MifareClassicAppReset +000036da T MifareClassicAppTask +000036dc T MifareClassicAppProcess +00004264 T MifareClassicGetUid +000042a6 T MifareClassicSetUid +00004304 T ISO14443AAppendCRCA +00004362 T ISO14443ACheckCRCA +000043e0 t Crypto1LFSR +0000446c T Crypto1FilterOutput +000044d4 T Crypto1Setup +00004814 T Crypto1Auth +00004866 T Crypto1Byte +000048e8 T Crypto1Nibble +00004930 T Crypto1PRNG +000049e6 T USB_Device_ProcessControlRequest +00004c7c W EVENT_USB_Device_Reset +00004c7c W EVENT_USB_Device_StartOfFrame +00004c7c W EVENT_USB_Device_Suspend +00004c7c W EVENT_USB_Device_WakeUp +00004c7c T USB_Event_Stub +00004c7e T USB_USBTask +00004ca8 T Endpoint_Write_Stream_LE +00004d80 T Endpoint_Write_Control_Stream_LE +00004ec2 T Endpoint_Write_Control_PStream_LE +00005000 T Endpoint_ClearIN +00005032 T Endpoint_ClearOUT +00005050 T Endpoint_Read_8 +0000506e T Endpoint_Write_8 +0000508c T Endpoint_SelectEndpoint +000050fe T Endpoint_StallTransaction +00005136 T Endpoint_ClearSETUP +0000518e T Endpoint_IsSETUPReceived +000051c0 T Endpoint_IsOUTReceived +000051f2 T Endpoint_IsINReady +0000520a T Endpoint_ConfigureEndpoint_PRV +000052a4 T Endpoint_ConfigureEndpointTable +00005390 T Endpoint_ClearEndpoints +00005400 T Endpoint_ClearStatusStage +0000542c T Endpoint_WaitUntilReady +000054d2 T USB_Disable +000054ec T USB_ResetInterface +00005548 T USB_Init +0000559a T USB_INT_DisableAllInterrupts +000055a8 T USB_INT_ClearAllInterrupts +000055b4 T __vector_125 +0000568e T CDC_Device_ConfigureEndpoints +000056d8 T CDC_Device_SendString +0000572a T CDC_Device_SendData +0000577e T CDC_Device_SendByte +000057ec T CDC_Device_Flush +0000587c T CDC_Device_USBTask +000058b2 T CDC_Device_ReceiveByte +00005970 T CDC_Device_Event_Stub +00005970 W EVENT_CDC_Device_BreakSent +00005970 W EVENT_CDC_Device_ControLineStateChanged +00005970 W EVENT_CDC_Device_LineEncodingChanged +00005972 T CDC_Device_ProcessControlRequest +00005aac T __mulshisi3 +00005ab0 T __mulohisi3 +00005ab8 T __muluhisi3 +00005acc T __umulhisi3 +00005ae4 t do_rand +00005b7a T rand_r +00005b7c T rand +00005b82 T srand +00005b98 T memcpy_P +00005baa T strcmp_P +00005bbc T strncat_P +00005bdc T strncpy_P +00005bfa T memcpy +00005c0c T snprintf_P +00005c66 T vfprintf +00006000 T __eerd_block_x32a4u +00006016 T __eewr_block_x32a4u +00006028 T __eewr_byte_x32a4u +0000602a T __eewr_r18_x32a4u +0000606e T strnlen_P +00006084 T strnlen +0000609a T fputc +000060f2 T __ultoa_invert +000061ae T __divmodsi4 +000061c4 t __divmodsi4_neg1 +000061d4 t __divmodsi4_neg2 +000061e2 t __divmodsi4_exit +000061e4 T __prologue_saves__ +00006216 T __epilogue_restores__ +00006246 T __udivmodsi4 +00006252 t __udivmodsi4_loop +0000626c t __udivmodsi4_ep +0000628a T _exit +0000628a W exit +0000628c t __stop_program +0000628e A __data_load_start +0000628e T _etext +00006320 A __data_load_end +00802000 D __data_start +00802000 D TerminalHandle +0080201b d TerminalInitDelay +0080201c d next +00802020 d TableAB +00802070 d TableC +00802092 B __bss_start +00802092 D __data_end +00802092 D _edata +00802092 b Memory +00802492 b PressTickCounter.4306 +00802493 b LogMem +00802893 b LogMemPtr +00802895 b LogMemLeft +00802897 B LEDRedAction +00802898 B LEDGreenAction +00802899 b BlinkPrescaler.4245 +0080289a B TerminalState +0080289b b State +0080289c b CurrentFrameNumber +0080289d b RetryCount +0080289e b RetryTimeout +008028a0 b BlockAddress +008028a4 b CallbackFunc +008028a6 b BufferIdx +008028a8 b Checksum +008028a9 b ReceivedFrameNumber +008028aa b BufferIdx +008028ac b SamplePosition +008028ad b LoadModState +008028ae b LastBit +008028af b IsParityBit +008028b0 b SampleRegister +008028b1 b DataRegister +008028b2 b BitSent +008028b4 b BitCount +008028b6 b Flags +008028b8 b CodecBufferPtr +008028ba b ParityBufferPtr +008028bc b State +008028bd b CompatWritePageAddress +008028be b State +008028bf b CardATQAValue +008028c1 b CardSAKValue +008028c2 b _7BUID +008028c3 b CurrentAddress +008028c4 b ReaderResponse +008028c8 b CardResponse +008028cc b BlockBuffer +008028dc b StateOdd +008028df b StateEven +008028e2 B ActiveConfiguration +00802907 B LogFunc +00802909 B GlobalSettings +0080293c B TerminalBuffer +00802a3c B CodecBuffer +00802b3c B USB_Device_ConfigurationNumber +00802b3d B USB_Device_CurrentlySelfPowered +00802b3e B USB_Device_RemoteWakeupEnabled +00802b3f B USB_IsInitialized +00802b40 B USB_DeviceState +00802b41 B USB_ControlRequest +00802b49 B USB_Endpoint_SelectedFIFO +00802b4b B USB_Endpoint_SelectedHandle +00802b4d B USB_Endpoint_SelectedEndpoint +00802b4e B USB_Endpoint_FIFOs +00802e66 B USB_EndpointTable +00802ec9 B __bss_end +00802ec9 B _end +00810000 D StoredSettings +00810033 D __eeprom_end diff --git a/Firmware/Chameleon-Mini/Codec/Codec.c b/Firmware/Chameleon-Mini/Codec/Codec.c index 0f30957..d31ed95 100644 --- a/Firmware/Chameleon-Mini/Codec/Codec.c +++ b/Firmware/Chameleon-Mini/Codec/Codec.c @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * CODEC.c * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 18.02.2013 + * Author: skuser */ #include "Codec.h" diff --git a/Firmware/Chameleon-Mini/Codec/Codec.h b/Firmware/Chameleon-Mini/Codec/Codec.h index 5b001a7..714c176 100644 --- a/Firmware/Chameleon-Mini/Codec/Codec.h +++ b/Firmware/Chameleon-Mini/Codec/Codec.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * CODEC.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 18.02.2013 + * Author: skuser */ #ifndef CODEC_H_ @@ -68,12 +20,12 @@ #define CODEC_DEMOD_POWER_MASK PIN1_bm #define CODEC_DEMOD_IN_PORT PORTB #define CODEC_DEMOD_IN_MASK (CODEC_DEMOD_IN_MASK0 | CODEC_DEMOD_IN_MASK1) -#define CODEC_DEMOD_IN_MASK0 PIN0_bm -#define CODEC_DEMOD_IN_MASK1 PIN2_bm -#define CODEC_DEMOD_IN_PINCTRL0 PIN0CTRL -#define CODEC_DEMOD_IN_PINCTRL1 PIN2CTRL -#define CODEC_DEMOD_IN_EVMUX0 EVSYS_CHMUX_PORTB_PIN0_gc -#define CODEC_DEMOD_IN_EVMUX1 EVSYS_CHMUX_PORTB_PIN2_gc +#define CODEC_DEMOD_IN_MASK0 PIN2_bm +#define CODEC_DEMOD_IN_MASK1 PIN0_bm +#define CODEC_DEMOD_IN_PINCTRL0 PIN2CTRL +#define CODEC_DEMOD_IN_PINCTRL1 PIN0CTRL +#define CODEC_DEMOD_IN_EVMUX0 EVSYS_CHMUX_PORTB_PIN2_gc +#define CODEC_DEMOD_IN_EVMUX1 EVSYS_CHMUX_PORTB_PIN0_gc #define CODEC_DEMOD_IN_INT0_VECT PORTB_INT0_vect #define CODEC_LOADMOD_PORT PORTC #define CODEC_LOADMOD_MASK PIN6_bm diff --git a/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c b/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c index 6527171..1db5986 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c +++ b/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c @@ -1,62 +1,16 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * ISO14443A.c * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 18.02.2013 + * Author: skuser */ #include "ISO14443-2A.h" #include "../System.h" #include "../Application/Application.h" +#include "../LED.h" #include "Codec.h" +#include "Log.h" /* Timing definitions for ISO14443A */ #define ISO14443A_SUBCARRIER_DIVIDER 16 @@ -133,6 +87,14 @@ static void StartDemod(void) { /* Activate Power for demodulator */ CodecSetDemodPower(true); + CodecBufferPtr = CodecBuffer; + ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; + DataRegister = 0; + SampleRegister = 0; + SamplePosition = 0; + BitCount = 0; + IsParityBit = false; + /* Configure sampling-timer free running and sync to first modulation-pause. */ CODEC_TIMER_SAMPLING.CNT = 0; CODEC_TIMER_SAMPLING.PER = SAMPLE_RATE_SYSTEM_CYCLES - 1; @@ -143,19 +105,14 @@ static void StartDemod(void) { /* Start looking out for modulation pause via interrupt. */ CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0; + SystemSleepSetMode(SYSTEM_SMODE_PSAVE); } ISR(CODEC_DEMOD_IN_INT0_VECT) { /* This is the first edge of the first modulation-pause after StartDemod. - * Now we have time to prepare our timers and variables to start + * Now we have time to start * demodulating beginning from one bit-width after this edge. */ - CodecBufferPtr = CodecBuffer; - ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; - DataRegister = 0; - SampleRegister = 0; - SamplePosition = 0; - BitCount = 0; - IsParityBit = false; + SystemSleepSetMode(SYSTEM_SMODE_IDLE); /* Sampling timer has been preset to sample-rate and has automatically synced * to THIS first modulation pause. Thus after exactly one bit-width from here, @@ -441,6 +398,9 @@ void ISO14443ACodecTask(void) { uint16_t AnswerBitCount = ISO14443A_APP_NO_RESPONSE; if (DemodBitCount > 0) { + LogEntry(LOG_INFO_RX_DATA, CodecBuffer, (DemodBitCount+7)/8); + LEDTrigger(LED_CODEC_RX, LED_PULSE); + /* Call application if we received data */ AnswerBitCount = ApplicationProcess(CodecBuffer, DemodBitCount); @@ -461,6 +421,9 @@ void ISO14443ACodecTask(void) { } if (AnswerBitCount != ISO14443A_APP_NO_RESPONSE) { + LogEntry(LOG_INFO_TX_DATA, CodecBuffer, (AnswerBitCount + 7) / 8); + LEDTrigger(LED_CODEC_TX, LED_PULSE); + BitCount = AnswerBitCount; BitSent = 0; CodecBufferPtr = CodecBuffer; @@ -481,5 +444,7 @@ void ISO14443ACodecTask(void) { * for incoming data again. */ StartDemod(); } + + //SystemSleep(); } diff --git a/Firmware/Chameleon-Mini/Codec/ISO14443-2A.h b/Firmware/Chameleon-Mini/Codec/ISO14443-2A.h index 0fbcaa5..1f17f05 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO14443-2A.h +++ b/Firmware/Chameleon-Mini/Codec/ISO14443-2A.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * ISO14443-2A.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 18.02.2013 + * Author: skuser */ #ifndef ISO14443_2A_H_ diff --git a/Firmware/Chameleon-Mini/Common.c b/Firmware/Chameleon-Mini/Common.c index 2406493..d53804d 100644 --- a/Firmware/Chameleon-Mini/Common.c +++ b/Firmware/Chameleon-Mini/Common.c @@ -1,58 +1,3 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. - * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ - #include "Common.h" uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount) diff --git a/Firmware/Chameleon-Mini/Common.h b/Firmware/Chameleon-Mini/Common.h index 0ae3835..b0a97d9 100644 --- a/Firmware/Chameleon-Mini/Common.h +++ b/Firmware/Chameleon-Mini/Common.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * Common.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 20.03.2013 + * Author: skuser */ #ifndef COMMON_H_ diff --git a/Firmware/Chameleon-Mini/Configuration.c b/Firmware/Chameleon-Mini/Configuration.c index faf2462..eb60560 100644 --- a/Firmware/Chameleon-Mini/Configuration.c +++ b/Firmware/Chameleon-Mini/Configuration.c @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * Standards.c * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 15.02.2013 + * Author: skuser */ #include "Configuration.h" @@ -86,6 +38,23 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .MemorySize = 0, .ReadOnly = true }, +#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT + [CONFIG_MF_ULTRALIGHT] = { + .ConfigurationID = CONFIG_MF_ULTRALIGHT, + .ConfigurationName = "MF_ULTRALIGHT", + .CodecInitFunc = ISO14443ACodecInit, + .CodecTaskFunc = ISO14443ACodecTask, + .ApplicationInitFunc = MifareUltralightAppInit, + .ApplicationResetFunc = MifareUltralightAppReset, + .ApplicationTaskFunc = MifareUltralightAppTask, + .ApplicationProcessFunc = MifareUltralightAppProcess, + .ApplicationGetUidFunc = MifareUltralightGetUid, + .ApplicationSetUidFunc = MifareUltralightSetUid, + .UidSize = MIFARE_ULTRALIGHT_UID_SIZE, + .MemorySize = MIFARE_ULTRALIGHT_MEM_SIZE, + .ReadOnly = false + }, +#endif #ifdef CONFIG_MF_CLASSIC_1K_SUPPORT [CONFIG_MF_CLASSIC_1K] = { .ConfigurationID = CONFIG_MF_CLASSIC_1K, @@ -103,6 +72,23 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ReadOnly = false }, #endif +#ifdef CONFIG_MF_Plus1k_7B_SUPPORT +[CONFIG_MF_Plus1k_7B] = { + .ConfigurationID = CONFIG_MF_Plus1k_7B, + .ConfigurationName = "MF_PLUS1K_7B", + .CodecInitFunc = ISO14443ACodecInit, + .CodecTaskFunc = ISO14443ACodecTask, + .ApplicationInitFunc = MifarePlus1kAppInit_7B, + .ApplicationResetFunc = MifareClassicAppReset, + .ApplicationTaskFunc = MifareClassicAppTask, + .ApplicationProcessFunc = MifareClassicAppProcess, + .ApplicationGetUidFunc = MifareClassicGetUid, + .ApplicationSetUidFunc = MifareClassicSetUid, + .UidSize = ISO14443A_UID_SIZE_DOUBLE, + .MemorySize = MIFARE_CLASSIC_1K_MEM_SIZE, + .ReadOnly = false +}, +#endif #ifdef CONFIG_MF_CLASSIC_4K_SUPPORT [CONFIG_MF_CLASSIC_4K] = { .ConfigurationID = CONFIG_MF_CLASSIC_4K, @@ -120,6 +106,24 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ReadOnly = false }, #endif +#ifdef CONFIG_ISO14443A_SNIFF_SUPPORT + [CONFIG_ISO14443A_SNIFF] = { + .ConfigurationID = CONFIG_ISO14443A_SNIFF, + .ConfigurationName = "ISO14443A_SNIFF", + .CodecInitFunc = ISO14443ACodecInit, + .CodecTaskFunc = ISO14443ACodecTask, + .ApplicationInitFunc = ApplicationInitDummy, + .ApplicationResetFunc = ApplicationResetDummy, + .ApplicationTaskFunc = ApplicationTaskDummy, + .ApplicationProcessFunc = ApplicationProcessDummy, + .ApplicationGetUidFunc = ApplicationGetUidDummy, + .ApplicationSetUidFunc = ApplicationSetUidDummy, + .UidSize = 0, + .MemorySize = 0, + .ReadOnly = true + }, +#endif + }; ConfigurationType ActiveConfiguration; diff --git a/Firmware/Chameleon-Mini/Configuration.h b/Firmware/Chameleon-Mini/Configuration.h index 6c814b8..1e1d3bc 100644 --- a/Firmware/Chameleon-Mini/Configuration.h +++ b/Firmware/Chameleon-Mini/Configuration.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * Standards.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 15.02.2013 + * Author: skuser */ #ifndef STANDARDS_H_ @@ -74,20 +26,15 @@ typedef enum { #ifdef CONFIG_MF_CLASSIC_1K_SUPPORT CONFIG_MF_CLASSIC_1K, #endif +#ifdef CONFIG_MF_Plus1k_7B_SUPPORT + CONFIG_MF_Plus1k_7B, +#endif #ifdef CONFIG_MF_CLASSIC_4K_SUPPORT CONFIG_MF_CLASSIC_4K, #endif -#ifdef CONFIG_ISO15693_GEN_SUPPORT - CONFIG_ISO15693_GEN, -#endif #ifdef CONFIG_ISO14443A_SNIFF_SUPPORT CONFIG_ISO14443A_SNIFF, #endif -#ifdef CONFIG_ISO15693_SNIFF_SUPPORT - CONFIG_ISO15693_SNIFF, -#endif - //CONFIG_MF_DESFIRE, - //CONFIG_ISO14443A_RELAY diff --git a/Firmware/Chameleon-Mini/LED.c b/Firmware/Chameleon-Mini/LED.c index d3360d6..997a19e 100644 --- a/Firmware/Chameleon-Mini/LED.c +++ b/Firmware/Chameleon-Mini/LED.c @@ -1,58 +1,201 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. - * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ - #include "LED.h" +#include "Settings.h" + +#define BLINK_PRESCALER 1 /* x LEDTick(); */ + +LEDActionEnum LEDGreenAction = LED_NO_ACTION; +LEDActionEnum LEDRedAction = LED_NO_ACTION; + +static const char PROGMEM LEDFuncTable[][32] = +{ + [LED_NO_FUNC] = "NONE", + [LED_TERMINAL_CONN] = "TERMINAL_CONN", + [LED_TERMINAL_RXTX] = "TERMINAL_RXTX", + [LED_SETTING_CHANGE] = "SETTING_CHANGE", + [LED_MEMORY_STORED] = "MEMORY_STORED", + [LED_MEMORY_CHANGED] = "MEMORY_CHANGED", + //TODO: [LED_FIELD_DETECTED] = "FIELD_DETECTED", + [LED_CODEC_RX] = "CODEC_RX", + [LED_CODEC_TX] = "CODEC_TX", + //TODO: [LED_APP_SELECTED] = "APP_SELECTED", + +}; + +INLINE void Tick(uint8_t Mask, LEDActionEnum* Action) +{ + static uint8_t BlinkPrescaler = 0; + + switch (*Action) + { + case LED_NO_ACTION: + /* Do nothing */ + break; + + case LED_OFF: + LED_PORT.OUTCLR = Mask; + *Action = LED_NO_ACTION; + break; + + case LED_ON: + LED_PORT.OUTSET = Mask; + *Action = LED_NO_ACTION; + break; + + case LED_TOGGLE: + LED_PORT.OUTTGL = Mask; + *Action = LED_NO_ACTION; + break; + + case LED_PULSE: + if (!(LED_PORT.OUT & Mask)) { + LED_PORT.OUTSET = Mask; + } else { + LED_PORT.OUTCLR = Mask; + *Action = LED_NO_ACTION; + } + break; + + case LED_BLINK_1X ... LED_BLINK_8X: + if (++BlinkPrescaler == BLINK_PRESCALER) { + BlinkPrescaler = 0; + /* Blink functionality occurs at slower speed than Tick-frequency */ + + if (!(LED_PORT.OUT & Mask)) { + /* LED is off, turn it on */ + LED_PORT.OUTSET = Mask; + } else { + /* LED is on, turn it off and change state */ + LED_PORT.OUTCLR = Mask; + + if (*Action == LED_BLINK_1X) { + *Action = LED_NO_ACTION; + } else { + /* Still some blinks to do. Use the fact that LED_BLINK_XY are ordered sequentially */ + *Action = *Action - 1; + } + } + } + break; + + default: + /* Should not happen (TM) */ + *Action = LED_NO_ACTION; + break; + + } +} + +void LEDInit(void) +{ + LED_PORT.DIRSET = LED_MASK; +} + + +void LEDTick(void) +{ + Tick(LED_RED, &LEDRedAction); + Tick(LED_GREEN, &LEDGreenAction); +} + +/* TODO: This would be nicer as INLINE */ +void LEDTrigger(LEDFunctionEnum Func, LEDActionEnum Action) { + if (GlobalSettings.ActiveSettingPtr->LEDGreenFunction == Func) { + LEDGreenAction = Action; + } + + if (GlobalSettings.ActiveSettingPtr->LEDRedFunction == Func) { + LEDRedAction = Action; + } +} + +void LEDGetFuncList(char* ListOut, uint16_t BufferSize) +{ + uint8_t i; + + /* Account for '\0' */ + BufferSize--; + + for (i=0; i sizeof(LEDFuncTable[i]) ) { + /* While not end-of-string and enough buffer to + * put a complete configuration name */ + *ListOut++ = c; + FuncName++; + BufferSize--; + } + + if ( i < (LED_FUNC_COUNT - 1) ) { + /* No comma on last configuration */ + *ListOut++ = ','; + BufferSize--; + } + } + + *ListOut = '\0'; +} + +void LEDSetFuncById(uint8_t Mask, LEDFunctionEnum Func) +{ +#ifndef LED_SETTING_GLOBAL + if (Mask & LED_GREEN) { + GlobalSettings.ActiveSettingPtr->LEDGreenFunction = Func; + } + + if (Mask & LED_RED) { + GlobalSettings.ActiveSettingPtr->LEDRedFunction = Func; + } +#else + /* Write LED func to all settings when using global settings */ + for (uint8_t i=0; iLEDGreenFunction], BufferSize); + } else if (Mask == LED_RED) { + strncpy_P(FuncOut, LEDFuncTable[GlobalSettings.ActiveSettingPtr->LEDRedFunction], BufferSize); + } else { + *FuncOut = '\0'; + } +} + +bool LEDSetFuncByName(uint8_t Mask, const char* FuncName) +{ + uint8_t i; + + for (i=0; i +#include "Common.h" -#define LED_PORT PORTA -#define LED_GREEN PIN5_bm -#define LED_RED PIN4_bm -#define LED_MASK (LED_GREEN | LED_RED) +#define LED_PORT PORTA +#define LED_GREEN PIN5_bm +#define LED_RED PIN4_bm +#define LED_MASK (LED_GREEN | LED_RED) -extern uint8_t LEDPulseMask; +typedef enum LEDFunctionEnum { + LED_NO_FUNC = 0, /* Don't light up the LED */ + LED_TERMINAL_CONN, /* A Terminal/USB connection has been established */ + LED_TERMINAL_RXTX, /* There is traffic on the terminal */ -static inline -void LEDInit(void) { - LED_PORT.DIRSET = LED_MASK; -} + LED_SETTING_CHANGE, /* Outputs a blink code that shows the current setting */ -static inline -void LEDSetOn(uint8_t Mask) { - LED_PORT.OUTSET = Mask; -} + LED_MEMORY_STORED, /* Blink once when memory has been stored to flash */ + LED_MEMORY_CHANGED, /* Switch LED on when card memory has changed compared to flash */ -static inline -void LEDSetOff(uint8_t Mask) { - LED_PORT.OUTCLR = Mask; -} + //TODO: LED_FIELD_DETECTED, /* Shows LED while a reader field is being detected */ -static inline -void LEDToggle(uint8_t Mask) { - LED_PORT.OUTTGL = Mask; -} + LED_CODEC_RX, /* Blink LED when receiving codec data */ + LED_CODEC_TX, /* Blink LED when transmitting codec data */ -static inline -void LEDPulse(uint8_t Mask) { - LEDPulseMask = Mask; - LED_PORT.OUTSET = Mask; -} + //TODO: LED_APP_SELECTED, /* Show LED while the correct UID has been selected and the application is active */ -static inline -void LEDTick(void) { - LED_PORT.OUTCLR = LEDPulseMask; - LEDPulseMask = 0; -} + /* Has to be last element */ + LED_FUNC_COUNT +} LEDFunctionEnum; + +typedef enum LEDActionEnum { + LED_NO_ACTION = 0x00, + LED_OFF = 0x10, + LED_ON = 0x11, + LED_TOGGLE = 0x12, + LED_PULSE = 0x13, + LED_BLINK = 0x20, + LED_BLINK_1X = 0x20, + LED_BLINK_2X, /* Have to be sequentially ordered */ + LED_BLINK_3X, + LED_BLINK_4X, + LED_BLINK_5X, + LED_BLINK_6X, + LED_BLINK_7X, + LED_BLINK_8X, +} LEDActionEnum; + +extern LEDActionEnum LEDGreenAction; +extern LEDActionEnum LEDRedAction; + +void LEDInit(void); +void LEDTick(void); + +void LEDTrigger(LEDFunctionEnum Func, LEDActionEnum Action); + +void LEDGetFuncList(char* ListOut, uint16_t BufferSize); +void LEDSetFuncById(uint8_t Mask, LEDFunctionEnum Func); +void LEDGetFuncByName(uint8_t Mask, char* FuncOut, uint16_t BufferSize); +bool LEDSetFuncByName(uint8_t Mask, const char* FuncName); #endif /* LED_H */ diff --git a/Firmware/Chameleon-Mini/Log.c b/Firmware/Chameleon-Mini/Log.c new file mode 100644 index 0000000..f362e3a --- /dev/null +++ b/Firmware/Chameleon-Mini/Log.c @@ -0,0 +1,152 @@ +#include "Log.h" +#include "Settings.h" +#include "Terminal/Terminal.h" +#include + +static uint8_t LogMem[1024]; +static uint8_t* LogMemPtr; +static uint16_t LogMemLeft; +LogFuncType LogFunc; + +static const char PROGMEM LogModeTable[][16] = { + [LOG_MODE_OFF] = "OFF", + [LOG_MODE_MEMORY] = "MEMORY", + [LOG_MODE_TERMINAL] = "TERMINAL" +}; + +static void LogFuncOff(LogEntryEnum Entry, void* Data, uint8_t Length) +{ + /* Do nothing */ +} + +static void LogFuncMemory(LogEntryEnum Entry, void* Data, uint8_t Length) +{ + if (LogMemLeft >= (Length + 2)) { + LogMemLeft -= Length + 2; + + uint8_t* DataPtr = (uint8_t*) Data; + + *LogMemPtr++ = (uint8_t) Entry; + *LogMemPtr++ = (uint8_t) Length; + + while(Length--) { + *LogMemPtr++ = *DataPtr++; + } + } else { + /* If memory full. Deactivate logmode */ + LogSetModeById(LOG_MODE_OFF); + } +} + +static void LogFuncTerminal(LogEntryEnum Entry, void* Data, uint8_t Length) +{ + TerminalSendByte((uint8_t) Entry); + TerminalSendByte((uint8_t) Length); + TerminalSendBlock(Data, Length); +} + +void LogInit(void) +{ + LogMemClear(); + LogSetModeById(GlobalSettings.ActiveSettingPtr->LogMode); +} + +void LogTick(void) +{ + +} + +void LogTask(void) +{ + +} + +bool LogMemLoadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) +{ + if (BlockAddress < sizeof(LogMem)) { + uint8_t* DataPtr = (uint8_t*) Buffer; + uint8_t* MemPtr = &LogMem[BlockAddress]; + + while(ByteCount-- > 0) { + *DataPtr++ = *MemPtr++; + } + + return true; + } else { + return false; + } +} + +void LogMemClear(void) +{ + uint16_t i; + + for (i=0; iLogMode = Mode; + + switch(Mode) { + case LOG_MODE_OFF: + LogFunc = LogFuncOff; + break; + + case LOG_MODE_MEMORY: + LogFunc = LogFuncMemory; + break; + + case LOG_MODE_TERMINAL: + LogFunc = LogFuncTerminal; + break; + + default: + break; + } + +} + +bool LogSetModeByName(const char* Name) +{ + uint8_t i; + + for (i=0; i<(sizeof(LogModeTable) / sizeof(*LogModeTable)); i++) { + if (strcmp_P(Name, LogModeTable[i]) == 0) { + LogSetModeById(i); + return true; + } + } + + return false; +} + +void LogGetModeByName(char* Name, uint16_t BufferSize) +{ + strncpy_P(Name, LogModeTable[GlobalSettings.ActiveSettingPtr->LogMode], BufferSize); +} + +void LogGetModeList(char* List, uint16_t BufferSize) +{ + uint8_t i; + + *List = '\0'; + + for (i=0; i<(sizeof(LogModeTable) / sizeof(*LogModeTable)); i++) { + strncat_P(List, LogModeTable[i], BufferSize); + + if (i < (sizeof(LogModeTable) / sizeof(*LogModeTable) - 1)) { + strncat_P(List, PSTR(","), BufferSize); + } + } +} diff --git a/Firmware/Chameleon-Mini/Log.h b/Firmware/Chameleon-Mini/Log.h new file mode 100644 index 0000000..fa30f95 --- /dev/null +++ b/Firmware/Chameleon-Mini/Log.h @@ -0,0 +1,49 @@ +#ifndef LOG_H_ +#define LOG_H_ + +#include "Common.h" + +typedef enum { + /* Generic */ + LOG_INFO_GENERIC = 0x10, + LOG_INFO_CONFIG_CHANGED = 0x11, + + /* Codec */ + LOG_INFO_RX_DATA = 0x20, + LOG_INFO_TX_DATA = 0x21, + + /* App */ + LOG_INFO_APP_RESET = 0x30, + LOG_ERR_APP_AUTH_FAIL = 0x31, + LOG_ERR_APP_CHECKSUM_FAIL = 0x32, + + LOG_EMPTY = 0xFF +} LogEntryEnum; + +typedef enum { + LOG_MODE_OFF, + LOG_MODE_MEMORY, + LOG_MODE_TERMINAL +} LogModeEnum; + +typedef void (*LogFuncType) (LogEntryEnum Entry, void* Data, uint8_t Length); + +extern LogFuncType LogFunc; + +void LogInit(void); +void LogTick(void); +void LogTask(void); + +void LogMemClear(void); +uint16_t LogMemFree(void); +/* XModem callback */ +bool LogMemLoadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount); + +void LogSetModeById(LogModeEnum Mode); +bool LogSetModeByName(const char* Name); +void LogGetModeByName(char* Name, uint16_t BufferSize); +void LogGetModeList(char* List, uint16_t BufferSize); + +INLINE void LogEntry(LogEntryEnum Entry, void* Data, uint8_t Length) { LogFunc(Entry, Data, Length); } + +#endif /* LOG_H_ */ diff --git a/Firmware/Chameleon-Mini/Makefile b/Firmware/Chameleon-Mini/Makefile index 11c3204..2978a11 100644 --- a/Firmware/Chameleon-Mini/Makefile +++ b/Firmware/Chameleon-Mini/Makefile @@ -1,57 +1,3 @@ -# Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL -# AUTHORS"). All rights reserved. -# -# DEFINITIONS: -# -# "WORK": The material covered by this license includes the schematic -# diagrams, designs, circuit or circuit board layouts, mechanical -# drawings, documentation (in electronic or printed form), source code, -# binary software, data files, assembled devices, and any additional -# material provided by the ORIGINAL AUTHORS in the ChameleonMini project -# (https://github.com/skuep/ChameleonMini). -# -# LICENSE TERMS: -# -# Redistributions and use of this WORK, with or without modification, or -# of substantial portions of this WORK are permitted provided that the -# following conditions are met: -# -# Redistributions and use of this WORK, with or without modification, or -# of substantial portions of this WORK must include the above copyright -# notice, this list of conditions, the below disclaimer, and the following -# attribution: -# -# "Based on ChameleonMini an open-source RFID emulator: -# https://github.com/skuep/ChameleonMini" -# -# The attribution must be clearly visible to a user, for example, by being -# printed on the circuit board and an enclosure, and by being displayed by -# software (both in binary and source code form). -# -# At any time, the majority of the ORIGINAL AUTHORS may decide to give -# written permission to an entity to use or redistribute the WORK (with or -# without modification) WITHOUT having to include the above copyright -# notice, this list of conditions, the below disclaimer, and the above -# attribution. -# -# DISCLAIMER: -# -# THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF -# THE POSSIBILITY OF SUCH DAMAGE. -# -# The views and conclusions contained in the hardware, software, and -# documentation should not be interpreted as representing official -# policies, either expressed or implied, of the ORIGINAL AUTHORS. - # This makefile uses sh in order to build the project. # Note when using AVR-Toolchain, you have to install cygwin and # append cygwin's bin directory to the PATH environment variable @@ -60,41 +6,83 @@ SHELL = /bin/sh #Supported configurations SETTINGS += -DCONFIG_MF_CLASSIC_1K_SUPPORT +SETTINGS += -DCONFIG_MF_Plus1k_7B_SUPPORT SETTINGS += -DCONFIG_MF_CLASSIC_4K_SUPPORT +SETTINGS += -DCONFIG_MF_ULTRALIGHT_SUPPORT +SETTINGS += -DCONFIG_ISO14443A_SNIFF_SUPPORT + +#Support magic mode on mifare classic configuration +SETTINGS += -DSUPPORT_MF_CLASSIC_MAGIC_MODE #Support activating firmware upgrade mode through command-line SETTINGS += -DSUPPORT_FIRMWARE_UPGRADE #Default configuration +#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_Plus1k_7B +#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_CLASSIC_1K +#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_CLASSIC_4K +#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_ULTRALIGHT SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_NONE -#Default button action +#Default button actions #SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_RANDOM #SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_LEFT_INCREMENT #SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_RIGHT_INCREMENT #SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_LEFT_DECREMENT #SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_RIGHT_DECREMENT SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_CYCLE_SETTINGS +#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_STORE_MEM +SETTINGS += -DDEFAULT_BUTTON_LONG_ACTION=BUTTON_ACTION_RECALL_MEM + +#Define if button action setting should be independent of active setting +SETTINGS += -DBUTTON_SETTING_GLOBAL + +#Default LED functions + +#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_TERMINAL_CONN +#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_TERMINAL_RXTX +SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_SETTING_CHANGE +#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_MEMORY_STORED +#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_MEMORY_CHANGED +#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_CODEC_RX +#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_CODEC_TX + +SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_TERMINAL_CONN +#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_TERMINAL_RXTX +#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_SETTING_CHANGE +#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_MEMORY_STORED +#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_MEMORY_CHANGED +#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_CODEC_RX +#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_CODEC_TX + + +#Define if LED function setting should be independent of active setting +SETTINGS += -DLED_SETTING_GLOBAL + +#Default logging mode +SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_OFF +#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_MEMORY +#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_TERMINAL #Default setting -SETTINGS += -DDEFAULT_SETTING=0 +SETTINGS += -DDEFAULT_SETTING=SETTINGS_FIRST #Use EEPROM to store settings SETTINGS += -DENABLE_EEPROM_SETTINGS #Build configuration BUILD_DATE = $(shell date +'\"%y%m%d\"') -MCU = atxmega32a4u +MCU = atxmega32a4u #atxmega128a4u ARCH = XMEGA BOARD = NONE F_CPU = 32000000 F_USB = 48000000 TARGET = Chameleon-Mini OPTIMIZATION = 3 -SRC += $(TARGET).c LUFADescriptors.c System.c Configuration.c Random.c Common.c Memory.c Button.c Settings.c LED.c +SRC += $(TARGET).c LUFADescriptors.c System.c Configuration.c Random.c Common.c Memory.c Button.c Log.c Settings.c LED.c SRC += Terminal/Terminal.c Terminal/Commands.c Terminal/XModem.c Terminal/CommandLine.c SRC += Codec/Codec.c Codec/ISO14443-2A.c -SRC += Application/MifareClassic.c Application/ISO14443-3A.c Application/Crypto1.c +SRC += Application/MifareUltralight.c Application/MifareClassic.c Application/ISO14443-3A.c Application/Crypto1.c SRC += $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) LUFA_PATH = ../LUFA CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -DBUILD_DATE=$(BUILD_DATE) $(SETTINGS) diff --git a/Firmware/Chameleon-Mini/Memory.c b/Firmware/Chameleon-Mini/Memory.c index 936f537..0a24fe7 100644 --- a/Firmware/Chameleon-Mini/Memory.c +++ b/Firmware/Chameleon-Mini/Memory.c @@ -1,63 +1,15 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * Flash.c * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 20.03.2013 + * Author: skuser */ - #include "Memory.h" #include "Configuration.h" #include "Common.h" #include "Settings.h" +#include "LED.h" #define FLASH_CMD_STATUS_REG_READ 0xD7 #define FLASH_CMD_MEM_TO_BUF1 0x53 @@ -203,6 +155,7 @@ INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) ByteCount -= PageBytes; Address += PageBytes; + Buffer += PageBytes; } } @@ -228,9 +181,9 @@ void MemoryInit(void) MEMORY_FLASH_PORT.DIRSET = MEMORY_FLASH_SCK | MEMORY_FLASH_MOSI | MEMORY_FLASH_CS; - MEMORY_FLASH_USART.BAUDCTRLA = 0; + MEMORY_FLASH_USART.BAUDCTRLA = 15;//0; MEMORY_FLASH_USART.BAUDCTRLB = 0; - MEMORY_FLASH_USART.CTRLC = USART_CMODE_MSPI_gc; + MEMORY_FLASH_USART.CTRLC = USART_CMODE_MSPI_gc; // | USART_CHSIZE_8BIT_gc; MEMORY_FLASH_USART.CTRLB = USART_RXEN_bm | USART_TXEN_bm; @@ -267,6 +220,8 @@ void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount) while(ByteCount--) { *DstPtr++ = *SrcPtr++; } + + LEDTrigger(LED_MEMORY_CHANGED, LED_ON); } void MemoryClear(void) @@ -279,13 +234,16 @@ void MemoryClear(void) void MemoryRecall(void) { /* Recall memory from permanent flash */ - FlashRead(Memory, (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); + FlashRead(Memory, (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); } void MemoryStore(void) { /* Store current memory into permanent flash */ - FlashWrite(Memory, (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); + FlashWrite(Memory, (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING); + + LEDTrigger(LED_MEMORY_CHANGED, LED_OFF); + LEDTrigger(LED_MEMORY_STORED, LED_PULSE); } bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) @@ -296,7 +254,7 @@ bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) } else { /* Calculate bytes left in memory and start writing */ uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; - uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; + uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING; ByteCount = MIN(ByteCount, BytesLeft); /* Store into flash */ @@ -336,4 +294,5 @@ bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount return true; } -} \ No newline at end of file +} + diff --git a/Firmware/Chameleon-Mini/Memory.h b/Firmware/Chameleon-Mini/Memory.h index e492dc7..ec54dc6 100644 --- a/Firmware/Chameleon-Mini/Memory.h +++ b/Firmware/Chameleon-Mini/Memory.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * Flash.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 20.03.2013 + * Author: skuser */ #ifndef MEMORY_H_ @@ -81,4 +33,3 @@ bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount); bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount); #endif /* MEMORY_H_ */ - diff --git a/Firmware/Chameleon-Mini/ProgramViaBootloader.bat b/Firmware/Chameleon-Mini/ProgramViaBootloader.bat index 7c2e602..0818b8b 100644 --- a/Firmware/Chameleon-Mini/ProgramViaBootloader.bat +++ b/Firmware/Chameleon-Mini/ProgramViaBootloader.bat @@ -1,6 +1,11 @@ @ECHO OFF + +REM This script programs the Chameleon using batchisp (Atmel Flip) and DFU (device firmware upgrade via USB) +REM You need to install Flip, otherwise it does not work +REM Make sure to adjust the COMPORT variable to the actual com port the CDC Device enumerates as +REM This is necessary to send the upgrade command and thus set the chameleon into DFU mode + SET COMPORT=COM5 -SET BATCHISP=C:\Programme\Atmel\Flip 3.4.7\bin SET TIMEOUT=5 SET COMMAND=UPGRADE @@ -13,5 +18,4 @@ ECHO Waiting for DFU Bootloader ping 127.0.0.1 -n %TIMEOUT% -w 1000 > nul ECHO Start Programming -SET PATH=%BATCHISP%;%PATH% make dfu-flip diff --git a/Firmware/Chameleon-Mini/README.txt b/Firmware/Chameleon-Mini/README.txt new file mode 100644 index 0000000..1d264bc --- /dev/null +++ b/Firmware/Chameleon-Mini/README.txt @@ -0,0 +1,9 @@ +== Compiling the firmware == +For compiling under windows you need to do the following: +1. Install AVR GNU Toolchain from Atmel +2. Install Cygwin for sh.exe (base installation is sufficient) +3. Add the bin path of cygwin (containing sh.exe) to the PATH environment variable for MAKE to find it + +Then you should be good to go to build the firmware by typing in the following: +> make + diff --git a/Firmware/Chameleon-Mini/Random.c b/Firmware/Chameleon-Mini/Random.c index 74bb572..697c351 100644 --- a/Firmware/Chameleon-Mini/Random.c +++ b/Firmware/Chameleon-Mini/Random.c @@ -1,58 +1,3 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. - * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ - #include "Random.h" #include diff --git a/Firmware/Chameleon-Mini/Random.h b/Firmware/Chameleon-Mini/Random.h index a40f086..de778a9 100644 --- a/Firmware/Chameleon-Mini/Random.h +++ b/Firmware/Chameleon-Mini/Random.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * Random.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 22.03.2013 + * Author: skuser */ #ifndef RANDOM_H_ diff --git a/Firmware/Chameleon-Mini/Settings.c b/Firmware/Chameleon-Mini/Settings.c index 9dbe8ae..6be3d03 100644 --- a/Firmware/Chameleon-Mini/Settings.c +++ b/Firmware/Chameleon-Mini/Settings.c @@ -1,71 +1,25 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. - * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ - #include "Settings.h" #include #include "Configuration.h" +#include "Log.h" #include "Memory.h" +#include "LED.h" + +#define SETTING_TO_INDEX(S) (S - SETTINGS_FIRST) +#define INDEX_TO_SETTING(I) (I + SETTINGS_FIRST) SettingsType GlobalSettings; SettingsType EEMEM StoredSettings = { - .ActiveSetting = DEFAULT_SETTING, - .ActiveSettingPtr = &GlobalSettings.Settings[DEFAULT_SETTING], + .ActiveSettingIdx = SETTING_TO_INDEX(DEFAULT_SETTING), + .ActiveSettingPtr = &GlobalSettings.Settings[SETTING_TO_INDEX(DEFAULT_SETTING)], .Settings = { [0 ... (SETTINGS_COUNT-1)] = { .Configuration = DEFAULT_CONFIGURATION, .ButtonAction = DEFAULT_BUTTON_ACTION, + .ButtonLongAction = DEFAULT_BUTTON_LONG_ACTION, + .LogMode = DEFAULT_LOG_MODE, + .LEDRedFunction = DEFAULT_RED_LED_ACTION, + .LEDGreenFunction = DEFAULT_GREEN_LED_ACTION } } }; @@ -81,37 +35,48 @@ void SettingsSave(void) { void SettingsCycle(void) { uint8_t i = SETTINGS_COUNT; - uint8_t Setting = GlobalSettings.ActiveSetting; + uint8_t SettingIdx = GlobalSettings.ActiveSettingIdx; while (i-- > 0) { - Setting = (Setting + 1) % SETTINGS_COUNT; + /* Try to set one of the SETTINGS_COUNT following settings. + * But only set if it is not CONFIG_NONE. */ + SettingIdx = (SettingIdx + 1) % SETTINGS_COUNT; - if (GlobalSettings.Settings[Setting].Configuration != CONFIG_NONE) { - SettingsSetActiveById(Setting); + if (GlobalSettings.Settings[SettingIdx].Configuration != CONFIG_NONE) { + SettingsSetActiveById(INDEX_TO_SETTING(SettingIdx)); break; } } } -void SettingsSetActiveById(uint8_t Setting) { - if (Setting < SETTINGS_COUNT) { +bool SettingsSetActiveById(uint8_t Setting) { + if ( (Setting >= SETTINGS_FIRST) && (Setting <= SETTINGS_LAST) ) { + uint8_t SettingIdx = SETTING_TO_INDEX(Setting); /* Store current memory contents permanently */ MemoryStore(); - - GlobalSettings.ActiveSetting = Setting; + + GlobalSettings.ActiveSettingIdx = SettingIdx; GlobalSettings.ActiveSettingPtr = - &GlobalSettings.Settings[GlobalSettings.ActiveSetting]; + &GlobalSettings.Settings[SettingIdx]; /* Settings have changed. Progress changes through system */ ConfigurationInit(); - + LogInit(); + /* Recall new memory contents */ MemoryRecall(); + + /* Notify LED. blink according to current setting */ + LEDTrigger(LED_SETTING_CHANGE, LED_BLINK + SettingIdx); + + return true; + } else { + return false; } } uint8_t SettingsGetActiveById(void) { - return GlobalSettings.ActiveSetting; + return INDEX_TO_SETTING(GlobalSettings.ActiveSettingIdx); } void SettingsGetActiveByName(char* SettingOut, uint16_t BufferSize) { @@ -122,9 +87,8 @@ void SettingsGetActiveByName(char* SettingOut, uint16_t BufferSize) { bool SettingsSetActiveByName(const char* Setting) { uint8_t SettingNr = Setting[0] - '0'; - if ((Setting[1] == '\0') && (SettingNr < SETTINGS_COUNT)) { - SettingsSetActiveById(SettingNr); - return true; + if (Setting[1] == '\0') { + return SettingsSetActiveById(SettingNr); } else { return false; } diff --git a/Firmware/Chameleon-Mini/Settings.h b/Firmware/Chameleon-Mini/Settings.h index 59e675e..f8ce4dc 100644 --- a/Firmware/Chameleon-Mini/Settings.h +++ b/Firmware/Chameleon-Mini/Settings.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * Settings.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 21.12.2013 + * Author: skuser */ #ifndef SETTINGS_H_ @@ -58,16 +10,24 @@ #include "Button.h" #include "Configuration.h" +#include "Log.h" +#include "LED.h" #define SETTINGS_COUNT 8 +#define SETTINGS_FIRST 1 +#define SETTINGS_LAST (SETTINGS_FIRST + SETTINGS_COUNT - 1) typedef struct { ButtonActionEnum ButtonAction; + ButtonActionEnum ButtonLongAction; + LogModeEnum LogMode; ConfigurationEnum Configuration; + LEDFunctionEnum LEDRedFunction; + LEDFunctionEnum LEDGreenFunction; } SettingsEntryType; typedef struct { - uint8_t ActiveSetting; + uint8_t ActiveSettingIdx; SettingsEntryType* ActiveSettingPtr; SettingsEntryType Settings[SETTINGS_COUNT]; } SettingsType; @@ -78,7 +38,7 @@ void SettingsLoad(void); void SettingsSave(void); void SettingsCycle(void); -void SettingsSetActiveById(uint8_t Setting); +bool SettingsSetActiveById(uint8_t Setting); uint8_t SettingsGetActiveById(void); void SettingsGetActiveByName(char* SettingOut, uint16_t BufferSize); bool SettingsSetActiveByName(const char* Setting); diff --git a/Firmware/Chameleon-Mini/System.c b/Firmware/Chameleon-Mini/System.c index f21bcfa..db5b42a 100644 --- a/Firmware/Chameleon-Mini/System.c +++ b/Firmware/Chameleon-Mini/System.c @@ -1,71 +1,21 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * System.c * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 10.02.2013 + * Author: skuser */ #include "System.h" #include "LED.h" - -/* AVR Toolchain changed defines */ -#ifndef WDT_PER_500CLK_gc -#define WDT_PER_500CLK_gc WDT_PER_512CLK_gc -#endif +#include ISR(BADISR_vect) { while(1); } +EMPTY_INTERRUPT(RTC_OVF_vect); + void SystemInit(void) { if (RST.STATUS & RST_WDRF_bm) { @@ -96,9 +46,14 @@ void SystemInit(void) TCE0.PER = F_CPU / 256 / SYSTEM_TICK_FREQ - 1; TCE0.CTRLA = TC_CLKSEL_DIV256_gc; - /* Enable RTC with roughly 1kHz clock */ + /* Enable RTC with roughly 1kHz clock for system tick + * and to wake up while sleeping. */ CLK.RTCCTRL = CLK_RTCSRC_ULP_gc | CLK_RTCEN_bm; + RTC.PER = 1000 / SYSTEM_TICK_FREQ - 1; + RTC.COMP = 1000 / SYSTEM_TICK_FREQ - 1; RTC.CTRL = RTC_PRESCALER_DIV1_gc; + RTC.INTCTRL = RTC_OVFINTLVL_LO_gc; + /* Enable EEPROM data memory mapping */ NVM.CTRLB |= NVM_EEMAPEN_bm; @@ -121,6 +76,8 @@ void SystemEnterBootloader(void) void SystemStartUSBClock(void) { + SystemSleepDisable(); + /* 48MHz USB Clock using 12MHz XTAL */ OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc; OSC.CTRL |= OSC_XOSCEN_bm; @@ -136,6 +93,8 @@ void SystemStartUSBClock(void) void SystemStopUSBClock(void) { + SystemSleepEnable(); + /* Disable USB Clock to minimize power consumption */ CLK.USBCTRL &= ~CLK_USBSEN_bm; OSC.CTRL &= ~OSC_PLLEN_bm; @@ -148,3 +107,4 @@ void SystemInterruptInit(void) PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; sei(); } + diff --git a/Firmware/Chameleon-Mini/System.h b/Firmware/Chameleon-Mini/System.h index 63f7c74..240036f 100644 --- a/Firmware/Chameleon-Mini/System.h +++ b/Firmware/Chameleon-Mini/System.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * System.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 10.02.2013 + * Author: skuser */ #ifndef SYSTEM_H @@ -72,6 +24,9 @@ typedef uint16_t SystemRTCType; #define SYSTEM_TICK_FREQ 10 #define SYSTEM_TICK_MS (1000/SYSTEM_TICK_FREQ) +#define SYSTEM_SMODE_PSAVE SLEEP_SMODE_PSAVE_gc +#define SYSTEM_SMODE_IDLE SLEEP_SMODE_IDLE_gc + void SystemInit(void); void SystemReset(void); void SystemEnterBootloader(void); @@ -79,23 +34,42 @@ void SystemStartUSBClock(void); void SystemStopUSBClock(void); void SystemInterruptInit(void); INLINE bool SystemTick100ms(void); -INLINE SystemRTCType SystemGetRTC(void); - - -INLINE SystemRTCType SystemGetRTC(void) -{ - return RTC.CNT; -} +INLINE void SystemSleep(void); +INLINE void SystemSleepEnable(void); +INLINE void SystemSleepDisable(void); +INLINE void SystemSleepSetMode(uint8_t SleepMode); INLINE bool SystemTick100ms(void) { - if (TCE0.INTFLAGS & TC0_OVFIF_bm) { - TCE0.INTFLAGS = TC0_OVFIF_bm; + if (RTC.INTFLAGS & RTC_COMPIF_bm) { + while(RTC.STATUS & RTC_SYNCBUSY_bm) + ; - return true; + RTC.INTFLAGS = RTC_COMPIF_bm; + return true; } return false; } +INLINE void SystemSleep(void) +{ + asm volatile("sleep"); +} + +INLINE void SystemSleepEnable(void) +{ + SLEEP.CTRL |= SLEEP_SEN_bm; +} + +INLINE void SystemSleepDisable(void) +{ + SLEEP.CTRL &= ~SLEEP_SEN_bm; +} + +INLINE void SystemSleepSetMode(uint8_t SleepMode) +{ + SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SleepMode; +} + #endif /* SYSTEM_H */ diff --git a/Firmware/Chameleon-Mini/Terminal/CommandLine.c b/Firmware/Chameleon-Mini/Terminal/CommandLine.c index 5c49777..0ffc6a8 100644 --- a/Firmware/Chameleon-Mini/Terminal/CommandLine.c +++ b/Firmware/Chameleon-Mini/Terminal/CommandLine.c @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * CommandLine.c * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 04.05.2013 + * Author: skuser */ #include "CommandLine.h" @@ -152,6 +104,36 @@ const PROGMEM CommandEntryType CommandTable[] = { .SetFunc = CommandSetButton, .GetFunc = CommandGetButton }, + { + .Command = COMMAND_BUTTON_LONG, + .ExecFunc = CommandExecButtonLong, + .SetFunc = CommandSetButtonLong, + .GetFunc = CommandGetButtonLong + }, + { + .Command = COMMAND_LEDGREEN, + .ExecFunc = CommandExecLedGreen, + .SetFunc = CommandSetLedGreen, + .GetFunc = CommandGetLedGreen + }, + { + .Command = COMMAND_LEDRED, + .ExecFunc = CommandExecLedRed, + .SetFunc = CommandSetLedRed, + .GetFunc = CommandGetLedRed + }, + { + .Command = COMMAND_LOGMODE, + .ExecFunc = CommandExecLogMode, + .SetFunc = CommandSetLogMode, + .GetFunc = CommandGetLogMode + }, + { + .Command = COMMAND_LOGMEM, + .ExecFunc = CommandExecLogMem, + .SetFunc = CommandSetLogMem, + .GetFunc = CommandGetLogMem + }, { .Command = COMMAND_SETTING, .ExecFunc = NO_FUNCTION, diff --git a/Firmware/Chameleon-Mini/Terminal/CommandLine.h b/Firmware/Chameleon-Mini/Terminal/CommandLine.h index aee76dd..230b6de 100644 --- a/Firmware/Chameleon-Mini/Terminal/CommandLine.h +++ b/Firmware/Chameleon-Mini/Terminal/CommandLine.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * CommandLine.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 04.05.2013 + * Author: skuser */ #ifndef COMMANDLINE_H_ diff --git a/Firmware/Chameleon-Mini/Terminal/Commands.c b/Firmware/Chameleon-Mini/Terminal/Commands.c index e49f665..60837f9 100644 --- a/Firmware/Chameleon-Mini/Terminal/Commands.c +++ b/Firmware/Chameleon-Mini/Terminal/Commands.c @@ -1,57 +1,3 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. - * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ #include "Commands.h" #include @@ -226,14 +172,14 @@ CommandStatusIdType CommandExecButton(char* OutMessage) CommandStatusIdType CommandGetButton(char* OutParam) { - ButtonGetActionByName(OutParam, TERMINAL_BUFFER_SIZE); + ButtonGetActionByName(BUTTON_PRESS_SHORT, OutParam, TERMINAL_BUFFER_SIZE); return COMMAND_INFO_OK_WITH_TEXT_ID; } CommandStatusIdType CommandSetButton(const char* InParam) { - if (ButtonSetActionByName(InParam)) { + if (ButtonSetActionByName(BUTTON_PRESS_SHORT, InParam)) { SettingsSave(); return COMMAND_INFO_OK_ID; } else { @@ -241,6 +187,134 @@ CommandStatusIdType CommandSetButton(const char* InParam) } } +CommandStatusIdType CommandExecButtonLong(char* OutMessage) +{ + ButtonGetActionList(OutMessage, TERMINAL_BUFFER_SIZE); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandGetButtonLong(char* OutParam) +{ + ButtonGetActionByName(BUTTON_PRESS_LONG, OutParam, TERMINAL_BUFFER_SIZE); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandSetButtonLong(const char* InParam) +{ + if (ButtonSetActionByName(BUTTON_PRESS_LONG, InParam)) { + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + } +} + +CommandStatusIdType CommandExecLedGreen(char* OutMessage) +{ + LEDGetFuncList(OutMessage, TERMINAL_BUFFER_SIZE); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandGetLedGreen(char* OutParam) +{ + LEDGetFuncByName(LED_GREEN, OutParam, TERMINAL_BUFFER_SIZE); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandSetLedGreen(const char* InParam) +{ + if (LEDSetFuncByName(LED_GREEN, InParam)) { + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + } +} + +CommandStatusIdType CommandExecLedRed(char* OutMessage) +{ + LEDGetFuncList(OutMessage, TERMINAL_BUFFER_SIZE); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandGetLedRed(char* OutParam) +{ + LEDGetFuncByName(LED_RED, OutParam, TERMINAL_BUFFER_SIZE); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandSetLedRed(const char* InParam) +{ + if (LEDSetFuncByName(LED_RED, InParam)) { + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + } +} + +CommandStatusIdType CommandExecLogMode(char* OutMessage) +{ + /* Get list of log modes */ + LogGetModeList(OutMessage, TERMINAL_BUFFER_SIZE); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandGetLogMode(char* OutParam) +{ + /* Get Logmode */ + LogGetModeByName(OutParam, TERMINAL_BUFFER_SIZE); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandSetLogMode(const char* InParam) +{ + if (LogSetModeByName(InParam)) { + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + } +} + +CommandStatusIdType CommandExecLogMem(char* OutMessage) +{ + snprintf_P(OutMessage, TERMINAL_BUFFER_SIZE, + PSTR("%S,%S"), PSTR(COMMAND_LOGMEM_LOADBIN), PSTR(COMMAND_LOGMEM_CLEAR) ); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandGetLogMem(char* OutParam) +{ + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, + PSTR("%u"), LogMemFree()); + + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandSetLogMem(const char* InParam) +{ + if (strcmp_P(InParam, PSTR(COMMAND_LOGMEM_LOADBIN)) == 0) { + XModemSend(LogMemLoadBlock); + return COMMAND_INFO_XMODEM_WAIT_ID; + } else if (strcmp_P(InParam, PSTR(COMMAND_LOGMEM_CLEAR)) == 0) { + LogMemClear(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + } +} + CommandStatusIdType CommandGetSetting(char* OutParam) { SettingsGetActiveByName(OutParam, TERMINAL_BUFFER_SIZE); diff --git a/Firmware/Chameleon-Mini/Terminal/Commands.h b/Firmware/Chameleon-Mini/Terminal/Commands.h index 2ca30d7..f0da172 100644 --- a/Firmware/Chameleon-Mini/Terminal/Commands.h +++ b/Firmware/Chameleon-Mini/Terminal/Commands.h @@ -1,57 +1,4 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. - * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ + #ifndef COMMANDS_H_ #define COMMANDS_H_ @@ -135,6 +82,33 @@ CommandStatusIdType CommandExecButton(char* OutMessage); CommandStatusIdType CommandGetButton(char* OutParam); CommandStatusIdType CommandSetButton(const char* InParam); +#define COMMAND_BUTTON_LONG "BUTTON_LONG" +CommandStatusIdType CommandExecButtonLong(char* OutMessage); +CommandStatusIdType CommandGetButtonLong(char* OutParam); +CommandStatusIdType CommandSetButtonLong(const char* InParam); + +#define COMMAND_LEDGREEN "LEDGREEN" +CommandStatusIdType CommandExecLedGreen(char* OutMessage); +CommandStatusIdType CommandGetLedGreen(char* OutParam); +CommandStatusIdType CommandSetLedGreen(const char* InParam); + +#define COMMAND_LEDRED "LEDRED" +CommandStatusIdType CommandExecLedRed(char* OutMessage); +CommandStatusIdType CommandGetLedRed(char* OutParam); +CommandStatusIdType CommandSetLedRed(const char* InParam); + +#define COMMAND_LOGMODE "LOGMODE" +CommandStatusIdType CommandExecLogMode(char* OutMessage); +CommandStatusIdType CommandGetLogMode(char* OutParam); +CommandStatusIdType CommandSetLogMode(const char* InParam); + +#define COMMAND_LOGMEM "LOGMEM" +#define COMMAND_LOGMEM_LOADBIN "LOADBIN" +#define COMMAND_LOGMEM_CLEAR "CLEAR" +CommandStatusIdType CommandExecLogMem(char* OutMessage); +CommandStatusIdType CommandGetLogMem(char* OutParam); +CommandStatusIdType CommandSetLogMem(const char* InParam); + #define COMMAND_SETTING "SETTING" CommandStatusIdType CommandGetSetting(char* OutParam); CommandStatusIdType CommandSetSetting(const char* InParam); diff --git a/Firmware/Chameleon-Mini/Terminal/Terminal.c b/Firmware/Chameleon-Mini/Terminal/Terminal.c index 5e20bd0..d1360a9 100644 --- a/Firmware/Chameleon-Mini/Terminal/Terminal.c +++ b/Firmware/Chameleon-Mini/Terminal/Terminal.c @@ -1,57 +1,3 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. - * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ #include "Terminal.h" #include "../System.h" @@ -121,7 +67,7 @@ static void ProcessByte(void) { if (Byte >= 0) { /* Byte received */ - LEDPulse(LED_RED); + LEDTrigger(LED_TERMINAL_RXTX, LED_PULSE); if (XModemProcessByte(Byte)) { /* XModem handled the byte */ @@ -178,30 +124,34 @@ void TerminalInit(void) void TerminalTask(void) { - CDC_Device_USBTask(&TerminalHandle); - USB_USBTask(); + if (TerminalState == TERMINAL_INITIALIZED) { + CDC_Device_USBTask(&TerminalHandle); + USB_USBTask(); - ProcessByte(); + ProcessByte(); + } } void TerminalTick(void) { SenseVBus(); - XModemTick(); - CommandLineTick(); + if (TerminalState == TERMINAL_INITIALIZED) { + XModemTick(); + CommandLineTick(); + } } /** Event handler for the library USB Connection event. */ void EVENT_USB_Device_Connect(void) { - LEDSetOn(LED_GREEN); + LEDTrigger(LED_TERMINAL_CONN, LED_ON); } /** Event handler for the library USB Disconnection event. */ void EVENT_USB_Device_Disconnect(void) { - LEDSetOff(LED_GREEN); + LEDTrigger(LED_TERMINAL_CONN, LED_OFF); } diff --git a/Firmware/Chameleon-Mini/Terminal/Terminal.h b/Firmware/Chameleon-Mini/Terminal/Terminal.h index 840d55e..2cd4753 100644 --- a/Firmware/Chameleon-Mini/Terminal/Terminal.h +++ b/Firmware/Chameleon-Mini/Terminal/Terminal.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * CommandLine.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 10.02.2013 + * Author: skuser */ #ifndef TERMINAL_H_ diff --git a/Firmware/Chameleon-Mini/Terminal/XModem.c b/Firmware/Chameleon-Mini/Terminal/XModem.c index 66074e5..a24a4ba 100644 --- a/Firmware/Chameleon-Mini/Terminal/XModem.c +++ b/Firmware/Chameleon-Mini/Terminal/XModem.c @@ -1,58 +1,3 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. - * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. - */ - #include "XModem.h" #include "Terminal.h" @@ -62,12 +7,13 @@ #define BYTE_CAN 0x18 #define BYTE_EOF 0x1A #define BYTE_EOT 0x04 +#define BYTE_ESC 0x1B #define XMODEM_BLOCK_SIZE 128 -#define RECV_INIT_TIMEOUT 5 /* x 100ms */ -#define RECV_INIT_COUNT 20 /* 10 secs */ -#define SEND_INIT_TIMEOUT 100 /* x 100ms */ +#define RECV_INIT_TIMEOUT 5 /* #Ticks between sending of NAKs to the sender */ +#define RECV_INIT_COUNT 60 /* #Timeouts until receive failure */ +#define SEND_INIT_TIMEOUT 300 /* #Ticks waiting for NAKs from the receiver before failure */ #define FIRST_FRAME_NUMBER 1 #define CHECKSUM_INIT_VALUE 0 @@ -89,7 +35,7 @@ static uint8_t CurrentFrameNumber; static uint8_t ReceivedFrameNumber; static uint8_t Checksum; static uint8_t RetryCount; -static uint8_t RetryTimeout; +static uint16_t RetryTimeout; static uint16_t BufferIdx; static uint32_t BlockAddress; @@ -140,7 +86,7 @@ bool XModemProcessByte(uint8_t Byte) /* Transmission finished */ TerminalSendByte(BYTE_ACK); State = STATE_OFF; - } else if (Byte == BYTE_CAN) { + } else if ( (Byte == BYTE_CAN) || (Byte == BYTE_ESC) ) { /* Cancel transmission */ State = STATE_OFF; } else { @@ -218,6 +164,8 @@ bool XModemProcessByte(uint8_t Byte) if (Byte == BYTE_NAK) { CurrentFrameNumber = FIRST_FRAME_NUMBER - 1; Byte = BYTE_ACK; + } else if (Byte == BYTE_ESC) { + State = STATE_OFF; } /* Fallthrough */ diff --git a/Firmware/Chameleon-Mini/Terminal/XModem.h b/Firmware/Chameleon-Mini/Terminal/XModem.h index fa35d20..d9f9d5d 100644 --- a/Firmware/Chameleon-Mini/Terminal/XModem.h +++ b/Firmware/Chameleon-Mini/Terminal/XModem.h @@ -1,56 +1,8 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL - * AUTHORS"). All rights reserved. +/* + * TerminalXModem.h * - * DEFINITIONS: - * - * "WORK": The material covered by this license includes the schematic - * diagrams, designs, circuit or circuit board layouts, mechanical - * drawings, documentation (in electronic or printed form), source code, - * binary software, data files, assembled devices, and any additional - * material provided by the ORIGINAL AUTHORS in the ChameleonMini project - * (https://github.com/skuep/ChameleonMini). - * - * LICENSE TERMS: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK are permitted provided that the - * following conditions are met: - * - * Redistributions and use of this WORK, with or without modification, or - * of substantial portions of this WORK must include the above copyright - * notice, this list of conditions, the below disclaimer, and the following - * attribution: - * - * "Based on ChameleonMini an open-source RFID emulator: - * https://github.com/skuep/ChameleonMini" - * - * The attribution must be clearly visible to a user, for example, by being - * printed on the circuit board and an enclosure, and by being displayed by - * software (both in binary and source code form). - * - * At any time, the majority of the ORIGINAL AUTHORS may decide to give - * written permission to an entity to use or redistribute the WORK (with or - * without modification) WITHOUT having to include the above copyright - * notice, this list of conditions, the below disclaimer, and the above - * attribution. - * - * DISCLAIMER: - * - * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the hardware, software, and - * documentation should not be interpreted as representing official - * policies, either expressed or implied, of the ORIGINAL AUTHORS. + * Created on: 22.03.2013 + * Author: skuser */ #ifndef XMODEM_H_