diff --git a/.github/ci/book.sh b/.github/ci/book.sh new file mode 100755 index 000000000..285cdc8fa --- /dev/null +++ b/.github/ci/book.sh @@ -0,0 +1,17 @@ +#!/bin/bash +## on push branch=main + +set -euxo pipefail + +make -C docs + +export KUBECONFIG=/ci/secrets/kubeconfig.yml +POD=$(kubectl -n embassy get po -l app=website -o jsonpath={.items[0].metadata.name}) + +mkdir -p build +mv docs/book build/book +tar -C build -cf book.tar book +kubectl exec $POD -- mkdir -p /usr/share/nginx/html +kubectl cp book.tar $POD:/usr/share/nginx/html/ +kubectl exec $POD -- find /usr/share/nginx/html +kubectl exec $POD -- tar -C /usr/share/nginx/html -xvf /usr/share/nginx/html/book.tar diff --git a/.github/ci/build.sh b/.github/ci/build.sh index 77d2b3cab..68a7c0c34 100755 --- a/.github/ci/build.sh +++ b/.github/ci/build.sh @@ -7,7 +7,7 @@ set -euo pipefail export RUSTUP_HOME=/ci/cache/rustup export CARGO_HOME=/ci/cache/cargo export CARGO_TARGET_DIR=/ci/cache/target -if [ -f /ci/secrets/teleprobe-token.txt ]; then +if [ -f /ci/secrets/teleprobe-token.txt ]; then echo Got teleprobe token! export TELEPROBE_HOST=https://teleprobe.embassy.dev export TELEPROBE_TOKEN=$(cat /ci/secrets/teleprobe-token.txt) diff --git a/.github/ci/doc.sh b/.github/ci/doc.sh index 7112d8aaa..47babe8f5 100755 --- a/.github/ci/doc.sh +++ b/.github/ci/doc.sh @@ -38,6 +38,7 @@ docserver-builder -i ./embassy-usb -o webroot/crates/embassy-usb/git.zup docserver-builder -i ./embassy-usb-dfu -o webroot/crates/embassy-usb-dfu/git.zup docserver-builder -i ./embassy-usb-driver -o webroot/crates/embassy-usb-driver/git.zup docserver-builder -i ./embassy-usb-logger -o webroot/crates/embassy-usb-logger/git.zup +docserver-builder -i ./embassy-usb-synopsys-otg -o webroot/crates/embassy-usb-synopsys-otg/git.zup docserver-builder -i ./embassy-net -o webroot/crates/embassy-net/git.zup docserver-builder -i ./embassy-net-driver -o webroot/crates/embassy-net-driver/git.zup diff --git a/.github/ci/test-nightly.sh b/.github/ci/test-nightly.sh index d6e5dc574..1724ffe89 100755 --- a/.github/ci/test-nightly.sh +++ b/.github/ci/test-nightly.sh @@ -11,3 +11,4 @@ mv rust-toolchain-nightly.toml rust-toolchain.toml MIRIFLAGS=-Zmiri-ignore-leaks cargo miri test --manifest-path ./embassy-executor/Cargo.toml MIRIFLAGS=-Zmiri-ignore-leaks cargo miri test --manifest-path ./embassy-executor/Cargo.toml --features nightly +MIRIFLAGS=-Zmiri-ignore-leaks cargo miri test --manifest-path ./embassy-sync/Cargo.toml diff --git a/.github/ci/test.sh b/.github/ci/test.sh index 8a58939f6..41da644fc 100755 --- a/.github/ci/test.sh +++ b/.github/ci/test.sh @@ -8,9 +8,10 @@ export RUSTUP_HOME=/ci/cache/rustup export CARGO_HOME=/ci/cache/cargo export CARGO_TARGET_DIR=/ci/cache/target -cargo test --manifest-path ./embassy-sync/Cargo.toml -cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml -cargo test --manifest-path ./embassy-hal-internal/Cargo.toml +cargo test --manifest-path ./embassy-futures/Cargo.toml +cargo test --manifest-path ./embassy-sync/Cargo.toml +cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml +cargo test --manifest-path ./embassy-hal-internal/Cargo.toml cargo test --manifest-path ./embassy-time/Cargo.toml --features generic-queue,mock-driver cargo test --manifest-path ./embassy-time-driver/Cargo.toml diff --git a/.vscode/settings.json b/.vscode/settings.json index 343331950..48d0957e6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,25 +9,29 @@ "rust-analyzer.check.noDefaultFeatures": true, "rust-analyzer.cargo.noDefaultFeatures": true, "rust-analyzer.showUnlinkedFileNotification": false, - // uncomment the target of your chip. - "rust-analyzer.cargo.target": "thumbv6m-none-eabi", + // Uncomment the target of your chip. + //"rust-analyzer.cargo.target": "thumbv6m-none-eabi", //"rust-analyzer.cargo.target": "thumbv7m-none-eabi", - //"rust-analyzer.cargo.target": "thumbv7em-none-eabi", + "rust-analyzer.cargo.target": "thumbv7em-none-eabi", + //"rust-analyzer.cargo.target": "thumbv7em-none-eabihf", //"rust-analyzer.cargo.target": "thumbv8m.main-none-eabihf", - /* "rust-analyzer.cargo.features": [ - "stm32f103c8", + "rust-analyzer.cargo.features": [ + // Comment out these features when working on the examples. Most example crates do not have any cargo features. + "stm32f446re", "time-driver-any", "unstable-pac", "exti", - ], */ + "rt", + ], "rust-analyzer.linkedProjects": [ - // Uncomment ONE line for the chip you want to work on. + "embassy-stm32/Cargo.toml", + // To work on the examples, comment the line above and all of the cargo.features lines, + // then uncomment ONE line below to select the chip you want to work on. // This makes rust-analyzer work on the example crate and all its dependencies. - // "embassy-stm32/Cargo.toml", // "examples/nrf52840-rtic/Cargo.toml", // "examples/nrf5340/Cargo.toml", // "examples/nrf-rtos-trace/Cargo.toml", - "examples/rp/Cargo.toml", + // "examples/rp/Cargo.toml", // "examples/std/Cargo.toml", // "examples/stm32c0/Cargo.toml", // "examples/stm32f0/Cargo.toml", diff --git a/LICENSE-CC-BY-SA b/LICENSE-CC-BY-SA new file mode 100644 index 000000000..a73481c4b --- /dev/null +++ b/LICENSE-CC-BY-SA @@ -0,0 +1,428 @@ +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + + including for purposes of Section 3(b); and + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. + diff --git a/NOTICE.md b/NOTICE.md index 868bec08f..a50b39494 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -12,5 +12,5 @@ listed source code repository logs. This program and the accompanying materials are made available under the terms of the Apache Software License 2.0 which is available at -https://www.apache.org/licenses/LICENSE-2.0, or the MIT license which is +https://www.apache.org/licenses/LICENSE-2.0, or the MIT license which is available at https://opensource.org/licenses/MIT diff --git a/README.md b/README.md index b6f667f75..8952b0358 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,12 @@ Embassy is the next-generation framework for embedded applications. Write safe, correct and energy-efficient embedded code faster, using the Rust programming language, its async facilities, and the Embassy libraries. -## <a href="https://embassy.dev/book/dev/index.html">Documentation</a> - <a href="https://docs.embassy.dev/">API reference</a> - <a href="https://embassy.dev/">Website</a> - <a href="https://matrix.to/#/#embassy-rs:matrix.org">Chat</a> +## <a href="https://embassy.dev/book/index.html">Documentation</a> - <a href="https://docs.embassy.dev/">API reference</a> - <a href="https://embassy.dev/">Website</a> - <a href="https://matrix.to/#/#embassy-rs:matrix.org">Chat</a> ## Rust + async ❤️ embedded The Rust programming language is blazingly fast and memory-efficient, with no runtime, garbage collector or OS. It catches a wide variety of bugs at compile time, thanks to its full memory- and thread-safety, and expressive type system. -Rust's <a href="https://rust-lang.github.io/async-book/">async/await</a> allows for unprecedently easy and efficient multitasking in embedded systems. Tasks get transformed at compile time into state machines that get run cooperatively. It requires no dynamic memory allocation, and runs on a single stack, so no per-task stack size tuning is required. It obsoletes the need for a traditional RTOS with kernel context switching, and is <a href="https://tweedegolf.nl/en/blog/65/async-rust-vs-rtos-showdown">faster and smaller than one!</a> +Rust's <a href="https://rust-lang.github.io/async-book/">async/await</a> allows for unprecedentedly easy and efficient multitasking in embedded systems. Tasks get transformed at compile time into state machines that get run cooperatively. It requires no dynamic memory allocation, and runs on a single stack, so no per-task stack size tuning is required. It obsoletes the need for a traditional RTOS with kernel context switching, and is <a href="https://tweedegolf.nl/en/blog/65/async-rust-vs-rtos-showdown">faster and smaller than one!</a> ## Batteries included @@ -18,6 +18,7 @@ Rust's <a href="https://rust-lang.github.io/async-book/">async/await</a> allows - <a href="https://github.com/esp-rs">esp-rs</a>, for the Espressif Systems ESP32 series of chips. - Embassy HAL support for Espressif chips is being developed in the [esp-rs/esp-hal](https://github.com/esp-rs/esp-hal) repository. - Async WiFi, Bluetooth and ESP-NOW is being developed in the [esp-rs/esp-wifi](https://github.com/esp-rs/esp-wifi) repository. + - <a href="https://github.com/ch32-rs/ch32-hal">ch32-hal</a>, for the WCH 32-bit RISC-V(CH32V) series of chips. - **Time that Just Works** - No more messing with hardware timers. <a href="https://docs.embassy.dev/embassy-time">embassy_time</a> provides Instant, Duration and Timer types that are globally available and never overflow. @@ -89,7 +90,7 @@ async fn main(spawner: Spawner) { ## Examples -Examples are found in the `examples/` folder seperated by the chip manufacturer they are designed to run on. For example: +Examples are found in the `examples/` folder separated by the chip manufacturer they are designed to run on. For example: * `examples/nrf52840` run on the `nrf52840-dk` board (PCA10056) but should be easily adaptable to other nRF52 chips and boards. * `examples/nrf5340` run on the `nrf5340-dk` board (PCA10095). @@ -99,12 +100,7 @@ Examples are found in the `examples/` folder seperated by the chip manufacturer ### Running examples -- Install `probe-rs`. - -```bash -cargo install probe-rs --features cli -``` - +- Install `probe-rs` following the instructions at <https://probe.rs>. - Change directory to the sample's base directory. For example: ```bash @@ -130,8 +126,8 @@ For more help getting started, see [Getting Started][1] and [Running the Example ## Developing Embassy with Rust Analyzer based editors The [Rust Analyzer](https://rust-analyzer.github.io/) is used by [Visual Studio Code](https://code.visualstudio.com/) -and others. Given the multiple targets that Embassy serves, there is no Cargo workspace file. Instead, the Rust Analyzer -must be told of the target project to work with. In the case of Visual Studio Code, +and others. Given the multiple targets that Embassy serves, there is no Cargo workspace file. Instead, the Rust Analyzer +must be told of the target project to work with. In the case of Visual Studio Code, please refer to the `.vscode/settings.json` file's `rust-analyzer.linkedProjects`setting. ## Minimum supported Rust version (MSRV) diff --git a/ci.sh b/ci.sh index d17f4e13e..ee2f320b5 100755 --- a/ci.sh +++ b/ci.sh @@ -125,6 +125,10 @@ cargo batch \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h725re,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7b3ai,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7b3ai,defmt,exti,time-driver-tim1,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7r3z8,defmt,exti,time-driver-tim1,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7r7a8,defmt,exti,time-driver-tim1,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7s3a8,defmt,exti,time-driver-tim1,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7s7z8,defmt,exti,time-driver-tim1,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l431cb,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l422cb,defmt,exti,time-driver-any,time \ @@ -147,8 +151,15 @@ cargo batch \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f103re,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f100c4,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32h503rb,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32h523cc,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32h562ag,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32wba50ke,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32wba55ug,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32u5g9nj,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb35ce,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u031r8,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u073mb,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u083rc,defmt,exti,time-driver-any,time \ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \ @@ -160,11 +171,12 @@ cargo batch \ --- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns \ --- build --release --manifest-path embassy-boot-rp/Cargo.toml --target thumbv6m-none-eabi \ --- build --release --manifest-path embassy-boot-stm32/Cargo.toml --target thumbv7em-none-eabi --features embassy-stm32/stm32wl55jc-cm4 \ - --- build --release --manifest-path docs/modules/ROOT/examples/basic/Cargo.toml --target thumbv7em-none-eabi \ - --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-pac/Cargo.toml --target thumbv7em-none-eabi \ - --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-hal/Cargo.toml --target thumbv7em-none-eabi \ - --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-irq/Cargo.toml --target thumbv7em-none-eabi \ - --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-async/Cargo.toml --target thumbv7em-none-eabi \ + --- build --release --manifest-path docs/examples/basic/Cargo.toml --target thumbv7em-none-eabi \ + --- build --release --manifest-path docs/examples/layer-by-layer/blinky-pac/Cargo.toml --target thumbv7em-none-eabi \ + --- build --release --manifest-path docs/examples/layer-by-layer/blinky-hal/Cargo.toml --target thumbv7em-none-eabi \ + --- build --release --manifest-path docs/examples/layer-by-layer/blinky-irq/Cargo.toml --target thumbv7em-none-eabi \ + --- build --release --manifest-path docs/examples/layer-by-layer/blinky-async/Cargo.toml --target thumbv7em-none-eabi \ + --- build --release --manifest-path examples/nrf52810/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52810 \ --- build --release --manifest-path examples/nrf52840/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52840 \ --- build --release --manifest-path examples/nrf5340/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/nrf5340 \ --- build --release --manifest-path examples/nrf9160/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/nrf9160 \ @@ -176,16 +188,19 @@ cargo batch \ --- build --release --manifest-path examples/stm32f3/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32f3 \ --- build --release --manifest-path examples/stm32f334/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32f334 \ --- build --release --manifest-path examples/stm32f4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32f4 \ + --- build --release --manifest-path examples/stm32f469/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32f469 \ --- build --release --manifest-path examples/stm32f7/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32f7 \ --- build --release --manifest-path examples/stm32c0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32c0 \ --- build --release --manifest-path examples/stm32g0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32g0 \ --- build --release --manifest-path examples/stm32g4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32g4 \ --- build --release --manifest-path examples/stm32h5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32h5 \ --- build --release --manifest-path examples/stm32h7/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32h7 \ + --- build --release --manifest-path examples/stm32h7rs/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32h7rs \ --- build --release --manifest-path examples/stm32l0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32l0 \ --- build --release --manifest-path examples/stm32l1/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32l1 \ --- build --release --manifest-path examples/stm32l4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32l4 \ --- build --release --manifest-path examples/stm32l5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32l5 \ + --- build --release --manifest-path examples/stm32u0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32u0 \ --- build --release --manifest-path examples/stm32u5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32u5 \ --- build --release --manifest-path examples/stm32wb/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32wb \ --- build --release --manifest-path examples/stm32wba/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32wba \ @@ -232,8 +247,10 @@ cargo batch \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303ze --out-dir out/tests/stm32f303ze \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l496zg --out-dir out/tests/stm32l496zg \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55jc --out-dir out/tests/stm32wl55jc \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7s3l8 --out-dir out/tests/stm32h7s3l8 \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32f091rc --out-dir out/tests/stm32f091rc \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32h503rb --out-dir out/tests/stm32h503rb \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u083rc --out-dir out/tests/stm32u083rc \ --- build --release --manifest-path tests/rp/Cargo.toml --target thumbv6m-none-eabi --out-dir out/tests/rpi-pico \ --- build --release --manifest-path tests/nrf52840/Cargo.toml --target thumbv7em-none-eabi --out-dir out/tests/nrf52840-dk \ --- build --release --manifest-path tests/nrf51422/Cargo.toml --target thumbv6m-none-eabi --out-dir out/tests/nrf51-dk \ @@ -250,6 +267,9 @@ rm out/tests/stm32f207zg/eth # doesn't work, gives "noise error", no idea why. usart_dma does pass. rm out/tests/stm32u5a5zj/usart +# flaky, perhaps bad wire +rm out/tests/stm32l152re/usart_rx_ringbuffered + if [[ -z "${TELEPROBE_TOKEN-}" ]]; then echo No teleprobe token found, skipping running HIL tests exit diff --git a/cyw43/Cargo.toml b/cyw43/Cargo.toml index f279739e4..7d060c9c8 100644 --- a/cyw43/Cargo.toml +++ b/cyw43/Cargo.toml @@ -18,7 +18,7 @@ firmware-logs = [] [dependencies] embassy-time = { version = "0.3.0", path = "../embassy-time"} -embassy-sync = { version = "0.5.0", path = "../embassy-sync"} +embassy-sync = { version = "0.6.0", path = "../embassy-sync"} embassy-futures = { version = "0.1.0", path = "../embassy-futures"} embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"} diff --git a/cyw43/README.md b/cyw43/README.md index dabdf0471..5b4a5d789 100644 --- a/cyw43/README.md +++ b/cyw43/README.md @@ -23,7 +23,7 @@ TODO: ## Running the examples -- `cargo install probe-rs --features cli` +- Install `probe-rs` following the instructions at <https://probe.rs>. - `cd examples/rp` ### Example 1: Scan the wifi stations - `cargo run --release --bin wifi_scan` diff --git a/cyw43/src/control.rs b/cyw43/src/control.rs index 135b8c245..cd890c982 100644 --- a/cyw43/src/control.rs +++ b/cyw43/src/control.rs @@ -124,8 +124,7 @@ impl<'a> Control<'a> { self.set_iovar_u32("apsta", 1).await; // read MAC addr. - let mut mac_addr = [0; 6]; - assert_eq!(self.get_iovar("cur_etheraddr", &mut mac_addr).await, 6); + let mac_addr = self.address().await; debug!("mac addr: {:02x}", Bytes(&mac_addr)); let country = countries::WORLD_WIDE_XX; @@ -229,8 +228,8 @@ impl<'a> Control<'a> { self.wait_for_join(i).await } - /// Join an protected network with the provided ssid and passphrase. - pub async fn join_wpa2(&mut self, ssid: &str, passphrase: &str) -> Result<(), Error> { + /// Join a protected network with the provided ssid and [`PassphraseInfo`]. + async fn join_wpa2_passphrase_info(&mut self, ssid: &str, passphrase_info: &PassphraseInfo) -> Result<(), Error> { self.set_iovar_u32("ampdu_ba_wsize", 8).await; self.ioctl_set_u32(134, 0, 4).await; // wsec = wpa2 @@ -240,14 +239,13 @@ impl<'a> Control<'a> { Timer::after_millis(100).await; - let mut pfi = PassphraseInfo { - len: passphrase.len() as _, - flags: 1, - passphrase: [0; 64], - }; - pfi.passphrase[..passphrase.len()].copy_from_slice(passphrase.as_bytes()); - self.ioctl(IoctlType::Set, IOCTL_CMD_SET_PASSPHRASE, 0, &mut pfi.to_bytes()) - .await; // WLC_SET_WSEC_PMK + self.ioctl( + IoctlType::Set, + IOCTL_CMD_SET_PASSPHRASE, + 0, + &mut passphrase_info.to_bytes(), + ) + .await; // WLC_SET_WSEC_PMK self.ioctl_set_u32(20, 0, 1).await; // set_infra = 1 self.ioctl_set_u32(22, 0, 0).await; // set_auth = 0 (open) @@ -262,6 +260,28 @@ impl<'a> Control<'a> { self.wait_for_join(i).await } + /// Join a protected network with the provided ssid and passphrase. + pub async fn join_wpa2(&mut self, ssid: &str, passphrase: &str) -> Result<(), Error> { + let mut pfi = PassphraseInfo { + len: passphrase.len() as _, + flags: 1, + passphrase: [0; 64], + }; + pfi.passphrase[..passphrase.len()].copy_from_slice(passphrase.as_bytes()); + self.join_wpa2_passphrase_info(ssid, &pfi).await + } + + /// Join a protected network with the provided ssid and precomputed PSK. + pub async fn join_wpa2_psk(&mut self, ssid: &str, psk: &[u8; 32]) -> Result<(), Error> { + let mut pfi = PassphraseInfo { + len: psk.len() as _, + flags: 0, + passphrase: [0; 64], + }; + pfi.passphrase[..psk.len()].copy_from_slice(psk); + self.join_wpa2_passphrase_info(ssid, &pfi).await + } + async fn wait_for_join(&mut self, i: SsidInfo) -> Result<(), Error> { self.events.mask.enable(&[Event::SET_SSID, Event::AUTH]); let mut subscriber = self.events.queue.subscriber().unwrap(); @@ -574,6 +594,13 @@ impl<'a> Control<'a> { self.ioctl(IoctlType::Set, IOCTL_CMD_DISASSOC, 0, &mut []).await; info!("Disassociated") } + + /// Gets the MAC address of the device + pub async fn address(&mut self) -> [u8; 6] { + let mut mac_addr = [0; 6]; + assert_eq!(self.get_iovar("cur_etheraddr", &mut mac_addr).await, 6); + mac_addr + } } /// WiFi network scanner. diff --git a/cyw43/src/runner.rs b/cyw43/src/runner.rs index c72cf0def..e90316302 100644 --- a/cyw43/src/runner.rs +++ b/cyw43/src/runner.rs @@ -1,6 +1,5 @@ use embassy_futures::select::{select3, Either3}; use embassy_net_driver_channel as ch; -use embassy_sync::pubsub::PubSubBehavior; use embassy_time::{block_for, Duration, Timer}; use embedded_hal_1::digital::OutputPin; @@ -438,13 +437,16 @@ where // publish() is a deadlock risk in the current design as awaiting here prevents ioctls // The `Runner` always yields when accessing the device, so consumers always have a chance to receive the event // (if they are actively awaiting the queue) - self.events.queue.publish_immediate(events::Message::new( - Status { - event_type: evt_type, - status, - }, - event_payload, - )); + self.events + .queue + .immediate_publisher() + .publish_immediate(events::Message::new( + Status { + event_type: evt_type, + status, + }, + event_payload, + )); } } CHANNEL_TYPE_DATA => { diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 000000000..834802d3b --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,8 @@ +all: + asciidoctor -d book -D book/ index.adoc + cp -r images book + +clean: + rm -rf book + +.PHONY: all clean diff --git a/docs/README.md b/docs/README.md index 0bf3a6c89..d766a86d9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,29 @@ # embassy docs -The documentation hosted at [https://embassy.dev/book](https://embassy.dev/book). Building the documentation requires -cloning the [embassy-book](https://github.com/embassy-rs/embassy-book) repository and following the instructions. +The documentation hosted at [https://embassy.dev/book](https://embassy.dev/book). Building the documentation requires the [asciidoctor](https://asciidoctor.org/) tool, and can built running `make` in this folder: + +``` +make +``` + +Then open the generated file `thebook/index.html`. + +## License + +The Embassy Docs (this folder) is distributed under the following licenses: + +* The code samples and free-standing Cargo projects contained within these docs are licensed under the terms of both the [MIT License] and the [Apache License v2.0]. +* The written prose contained within these docs are licensed under the terms of the Creative Commons [CC-BY-SA v4.0] license. + +Copies of the licenses used by this project may also be found here: + +* [MIT License Hosted] +* [Apache License v2.0 Hosted] +* [CC-BY-SA v4.0 Hosted] + +[MIT License]: ./../LICENSE-MIT +[Apache License v2.0]: ./../LICENSE-APACHE +[CC-BY-SA v4.0]: ./../LICENSE-CC-BY-SA +[MIT License Hosted]: https://opensource.org/licenses/MIT +[Apache License v2.0 Hosted]: http://www.apache.org/licenses/LICENSE-2.0 +[CC-BY-SA v4.0 Hosted]: https://creativecommons.org/licenses/by-sa/4.0/legalcode diff --git a/docs/antora.yml b/docs/antora.yml deleted file mode 100644 index 9a00fa820..000000000 --- a/docs/antora.yml +++ /dev/null @@ -1,5 +0,0 @@ -name: ROOT -title: Embassy -version: dev -nav: - - modules/ROOT/nav.adoc diff --git a/docs/modules/ROOT/examples/basic/.cargo/config.toml b/docs/examples/basic/.cargo/config.toml similarity index 100% rename from docs/modules/ROOT/examples/basic/.cargo/config.toml rename to docs/examples/basic/.cargo/config.toml diff --git a/docs/examples/basic/Cargo.toml b/docs/examples/basic/Cargo.toml new file mode 100644 index 000000000..d86d4a809 --- /dev/null +++ b/docs/examples/basic/Cargo.toml @@ -0,0 +1,18 @@ +[package] +authors = ["Dario Nieuwenhuis <dirbaio@dirbaio.net>"] +edition = "2018" +name = "embassy-basic-example" +version = "0.1.0" +license = "MIT OR Apache-2.0" + +[dependencies] +embassy-executor = { version = "0.5.0", path = "../../../embassy-executor", features = ["defmt", "integrated-timers", "arch-cortex-m", "executor-thread"] } +embassy-time = { version = "0.3.0", path = "../../../embassy-time", features = ["defmt"] } +embassy-nrf = { version = "0.1.0", path = "../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote"] } + +defmt = "0.3" +defmt-rtt = "0.3" + +cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } +cortex-m-rt = "0.7.0" +panic-probe = { version = "0.3", features = ["print-defmt"] } diff --git a/docs/modules/ROOT/examples/basic/build.rs b/docs/examples/basic/build.rs similarity index 100% rename from docs/modules/ROOT/examples/basic/build.rs rename to docs/examples/basic/build.rs diff --git a/docs/modules/ROOT/examples/basic/memory.x b/docs/examples/basic/memory.x similarity index 100% rename from docs/modules/ROOT/examples/basic/memory.x rename to docs/examples/basic/memory.x diff --git a/docs/modules/ROOT/examples/basic/src/main.rs b/docs/examples/basic/src/main.rs similarity index 100% rename from docs/modules/ROOT/examples/basic/src/main.rs rename to docs/examples/basic/src/main.rs diff --git a/docs/examples/examples b/docs/examples/examples new file mode 120000 index 000000000..d15735c1d --- /dev/null +++ b/docs/examples/examples @@ -0,0 +1 @@ +../../examples \ No newline at end of file diff --git a/docs/modules/ROOT/examples/layer-by-layer/.cargo/config.toml b/docs/examples/layer-by-layer/.cargo/config.toml similarity index 100% rename from docs/modules/ROOT/examples/layer-by-layer/.cargo/config.toml rename to docs/examples/layer-by-layer/.cargo/config.toml diff --git a/docs/modules/ROOT/examples/layer-by-layer/Cargo.toml b/docs/examples/layer-by-layer/Cargo.toml similarity index 69% rename from docs/modules/ROOT/examples/layer-by-layer/Cargo.toml rename to docs/examples/layer-by-layer/Cargo.toml index 943249a17..0f233eae5 100644 --- a/docs/modules/ROOT/examples/layer-by-layer/Cargo.toml +++ b/docs/examples/layer-by-layer/Cargo.toml @@ -8,8 +8,8 @@ members = [ ] [patch.crates-io] -embassy-executor = { path = "../../../../../embassy-executor" } -embassy-stm32 = { path = "../../../../../embassy-stm32" } +embassy-executor = { path = "../../../embassy-executor" } +embassy-stm32 = { path = "../../../embassy-stm32" } [profile.release] codegen-units = 1 diff --git a/docs/modules/ROOT/examples/layer-by-layer/blinky-async/Cargo.toml b/docs/examples/layer-by-layer/blinky-async/Cargo.toml similarity index 100% rename from docs/modules/ROOT/examples/layer-by-layer/blinky-async/Cargo.toml rename to docs/examples/layer-by-layer/blinky-async/Cargo.toml diff --git a/docs/modules/ROOT/examples/layer-by-layer/blinky-async/src/main.rs b/docs/examples/layer-by-layer/blinky-async/src/main.rs similarity index 100% rename from docs/modules/ROOT/examples/layer-by-layer/blinky-async/src/main.rs rename to docs/examples/layer-by-layer/blinky-async/src/main.rs diff --git a/docs/modules/ROOT/examples/layer-by-layer/blinky-hal/Cargo.toml b/docs/examples/layer-by-layer/blinky-hal/Cargo.toml similarity index 100% rename from docs/modules/ROOT/examples/layer-by-layer/blinky-hal/Cargo.toml rename to docs/examples/layer-by-layer/blinky-hal/Cargo.toml diff --git a/docs/modules/ROOT/examples/layer-by-layer/blinky-hal/src/main.rs b/docs/examples/layer-by-layer/blinky-hal/src/main.rs similarity index 100% rename from docs/modules/ROOT/examples/layer-by-layer/blinky-hal/src/main.rs rename to docs/examples/layer-by-layer/blinky-hal/src/main.rs diff --git a/docs/modules/ROOT/examples/layer-by-layer/blinky-irq/Cargo.toml b/docs/examples/layer-by-layer/blinky-irq/Cargo.toml similarity index 100% rename from docs/modules/ROOT/examples/layer-by-layer/blinky-irq/Cargo.toml rename to docs/examples/layer-by-layer/blinky-irq/Cargo.toml diff --git a/docs/modules/ROOT/examples/layer-by-layer/blinky-irq/src/main.rs b/docs/examples/layer-by-layer/blinky-irq/src/main.rs similarity index 100% rename from docs/modules/ROOT/examples/layer-by-layer/blinky-irq/src/main.rs rename to docs/examples/layer-by-layer/blinky-irq/src/main.rs diff --git a/docs/modules/ROOT/examples/layer-by-layer/blinky-pac/Cargo.toml b/docs/examples/layer-by-layer/blinky-pac/Cargo.toml similarity index 100% rename from docs/modules/ROOT/examples/layer-by-layer/blinky-pac/Cargo.toml rename to docs/examples/layer-by-layer/blinky-pac/Cargo.toml diff --git a/docs/modules/ROOT/examples/layer-by-layer/blinky-pac/src/main.rs b/docs/examples/layer-by-layer/blinky-pac/src/main.rs similarity index 100% rename from docs/modules/ROOT/examples/layer-by-layer/blinky-pac/src/main.rs rename to docs/examples/layer-by-layer/blinky-pac/src/main.rs diff --git a/docs/modules/ROOT/images/bootloader_flash.png b/docs/images/bootloader_flash.png similarity index 100% rename from docs/modules/ROOT/images/bootloader_flash.png rename to docs/images/bootloader_flash.png diff --git a/docs/modules/ROOT/images/embassy_executor.drawio b/docs/images/embassy_executor.drawio similarity index 100% rename from docs/modules/ROOT/images/embassy_executor.drawio rename to docs/images/embassy_executor.drawio diff --git a/docs/modules/ROOT/images/embassy_executor.png b/docs/images/embassy_executor.png similarity index 100% rename from docs/modules/ROOT/images/embassy_executor.png rename to docs/images/embassy_executor.png diff --git a/docs/modules/ROOT/images/embassy_irq.drawio b/docs/images/embassy_irq.drawio similarity index 100% rename from docs/modules/ROOT/images/embassy_irq.drawio rename to docs/images/embassy_irq.drawio diff --git a/docs/modules/ROOT/images/embassy_irq.png b/docs/images/embassy_irq.png similarity index 100% rename from docs/modules/ROOT/images/embassy_irq.png rename to docs/images/embassy_irq.png diff --git a/docs/index.adoc b/docs/index.adoc new file mode 100644 index 000000000..9c6150196 --- /dev/null +++ b/docs/index.adoc @@ -0,0 +1,16 @@ +:description: Embassy Book +:sectanchors: +:doctype: book +:toc: +:toc-placement: left +:toclevels: 2 +:imagesdir: images + +# Embassy Book + +Welcome to the Embassy Book. The Embassy Book is for everyone who wants to use Embassy and understand how Embassy works. + +include::pages/overview.adoc[leveloffset = 1] +include::pages/beginners.adoc[leveloffset = 1] +include::pages/system.adoc[leveloffset = 1] +include::pages/faq.adoc[leveloffset = 1] diff --git a/docs/modules/ROOT/examples/basic/Cargo.toml b/docs/modules/ROOT/examples/basic/Cargo.toml deleted file mode 100644 index 2c282145d..000000000 --- a/docs/modules/ROOT/examples/basic/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -authors = ["Dario Nieuwenhuis <dirbaio@dirbaio.net>"] -edition = "2018" -name = "embassy-basic-example" -version = "0.1.0" -license = "MIT OR Apache-2.0" - -[dependencies] -embassy-executor = { version = "0.5.0", path = "../../../../../embassy-executor", features = ["defmt", "integrated-timers", "arch-cortex-m", "executor-thread"] } -embassy-time = { version = "0.3.0", path = "../../../../../embassy-time", features = ["defmt"] } -embassy-nrf = { version = "0.1.0", path = "../../../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote"] } - -defmt = "0.3" -defmt-rtt = "0.3" - -cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } -cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } diff --git a/docs/modules/ROOT/examples/examples b/docs/modules/ROOT/examples/examples deleted file mode 120000 index 1929330b0..000000000 --- a/docs/modules/ROOT/examples/examples +++ /dev/null @@ -1 +0,0 @@ -../../../../examples \ No newline at end of file diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc deleted file mode 100644 index 44b0eddb9..000000000 --- a/docs/modules/ROOT/nav.adoc +++ /dev/null @@ -1,19 +0,0 @@ -* xref:getting_started.adoc[Getting started] -** xref:basic_application.adoc[Basic application] -** xref:project_structure.adoc[Project Structure] -** xref:new_project.adoc[Starting a new Embassy project] -** xref:best_practices.adoc[Best Practices] -* xref:runtime.adoc[Executor] -* xref::time_keeping.adoc[Time-keeping] -* xref:sharing_peripherals.adoc[Sharing peripherals] -* xref:hal.adoc[HAL] -** xref:layer_by_layer.adoc[Anatomy of an async HAL] -** xref:nrf.adoc[nRF] -** xref:stm32.adoc[STM32] -* xref:bootloader.adoc[Bootloader] - -* xref:examples.adoc[Examples] -* xref:developer.adoc[Developer Docs] -** xref:developer_stm32.adoc[Developer Docs: STM32] -* xref:embassy_in_the_wild.adoc[Embassy in the wild] -* xref:faq.adoc[Frequently Asked Questions] diff --git a/docs/modules/ROOT/pages/basic_application.adoc b/docs/pages/basic_application.adoc similarity index 85% rename from docs/modules/ROOT/pages/basic_application.adoc rename to docs/pages/basic_application.adoc index d5aad806d..7b4ebda4f 100644 --- a/docs/modules/ROOT/pages/basic_application.adoc +++ b/docs/pages/basic_application.adoc @@ -1,10 +1,10 @@ = A basic Embassy application -So you've got one of the xref:examples.adoc[examples] running, but what now? Let's go through a simple Embassy application for the nRF52 DK to understand it better. +So you've got one of the examples running, but what now? Let's go through a simple Embassy application for the nRF52 DK to understand it better. == Main -The full example can be found link:https://github.com/embassy-rs/embassy/tree/master/docs/modules/ROOT/examples/basic[here]. +The full example can be found link:https://github.com/embassy-rs/embassy/tree/master/docs/examples/basic[here]. NOTE: If you’re using VS Code and rust-analyzer to view and edit the examples, you may need to make some changes to `.vscode/settings.json` to tell it which project we’re working on. Follow the instructions commented in that file to get rust-analyzer working correctly. @@ -14,7 +14,7 @@ The first thing you’ll notice are two attributes at the top of the file. These [source,rust] ---- -include::example$basic/src/main.rs[lines="1..2"] +include::../examples/basic/src/main.rs[lines="1..2"] ---- === Dealing with errors @@ -23,7 +23,7 @@ Then, what follows are some declarations on how to deal with panics and faults. [source,rust] ---- -include::example$basic/src/main.rs[lines="8"] +include::../examples/basic/src/main.rs[lines="8"] ---- === Task declaration @@ -32,7 +32,7 @@ After a bit of import declaration, the tasks run by the application should be de [source,rust] ---- -include::example$basic/src/main.rs[lines="10..18"] +include::../examples/basic/src/main.rs[lines="10..18"] ---- An embassy task must be declared `async`, and may NOT take generic arguments. In this case, we are handed the LED that should be blinked and the interval of the blinking. @@ -47,7 +47,7 @@ We then initialize the HAL with a default config, which gives us a `Peripherals` [source,rust] ---- -include::example$basic/src/main.rs[lines="20..-1"] +include::../examples/basic/src/main.rs[lines="20..-1"] ---- What happens when the `blinker` task has been spawned and main returns? Well, the main entry point is actually just like any other task, except that you can only have one and it takes some specific type arguments. The magic lies within the `#[embassy_executor::main]` macro. The macro does the following: @@ -64,7 +64,7 @@ The project definition needs to contain the embassy dependencies: [source,toml] ---- -include::example$basic/Cargo.toml[lines="9..11"] +include::../examples/basic/Cargo.toml[lines="9..11"] ---- Depending on your microcontroller, you may need to replace `embassy-nrf` with something else (`embassy-stm32` for STM32. Remember to update feature flags as well). diff --git a/docs/pages/beginners.adoc b/docs/pages/beginners.adoc new file mode 100644 index 000000000..48c9f4541 --- /dev/null +++ b/docs/pages/beginners.adoc @@ -0,0 +1,11 @@ += For beginners + +The articles in this section are primarily aimed at users new to Embassy, +showing how to get started, how to structure your project and other best practices. + +include::getting_started.adoc[leveloffset = 2] +include::basic_application.adoc[leveloffset = 2] +include::project_structure.adoc[leveloffset = 2] +include::new_project.adoc[leveloffset = 2] +include::best_practices.adoc[leveloffset = 2] +include::layer_by_layer.adoc[leveloffset = 2] diff --git a/docs/modules/ROOT/pages/best_practices.adoc b/docs/pages/best_practices.adoc similarity index 100% rename from docs/modules/ROOT/pages/best_practices.adoc rename to docs/pages/best_practices.adoc diff --git a/docs/modules/ROOT/pages/bootloader.adoc b/docs/pages/bootloader.adoc similarity index 100% rename from docs/modules/ROOT/pages/bootloader.adoc rename to docs/pages/bootloader.adoc diff --git a/docs/modules/ROOT/pages/developer.adoc b/docs/pages/developer.adoc similarity index 100% rename from docs/modules/ROOT/pages/developer.adoc rename to docs/pages/developer.adoc diff --git a/docs/modules/ROOT/pages/developer_stm32.adoc b/docs/pages/developer_stm32.adoc similarity index 100% rename from docs/modules/ROOT/pages/developer_stm32.adoc rename to docs/pages/developer_stm32.adoc diff --git a/docs/modules/ROOT/pages/embassy_in_the_wild.adoc b/docs/pages/embassy_in_the_wild.adoc similarity index 72% rename from docs/modules/ROOT/pages/embassy_in_the_wild.adoc rename to docs/pages/embassy_in_the_wild.adoc index 4b650449f..76b1169bd 100644 --- a/docs/modules/ROOT/pages/embassy_in_the_wild.adoc +++ b/docs/pages/embassy_in_the_wild.adoc @@ -1,14 +1,17 @@ = Embassy in the wild! -Here are known examples of real-world projects which make use of Embassy. Feel free to link:https://github.com/embassy-rs/embassy/blob/main/docs/modules/ROOT/pages/embassy_in_the_wild.adoc[add more]! +Here are known examples of real-world projects which make use of Embassy. Feel free to link:https://github.com/embassy-rs/embassy/blob/main/docs/pages/embassy_in_the_wild.adoc[add more]! +* link:https://github.com/haobogu/rmk/[RMK: A feature-rich Rust keyboard firmware] +** RMK has built-in layer support, wireless(BLE) support, real-time key editing support using vial, and more! +** Targets STM32, RP2040, nRF52 and ESP32 MCUs * link:https://github.com/cbruiz/printhor/[Printhor: The highly reliable but not necessarily functional 3D printer firmware] ** Targets some STM32 MCUs * link:https://github.com/card-io-ecg/card-io-fw[Card/IO firmware] - firmware for an open source ECG device ** Targets the ESP32-S3 or ESP32-C6 MCU * The link:https://github.com/lora-rs/lora-rs[lora-rs] project includes link:https://github.com/lora-rs/lora-rs/tree/main/examples/stm32l0/src/bin[various standalone examples] for NRF52840, RP2040, STM32L0 and STM32WL -** link:https://github.com/matoushybl/air-force-one[Air force one: A simple air quality monitoring system] -*** Targets nRF52 and uses nrf-softdevice +* link:https://github.com/matoushybl/air-force-one[Air force one: A simple air quality monitoring system] +** Targets nRF52 and uses nrf-softdevice * link:https://github.com/schmettow/ylab-edge-go[YLab Edge Go] and link:https://github.com/schmettow/ylab-edge-pro[YLab Edge Pro] projects develop firmware (RP2040, STM32) for capturing physiological data in behavioural science research. Included so far are: diff --git a/docs/modules/ROOT/pages/examples.adoc b/docs/pages/examples.adoc similarity index 74% rename from docs/modules/ROOT/pages/examples.adoc rename to docs/pages/examples.adoc index c852f5205..82381a2c5 100644 --- a/docs/modules/ROOT/pages/examples.adoc +++ b/docs/pages/examples.adoc @@ -7,5 +7,5 @@ Main loop example [source,rust] ---- -include::example$examples/std/src/bin/tick.rs[] +include::../examples/examples/std/src/bin/tick.rs[] ---- diff --git a/docs/modules/ROOT/pages/faq.adoc b/docs/pages/faq.adoc similarity index 50% rename from docs/modules/ROOT/pages/faq.adoc rename to docs/pages/faq.adoc index c6b893de5..bb088dfb6 100644 --- a/docs/modules/ROOT/pages/faq.adoc +++ b/docs/pages/faq.adoc @@ -2,7 +2,7 @@ These are a list of unsorted, commonly asked questions and answers. -Please feel free to add items to link:https://github.com/embassy-rs/embassy/edit/main/docs/modules/ROOT/pages/faq.adoc[this page], especially if someone in the chat answered a question for you! +Please feel free to add items to link:https://github.com/embassy-rs/embassy/edit/main/docs/pages/faq.adoc[this page], especially if someone in the chat answered a question for you! == How to deploy to RP2040 without a debugging probe. @@ -231,3 +231,129 @@ Please refer to the STM32 documentation for the specific values suitable for you Look for the `MEMORY` section and try to determine the FLASH and RAM sizes and section start. If you find a case where the memory.x is wrong, please report it on [this Github issue](https://github.com/embassy-rs/stm32-data/issues/301) so other users are not caught by surprise. + +== The USB examples are not working on my board, is there anything else I need to configure? + +If you are trying out the USB examples and your device doesn not connect, the most common issues are listed below. + +=== Incorrect RCC config + +Check your board and crystal/oscillator, in particular make sure that `HSE` is set to the correct value, e.g. `8_000_000` Hertz if your board does indeed run on a 8 MHz oscillator. + +=== VBUS detection on STM32 platform + +The USB specification requires that all USB devices monitor the bus for detection of plugging/unplugging actions. The devices must pull-up the D+ or D- lane as soon as the host supplies VBUS. + +See the docs, for example at link:https://docs.embassy.dev/embassy-stm32/git/stm32f401vc/usb/struct.Config.html[`usb/struct.Config.html`] for information on how to enable/disable `vbus_detection`. + +When the device is powered only from the USB bus that simultaneously serves as the data connection, this is optional. (If there's no power in VBUS the device would be off anyway, so it's safe to always assume there's power in VBUS, i.e. the USB cable is always plugged in). If your device doesn't have the required connections in place to allow VBUS sensing (see below), then this option needs to be set to `false` to work. + +When the device is powered from another power source and therefore can stay powered through USB cable plug/unplug events, then this must be implemented and `vbus_detection` MUST be set to `true`. + +If your board is powered from the USB and you are unsure whether it supports `vbus_detection`, consult the schematics of your board to see if VBUS is connected to PA9 for USB Full Speed or PB13 for USB High Speed, vice versa, possibly with a voltage divider. When designing your own hardware, see ST application note AN4879 (in particular section 2.6) and the reference manual of your specific chip for more details. + +== Known issues (details and/or mitigations) + +These are issues that are commonly reported. Help wanted fixing them, or improving the UX when possible! + +=== STM32H5 and STM32H7 power issues + +STM32 chips with built-in power management (SMPS and LDO) settings often cause user problems when the configuration does not match how the board was designed. + +Settings from the examples, or even from other working boards, may not work on YOUR board, because they are wired differently. + +Additionally, some PWR settings require a full device reboot (and enough time to discharge any power capacitors!), making this hard to troubleshoot. Also, some +"wrong" power settings will ALMOST work, meaning it will sometimes work on some boots, or for a while, but crash unexpectedly. + +There is not a fix for this yet, as it is board/hardware dependant. See link:https://github.com/embassy-rs/embassy/issues/2806[this tracking issue] for more details + +=== STM32 BDMA only working out of some RAM regions + +The STM32 BDMA controller included in some STM32H7 chips has to be configured to use only certain regions of RAM, +otherwise the transfer will fail. + +If you see errors that look like this: + +[source,plain] +---- +DMA: error on BDMA@1234ABCD channel 4 +---- + +You need to set up your linker script to define a special region for this area and copy data to that region before using with BDMA. + +General steps: + +1. Find out which memory region BDMA has access to. You can get this information from the bus matrix and the memory mapping table in the STM32 datasheet. +2. Add the memory region to `memory.x`, you can modify the generated one from https://github.com/embassy-rs/stm32-data-generated/tree/main/data/chips. +3. You might need to modify `build.rs` to make cargo pick up the modified `memory.x`. +4. In your code, access the defined memory region using `#[link_section = ".xxx"]` +5. Copy data to that region before using BDMA. + +See link:https://github.com/embassy-rs/embassy/blob/main/examples/stm32h7/src/bin/spi_bdma.rs[SMT32H7 SPI BDMA example] for more details. + +== How do I switch to the `main` branch? + +Sometimes to test new changes or fixes, you'll want to switch your project to using a version from GitHub. + +You can add a section to your `Cargo.toml` file like this, you'll need to patch ALL embassy crates to the same revision: + +Using `patch` will replace all direct AND indirect dependencies. + +See the link:https://embassy.dev/book/dev/new_project.html#_cargo_toml[new project docs] for more details on this approach. + +[source,toml] +---- +[patch.crates-io] +# make sure to get the latest git rev from github, you can see the latest one here: +# https://github.com/embassy-rs/embassy/commits/main/ +embassy-embedded-hal = { git = "https://github.com/embassy-rs/embassy", rev = "4cade64ebd34bf93458f17cfe85c5f710d0ff13c" } +embassy-executor = { git = "https://github.com/embassy-rs/embassy", rev = "4cade64ebd34bf93458f17cfe85c5f710d0ff13c" } +embassy-rp = { git = "https://github.com/embassy-rs/embassy", rev = "4cade64ebd34bf93458f17cfe85c5f710d0ff13c" } +embassy-sync = { git = "https://github.com/embassy-rs/embassy", rev = "4cade64ebd34bf93458f17cfe85c5f710d0ff13c" } +embassy-time = { git = "https://github.com/embassy-rs/embassy", rev = "4cade64ebd34bf93458f17cfe85c5f710d0ff13c" } +embassy-usb = { git = "https://github.com/embassy-rs/embassy", rev = "4cade64ebd34bf93458f17cfe85c5f710d0ff13c" } +embassy-usb-driver = { git = "https://github.com/embassy-rs/embassy", rev = "4cade64ebd34bf93458f17cfe85c5f710d0ff13c" } +---- + +== How do I add support for a new microcontroller to embassy? + +This is particularly for cortex-m, and potentially risc-v, where there is already support for basics like interrupt handling, or even already embassy-executor support for your architecture. + +This is a *much harder path* than just using Embassy on an already supported chip. If you are a beginner, consider using embassy on an existing, well supported chip for a while, before you decide to write drivers from scratch. It's also worth reading the existing source of supported Embassy HALs, to get a feel for how drivers are implemented for various chips. You should already be comfortable reading and writing unsafe code, and understanding the responsibilities of writing safe abstractions for users of your HAL. + +This is not the only possible approach, but if you are looking for where to start, this is a reasonable way to tackle the task: + +1. First, drop by the Matrix room or search around to see if someone has already started writing drivers, either in Embassy or otherwise in Rust. You might not have to start from scratch! +2. Make sure the target is supported in probe-rs, it likely is, and if not, there is likely a cmsis-pack you can use to add support so that flashing and debugging is possible. You will definitely appreciate being able to debug with SWD or JTAG when writing drivers! +3. See if there is an SVD (or SVDs, if it's a family) available, if it is, run it through chiptool to create a PAC for low level register access. If not, there are other ways (like scraping the PDF datasheets or existing C header files), but these are more work than starting from the SVD file to define peripheral memory locations necessary for writing drivers. +4. Either make a fork of embassy repo, and add your target there, or make a repo that just contains the PAC and an empty HAL. It doesn't necessarily have to live in the embassy repo at first. +5. Get a hello world binary working on your chip, either with minimal HAL or just PAC access, use delays and blink a light or send some raw data on some interface, make sure it works and you can flash, debug with defmt + RTT, write a proper linker script, etc. +6. Get basic timer operations and timer interrupts working, upgrade your blinking application to use hardware timers and interrupts, and ensure they are accurate (with a logic analyzer or oscilloscope, if possible). +7. Implement the embassy-time driver API with your timer and timer interrupt code, so that you can use embassy-time operations in your drivers and applications. +8. Then start implementing whatever peripherals you need, like GPIOs, UART, SPI, I2C, etc. This is the largest part of the work, and will likely continue for a while! Don't feel like you need 100% coverage of all peripherals at first, this is likely to be an ongoing process over time. +9. Start implementing the embedded-hal, embedded-io, and embedded-hal-async traits on top of your HAL drivers, once you start having more features completed. This will allow users to use standard external device drivers (e.g. sensors, actuators, displays, etc.) with your HAL. +10. Discuss upstreaming the PAC/HAL for embassy support, or make sure your drivers are added to the awesome-embedded-rust list so that people can find it. + +== Multiple Tasks, or one task with multiple futures? + +Some examples end like this in main: + +[source,rust] +---- +// Run everything concurrently. +// If we had made everything `'static` above instead, we could do this using separate tasks instead. +join(usb_fut, join(echo_fut, log_fut)).await; +---- + +There are two main ways to handle concurrency in Embassy: + +1. Spawn multiple tasks, e.g. with `#[embassy_executor::task]` +2. Manage multiple futures inside ONE task using `join()` or `select()` (as shown above) + +In general, either of these approaches will work. The main differences of these approaches are: + +When using **separate tasks**, each task needs its own RAM allocation, so there's a little overhead for each task, so one task that does three things will likely be a little bit smaller than three tasks that do one thing (not a lot, probably a couple dozen bytes). In contrast, with **multiple futures in one task**, you don't need multiple task allocations, and it will generally be easier to share data, or use borrowed resources, inside of a single task. + +But when it comes to "waking" tasks, for example when a data transfer is complete or a button is pressed, it's faster to wake a dedicated task, because that task does not need to check which future is actually ready. `join` and `select` must check ALL of the futures they are managing to see which one (or which ones) are ready to do more work. This is because all Rust executors (like Embassy or Tokio) only have the ability to wake tasks, not specific futures. This means you will use slightly less CPU time juggling futures when using dedicated tasks. + +Practically, there's not a LOT of difference either way - so go with what makes it easier for you and your code first, but there will be some details that are slightly different in each case. diff --git a/docs/modules/ROOT/pages/getting_started.adoc b/docs/pages/getting_started.adoc similarity index 96% rename from docs/modules/ROOT/pages/getting_started.adoc rename to docs/pages/getting_started.adoc index 73cb5530d..465059922 100644 --- a/docs/modules/ROOT/pages/getting_started.adoc +++ b/docs/pages/getting_started.adoc @@ -137,7 +137,7 @@ If you’re still having problems, check the link:https://embassy.dev/book/dev/f Congratulations, you have your first Embassy application running! Here are some suggestions for where to go from here: -* Read more about the xref:runtime.adoc[executor]. -* Read more about the xref:hal.adoc[HAL]. -* Start xref:basic_application.adoc[writing your application]. -* Learn how to xref:new_project.adoc[start a new embassy project by adapting an example]. +* Read more about the xref:_embassy_executor[executor]. +* Read more about the xref:_hardware_abstraction_layer_hal[HAL]. +* Start xref:_a_basic_embassy_application[writing your application]. +* Learn how to xref:_starting_a_new_project[start a new embassy project by adapting an example]. diff --git a/docs/modules/ROOT/pages/hal.adoc b/docs/pages/hal.adoc similarity index 83% rename from docs/modules/ROOT/pages/hal.adoc rename to docs/pages/hal.adoc index b1382e8e5..14b85e1f1 100644 --- a/docs/modules/ROOT/pages/hal.adoc +++ b/docs/pages/hal.adoc @@ -10,3 +10,5 @@ These HALs implement async/await functionality for most peripherals while also i async traits in `embedded-hal` and `embedded-hal-async`. You can also use these HALs with another executor. For the ESP32 series, there is an link:https://github.com/esp-rs/esp-hal[esp-hal] which you can use. + +For the WCH 32-bit RISC-V series, there is an link:https://github.com/ch32-rs/ch32-hal[ch32-hal], which you can use. diff --git a/docs/modules/ROOT/pages/layer_by_layer.adoc b/docs/pages/layer_by_layer.adoc similarity index 90% rename from docs/modules/ROOT/pages/layer_by_layer.adoc rename to docs/pages/layer_by_layer.adoc index 1d7bdc89b..f87291c20 100644 --- a/docs/modules/ROOT/pages/layer_by_layer.adoc +++ b/docs/pages/layer_by_layer.adoc @@ -16,7 +16,7 @@ The blinky app using PAC is shown below: [source,rust] ---- -include::example$layer-by-layer/blinky-pac/src/main.rs[] +include::../examples/layer-by-layer/blinky-pac/src/main.rs[] ---- As you can see, a lot of code is needed to enable the peripheral clocks and to configure the input pins and the output pins of the application. @@ -35,7 +35,7 @@ The HAL example is shown below: [source,rust] ---- -include::example$layer-by-layer/blinky-hal/src/main.rs[] +include::../examples/layer-by-layer/blinky-hal/src/main.rs[] ---- As you can see, the application becomes a lot simpler, even without using any async code. The `Input` and `Output` types hide all the details of accessing the GPIO registers and allow you to use a much simpler API for querying the state of the button and toggling the LED output. @@ -52,7 +52,7 @@ Given Embassy focus on async Rust (which we'll come back to after this example), [source,rust] ---- -include::example$layer-by-layer/blinky-irq/src/main.rs[lines="1..57"] +include::../examples/layer-by-layer/blinky-irq/src/main.rs[lines="1..57"] ---- The simple application is now more complex again, primarily because of the need to keep the button and LED states in the global scope where it is accessible by the main application loop, as well as the interrupt handler. @@ -63,11 +63,11 @@ Luckily, there is an elegant solution to this problem when using Embassy. == Async version -It's time to use the Embassy capabilities to its fullest. At the core, Embassy has an async excecutor, or a runtime for async tasks if you will. The executor polls a set of tasks (defined at compile time), and whenever a task `blocks`, the executor will run another task, or put the microcontroller to sleep. +It's time to use the Embassy capabilities to its fullest. At the core, Embassy has an async executor, or a runtime for async tasks if you will. The executor polls a set of tasks (defined at compile time), and whenever a task `blocks`, the executor will run another task, or put the microcontroller to sleep. [source,rust] ---- -include::example$layer-by-layer/blinky-async/src/main.rs[] +include::../examples/layer-by-layer/blinky-async/src/main.rs[] ---- The async version looks very similar to the HAL version, apart from a few minor details: diff --git a/docs/modules/ROOT/pages/new_project.adoc b/docs/pages/new_project.adoc similarity index 96% rename from docs/modules/ROOT/pages/new_project.adoc rename to docs/pages/new_project.adoc index 320966bb6..346d9f0f8 100644 --- a/docs/modules/ROOT/pages/new_project.adoc +++ b/docs/pages/new_project.adoc @@ -1,17 +1,18 @@ -= Starting a new Embassy project += Starting a new project Once you’ve successfully xref:getting_started.adoc[run some example projects], the next step is to make a standalone Embassy project. -There are some tools for generating Embassy projects: (WIP) +== Tools for generating Embassy projects -==== CLI +=== CLI - link:https://github.com/adinack/cargo-embassy[cargo-embassy] (STM32 and NRF) -==== cargo-generate +=== cargo-generate - link:https://github.com/lulf/embassy-template[embassy-template] (STM32, NRF, and RP) - link:https://github.com/bentwire/embassy-rp2040-template[embassy-rp2040-template] (RP) -But if you want to start from scratch: + +== Starting a project from scratch As an example, let’s create a new embassy project from scratch for a STM32G474. The same instructions are applicable for any supported chip with some minor changes. @@ -35,7 +36,7 @@ stm32g474-example Looking in link:https://github.com/embassy-rs/embassy/tree/main/examples[the Embassy examples], we can see there’s a `stm32g4` folder. Find `src/blinky.rs` and copy its contents into our `src/main.rs`. -== .cargo/config.toml +=== The .cargo/config.toml Currently, we’d need to provide cargo with a target triple every time we run `cargo build` or `cargo run`. Let’s spare ourselves that work by copying `.cargo/config.toml` from `examples/stm32g4` into our project. @@ -66,7 +67,7 @@ and copying `STM32G474RETx` into `.cargo/config.toml` as so: runner = "probe-rs run --chip STM32G474RETx" ---- -== Cargo.toml +=== Cargo.toml Now that cargo knows what target to compile for (and probe-rs knows what chip to run it on), we’re ready to add some dependencies. @@ -117,7 +118,7 @@ Finally, copy the `[profile.release]` section from the example `Cargo.toml` into debug = 2 ---- -== rust-toolchain.toml +=== rust-toolchain.toml Before we can build our project, we need to add an additional file to tell cargo to use the nightly toolchain. Copy the `rust-toolchain.toml` from the embassy repo to ours, and trim the list of targets down to only the target triple relevent for our project — in this case, `thumbv7em-none-eabi`: @@ -142,7 +143,7 @@ components = [ "rust-src", "rustfmt", "llvm-tools", "miri" ] targets = ["thumbv7em-none-eabi"] ---- -== build.rs +=== build.rs In order to produce a working binary for our target, cargo requires a custom build script. Copy `build.rs` from the example to our project: @@ -158,7 +159,7 @@ stm32g474-example └── main.rs ---- -== Building and running +=== Building and running At this point, we‘re finally ready to build and run our project! Connect your board via a debug probe and run: diff --git a/docs/modules/ROOT/pages/nrf.adoc b/docs/pages/nrf.adoc similarity index 100% rename from docs/modules/ROOT/pages/nrf.adoc rename to docs/pages/nrf.adoc diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/pages/overview.adoc similarity index 94% rename from docs/modules/ROOT/pages/index.adoc rename to docs/pages/overview.adoc index e17adbbd7..1b9381bfe 100644 --- a/docs/modules/ROOT/pages/index.adoc +++ b/docs/pages/overview.adoc @@ -1,4 +1,4 @@ -= Embassy += Introduction Embassy is a project to make async/await a first-class option for embedded development. @@ -30,6 +30,7 @@ The Embassy project maintains HALs for select hardware, but you can still use HA * link:https://docs.embassy.dev/embassy-nrf/[embassy-nrf], for the Nordic Semiconductor nRF52, nRF53, nRF91 series. * link:https://docs.embassy.dev/embassy-rp/[embassy-rp], for the Raspberry Pi RP2040 microcontroller. * link:https://github.com/esp-rs[esp-rs], for the Espressif Systems ESP32 series of chips. +* link:https://github.com/ch32-rs/ch32-hal[ch32-hal], for the WCH 32-bit RISC-V(CH32V) series of chips. NOTE: A common question is if one can use the Embassy HALs standalone. Yes, it is possible! There are no dependency on the executor within the HALs. You can even use them without async, as they implement both the link:https://github.com/rust-embedded/embedded-hal[Embedded HAL] blocking and async traits. @@ -55,6 +56,20 @@ For most I/O in embedded devices, the peripheral doesn't directly support the tr The Direct Memory Access controller (DMA) is a controller that is present in MCUs that Embassy supports, including stm32 and nrf. The DMA allows the MCU to set up a transfer, either send or receive, and then wait for the transfer to complete. With DMA, once started, no MCU intervention is required until the transfer is complete, meaning that the MCU can perform other computation, or set up other I/O while the transfer is in progress. For high I/O rates, DMA can cut the time that the MCU spends handling I/O by over half. However, because DMA is more complex to set-up, it is less widely used in the embedded community. Embassy aims to change that by making DMA the first choice rather than the last. Using Embassy, there's no additional tuning required once I/O rates increase because your application is already set-up to handle them. +== Examples + +Embassy provides examples for all HALs supported. You can find them in the `examples/` folder. + + +Main loop example + +[source,rust] +---- +include::../examples/examples/std/src/bin/tick.rs[] +---- + +include::embassy_in_the_wild.adoc[leveloffset = 2] + == Resources For more reading material on async Rust and Embassy: diff --git a/docs/modules/ROOT/pages/project_structure.adoc b/docs/pages/project_structure.adoc similarity index 96% rename from docs/modules/ROOT/pages/project_structure.adoc rename to docs/pages/project_structure.adoc index 2adfcc1df..722ec8d9d 100644 --- a/docs/modules/ROOT/pages/project_structure.adoc +++ b/docs/pages/project_structure.adoc @@ -18,6 +18,7 @@ my-project |- rust-toolchain.toml ---- +[discrete] == .cargo/config.toml This directory/file describes what platform you're on, and configures link:https://github.com/probe-rs/probe-rs[probe-rs] to deploy to your device. @@ -36,21 +37,27 @@ target = "thumbv6m-none-eabi" # <-change for your platform DEFMT_LOG = "trace" # <- can change to info, warn, or error ---- +[discrete] == build.rs This is the build script for your project. It links defmt (what is link:https://defmt.ferrous-systems.com[defmt]?) and the `memory.x` file if needed. This file is pretty specific for each chipset, just copy and paste from the corresponding link:https://github.com/embassy-rs/embassy/tree/main/examples[example]. +[discrete] == Cargo.toml This is your manifest file, where you can configure all of the embassy components to use the features you need. -==== Features -===== Time +[discrete] +=== Features + +[discrete] +==== Time - tick-hz-x: Configures the tick rate of `embassy-time`. Higher tick rate means higher precision, and higher CPU wakes. - defmt-timestamp-uptime: defmt log entries will display the uptime in seconds. ...more to come +[discrete] == memory.x This file outlines the flash/ram usage of your program. It is especially useful when using link:https://github.com/embassy-rs/nrf-softdevice[nrf-softdevice] on an nRF5x. @@ -68,6 +75,7 @@ MEMORY } ---- +[discrete] == rust-toolchain.toml This file configures the rust version and configuration to use. diff --git a/docs/modules/ROOT/pages/runtime.adoc b/docs/pages/runtime.adoc similarity index 100% rename from docs/modules/ROOT/pages/runtime.adoc rename to docs/pages/runtime.adoc diff --git a/docs/modules/ROOT/pages/sharing_peripherals.adoc b/docs/pages/sharing_peripherals.adoc similarity index 93% rename from docs/modules/ROOT/pages/sharing_peripherals.adoc rename to docs/pages/sharing_peripherals.adoc index fcba0e27b..6bcd56b01 100644 --- a/docs/modules/ROOT/pages/sharing_peripherals.adoc +++ b/docs/pages/sharing_peripherals.adoc @@ -8,6 +8,7 @@ The following examples shows different ways to use the on-board LED on a Raspber Using mutual exclusion is the simplest way to share a peripheral. +TIP: Dependencies needed to run this example link:/book/dev/basic_application.html#_the_cargo_toml[can be found here]. [,rust] ---- use defmt::*; @@ -77,6 +78,7 @@ To indicate that the pin will be set to an Output. The `AnyPin` could have been A channel is another way to ensure exclusive access to a resource. Using a channel is great in the cases where the access can happen at a later point in time, allowing you to enqueue operations and do other things. +TIP: Dependencies needed to run this example link:/book/dev/basic_application.html#_the_cargo_toml[can be found here]. [,rust] ---- use defmt::*; @@ -123,4 +125,4 @@ async fn toggle_led(control: Sender<'static, ThreadModeRawMutex, LedState, 64>, ---- This example replaces the Mutex with a Channel, and uses another task (the main loop) to drive the LED. The advantage of this approach is that only a single task references the peripheral, separating concerns. However, using a Mutex has a lower overhead and might be necessary if you need to ensure -that the operation is ecompleted before continuing to do other work in your task. +that the operation is completed before continuing to do other work in your task. diff --git a/docs/modules/ROOT/pages/stm32.adoc b/docs/pages/stm32.adoc similarity index 100% rename from docs/modules/ROOT/pages/stm32.adoc rename to docs/pages/stm32.adoc diff --git a/docs/pages/system.adoc b/docs/pages/system.adoc new file mode 100644 index 000000000..985f92b18 --- /dev/null +++ b/docs/pages/system.adoc @@ -0,0 +1,13 @@ += System description + +This section describes different parts of Embassy in more detail. + +include::runtime.adoc[leveloffset = 2] +include::bootloader.adoc[leveloffset = 2] +include::time_keeping.adoc[leveloffset = 2] +include::hal.adoc[leveloffset = 2] +include::nrf.adoc[leveloffset = 2] +include::stm32.adoc[leveloffset = 2] +include::sharing_peripherals.adoc[leveloffset = 2] +include::developer.adoc[leveloffset = 2] +include::developer_stm32.adoc[leveloffset = 2] diff --git a/docs/modules/ROOT/pages/time_keeping.adoc b/docs/pages/time_keeping.adoc similarity index 89% rename from docs/modules/ROOT/pages/time_keeping.adoc rename to docs/pages/time_keeping.adoc index 5068216ed..17492a884 100644 --- a/docs/modules/ROOT/pages/time_keeping.adoc +++ b/docs/pages/time_keeping.adoc @@ -16,6 +16,7 @@ The `embassy::time::Timer` type provides two timing methods. An example of a delay is provided as follows: +TIP: Dependencies needed to run this example link:/book/dev/basic_application.html#_the_cargo_toml[can be found here]. [,rust] ---- use embassy::executor::{task, Executor}; @@ -40,6 +41,7 @@ that expect a generic delay implementation to be provided. An example of how this can be used: +TIP: Dependencies needed to run this example link:/book/dev/basic_application.html#_the_cargo_toml[can be found here]. [,rust] ---- use embassy::executor::{task, Executor}; diff --git a/embassy-boot-nrf/Cargo.toml b/embassy-boot-nrf/Cargo.toml index c056dc66a..e6bb27043 100644 --- a/embassy-boot-nrf/Cargo.toml +++ b/embassy-boot-nrf/Cargo.toml @@ -23,7 +23,7 @@ target = "thumbv7em-none-eabi" [dependencies] defmt = { version = "0.3", optional = true } -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embassy-nrf = { version = "0.1.0", path = "../embassy-nrf", default-features = false } embassy-boot = { version = "0.2.0", path = "../embassy-boot" } cortex-m = { version = "0.7.6" } diff --git a/embassy-boot-nrf/README.md b/embassy-boot-nrf/README.md index 9dc5b0eb9..f0d87e18c 100644 --- a/embassy-boot-nrf/README.md +++ b/embassy-boot-nrf/README.md @@ -2,7 +2,7 @@ An [Embassy](https://embassy.dev) project. -An adaptation of `embassy-boot` for nRF. +An adaptation of `embassy-boot` for nRF. ## Features diff --git a/embassy-boot-rp/Cargo.toml b/embassy-boot-rp/Cargo.toml index 305bc5995..0bd8abf4c 100644 --- a/embassy-boot-rp/Cargo.toml +++ b/embassy-boot-rp/Cargo.toml @@ -24,7 +24,7 @@ defmt = { version = "0.3", optional = true } defmt-rtt = { version = "0.4", optional = true } log = { version = "0.4", optional = true } -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embassy-rp = { version = "0.1.0", path = "../embassy-rp", default-features = false } embassy-boot = { version = "0.2.0", path = "../embassy-boot" } embassy-time = { version = "0.3.0", path = "../embassy-time" } diff --git a/embassy-boot-stm32/Cargo.toml b/embassy-boot-stm32/Cargo.toml index 6f8fbe355..a3661f6cb 100644 --- a/embassy-boot-stm32/Cargo.toml +++ b/embassy-boot-stm32/Cargo.toml @@ -25,7 +25,7 @@ defmt = { version = "0.3", optional = true } defmt-rtt = { version = "0.4", optional = true } log = { version = "0.4", optional = true } -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false } embassy-boot = { version = "0.2.0", path = "../embassy-boot" } cortex-m = { version = "0.7.6" } diff --git a/embassy-boot/Cargo.toml b/embassy-boot/Cargo.toml index 242caa229..16dc52bcc 100644 --- a/embassy-boot/Cargo.toml +++ b/embassy-boot/Cargo.toml @@ -29,7 +29,7 @@ digest = "0.10" log = { version = "0.4", optional = true } ed25519-dalek = { version = "2", default_features = false, features = ["digest"], optional = true } embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" } -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embedded-storage = "0.3.1" embedded-storage-async = { version = "0.4.1" } salty = { version = "0.3", optional = true } diff --git a/embassy-boot/README.md b/embassy-boot/README.md index 3c2d45e96..812c43524 100644 --- a/embassy-boot/README.md +++ b/embassy-boot/README.md @@ -15,7 +15,7 @@ The bootloader divides the storage into 4 main partitions, configurable when cre * BOOTLOADER - Where the bootloader is placed. The bootloader itself consumes about 8kB of flash, but if you need to debug it and have space available, increasing this to 24kB will allow you to run the bootloader with probe-rs. * ACTIVE - Where the main application is placed. The bootloader will attempt to load the application at the start of this partition. The minimum size required for this partition is the size of your application. * DFU - Where the application-to-be-swapped is placed. This partition is written to by the application. This partition must be at least 1 page bigger than the ACTIVE partition. -* BOOTLOADER STATE - Where the bootloader stores the current state describing if the active and dfu partitions need to be swapped. +* BOOTLOADER STATE - Where the bootloader stores the current state describing if the active and dfu partitions need to be swapped. For any partition, the following preconditions are required: diff --git a/embassy-embedded-hal/Cargo.toml b/embassy-embedded-hal/Cargo.toml index e89179740..1602e802c 100644 --- a/embassy-embedded-hal/Cargo.toml +++ b/embassy-embedded-hal/Cargo.toml @@ -28,7 +28,7 @@ default = ["time"] [dependencies] embassy-futures = { version = "0.1.0", path = "../embassy-futures" } -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embassy-time = { version = "0.3.0", path = "../embassy-time", optional = true } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [ "unproven", diff --git a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs index 9890f218d..30d4ecc36 100644 --- a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs @@ -55,13 +55,14 @@ where type Error = SpiDeviceError<BUS::Error, CS::Error>; } -impl<M, BUS, CS> spi::SpiDevice for SpiDevice<'_, M, BUS, CS> +impl<M, BUS, CS, Word> spi::SpiDevice<Word> for SpiDevice<'_, M, BUS, CS> where M: RawMutex, - BUS: spi::SpiBus, + BUS: spi::SpiBus<Word>, CS: OutputPin, + Word: Copy + 'static, { - async fn transaction(&mut self, operations: &mut [spi::Operation<'_, u8>]) -> Result<(), Self::Error> { + async fn transaction(&mut self, operations: &mut [spi::Operation<'_, Word>]) -> Result<(), Self::Error> { if cfg!(not(feature = "time")) && operations.iter().any(|op| matches!(op, Operation::DelayNs(_))) { return Err(SpiDeviceError::DelayNotSupported); } @@ -138,13 +139,14 @@ where type Error = SpiDeviceError<BUS::Error, CS::Error>; } -impl<M, BUS, CS> spi::SpiDevice for SpiDeviceWithConfig<'_, M, BUS, CS> +impl<M, BUS, CS, Word> spi::SpiDevice<Word> for SpiDeviceWithConfig<'_, M, BUS, CS> where M: RawMutex, - BUS: spi::SpiBus + SetConfig, + BUS: spi::SpiBus<Word> + SetConfig, CS: OutputPin, + Word: Copy + 'static, { - async fn transaction(&mut self, operations: &mut [spi::Operation<'_, u8>]) -> Result<(), Self::Error> { + async fn transaction(&mut self, operations: &mut [spi::Operation<'_, Word>]) -> Result<(), Self::Error> { if cfg!(not(feature = "time")) && operations.iter().any(|op| matches!(op, Operation::DelayNs(_))) { return Err(SpiDeviceError::DelayNotSupported); } diff --git a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs index 801899f9f..eb9c0c4f4 100644 --- a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs @@ -48,13 +48,14 @@ where type Error = SpiDeviceError<BUS::Error, CS::Error>; } -impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDevice<'_, M, BUS, CS> +impl<BUS, M, CS, Word> embedded_hal_1::spi::SpiDevice<Word> for SpiDevice<'_, M, BUS, CS> where M: RawMutex, - BUS: SpiBus, + BUS: SpiBus<Word>, CS: OutputPin, + Word: Copy + 'static, { - fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> { + fn transaction(&mut self, operations: &mut [embedded_hal_1::spi::Operation<'_, Word>]) -> Result<(), Self::Error> { if cfg!(not(feature = "time")) && operations.iter().any(|op| matches!(op, Operation::DelayNs(_))) { return Err(SpiDeviceError::DelayNotSupported); } @@ -90,47 +91,6 @@ where } } -impl<'d, M, BUS, CS, BusErr, CsErr> embedded_hal_02::blocking::spi::Transfer<u8> for SpiDevice<'_, M, BUS, CS> -where - M: RawMutex, - BUS: embedded_hal_02::blocking::spi::Transfer<u8, Error = BusErr>, - CS: OutputPin<Error = CsErr>, -{ - type Error = SpiDeviceError<BusErr, CsErr>; - fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { - self.bus.lock(|bus| { - let mut bus = bus.borrow_mut(); - self.cs.set_low().map_err(SpiDeviceError::Cs)?; - let op_res = bus.transfer(words); - let cs_res = self.cs.set_high(); - let op_res = op_res.map_err(SpiDeviceError::Spi)?; - cs_res.map_err(SpiDeviceError::Cs)?; - Ok(op_res) - }) - } -} - -impl<'d, M, BUS, CS, BusErr, CsErr> embedded_hal_02::blocking::spi::Write<u8> for SpiDevice<'_, M, BUS, CS> -where - M: RawMutex, - BUS: embedded_hal_02::blocking::spi::Write<u8, Error = BusErr>, - CS: OutputPin<Error = CsErr>, -{ - type Error = SpiDeviceError<BusErr, CsErr>; - - fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { - self.bus.lock(|bus| { - let mut bus = bus.borrow_mut(); - self.cs.set_low().map_err(SpiDeviceError::Cs)?; - let op_res = bus.write(words); - let cs_res = self.cs.set_high(); - let op_res = op_res.map_err(SpiDeviceError::Spi)?; - cs_res.map_err(SpiDeviceError::Cs)?; - Ok(op_res) - }) - } -} - /// SPI device on a shared bus, with its own configuration. /// /// This is like [`SpiDevice`], with an additional bus configuration that's applied @@ -163,13 +123,14 @@ where type Error = SpiDeviceError<BUS::Error, CS::Error>; } -impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDeviceWithConfig<'_, M, BUS, CS> +impl<BUS, M, CS, Word> embedded_hal_1::spi::SpiDevice<Word> for SpiDeviceWithConfig<'_, M, BUS, CS> where M: RawMutex, - BUS: SpiBus + SetConfig, + BUS: SpiBus<Word> + SetConfig, CS: OutputPin, + Word: Copy + 'static, { - fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> { + fn transaction(&mut self, operations: &mut [embedded_hal_1::spi::Operation<'_, Word>]) -> Result<(), Self::Error> { if cfg!(not(feature = "time")) && operations.iter().any(|op| matches!(op, Operation::DelayNs(_))) { return Err(SpiDeviceError::DelayNotSupported); } diff --git a/embassy-futures/src/yield_now.rs b/embassy-futures/src/yield_now.rs index bb3c67d17..4d4e535f2 100644 --- a/embassy-futures/src/yield_now.rs +++ b/embassy-futures/src/yield_now.rs @@ -9,10 +9,16 @@ use core::task::{Context, Poll}; /// hold, while still allowing other tasks to run concurrently (not monopolizing /// the executor thread). /// -/// ```rust,no_run +/// ```rust +/// # use embassy_futures::{block_on, yield_now}; +/// # async fn test_fn() { +/// # let mut iter_count: u32 = 0; +/// # let mut some_condition = || { iter_count += 1; iter_count > 10 }; /// while !some_condition() { /// yield_now().await; /// } +/// # } +/// # block_on(test_fn()); /// ``` /// /// The downside is this will spin in a busy loop, using 100% of the CPU, while diff --git a/embassy-hal-internal/src/atomic_ring_buffer.rs b/embassy-hal-internal/src/atomic_ring_buffer.rs index 34ceac852..00b7a1249 100644 --- a/embassy-hal-internal/src/atomic_ring_buffer.rs +++ b/embassy-hal-internal/src/atomic_ring_buffer.rs @@ -123,6 +123,11 @@ impl RingBuffer { Some(Writer(self)) } + /// Return if buffer is available. + pub fn is_available(&self) -> bool { + !self.buf.load(Ordering::Relaxed).is_null() && self.len.load(Ordering::Relaxed) != 0 + } + /// Return length of buffer. pub fn len(&self) -> usize { self.len.load(Ordering::Relaxed) @@ -478,8 +483,12 @@ mod tests { #[test] fn zero_len() { + let mut b = [0; 0]; + let rb = RingBuffer::new(); unsafe { + rb.init(b.as_mut_ptr(), b.len()); + assert_eq!(rb.is_empty(), true); assert_eq!(rb.is_full(), true); diff --git a/embassy-hal-internal/src/peripheral.rs b/embassy-hal-internal/src/peripheral.rs index f03f41507..0b0f13338 100644 --- a/embassy-hal-internal/src/peripheral.rs +++ b/embassy-hal-internal/src/peripheral.rs @@ -1,5 +1,5 @@ use core::marker::PhantomData; -use core::ops::Deref; +use core::ops::{Deref, DerefMut}; /// An exclusive reference to a peripheral. /// @@ -155,7 +155,7 @@ pub trait Peripheral: Sized { } } -impl<'b, T: Deref> Peripheral for T +impl<'b, T: DerefMut> Peripheral for T where T::Target: Peripheral, { @@ -163,6 +163,15 @@ where #[inline] unsafe fn clone_unchecked(&self) -> Self::P { - self.deref().clone_unchecked() + T::Target::clone_unchecked(self) + } +} + +impl<'b, T: Peripheral> Peripheral for PeripheralRef<'_, T> { + type P = T::P; + + #[inline] + unsafe fn clone_unchecked(&self) -> Self::P { + T::clone_unchecked(self) } } diff --git a/embassy-net-driver-channel/Cargo.toml b/embassy-net-driver-channel/Cargo.toml index c1ad11482..3bd7d288a 100644 --- a/embassy-net-driver-channel/Cargo.toml +++ b/embassy-net-driver-channel/Cargo.toml @@ -25,6 +25,6 @@ features = ["defmt"] defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } diff --git a/embassy-net-esp-hosted/Cargo.toml b/embassy-net-esp-hosted/Cargo.toml index dda65dbf9..337c749b6 100644 --- a/embassy-net-esp-hosted/Cargo.toml +++ b/embassy-net-esp-hosted/Cargo.toml @@ -9,12 +9,16 @@ license = "MIT OR Apache-2.0" repository = "https://github.com/embassy-rs/embassy" documentation = "https://docs.embassy.dev/embassy-net-esp-hosted" +[features] +defmt = [ "dep:defmt", "heapless/defmt-03" ] +log = [ "dep:log" ] + [dependencies] defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } embassy-time = { version = "0.3.0", path = "../embassy-time" } -embassy-sync = { version = "0.5.0", path = "../embassy-sync"} +embassy-sync = { version = "0.6.0", path = "../embassy-sync"} embassy-futures = { version = "0.1.0", path = "../embassy-futures"} embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"} diff --git a/embassy-net-ppp/Cargo.toml b/embassy-net-ppp/Cargo.toml index c4bea202f..cdfafaae1 100644 --- a/embassy-net-ppp/Cargo.toml +++ b/embassy-net-ppp/Cargo.toml @@ -21,7 +21,7 @@ embedded-io-async = { version = "0.6.1" } embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } ppproto = { version = "0.1.2"} -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } [package.metadata.embassy_docs] src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-ppp-v$VERSION/embassy-net-ppp/src/" diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index ee7289ad8..8c2daebf1 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -73,15 +73,10 @@ smoltcp = { version = "0.11.0", default-features = false, features = [ embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-time = { version = "0.3.0", path = "../embassy-time" } -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embedded-io-async = { version = "0.6.1" } managed = { version = "0.8.0", default-features = false, features = [ "map" ] } heapless = { version = "0.8", default-features = false } -as-slice = "0.2.1" -generic-array = { version = "0.14.4", default-features = false } -stable_deref_trait = { version = "1.2.0", default-features = false } -futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] } -atomic-pool = "1.0" embedded-nal-async = { version = "0.7.1" } document-features = "0.2.7" diff --git a/embassy-net/README.md b/embassy-net/README.md index 94aa6f550..ce59ea34a 100644 --- a/embassy-net/README.md +++ b/embassy-net/README.md @@ -13,8 +13,8 @@ memory management designed to work well for embedded systems, aiming for a more - TCP, UDP, DNS, DHCPv4, IGMPv4 - TCP sockets implement the `embedded-io` async traits. -See the [`smoltcp`](https://github.com/smoltcp-rs/smoltcp) README for a detailed list of implemented and -unimplemented features of the network protocols. +See the [`smoltcp`](https://github.com/smoltcp-rs/smoltcp) README for a detailed list of implemented and +unimplemented features of the network protocols. ## Hardware support diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 86ced1ded..12f5f30b4 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -25,13 +25,13 @@ pub mod udp; use core::cell::RefCell; use core::future::{poll_fn, Future}; +use core::pin::pin; use core::task::{Context, Poll}; pub use embassy_net_driver as driver; use embassy_net_driver::{Driver, LinkState}; use embassy_sync::waitqueue::WakerRegistration; use embassy_time::{Instant, Timer}; -use futures::pin_mut; #[allow(unused_imports)] use heapless::Vec; #[cfg(feature = "igmp")] @@ -905,8 +905,7 @@ impl<D: Driver> Inner<D> { } if let Some(poll_at) = s.iface.poll_at(timestamp, &mut s.sockets) { - let t = Timer::at(instant_from_smoltcp(poll_at)); - pin_mut!(t); + let t = pin!(Timer::at(instant_from_smoltcp(poll_at))); if t.poll(cx).is_ready() { cx.waker().wake_by_ref(); } diff --git a/embassy-net/src/raw.rs b/embassy-net/src/raw.rs index ad8d69853..7ecd913e7 100644 --- a/embassy-net/src/raw.rs +++ b/embassy-net/src/raw.rs @@ -91,7 +91,7 @@ impl<'a> RawSocket<'a> { /// Send a datagram. /// /// This method will wait until the datagram has been sent.` - pub async fn send<T>(&self, buf: &[u8]) -> Result<(), raw::SendError> { + pub async fn send(&self, buf: &[u8]) { poll_fn(move |cx| self.poll_send(buf, cx)).await } @@ -101,10 +101,10 @@ impl<'a> RawSocket<'a> { /// /// When the socket's send buffer is full, this method will return `Poll::Pending` /// and register the current task to be notified when the buffer has space available. - pub fn poll_send(&self, buf: &[u8], cx: &mut Context<'_>) -> Poll<Result<(), raw::SendError>> { + pub fn poll_send(&self, buf: &[u8], cx: &mut Context<'_>) -> Poll<()> { self.with_mut(|s, _| match s.send_slice(buf) { // Entire datagram has been sent - Ok(()) => Poll::Ready(Ok(())), + Ok(()) => Poll::Ready(()), Err(raw::SendError::BufferFull) => { s.register_send_waker(cx.waker()); Poll::Pending diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index 57c9b7a04..9dfbba32b 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs @@ -555,7 +555,7 @@ mod embedded_io_impls { impl<'d> embedded_io_async::ReadReady for TcpSocket<'d> { fn read_ready(&mut self) -> Result<bool, Self::Error> { - Ok(self.io.with(|s, _| s.may_recv())) + Ok(self.io.with(|s, _| s.can_recv())) } } @@ -587,7 +587,7 @@ mod embedded_io_impls { impl<'d> embedded_io_async::ReadReady for TcpReader<'d> { fn read_ready(&mut self) -> Result<bool, Self::Error> { - Ok(self.io.with(|s, _| s.may_recv())) + Ok(self.io.with(|s, _| s.can_recv())) } } diff --git a/embassy-net/src/udp.rs b/embassy-net/src/udp.rs index a22cd8827..6e50c4e01 100644 --- a/embassy-net/src/udp.rs +++ b/embassy-net/src/udp.rs @@ -8,8 +8,8 @@ use core::task::{Context, Poll}; use embassy_net_driver::Driver; use smoltcp::iface::{Interface, SocketHandle}; use smoltcp::socket::udp; -pub use smoltcp::socket::udp::PacketMetadata; -use smoltcp::wire::{IpEndpoint, IpListenEndpoint}; +pub use smoltcp::socket::udp::{PacketMetadata, UdpMetadata}; +use smoltcp::wire::IpListenEndpoint; use crate::{SocketStack, Stack}; @@ -111,7 +111,7 @@ impl<'a> UdpSocket<'a> { /// This method will wait until a datagram is received. /// /// Returns the number of bytes received and the remote endpoint. - pub async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, IpEndpoint), RecvError> { + pub async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, UdpMetadata), RecvError> { poll_fn(move |cx| self.poll_recv_from(buf, cx)).await } @@ -122,9 +122,13 @@ impl<'a> UdpSocket<'a> { /// /// When a datagram is received, this method will return `Poll::Ready` with the /// number of bytes received and the remote endpoint. - pub fn poll_recv_from(&self, buf: &mut [u8], cx: &mut Context<'_>) -> Poll<Result<(usize, IpEndpoint), RecvError>> { + pub fn poll_recv_from( + &self, + buf: &mut [u8], + cx: &mut Context<'_>, + ) -> Poll<Result<(usize, UdpMetadata), RecvError>> { self.with_mut(|s, _| match s.recv_slice(buf) { - Ok((n, meta)) => Poll::Ready(Ok((n, meta.endpoint))), + Ok((n, meta)) => Poll::Ready(Ok((n, meta))), // No data ready Err(udp::RecvError::Truncated) => Poll::Ready(Err(RecvError::Truncated)), Err(udp::RecvError::Exhausted) => { @@ -141,9 +145,9 @@ impl<'a> UdpSocket<'a> { /// When the remote endpoint is not reachable, this method will return `Err(SendError::NoRoute)` pub async fn send_to<T>(&self, buf: &[u8], remote_endpoint: T) -> Result<(), SendError> where - T: Into<IpEndpoint>, + T: Into<UdpMetadata>, { - let remote_endpoint: IpEndpoint = remote_endpoint.into(); + let remote_endpoint: UdpMetadata = remote_endpoint.into(); poll_fn(move |cx| self.poll_send_to(buf, remote_endpoint, cx)).await } @@ -157,7 +161,7 @@ impl<'a> UdpSocket<'a> { /// When the remote endpoint is not reachable, this method will return `Poll::Ready(Err(Error::NoRoute))`. pub fn poll_send_to<T>(&self, buf: &[u8], remote_endpoint: T, cx: &mut Context<'_>) -> Poll<Result<(), SendError>> where - T: Into<IpEndpoint>, + T: Into<UdpMetadata>, { self.with_mut(|s, _| match s.send_slice(buf, remote_endpoint) { // Entire datagram has been sent diff --git a/embassy-nrf/CHANGELOG.md b/embassy-nrf/CHANGELOG.md new file mode 100644 index 000000000..773a1a108 --- /dev/null +++ b/embassy-nrf/CHANGELOG.md @@ -0,0 +1,40 @@ +# Changelog for embassy-nrf + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +- Drop `sealed` mod +- nrf52840: Add dcdc voltage parameter to configure REG0 regulator +- radio: Add support for IEEE 802.15.4 and BLE via radio peripheral +- spim: Reduce trace-level messages ("Copying SPIM tx buffer..") +- uart: Add support for rx- or tx-only BufferedUart +- uart: Implement splitting Rx/Tx +- spi: Allow specifying OutputDrive for SPI spins +- pdm: Fix gain register value derivation +- spim: Implement chunked DMA transfers +- spi: Add bounds checks for EasyDMA buffer size +- uarte: Add support for handling RX errors +- nrf51: Implement support for nrf51 chip +- pwm: Expose `duty` method +- pwm: Fix infinite loop +- spi: Add support for configuring bit order for bus +- pwm: Expose `pwm::PWM_CLK_HZ` and add `is_enabled` method +- gpio: Drop GPIO Pin generics (API break) + +## 0.1.0 - 2024-01-12 + +- First release with support for following NRF chips: + - nrf52805 + - nrf52810 + - nrf52811 + - nrf52820 + - nrf52832 + - nrf52833 + - nrf52840 + - nrf5340 + - nrf9160 + diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 0045d9f97..bdf9ec8f5 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -126,7 +126,7 @@ _nrf52832_anomaly_109 = [] [dependencies] embassy-time-driver = { version = "0.1", path = "../embassy-time-driver", optional = true } embassy-time = { version = "0.3.0", path = "../embassy-time", optional = true } -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver" } diff --git a/embassy-nrf/src/pdm.rs b/embassy-nrf/src/pdm.rs index ef2662c85..c1501e02e 100644 --- a/embassy-nrf/src/pdm.rs +++ b/embassy-nrf/src/pdm.rs @@ -1,4 +1,4 @@ -//! Pulse Density Modulation (PDM) mirophone driver +//! Pulse Density Modulation (PDM) microphone driver #![macro_use] diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index 1318d3f94..12057f7dd 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs @@ -368,7 +368,7 @@ impl<'s> Sequence<'s> { } /// A single sequence that can be started and stopped. -/// Takes at one sequence along with its configuration. +/// Takes one sequence along with its configuration. #[non_exhaustive] pub struct SingleSequencer<'d, 's, T: Instance> { sequencer: Sequencer<'d, 's, T>, diff --git a/embassy-nrf/src/usb/mod.rs b/embassy-nrf/src/usb/mod.rs index 09cf87e97..8cbb1a350 100644 --- a/embassy-nrf/src/usb/mod.rs +++ b/embassy-nrf/src/usb/mod.rs @@ -471,12 +471,19 @@ impl<'d, T: Instance, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, T, Dir } async fn wait_enabled(&mut self) { + self.wait_enabled_state(true).await + } +} + +#[allow(private_bounds)] +impl<'d, T: Instance, Dir: EndpointDir> Endpoint<'d, T, Dir> { + async fn wait_enabled_state(&mut self, state: bool) { let i = self.info.addr.index(); assert!(i != 0); poll_fn(move |cx| { Dir::waker(i).register(cx.waker()); - if Dir::is_enabled(T::regs(), i) { + if Dir::is_enabled(T::regs(), i) == state { Poll::Ready(()) } else { Poll::Pending @@ -484,6 +491,11 @@ impl<'d, T: Instance, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, T, Dir }) .await } + + /// Wait for the endpoint to be disabled + pub async fn wait_disabled(&mut self) { + self.wait_enabled_state(false).await + } } impl<'d, T: Instance, Dir> Endpoint<'d, T, Dir> { diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 794f1109c..48f7ad138 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -81,7 +81,7 @@ boot2-w25q080 = [] boot2-w25x10cl = [] [dependencies] -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embassy-time-driver = { version = "0.1", path = "../embassy-time-driver", optional = true } embassy-time = { version = "0.3.0", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } @@ -96,7 +96,6 @@ cfg-if = "1.0.0" cortex-m-rt = ">=0.6.15,<0.8" cortex-m = "0.7.6" critical-section = "1.1" -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } chrono = { version = "0.4", default-features = false, optional = true } embedded-io = { version = "0.6.1" } embedded-io-async = { version = "0.6.1" } diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index bedb79464..d0c6c19bd 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs @@ -714,10 +714,6 @@ pub fn clk_rtc_freq() -> u16 { } fn start_xosc(crystal_hz: u32, delay_multiplier: u32) { - pac::XOSC - .ctrl() - .write(|w| w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ)); - let startup_delay = (((crystal_hz / 1000) * delay_multiplier) + 128) / 256; pac::XOSC.startup().write(|w| w.set_delay(startup_delay as u16)); pac::XOSC.ctrl().write(|w| { @@ -1027,7 +1023,7 @@ pub fn dormant_sleep() { let _stop_adc = set(pac::CLOCKS.clk_adc_ctrl(), |w| w.set_enable(false)); let _stop_usb = set(pac::CLOCKS.clk_usb_ctrl(), |w| w.set_enable(false)); let _stop_peri = set(pac::CLOCKS.clk_peri_ctrl(), |w| w.set_enable(false)); - // set up rosc. we could ask the use to tell us which clock source to wake from like + // set up rosc. we could ask the user to tell us which clock source to wake from like // the C SDK does, but that seems rather unfriendly. we *may* disturb rtc by changing // rosc configuration if it's currently the rtc clock source, so we'll configure rosc // to the slowest frequency to minimize that impact. diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs index 45b385cb4..6e2a823d8 100644 --- a/embassy-rp/src/flash.rs +++ b/embassy-rp/src/flash.rs @@ -374,6 +374,11 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> ReadNorFlash for Flash<' impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> MultiwriteNorFlash for Flash<'d, T, M, FLASH_SIZE> {} +impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash::MultiwriteNorFlash + for Flash<'d, T, Async, FLASH_SIZE> +{ +} + impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, M, FLASH_SIZE> { const WRITE_SIZE: usize = WRITE_SIZE; diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index 1c83e306d..507d42280 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs @@ -352,12 +352,60 @@ pub fn init(config: config::Config) -> Peripherals { peripherals } +#[cfg(feature = "rt")] +#[cortex_m_rt::pre_init] +unsafe fn pre_init() { + // SIO does not get reset when core0 is reset with either `scb::sys_reset()` or with SWD. + // Since we're using SIO spinlock 31 for the critical-section impl, this causes random + // hangs if we reset in the middle of a CS, because the next boot sees the spinlock + // as locked and waits forever. + // + // See https://github.com/embassy-rs/embassy/issues/1736 + // and https://github.com/rp-rs/rp-hal/issues/292 + // and https://matrix.to/#/!vhKMWjizPZBgKeknOo:matrix.org/$VfOkQgyf1PjmaXZbtycFzrCje1RorAXd8BQFHTl4d5M + // + // According to Raspberry Pi, this is considered Working As Intended, and not an errata, + // even though this behavior is different from every other ARM chip (sys_reset usually resets + // the *system* as its name implies, not just the current core). + // + // To fix this, reset SIO on boot. We must do this in pre_init because it's unsound to do it + // in `embassy_rp::init`, since the user could've acquired a CS by then. pre_init is guaranteed + // to run before any user code. + // + // A similar thing could happen with PROC1. It is unclear whether it's possible for PROC1 + // to stay unreset through a PROC0 reset, so we reset it anyway just in case. + // + // Important info from PSM logic (from Luke Wren in above Matrix thread) + // + // The logic is, each PSM stage is reset if either of the following is true: + // - The previous stage is in reset and FRCE_ON is false + // - FRCE_OFF is true + // + // The PSM order is SIO -> PROC0 -> PROC1. + // So, we have to force-on PROC0 to prevent it from getting reset when resetting SIO. + pac::PSM.frce_on().write_and_wait(|w| { + w.set_proc0(true); + }); + // Then reset SIO and PROC1. + pac::PSM.frce_off().write_and_wait(|w| { + w.set_sio(true); + w.set_proc1(true); + }); + // clear force_off first, force_on second. The other way around would reset PROC0. + pac::PSM.frce_off().write_and_wait(|_| {}); + pac::PSM.frce_on().write_and_wait(|_| {}); +} + /// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes. +#[allow(unused)] trait RegExt<T: Copy> { #[allow(unused)] fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R; fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R; fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R; + fn write_and_wait<R>(&self, f: impl FnOnce(&mut T) -> R) -> R + where + T: PartialEq; } impl<T: Default + Copy, A: pac::common::Write> RegExt<T> for pac::common::Reg<T, A> { @@ -390,4 +438,17 @@ impl<T: Default + Copy, A: pac::common::Write> RegExt<T> for pac::common::Reg<T, } res } + + fn write_and_wait<R>(&self, f: impl FnOnce(&mut T) -> R) -> R + where + T: PartialEq, + { + let mut val = Default::default(); + let res = f(&mut val); + unsafe { + self.as_ptr().write_volatile(val); + while self.as_ptr().read_volatile() != val {} + } + res + } } diff --git a/embassy-rp/src/pio/mod.rs b/embassy-rp/src/pio/mod.rs index 2e5c57a26..1f7adbda3 100644 --- a/embassy-rp/src/pio/mod.rs +++ b/embassy-rp/src/pio/mod.rs @@ -324,6 +324,10 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> { } /// Pull data from RX FIFO. + /// + /// This function doesn't check if there is data available to be read. + /// If the rx FIFO is empty, an undefined value is returned. If you only + /// want to pull if data is available, use `try_pull` instead. pub fn pull(&mut self) -> u32 { PIO::PIO.rxf(SM).read() } diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index a1f400cfb..20b5c4d58 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs @@ -81,24 +81,22 @@ impl From<InputMode> for Divmode { } /// PWM driver. -pub struct Pwm<'d, T: Slice> { - inner: PeripheralRef<'d, T>, +pub struct Pwm<'d> { pin_a: Option<PeripheralRef<'d, AnyPin>>, pin_b: Option<PeripheralRef<'d, AnyPin>>, + slice: usize, } -impl<'d, T: Slice> Pwm<'d, T> { +impl<'d> Pwm<'d> { fn new_inner( - inner: impl Peripheral<P = T> + 'd, + slice: usize, a: Option<PeripheralRef<'d, AnyPin>>, b: Option<PeripheralRef<'d, AnyPin>>, b_pull: Pull, config: Config, divmode: Divmode, ) -> Self { - into_ref!(inner); - - let p = inner.regs(); + let p = pac::PWM.ch(slice); p.csr().modify(|w| { w.set_divmode(divmode); w.set_en(false); @@ -117,51 +115,67 @@ impl<'d, T: Slice> Pwm<'d, T> { }); } Self { - inner, + // inner: p.into(), pin_a: a, pin_b: b, + slice, } } /// Create PWM driver without any configured pins. #[inline] - pub fn new_free(inner: impl Peripheral<P = T> + 'd, config: Config) -> Self { - Self::new_inner(inner, None, None, Pull::None, config, Divmode::DIV) + pub fn new_free<T: Slice>(slice: impl Peripheral<P = T> + 'd, config: Config) -> Self { + into_ref!(slice); + Self::new_inner(slice.number(), None, None, Pull::None, config, Divmode::DIV) } /// Create PWM driver with a single 'a' as output. #[inline] - pub fn new_output_a( - inner: impl Peripheral<P = T> + 'd, + pub fn new_output_a<T: Slice>( + slice: impl Peripheral<P = T> + 'd, a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, config: Config, ) -> Self { - into_ref!(a); - Self::new_inner(inner, Some(a.map_into()), None, Pull::None, config, Divmode::DIV) + into_ref!(slice, a); + Self::new_inner( + slice.number(), + Some(a.map_into()), + None, + Pull::None, + config, + Divmode::DIV, + ) } /// Create PWM driver with a single 'b' pin as output. #[inline] - pub fn new_output_b( - inner: impl Peripheral<P = T> + 'd, + pub fn new_output_b<T: Slice>( + slice: impl Peripheral<P = T> + 'd, b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, config: Config, ) -> Self { - into_ref!(b); - Self::new_inner(inner, None, Some(b.map_into()), Pull::None, config, Divmode::DIV) + into_ref!(slice, b); + Self::new_inner( + slice.number(), + None, + Some(b.map_into()), + Pull::None, + config, + Divmode::DIV, + ) } /// Create PWM driver with a 'a' and 'b' pins as output. #[inline] - pub fn new_output_ab( - inner: impl Peripheral<P = T> + 'd, + pub fn new_output_ab<T: Slice>( + slice: impl Peripheral<P = T> + 'd, a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, config: Config, ) -> Self { - into_ref!(a, b); + into_ref!(slice, a, b); Self::new_inner( - inner, + slice.number(), Some(a.map_into()), Some(b.map_into()), Pull::None, @@ -172,30 +186,30 @@ impl<'d, T: Slice> Pwm<'d, T> { /// Create PWM driver with a single 'b' as input pin. #[inline] - pub fn new_input( - inner: impl Peripheral<P = T> + 'd, + pub fn new_input<T: Slice>( + slice: impl Peripheral<P = T> + 'd, b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, b_pull: Pull, mode: InputMode, config: Config, ) -> Self { - into_ref!(b); - Self::new_inner(inner, None, Some(b.map_into()), b_pull, config, mode.into()) + into_ref!(slice, b); + Self::new_inner(slice.number(), None, Some(b.map_into()), b_pull, config, mode.into()) } /// Create PWM driver with a 'a' and 'b' pins in the desired input mode. #[inline] - pub fn new_output_input( - inner: impl Peripheral<P = T> + 'd, + pub fn new_output_input<T: Slice>( + slice: impl Peripheral<P = T> + 'd, a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, b_pull: Pull, mode: InputMode, config: Config, ) -> Self { - into_ref!(a, b); + into_ref!(slice, a, b); Self::new_inner( - inner, + slice.number(), Some(a.map_into()), Some(b.map_into()), b_pull, @@ -206,7 +220,7 @@ impl<'d, T: Slice> Pwm<'d, T> { /// Set the PWM config. pub fn set_config(&mut self, config: &Config) { - Self::configure(self.inner.regs(), config); + Self::configure(pac::PWM.ch(self.slice), config); } fn configure(p: pac::pwm::Channel, config: &Config) { @@ -228,22 +242,22 @@ impl<'d, T: Slice> Pwm<'d, T> { }); } - /// Advances a slice’s output phase by one count while it is running + /// Advances a slice's output phase by one count while it is running /// by inserting a pulse into the clock enable. The counter /// will not count faster than once per cycle. #[inline] pub fn phase_advance(&mut self) { - let p = self.inner.regs(); + let p = pac::PWM.ch(self.slice); p.csr().write_set(|w| w.set_ph_adv(true)); while p.csr().read().ph_adv() {} } - /// Retards a slice’s output phase by one count while it is running + /// Retards a slice's output phase by one count while it is running /// by deleting a pulse from the clock enable. The counter will not - /// count backward when clock enable is permenantly low. + /// count backward when clock enable is permanently low. #[inline] pub fn phase_retard(&mut self) { - let p = self.inner.regs(); + let p = pac::PWM.ch(self.slice); p.csr().write_set(|w| w.set_ph_ret(true)); while p.csr().read().ph_ret() {} } @@ -251,13 +265,13 @@ impl<'d, T: Slice> Pwm<'d, T> { /// Read PWM counter. #[inline] pub fn counter(&self) -> u16 { - self.inner.regs().ctr().read().ctr() + pac::PWM.ch(self.slice).ctr().read().ctr() } /// Write PWM counter. #[inline] pub fn set_counter(&self, ctr: u16) { - self.inner.regs().ctr().write(|w| w.set_ctr(ctr)) + pac::PWM.ch(self.slice).ctr().write(|w| w.set_ctr(ctr)) } /// Wait for channel interrupt. @@ -281,7 +295,7 @@ impl<'d, T: Slice> Pwm<'d, T> { #[inline] fn bit(&self) -> u32 { - 1 << self.inner.number() as usize + 1 << self.slice as usize } } @@ -291,7 +305,7 @@ pub struct PwmBatch(u32); impl PwmBatch { #[inline] /// Enable a PWM slice in this batch. - pub fn enable(&mut self, pwm: &Pwm<'_, impl Slice>) { + pub fn enable(&mut self, pwm: &Pwm<'_>) { self.0 |= pwm.bit(); } @@ -308,9 +322,9 @@ impl PwmBatch { } } -impl<'d, T: Slice> Drop for Pwm<'d, T> { +impl<'d> Drop for Pwm<'d> { fn drop(&mut self) { - self.inner.regs().csr().write_clear(|w| w.set_en(false)); + pac::PWM.ch(self.slice).csr().write_clear(|w| w.set_en(false)); if let Some(pin) = &self.pin_a { pin.gpio().ctrl().write(|w| w.set_funcsel(31)); } @@ -326,19 +340,14 @@ trait SealedSlice {} #[allow(private_bounds)] pub trait Slice: Peripheral<P = Self> + SealedSlice + Sized + 'static { /// Slice number. - fn number(&self) -> u8; - - /// Slice register block. - fn regs(&self) -> pac::pwm::Channel { - pac::PWM.ch(self.number() as _) - } + fn number(&self) -> usize; } macro_rules! slice { ($name:ident, $num:expr) => { impl SealedSlice for peripherals::$name {} impl Slice for peripherals::$name { - fn number(&self) -> u8 { + fn number(&self) -> usize { $num } } diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs index da1157984..c94164040 100644 --- a/embassy-rp/src/uart/buffered.rs +++ b/embassy-rp/src/uart/buffered.rs @@ -51,14 +51,20 @@ pub struct BufferedUartTx<'d, T: Instance> { pub(crate) fn init_buffers<'d, T: Instance + 'd>( _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, - tx_buffer: &'d mut [u8], - rx_buffer: &'d mut [u8], + tx_buffer: Option<&'d mut [u8]>, + rx_buffer: Option<&'d mut [u8]>, ) { let state = T::buffered_state(); - let len = tx_buffer.len(); - unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; - let len = rx_buffer.len(); - unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; + + if let Some(tx_buffer) = tx_buffer { + let len = tx_buffer.len(); + unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; + } + + if let Some(rx_buffer) = rx_buffer { + let len = rx_buffer.len(); + unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; + } // From the datasheet: // "The transmit interrupt is based on a transition through a level, rather @@ -95,7 +101,7 @@ impl<'d, T: Instance> BufferedUart<'d, T> { into_ref!(tx, rx); super::Uart::<'d, T, Async>::init(Some(tx.map_into()), Some(rx.map_into()), None, None, config); - init_buffers::<T>(irq, tx_buffer, rx_buffer); + init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer)); Self { rx: BufferedUartRx { phantom: PhantomData }, @@ -124,7 +130,7 @@ impl<'d, T: Instance> BufferedUart<'d, T> { Some(cts.map_into()), config, ); - init_buffers::<T>(irq, tx_buffer, rx_buffer); + init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer)); Self { rx: BufferedUartRx { phantom: PhantomData }, @@ -175,7 +181,7 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { into_ref!(rx); super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), None, None, config); - init_buffers::<T>(irq, &mut [], rx_buffer); + init_buffers::<T>(irq, None, Some(rx_buffer)); Self { phantom: PhantomData } } @@ -192,7 +198,7 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { into_ref!(rx, rts); super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), Some(rts.map_into()), None, config); - init_buffers::<T>(irq, &mut [], rx_buffer); + init_buffers::<T>(irq, None, Some(rx_buffer)); Self { phantom: PhantomData } } @@ -323,7 +329,7 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { into_ref!(tx); super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, None, config); - init_buffers::<T>(irq, tx_buffer, &mut []); + init_buffers::<T>(irq, Some(tx_buffer), None); Self { phantom: PhantomData } } @@ -340,12 +346,12 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { into_ref!(tx, cts); super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, Some(cts.map_into()), config); - init_buffers::<T>(irq, tx_buffer, &mut []); + init_buffers::<T>(irq, Some(tx_buffer), None); Self { phantom: PhantomData } } - fn write<'a>(buf: &'a [u8]) -> impl Future<Output = Result<usize, Error>> + 'a { + fn write(buf: &[u8]) -> impl Future<Output = Result<usize, Error>> + '_ { poll_fn(move |cx| { if buf.is_empty() { return Poll::Ready(Ok(0)); @@ -459,9 +465,9 @@ impl<'d, T: Instance> Drop for BufferedUartRx<'d, T> { let state = T::buffered_state(); unsafe { state.rx_buf.deinit() } - // TX is inactive if the the buffer is not available. + // TX is inactive if the buffer is not available. // We can now unregister the interrupt handler - if state.tx_buf.is_empty() { + if !state.tx_buf.is_available() { T::Interrupt::disable(); } } @@ -472,9 +478,9 @@ impl<'d, T: Instance> Drop for BufferedUartTx<'d, T> { let state = T::buffered_state(); unsafe { state.tx_buf.deinit() } - // RX is inactive if the the buffer is not available. + // RX is inactive if the buffer is not available. // We can now unregister the interrupt handler - if state.rx_buf.is_empty() { + if !state.rx_buf.is_available() { T::Interrupt::disable(); } } @@ -520,64 +526,68 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for BufferedInterr } // RX - let mut rx_writer = unsafe { s.rx_buf.writer() }; - let rx_buf = rx_writer.push_slice(); - let mut n_read = 0; - let mut error = false; - for rx_byte in rx_buf { - if r.uartfr().read().rxfe() { - break; + if s.rx_buf.is_available() { + let mut rx_writer = unsafe { s.rx_buf.writer() }; + let rx_buf = rx_writer.push_slice(); + let mut n_read = 0; + let mut error = false; + for rx_byte in rx_buf { + if r.uartfr().read().rxfe() { + break; + } + let dr = r.uartdr().read(); + if (dr.0 >> 8) != 0 { + s.rx_error.fetch_or((dr.0 >> 8) as u8, Ordering::Relaxed); + error = true; + // only fill the buffer with valid characters. the current character is fine + // if the error is an overrun, but if we add it to the buffer we'll report + // the overrun one character too late. drop it instead and pretend we were + // a bit slower at draining the rx fifo than we actually were. + // this is consistent with blocking uart error reporting. + break; + } + *rx_byte = dr.data(); + n_read += 1; } - let dr = r.uartdr().read(); - if (dr.0 >> 8) != 0 { - s.rx_error.fetch_or((dr.0 >> 8) as u8, Ordering::Relaxed); - error = true; - // only fill the buffer with valid characters. the current character is fine - // if the error is an overrun, but if we add it to the buffer we'll report - // the overrun one character too late. drop it instead and pretend we were - // a bit slower at draining the rx fifo than we actually were. - // this is consistent with blocking uart error reporting. - break; + if n_read > 0 { + rx_writer.push_done(n_read); + s.rx_waker.wake(); + } else if error { + s.rx_waker.wake(); + } + // Disable any further RX interrupts when the buffer becomes full or + // errors have occurred. This lets us buffer additional errors in the + // fifo without needing more error storage locations, and most applications + // will want to do a full reset of their uart state anyway once an error + // has happened. + if s.rx_buf.is_full() || error { + r.uartimsc().write_clear(|w| { + w.set_rxim(true); + w.set_rtim(true); + }); } - *rx_byte = dr.data(); - n_read += 1; - } - if n_read > 0 { - rx_writer.push_done(n_read); - s.rx_waker.wake(); - } else if error { - s.rx_waker.wake(); - } - // Disable any further RX interrupts when the buffer becomes full or - // errors have occurred. This lets us buffer additional errors in the - // fifo without needing more error storage locations, and most applications - // will want to do a full reset of their uart state anyway once an error - // has happened. - if s.rx_buf.is_full() || error { - r.uartimsc().write_clear(|w| { - w.set_rxim(true); - w.set_rtim(true); - }); } // TX - let mut tx_reader = unsafe { s.tx_buf.reader() }; - let tx_buf = tx_reader.pop_slice(); - let mut n_written = 0; - for tx_byte in tx_buf.iter_mut() { - if r.uartfr().read().txff() { - break; + if s.tx_buf.is_available() { + let mut tx_reader = unsafe { s.tx_buf.reader() }; + let tx_buf = tx_reader.pop_slice(); + let mut n_written = 0; + for tx_byte in tx_buf.iter_mut() { + if r.uartfr().read().txff() { + break; + } + r.uartdr().write(|w| w.set_data(*tx_byte)); + n_written += 1; } - r.uartdr().write(|w| w.set_data(*tx_byte)); - n_written += 1; + if n_written > 0 { + tx_reader.pop_done(n_written); + s.tx_waker.wake(); + } + // The TX interrupt only triggers once when the FIFO threshold is + // crossed. No need to disable it when the buffer becomes empty + // as it does re-trigger anymore once we have cleared it. } - if n_written > 0 { - tx_reader.pop_done(n_written); - s.tx_waker.wake(); - } - // The TX interrupt only triggers once when the FIFO threshold is - // crossed. No need to disable it when the buffer becomes empty - // as it does re-trigger anymore once we have cleared it. } } diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index ee2dcb27d..30ece15bd 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs @@ -231,7 +231,7 @@ impl<'d, T: Instance> UartTx<'d, T, Blocking> { irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, tx_buffer: &'d mut [u8], ) -> BufferedUartTx<'d, T> { - buffered::init_buffers::<T>(irq, tx_buffer, &mut []); + buffered::init_buffers::<T>(irq, Some(tx_buffer), None); BufferedUartTx { phantom: PhantomData } } @@ -352,7 +352,7 @@ impl<'d, T: Instance> UartRx<'d, T, Blocking> { irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, rx_buffer: &'d mut [u8], ) -> BufferedUartRx<'d, T> { - buffered::init_buffers::<T>(irq, &mut [], rx_buffer); + buffered::init_buffers::<T>(irq, None, Some(rx_buffer)); BufferedUartRx { phantom: PhantomData } } @@ -690,7 +690,7 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> { tx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8], ) -> BufferedUart<'d, T> { - buffered::init_buffers::<T>(irq, tx_buffer, rx_buffer); + buffered::init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer)); BufferedUart { rx: BufferedUartRx { phantom: PhantomData }, @@ -860,7 +860,7 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { }); } - /// sets baudrate on runtime + /// sets baudrate on runtime pub fn set_baudrate(&mut self, baudrate: u32) { Self::set_baudrate_inner(baudrate); } diff --git a/embassy-rp/src/usb.rs b/embassy-rp/src/usb.rs index 37d37d6d9..512271ae4 100644 --- a/embassy-rp/src/usb.rs +++ b/embassy-rp/src/usb.rs @@ -412,12 +412,41 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { .await } - fn endpoint_set_stalled(&mut self, _ep_addr: EndpointAddress, _stalled: bool) { - todo!(); + fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) { + let n = ep_addr.index(); + + if n == 0 { + T::regs().ep_stall_arm().modify(|w| { + if ep_addr.is_in() { + w.set_ep0_in(stalled); + } else { + w.set_ep0_out(stalled); + } + }); + } + + let ctrl = if ep_addr.is_in() { + T::dpram().ep_in_buffer_control(n) + } else { + T::dpram().ep_out_buffer_control(n) + }; + + ctrl.modify(|w| w.set_stall(stalled)); + + let wakers = if ep_addr.is_in() { &EP_IN_WAKERS } else { &EP_OUT_WAKERS }; + wakers[n].wake(); } - fn endpoint_is_stalled(&mut self, _ep_addr: EndpointAddress) -> bool { - todo!(); + fn endpoint_is_stalled(&mut self, ep_addr: EndpointAddress) -> bool { + let n = ep_addr.index(); + + let ctrl = if ep_addr.is_in() { + T::dpram().ep_in_buffer_control(n) + } else { + T::dpram().ep_out_buffer_control(n) + }; + + ctrl.read().stall() } fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool) { diff --git a/embassy-rp/src/watchdog.rs b/embassy-rp/src/watchdog.rs index f1e986ec7..229a306fe 100644 --- a/embassy-rp/src/watchdog.rs +++ b/embassy-rp/src/watchdog.rs @@ -46,7 +46,7 @@ impl Watchdog { /// or when JTAG is accessing bus fabric pub fn pause_on_debug(&mut self, pause: bool) { let watchdog = pac::WATCHDOG; - watchdog.ctrl().write(|w| { + watchdog.ctrl().modify(|w| { w.set_pause_dbg0(pause); w.set_pause_dbg1(pause); w.set_pause_jtag(pause); @@ -60,7 +60,7 @@ impl Watchdog { fn enable(&self, bit: bool) { let watchdog = pac::WATCHDOG; - watchdog.ctrl().write(|w| w.set_enable(bit)) + watchdog.ctrl().modify(|w| w.set_enable(bit)) } // Configure which hardware will be reset by the watchdog diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index 360ca5f4b..11a0adab2 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml @@ -20,7 +20,7 @@ features = ["stm32wb55rg"] [dependencies] embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" } -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embassy-time = { version = "0.3.0", path = "../embassy-time", optional = true } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-hal-internal = { version = "0.1.0", path = "../embassy-hal-internal" } @@ -35,7 +35,7 @@ aligned = "0.4.1" bit_field = "0.10.2" stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } stm32wb-hci = { version = "0.17.0", optional = true } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } +futures-util = { version = "0.3.30", default-features = false } bitflags = { version = "2.3.3", optional = true } [features] diff --git a/embassy-stm32-wpan/src/mac/control.rs b/embassy-stm32-wpan/src/mac/control.rs index 8a13de81c..e8d2f9f7b 100644 --- a/embassy-stm32-wpan/src/mac/control.rs +++ b/embassy-stm32-wpan/src/mac/control.rs @@ -5,7 +5,7 @@ use core::task::Poll; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::mutex::MutexGuard; use embassy_sync::signal::Signal; -use futures::FutureExt; +use futures_util::FutureExt; use super::commands::MacCommand; use super::event::MacEvent; diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 89b24f0eb..fde5b4786 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -24,12 +24,13 @@ flavors = [ { regex_feature = "stm32c0.*", target = "thumbv6m-none-eabi" }, { regex_feature = "stm32g0.*", target = "thumbv6m-none-eabi" }, { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi", features = ["low-power"] }, - { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf" }, + { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf", features = ["low-power"] }, { regex_feature = "stm32h7.*", target = "thumbv7em-none-eabi" }, { regex_feature = "stm32l0.*", target = "thumbv6m-none-eabi", features = ["low-power"] }, { regex_feature = "stm32l1.*", target = "thumbv7m-none-eabi" }, { regex_feature = "stm32l4.*", target = "thumbv7em-none-eabi" }, { regex_feature = "stm32l5.*", target = "thumbv8m.main-none-eabihf", features = ["low-power"] }, + { regex_feature = "stm32u0.*", target = "thumbv6m-none-eabi" }, { regex_feature = "stm32u5.*", target = "thumbv8m.main-none-eabihf" }, { regex_feature = "stm32wb.*", target = "thumbv7em-none-eabi" }, { regex_feature = "stm32wba.*", target = "thumbv8m.main-none-eabihf" }, @@ -41,7 +42,7 @@ features = ["defmt", "unstable-pac", "exti", "time-driver-any", "time", "stm32h7 rustdoc-args = ["--cfg", "docsrs"] [dependencies] -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embassy-time = { version = "0.3.0", path = "../embassy-time", optional = true } embassy-time-driver = { version = "0.1", path = "../embassy-time-driver", optional = true } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } @@ -49,6 +50,7 @@ embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", fea embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver" } +embassy-usb-synopsys-otg = {version = "0.1.0", path = "../embassy-usb-synopsys-otg" } embassy-executor = { version = "0.5.0", path = "../embassy-executor", optional = true } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } @@ -65,12 +67,12 @@ defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } cortex-m-rt = ">=0.6.15,<0.8" cortex-m = "0.7.6" -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } +futures-util = { version = "0.3.30", default-features = false } rand_core = "0.6.3" sdio-host = "0.5.0" critical-section = "1.1" #stm32-metapac = { version = "15" } -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2b7ec569a5510c324693f0515ac8ea20b12917a9" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-34c0188a682b32c32ff147d377e0629b1ebe8318" } vcell = "0.1.3" nb = "1.0.0" @@ -87,7 +89,6 @@ volatile-register = { version = "0.2.1" } bitflags = "2.4.2" - [dev-dependencies] critical-section = { version = "1.1", features = ["std"] } @@ -96,7 +97,7 @@ proc-macro2 = "1.0.36" quote = "1.0.15" #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2b7ec569a5510c324693f0515ac8ea20b12917a9", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-34c0188a682b32c32ff147d377e0629b1ebe8318", default-features = false, features = ["metadata"]} [features] default = ["rt"] @@ -114,6 +115,9 @@ low-power-debug-with-sleep = [] ## Automatically generate `memory.x` file using [`stm32-metapac`](https://docs.rs/stm32-metapac/) memory-x = ["stm32-metapac/memory-x"] +## Use secure registers when TrustZone is enabled +trustzone-secure = [] + ## Re-export stm32-metapac at `embassy_stm32::pac`. ## This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version. ## If this is an issue for you, you're encouraged to directly depend on a fixed version of the PAC. @@ -910,6 +914,20 @@ stm32h503cb = [ "stm32-metapac/stm32h503cb" ] stm32h503eb = [ "stm32-metapac/stm32h503eb" ] stm32h503kb = [ "stm32-metapac/stm32h503kb" ] stm32h503rb = [ "stm32-metapac/stm32h503rb" ] +stm32h523cc = [ "stm32-metapac/stm32h523cc" ] +stm32h523ce = [ "stm32-metapac/stm32h523ce" ] +stm32h523he = [ "stm32-metapac/stm32h523he" ] +stm32h523rc = [ "stm32-metapac/stm32h523rc" ] +stm32h523re = [ "stm32-metapac/stm32h523re" ] +stm32h523vc = [ "stm32-metapac/stm32h523vc" ] +stm32h523ve = [ "stm32-metapac/stm32h523ve" ] +stm32h523zc = [ "stm32-metapac/stm32h523zc" ] +stm32h523ze = [ "stm32-metapac/stm32h523ze" ] +stm32h533ce = [ "stm32-metapac/stm32h533ce" ] +stm32h533he = [ "stm32-metapac/stm32h533he" ] +stm32h533re = [ "stm32-metapac/stm32h533re" ] +stm32h533ve = [ "stm32-metapac/stm32h533ve" ] +stm32h533ze = [ "stm32-metapac/stm32h533ze" ] stm32h562ag = [ "stm32-metapac/stm32h562ag" ] stm32h562ai = [ "stm32-metapac/stm32h562ai" ] stm32h562ig = [ "stm32-metapac/stm32h562ig" ] @@ -1076,6 +1094,26 @@ stm32h7b3qi = [ "stm32-metapac/stm32h7b3qi" ] stm32h7b3ri = [ "stm32-metapac/stm32h7b3ri" ] stm32h7b3vi = [ "stm32-metapac/stm32h7b3vi" ] stm32h7b3zi = [ "stm32-metapac/stm32h7b3zi" ] +stm32h7r3a8 = [ "stm32-metapac/stm32h7r3a8" ] +stm32h7r3i8 = [ "stm32-metapac/stm32h7r3i8" ] +stm32h7r3l8 = [ "stm32-metapac/stm32h7r3l8" ] +stm32h7r3r8 = [ "stm32-metapac/stm32h7r3r8" ] +stm32h7r3v8 = [ "stm32-metapac/stm32h7r3v8" ] +stm32h7r3z8 = [ "stm32-metapac/stm32h7r3z8" ] +stm32h7r7a8 = [ "stm32-metapac/stm32h7r7a8" ] +stm32h7r7i8 = [ "stm32-metapac/stm32h7r7i8" ] +stm32h7r7l8 = [ "stm32-metapac/stm32h7r7l8" ] +stm32h7r7z8 = [ "stm32-metapac/stm32h7r7z8" ] +stm32h7s3a8 = [ "stm32-metapac/stm32h7s3a8" ] +stm32h7s3i8 = [ "stm32-metapac/stm32h7s3i8" ] +stm32h7s3l8 = [ "stm32-metapac/stm32h7s3l8" ] +stm32h7s3r8 = [ "stm32-metapac/stm32h7s3r8" ] +stm32h7s3v8 = [ "stm32-metapac/stm32h7s3v8" ] +stm32h7s3z8 = [ "stm32-metapac/stm32h7s3z8" ] +stm32h7s7a8 = [ "stm32-metapac/stm32h7s7a8" ] +stm32h7s7i8 = [ "stm32-metapac/stm32h7s7i8" ] +stm32h7s7l8 = [ "stm32-metapac/stm32h7s7l8" ] +stm32h7s7z8 = [ "stm32-metapac/stm32h7s7z8" ] stm32l010c6 = [ "stm32-metapac/stm32l010c6" ] stm32l010f4 = [ "stm32-metapac/stm32l010f4" ] stm32l010k4 = [ "stm32-metapac/stm32l010k4" ] @@ -1419,6 +1457,38 @@ stm32l562qe = [ "stm32-metapac/stm32l562qe" ] stm32l562re = [ "stm32-metapac/stm32l562re" ] stm32l562ve = [ "stm32-metapac/stm32l562ve" ] stm32l562ze = [ "stm32-metapac/stm32l562ze" ] +stm32u031c6 = [ "stm32-metapac/stm32u031c6" ] +stm32u031c8 = [ "stm32-metapac/stm32u031c8" ] +stm32u031f4 = [ "stm32-metapac/stm32u031f4" ] +stm32u031f6 = [ "stm32-metapac/stm32u031f6" ] +stm32u031f8 = [ "stm32-metapac/stm32u031f8" ] +stm32u031g6 = [ "stm32-metapac/stm32u031g6" ] +stm32u031g8 = [ "stm32-metapac/stm32u031g8" ] +stm32u031k4 = [ "stm32-metapac/stm32u031k4" ] +stm32u031k6 = [ "stm32-metapac/stm32u031k6" ] +stm32u031k8 = [ "stm32-metapac/stm32u031k8" ] +stm32u031r6 = [ "stm32-metapac/stm32u031r6" ] +stm32u031r8 = [ "stm32-metapac/stm32u031r8" ] +stm32u073c8 = [ "stm32-metapac/stm32u073c8" ] +stm32u073cb = [ "stm32-metapac/stm32u073cb" ] +stm32u073cc = [ "stm32-metapac/stm32u073cc" ] +stm32u073h8 = [ "stm32-metapac/stm32u073h8" ] +stm32u073hb = [ "stm32-metapac/stm32u073hb" ] +stm32u073hc = [ "stm32-metapac/stm32u073hc" ] +stm32u073k8 = [ "stm32-metapac/stm32u073k8" ] +stm32u073kb = [ "stm32-metapac/stm32u073kb" ] +stm32u073kc = [ "stm32-metapac/stm32u073kc" ] +stm32u073m8 = [ "stm32-metapac/stm32u073m8" ] +stm32u073mb = [ "stm32-metapac/stm32u073mb" ] +stm32u073mc = [ "stm32-metapac/stm32u073mc" ] +stm32u073r8 = [ "stm32-metapac/stm32u073r8" ] +stm32u073rb = [ "stm32-metapac/stm32u073rb" ] +stm32u073rc = [ "stm32-metapac/stm32u073rc" ] +stm32u083cc = [ "stm32-metapac/stm32u083cc" ] +stm32u083hc = [ "stm32-metapac/stm32u083hc" ] +stm32u083kc = [ "stm32-metapac/stm32u083kc" ] +stm32u083mc = [ "stm32-metapac/stm32u083mc" ] +stm32u083rc = [ "stm32-metapac/stm32u083rc" ] stm32u535cb = [ "stm32-metapac/stm32u535cb" ] stm32u535cc = [ "stm32-metapac/stm32u535cc" ] stm32u535ce = [ "stm32-metapac/stm32u535ce" ] @@ -1474,6 +1544,7 @@ stm32u599vj = [ "stm32-metapac/stm32u599vj" ] stm32u599zi = [ "stm32-metapac/stm32u599zi" ] stm32u599zj = [ "stm32-metapac/stm32u599zj" ] stm32u5a5aj = [ "stm32-metapac/stm32u5a5aj" ] +stm32u5a5qi = [ "stm32-metapac/stm32u5a5qi" ] stm32u5a5qj = [ "stm32-metapac/stm32u5a5qj" ] stm32u5a5rj = [ "stm32-metapac/stm32u5a5rj" ] stm32u5a5vj = [ "stm32-metapac/stm32u5a5vj" ] @@ -1482,6 +1553,19 @@ stm32u5a9bj = [ "stm32-metapac/stm32u5a9bj" ] stm32u5a9nj = [ "stm32-metapac/stm32u5a9nj" ] stm32u5a9vj = [ "stm32-metapac/stm32u5a9vj" ] stm32u5a9zj = [ "stm32-metapac/stm32u5a9zj" ] +stm32u5f7vi = [ "stm32-metapac/stm32u5f7vi" ] +stm32u5f7vj = [ "stm32-metapac/stm32u5f7vj" ] +stm32u5f9bj = [ "stm32-metapac/stm32u5f9bj" ] +stm32u5f9nj = [ "stm32-metapac/stm32u5f9nj" ] +stm32u5f9vi = [ "stm32-metapac/stm32u5f9vi" ] +stm32u5f9vj = [ "stm32-metapac/stm32u5f9vj" ] +stm32u5f9zi = [ "stm32-metapac/stm32u5f9zi" ] +stm32u5f9zj = [ "stm32-metapac/stm32u5f9zj" ] +stm32u5g7vj = [ "stm32-metapac/stm32u5g7vj" ] +stm32u5g9bj = [ "stm32-metapac/stm32u5g9bj" ] +stm32u5g9nj = [ "stm32-metapac/stm32u5g9nj" ] +stm32u5g9vj = [ "stm32-metapac/stm32u5g9vj" ] +stm32u5g9zj = [ "stm32-metapac/stm32u5g9zj" ] stm32wb10cc = [ "stm32-metapac/stm32wb10cc" ] stm32wb15cc = [ "stm32-metapac/stm32wb15cc" ] stm32wb30ce = [ "stm32-metapac/stm32wb30ce" ] @@ -1498,10 +1582,22 @@ stm32wb55vc = [ "stm32-metapac/stm32wb55vc" ] stm32wb55ve = [ "stm32-metapac/stm32wb55ve" ] stm32wb55vg = [ "stm32-metapac/stm32wb55vg" ] stm32wb55vy = [ "stm32-metapac/stm32wb55vy" ] +stm32wba50ke = [ "stm32-metapac/stm32wba50ke" ] +stm32wba50kg = [ "stm32-metapac/stm32wba50kg" ] stm32wba52ce = [ "stm32-metapac/stm32wba52ce" ] stm32wba52cg = [ "stm32-metapac/stm32wba52cg" ] stm32wba52ke = [ "stm32-metapac/stm32wba52ke" ] stm32wba52kg = [ "stm32-metapac/stm32wba52kg" ] +stm32wba54ce = [ "stm32-metapac/stm32wba54ce" ] +stm32wba54cg = [ "stm32-metapac/stm32wba54cg" ] +stm32wba54ke = [ "stm32-metapac/stm32wba54ke" ] +stm32wba54kg = [ "stm32-metapac/stm32wba54kg" ] +stm32wba55ce = [ "stm32-metapac/stm32wba55ce" ] +stm32wba55cg = [ "stm32-metapac/stm32wba55cg" ] +stm32wba55he = [ "stm32-metapac/stm32wba55he" ] +stm32wba55hg = [ "stm32-metapac/stm32wba55hg" ] +stm32wba55ue = [ "stm32-metapac/stm32wba55ue" ] +stm32wba55ug = [ "stm32-metapac/stm32wba55ug" ] stm32wl54cc-cm4 = [ "stm32-metapac/stm32wl54cc-cm4" ] stm32wl54cc-cm0p = [ "stm32-metapac/stm32wl54cc-cm0p" ] stm32wl54jc-cm4 = [ "stm32-metapac/stm32wl54jc-cm4" ] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 38b6c480c..7bf6ffba2 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -1,10 +1,13 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::fmt::Write as _; -use std::path::PathBuf; +use std::io::Write; +use std::path::{Path, PathBuf}; +use std::process::Command; use std::{env, fs}; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; +use stm32_metapac::metadata::ir::BitOffset; use stm32_metapac::metadata::{ MemoryRegionKind, PeripheralRccKernelClock, PeripheralRccRegister, PeripheralRegisters, StopMode, METADATA, }; @@ -49,6 +52,8 @@ fn main() { .unwrap() .to_ascii_lowercase(); + eprintln!("chip: {chip_name}"); + for p in METADATA.peripherals { if let Some(r) = &p.registers { println!("cargo:rustc-cfg={}", r.kind); @@ -272,8 +277,6 @@ fn main() { "Bank1" } else if region.name.starts_with("BANK_2") { "Bank2" - } else if region.name == "OTP" { - "Otp" } else { continue; } @@ -357,12 +360,17 @@ fn main() { // ======== // Extract the rcc registers + let rcc_registers = METADATA .peripherals .iter() .filter_map(|p| p.registers.as_ref()) .find(|r| r.kind == "rcc") .unwrap(); + for b in rcc_registers.ir.blocks { + eprintln!("{}", b.name); + } + let rcc_block = rcc_registers.ir.blocks.iter().find(|b| b.name == "Rcc").unwrap(); // ======== // Generate RccPeripheral impls @@ -379,7 +387,6 @@ fn main() { struct ClockGen<'a> { rcc_registers: &'a PeripheralRegisters, chained_muxes: HashMap<&'a str, &'a PeripheralRccRegister>, - force_refcount: HashSet<&'a str>, refcount_statics: BTreeSet<Ident>, clock_names: BTreeSet<String>, @@ -389,7 +396,6 @@ fn main() { let mut clock_gen = ClockGen { rcc_registers, chained_muxes: HashMap::new(), - force_refcount: HashSet::from(["usart"]), refcount_statics: BTreeSet::new(), clock_names: BTreeSet::new(), @@ -404,7 +410,16 @@ fn main() { }, ); } - if chip_name.starts_with("stm32h7") { + + if chip_name.starts_with("stm32h7r") || chip_name.starts_with("stm32h7s") { + clock_gen.chained_muxes.insert( + "PER", + &PeripheralRccRegister { + register: "AHBPERCKSELR", + field: "PERSEL", + }, + ); + } else if chip_name.starts_with("stm32h7") { clock_gen.chained_muxes.insert( "PER", &PeripheralRccRegister { @@ -525,13 +540,34 @@ fn main() { None => (TokenStream::new(), TokenStream::new()), }; - let ptype = if let Some(reg) = &p.registers { reg.kind } else { "" }; let pname = format_ident!("{}", p.name); let en_reg = format_ident!("{}", en.register.to_ascii_lowercase()); let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase()); + let en_reg_offs = rcc_block + .items + .iter() + .find(|i| i.name.eq_ignore_ascii_case(en.register)) + .unwrap() + .byte_offset; + let en_reg_offs: u8 = (en_reg_offs / 4).try_into().unwrap(); - let refcount = - clock_gen.force_refcount.contains(ptype) || *rcc_field_count.get(&(en.register, en.field)).unwrap() > 1; + let en_bit_offs = &rcc_registers + .ir + .fieldsets + .iter() + .find(|i| i.name.eq_ignore_ascii_case(en.register)) + .unwrap() + .fields + .iter() + .find(|i| i.name.eq_ignore_ascii_case(en.field)) + .unwrap() + .bit_offset; + let BitOffset::Regular(en_bit_offs) = en_bit_offs else { + panic!("cursed bit offset") + }; + let en_bit_offs: u8 = en_bit_offs.offset.try_into().unwrap(); + + let refcount = *rcc_field_count.get(&(en.register, en.field)).unwrap() > 1; let (before_enable, before_disable) = if refcount { let refcount_static = format_ident!("{}_{}", en.register.to_ascii_uppercase(), en.field.to_ascii_uppercase()); @@ -613,6 +649,9 @@ fn main() { crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); #decr_stop_refcount } + + const ENABLE_BIT: crate::rcc::ClockEnableBit = + unsafe { crate::rcc::ClockEnableBit::new(#en_reg_offs, #en_bit_offs) }; } impl crate::rcc::RccPeripheral for peripherals::#pname {} @@ -664,6 +703,7 @@ fn main() { #(pub use crate::pac::rcc::vals::#enum_names as #enum_names; )* #[derive(Clone, Copy)] + #[non_exhaustive] pub struct ClockMux { #( #struct_fields, )* } @@ -824,6 +864,35 @@ fn main() { (("dcmi", "HSYNC"), quote!(crate::dcmi::HSyncPin)), (("dcmi", "VSYNC"), quote!(crate::dcmi::VSyncPin)), (("dcmi", "PIXCLK"), quote!(crate::dcmi::PixClkPin)), + (("dsihost", "TE"), quote!(crate::dsihost::TePin)), + (("ltdc", "CLK"), quote!(crate::ltdc::ClkPin)), + (("ltdc", "HSYNC"), quote!(crate::ltdc::HsyncPin)), + (("ltdc", "VSYNC"), quote!(crate::ltdc::VsyncPin)), + (("ltdc", "DE"), quote!(crate::ltdc::DePin)), + (("ltdc", "R0"), quote!(crate::ltdc::R0Pin)), + (("ltdc", "R1"), quote!(crate::ltdc::R1Pin)), + (("ltdc", "R2"), quote!(crate::ltdc::R2Pin)), + (("ltdc", "R3"), quote!(crate::ltdc::R3Pin)), + (("ltdc", "R4"), quote!(crate::ltdc::R4Pin)), + (("ltdc", "R5"), quote!(crate::ltdc::R5Pin)), + (("ltdc", "R6"), quote!(crate::ltdc::R6Pin)), + (("ltdc", "R7"), quote!(crate::ltdc::R7Pin)), + (("ltdc", "G0"), quote!(crate::ltdc::G0Pin)), + (("ltdc", "G1"), quote!(crate::ltdc::G1Pin)), + (("ltdc", "G2"), quote!(crate::ltdc::G2Pin)), + (("ltdc", "G3"), quote!(crate::ltdc::G3Pin)), + (("ltdc", "G4"), quote!(crate::ltdc::G4Pin)), + (("ltdc", "G5"), quote!(crate::ltdc::G5Pin)), + (("ltdc", "G6"), quote!(crate::ltdc::G6Pin)), + (("ltdc", "G7"), quote!(crate::ltdc::G7Pin)), + (("ltdc", "B0"), quote!(crate::ltdc::B0Pin)), + (("ltdc", "B1"), quote!(crate::ltdc::B1Pin)), + (("ltdc", "B2"), quote!(crate::ltdc::B2Pin)), + (("ltdc", "B3"), quote!(crate::ltdc::B3Pin)), + (("ltdc", "B4"), quote!(crate::ltdc::B4Pin)), + (("ltdc", "B5"), quote!(crate::ltdc::B5Pin)), + (("ltdc", "B6"), quote!(crate::ltdc::B6Pin)), + (("ltdc", "B7"), quote!(crate::ltdc::B7Pin)), (("usb", "DP"), quote!(crate::usb::DpPin)), (("usb", "DM"), quote!(crate::usb::DmPin)), (("otg", "DP"), quote!(crate::usb::DpPin)), @@ -1018,6 +1087,38 @@ fn main() { (("octospi", "NCS"), quote!(crate::ospi::NSSPin)), (("octospi", "CLK"), quote!(crate::ospi::SckPin)), (("octospi", "NCLK"), quote!(crate::ospi::NckPin)), + (("tsc", "G1_IO1"), quote!(crate::tsc::G1IO1Pin)), + (("tsc", "G1_IO2"), quote!(crate::tsc::G1IO2Pin)), + (("tsc", "G1_IO3"), quote!(crate::tsc::G1IO3Pin)), + (("tsc", "G1_IO4"), quote!(crate::tsc::G1IO4Pin)), + (("tsc", "G2_IO1"), quote!(crate::tsc::G2IO1Pin)), + (("tsc", "G2_IO2"), quote!(crate::tsc::G2IO2Pin)), + (("tsc", "G2_IO3"), quote!(crate::tsc::G2IO3Pin)), + (("tsc", "G2_IO4"), quote!(crate::tsc::G2IO4Pin)), + (("tsc", "G3_IO1"), quote!(crate::tsc::G3IO1Pin)), + (("tsc", "G3_IO2"), quote!(crate::tsc::G3IO2Pin)), + (("tsc", "G3_IO3"), quote!(crate::tsc::G3IO3Pin)), + (("tsc", "G3_IO4"), quote!(crate::tsc::G3IO4Pin)), + (("tsc", "G4_IO1"), quote!(crate::tsc::G4IO1Pin)), + (("tsc", "G4_IO2"), quote!(crate::tsc::G4IO2Pin)), + (("tsc", "G4_IO3"), quote!(crate::tsc::G4IO3Pin)), + (("tsc", "G4_IO4"), quote!(crate::tsc::G4IO4Pin)), + (("tsc", "G5_IO1"), quote!(crate::tsc::G5IO1Pin)), + (("tsc", "G5_IO2"), quote!(crate::tsc::G5IO2Pin)), + (("tsc", "G5_IO3"), quote!(crate::tsc::G5IO3Pin)), + (("tsc", "G5_IO4"), quote!(crate::tsc::G5IO4Pin)), + (("tsc", "G6_IO1"), quote!(crate::tsc::G6IO1Pin)), + (("tsc", "G6_IO2"), quote!(crate::tsc::G6IO2Pin)), + (("tsc", "G6_IO3"), quote!(crate::tsc::G6IO3Pin)), + (("tsc", "G6_IO4"), quote!(crate::tsc::G6IO4Pin)), + (("tsc", "G7_IO1"), quote!(crate::tsc::G7IO1Pin)), + (("tsc", "G7_IO2"), quote!(crate::tsc::G7IO2Pin)), + (("tsc", "G7_IO3"), quote!(crate::tsc::G7IO3Pin)), + (("tsc", "G7_IO4"), quote!(crate::tsc::G7IO4Pin)), + (("tsc", "G8_IO1"), quote!(crate::tsc::G8IO1Pin)), + (("tsc", "G8_IO2"), quote!(crate::tsc::G8IO2Pin)), + (("tsc", "G8_IO3"), quote!(crate::tsc::G8IO3Pin)), + (("tsc", "G8_IO4"), quote!(crate::tsc::G8IO4Pin)), ].into(); for p in METADATA.peripherals { @@ -1166,42 +1267,52 @@ fn main() { let mut dupe = HashSet::new(); for ch in p.dma_channels { - // Some chips have multiple request numbers for the same (peri, signal, channel) combos. - // Ignore the dupes, picking the first one. Otherwise this causes conflicting trait impls - let key = (ch.signal, ch.channel); - if !dupe.insert(key) { - continue; - } - if let Some(tr) = signals.get(&(regs.kind, ch.signal)) { let peri = format_ident!("{}", p.name); - let channel = if let Some(channel) = &ch.channel { + let channels = if let Some(channel) = &ch.channel { // Chip with DMA/BDMA, without DMAMUX - let channel = format_ident!("{}", channel); - quote!({channel: #channel}) + vec![*channel] } else if let Some(dmamux) = &ch.dmamux { // Chip with DMAMUX - let dmamux = format_ident!("{}", dmamux); - quote!({dmamux: #dmamux}) + METADATA + .dma_channels + .iter() + .filter(|ch| ch.dmamux == Some(*dmamux)) + .map(|ch| ch.name) + .collect() } else if let Some(dma) = &ch.dma { // Chip with GPDMA - let dma = format_ident!("{}", dma); - quote!({dma: #dma}) + METADATA + .dma_channels + .iter() + .filter(|ch| ch.dma == *dma) + .map(|ch| ch.name) + .collect() } else { unreachable!(); }; - let request = if let Some(request) = ch.request { - let request = request as u8; - quote!(#request) - } else { - quote!(()) - }; + for channel in channels { + // Some chips have multiple request numbers for the same (peri, signal, channel) combos. + // Ignore the dupes, picking the first one. Otherwise this causes conflicting trait impls + let key = (ch.signal, channel.to_string()); + if !dupe.insert(key) { + continue; + } - g.extend(quote! { - dma_trait_impl!(#tr, #peri, #channel, #request); - }); + let request = if let Some(request) = ch.request { + let request = request as u8; + quote!(#request) + } else { + quote!(()) + }; + + let channel = format_ident!("{}", channel); + g.extend(quote! { + dma_trait_impl!(#tr, #peri, #channel, #request); + }); + } } } } @@ -1322,17 +1433,7 @@ fn main() { let mut interrupts_table: Vec<Vec<String>> = Vec::new(); let mut peripherals_table: Vec<Vec<String>> = Vec::new(); let mut pins_table: Vec<Vec<String>> = Vec::new(); - let mut adc_common_table: Vec<Vec<String>> = Vec::new(); - - /* - If ADC3_COMMON exists, ADC3 and higher are assigned to it - All other ADCs are assigned to ADC_COMMON - - ADC3 and higher are assigned to the adc34 clock in the table - The adc3_common cfg directive is added if ADC3_COMMON exists - */ - let has_adc3 = METADATA.peripherals.iter().any(|p| p.name == "ADC3_COMMON"); - let set_adc345 = HashSet::from(["ADC3", "ADC4", "ADC5"]); + let mut adc_table: Vec<Vec<String>> = Vec::new(); for m in METADATA .memory @@ -1389,14 +1490,18 @@ fn main() { } if regs.kind == "adc" { - let (adc_common, adc_clock) = if set_adc345.contains(p.name) && has_adc3 { - ("ADC3_COMMON", "adc34") - } else { - ("ADC_COMMON", "adc") - }; - - let row = vec![p.name.to_string(), adc_common.to_string(), adc_clock.to_string()]; - adc_common_table.push(row); + let adc_num = p.name.strip_prefix("ADC").unwrap(); + let mut adc_common = None; + for p2 in METADATA.peripherals { + if let Some(common_nums) = p2.name.strip_prefix("ADC").and_then(|s| s.strip_suffix("_COMMON")) { + if common_nums.contains(adc_num) { + adc_common = Some(p2); + } + } + } + let adc_common = adc_common.map(|p| p.name).unwrap_or("none"); + let row = vec![p.name.to_string(), adc_common.to_string(), "adc".to_string()]; + adc_table.push(row); } for irq in p.interrupts { @@ -1442,6 +1547,7 @@ fn main() { "dma" => quote!(crate::dma::DmaInfo::Dma(crate::pac::#dma)), "bdma" => quote!(crate::dma::DmaInfo::Bdma(crate::pac::#dma)), "gpdma" => quote!(crate::pac::#dma), + "lpdma" => quote!(unsafe { crate::pac::gpdma::Gpdma::from_ptr(crate::pac::#dma.as_ptr())}), _ => panic!("bad dma channel kind {}", bi.kind), }; @@ -1449,9 +1555,6 @@ fn main() { Some(dmamux) => { let dmamux = format_ident!("{}", dmamux); let num = ch.dmamux_channel.unwrap() as usize; - - g.extend(quote!(dmamux_channel_impl!(#name, #dmamux);)); - quote! { dmamux: crate::dma::DmamuxInfo { mux: crate::pac::#dmamux, @@ -1536,17 +1639,19 @@ fn main() { make_table(&mut m, "foreach_interrupt", &interrupts_table); make_table(&mut m, "foreach_peripheral", &peripherals_table); make_table(&mut m, "foreach_pin", &pins_table); - make_table(&mut m, "foreach_adc", &adc_common_table); + make_table(&mut m, "foreach_adc", &adc_table); let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); let out_file = out_dir.join("_macros.rs").to_string_lossy().to_string(); - fs::write(out_file, m).unwrap(); + fs::write(&out_file, m).unwrap(); + rustfmt(&out_file); // ======== // Write generated.rs let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string(); - fs::write(out_file, g.to_string()).unwrap(); + fs::write(&out_file, g.to_string()).unwrap(); + rustfmt(&out_file); // ======== // Multicore @@ -1569,13 +1674,6 @@ fn main() { println!("cargo:rustc-cfg={}_{}", &chip_name[..chip_name.len() - 2], core); } - // ======= - // ADC3_COMMON is present - #[allow(clippy::print_literal)] - if has_adc3 { - println!("cargo:rustc-cfg={}", "adc3_common"); - } - // ======= // Features for targeting groups of chips @@ -1585,7 +1683,11 @@ fn main() { println!("cargo:rustc-cfg=package_{}", &chip_name[10..11]); println!("cargo:rustc-cfg=flashsize_{}", &chip_name[11..12]); } else { - println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4 + if &chip_name[..8] == "stm32h7r" || &chip_name[..8] == "stm32h7s" { + println!("cargo:rustc-cfg=stm32h7rs"); + } else { + println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4 + } println!("cargo:rustc-cfg={}", &chip_name[..9]); // stm32f429 println!("cargo:rustc-cfg={}x", &chip_name[..8]); // stm32f42x println!("cargo:rustc-cfg={}x{}", &chip_name[..7], &chip_name[8..9]); // stm32f4x9 @@ -1668,3 +1770,23 @@ fn get_flash_region_type_name(name: &str) -> String { .replace("REGION", "Region") .replace('_', "") } + +/// rustfmt a given path. +/// Failures are logged to stderr and ignored. +fn rustfmt(path: impl AsRef<Path>) { + let path = path.as_ref(); + match Command::new("rustfmt").args([path]).output() { + Err(e) => { + eprintln!("failed to exec rustfmt {:?}: {:?}", path, e); + } + Ok(out) => { + if !out.status.success() { + eprintln!("rustfmt {:?} failed:", path); + eprintln!("=== STDOUT:"); + std::io::stderr().write_all(&out.stdout).unwrap(); + eprintln!("=== STDERR:"); + std::io::stderr().write_all(&out.stderr).unwrap(); + } + } + } +} diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs index cecf67947..3822d5032 100644 --- a/embassy-stm32/src/adc/f1.rs +++ b/embassy-stm32/src/adc/f1.rs @@ -3,9 +3,9 @@ use core::marker::PhantomData; use core::task::Poll; use embassy_hal_internal::into_ref; -use embedded_hal_02::blocking::delay::DelayUs; -use crate::adc::{Adc, AdcPin, Instance, SampleTime}; +use super::blocking_delay_us; +use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; use crate::time::Hertz; use crate::{interrupt, Peripheral}; @@ -32,30 +32,30 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl } pub struct Vref; -impl<T: Instance> AdcPin<T> for Vref {} -impl<T: Instance> super::SealedAdcPin<T> for Vref { +impl<T: Instance> AdcChannel<T> for Vref {} +impl<T: Instance> super::SealedAdcChannel<T> for Vref { fn channel(&self) -> u8 { 17 } } pub struct Temperature; -impl<T: Instance> AdcPin<T> for Temperature {} -impl<T: Instance> super::SealedAdcPin<T> for Temperature { +impl<T: Instance> AdcChannel<T> for Temperature {} +impl<T: Instance> super::SealedAdcChannel<T> for Temperature { fn channel(&self) -> u8 { 16 } } impl<'d, T: Instance> Adc<'d, T> { - pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { + pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { into_ref!(adc); T::enable_and_reset(); T::regs().cr2().modify(|reg| reg.set_adon(true)); // 11.4: Before starting a calibration, the ADC must have been in power-on state (ADON bit = ‘1’) - // for at least two ADC clock cycles - delay.delay_us((1_000_000 * 2) / Self::freq().0 + 1); + // for at least two ADC clock cycles. + blocking_delay_us((1_000_000 * 2) / Self::freq().0 + 1); // Reset calibration T::regs().cr2().modify(|reg| reg.set_rstcal(true)); @@ -70,7 +70,7 @@ impl<'d, T: Instance> Adc<'d, T> { } // One cycle after calibration - delay.delay_us((1_000_000) / Self::freq().0 + 1); + blocking_delay_us((1_000_000 * 1) / Self::freq().0 + 1); Self { adc, @@ -95,7 +95,7 @@ impl<'d, T: Instance> Adc<'d, T> { } } - pub fn enable_vref(&self, _delay: &mut impl DelayUs<u32>) -> Vref { + pub fn enable_vref(&self) -> Vref { T::regs().cr2().modify(|reg| { reg.set_tsvrefe(true); }); @@ -135,8 +135,8 @@ impl<'d, T: Instance> Adc<'d, T> { T::regs().dr().read().0 as u16 } - pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { - Self::set_channel_sample_time(pin.channel(), self.sample_time); + pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { + Self::set_channel_sample_time(channel.channel(), self.sample_time); T::regs().cr1().modify(|reg| { reg.set_scan(false); reg.set_discen(false); @@ -151,7 +151,7 @@ impl<'d, T: Instance> Adc<'d, T> { }); // Configure the channel to sample - T::regs().sqr3().write(|reg| reg.set_sq(0, pin.channel())); + T::regs().sqr3().write(|reg| reg.set_sq(0, channel.channel())); self.convert().await } diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs index c5581dba1..3f076d64b 100644 --- a/embassy-stm32/src/adc/f3.rs +++ b/embassy-stm32/src/adc/f3.rs @@ -3,9 +3,9 @@ use core::marker::PhantomData; use core::task::Poll; use embassy_hal_internal::into_ref; -use embedded_hal_02::blocking::delay::DelayUs; -use crate::adc::{Adc, AdcPin, Instance, SampleTime}; +use super::blocking_delay_us; +use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; use crate::interrupt::typelevel::Interrupt; use crate::time::Hertz; use crate::{interrupt, Peripheral}; @@ -32,8 +32,8 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl } pub struct Vref; -impl<T: Instance> AdcPin<T> for Vref {} -impl<T: Instance> super::SealedAdcPin<T> for Vref { +impl<T: Instance> AdcChannel<T> for Vref {} +impl<T: Instance> super::SealedAdcChannel<T> for Vref { fn channel(&self) -> u8 { 18 } @@ -47,8 +47,8 @@ impl Vref { } pub struct Temperature; -impl<T: Instance> AdcPin<T> for Temperature {} -impl<T: Instance> super::SealedAdcPin<T> for Temperature { +impl<T: Instance> AdcChannel<T> for Temperature {} +impl<T: Instance> super::SealedAdcChannel<T> for Temperature { fn channel(&self) -> u8 { 16 } @@ -58,7 +58,6 @@ impl<'d, T: Instance> Adc<'d, T> { pub fn new( adc: impl Peripheral<P = T> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, - delay: &mut impl DelayUs<u32>, ) -> Self { use crate::pac::adc::vals; @@ -71,7 +70,7 @@ impl<'d, T: Instance> Adc<'d, T> { T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::ENABLED)); // Wait for the regulator to stabilize - delay.delay_us(10); + blocking_delay_us(10); assert!(!T::regs().cr().read().aden()); @@ -81,8 +80,8 @@ impl<'d, T: Instance> Adc<'d, T> { while T::regs().cr().read().adcal() {} - // Wait more than 4 clock cycles after adcal is cleared (RM0364 p. 223) - delay.delay_us(1 + (6 * 1_000_000 / Self::freq().0)); + // Wait more than 4 clock cycles after adcal is cleared (RM0364 p. 223). + blocking_delay_us((1_000_000 * 4) / Self::freq().0 + 1); // Enable the adc T::regs().cr().modify(|w| w.set_aden(true)); @@ -117,7 +116,7 @@ impl<'d, T: Instance> Adc<'d, T> { } } - pub fn enable_vref(&self, _delay: &mut impl DelayUs<u32>) -> Vref { + pub fn enable_vref(&self) -> Vref { T::common_regs().ccr().modify(|w| w.set_vrefen(true)); Vref {} @@ -155,11 +154,11 @@ impl<'d, T: Instance> Adc<'d, T> { T::regs().dr().read().rdata() } - pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { - Self::set_channel_sample_time(pin.channel(), self.sample_time); + pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { + Self::set_channel_sample_time(channel.channel(), self.sample_time); // Configure the channel to sample - T::regs().sqr1().write(|w| w.set_sq(0, pin.channel())); + T::regs().sqr1().write(|w| w.set_sq(0, channel.channel())); self.convert().await } diff --git a/embassy-stm32/src/adc/f3_v1_1.rs b/embassy-stm32/src/adc/f3_v1_1.rs index 672ace04f..106956989 100644 --- a/embassy-stm32/src/adc/f3_v1_1.rs +++ b/embassy-stm32/src/adc/f3_v1_1.rs @@ -7,7 +7,7 @@ use embassy_hal_internal::into_ref; use embassy_time::Instant; use super::Resolution; -use crate::adc::{Adc, AdcPin, Instance, SampleTime}; +use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; use crate::interrupt::typelevel::Interrupt; use crate::time::Hertz; use crate::{interrupt, Peripheral}; @@ -64,8 +64,8 @@ fn update_vref<T: Instance>(op: i8) { } pub struct Vref<T: Instance>(core::marker::PhantomData<T>); -impl<T: Instance> AdcPin<T> for Vref<T> {} -impl<T: Instance> super::SealedAdcPin<T> for Vref<T> { +impl<T: Instance> AdcChannel<T> for Vref<T> {} +impl<T: Instance> super::SealedAdcChannel<T> for Vref<T> { fn channel(&self) -> u8 { 17 } @@ -123,8 +123,8 @@ impl<T: Instance> Drop for Vref<T> { } pub struct Temperature<T: Instance>(core::marker::PhantomData<T>); -impl<T: Instance> AdcPin<T> for Temperature<T> {} -impl<T: Instance> super::SealedAdcPin<T> for Temperature<T> { +impl<T: Instance> AdcChannel<T> for Temperature<T> {} +impl<T: Instance> super::SealedAdcChannel<T> for Temperature<T> { fn channel(&self) -> u8 { 16 } @@ -271,8 +271,8 @@ impl<'d, T: Instance> Adc<'d, T> { } } - pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { - self.set_sample_sequence(&[pin.channel()]).await; + pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { + self.set_sample_sequence(&[channel.channel()]).await; self.convert().await } @@ -283,18 +283,18 @@ impl<'d, T: Instance> Adc<'d, T> { } } - pub async fn set_sample_time(&mut self, pin: &mut impl AdcPin<T>, sample_time: SampleTime) { - if Self::get_channel_sample_time(pin.channel()) != sample_time { + pub async fn set_sample_time(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) { + if Self::get_channel_sample_time(channel.channel()) != sample_time { self.stop_adc().await; unsafe { - Self::set_channel_sample_time(pin.channel(), sample_time); + Self::set_channel_sample_time(channel.channel(), sample_time); } self.start_adc().await; } } - pub fn get_sample_time(&self, pin: &impl AdcPin<T>) -> SampleTime { - Self::get_channel_sample_time(pin.channel()) + pub fn get_sample_time(&self, channel: &impl AdcChannel<T>) -> SampleTime { + Self::get_channel_sample_time(channel.channel()) } /// Sets the channel sample time diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs new file mode 100644 index 000000000..ce7f5db70 --- /dev/null +++ b/embassy-stm32/src/adc/g4.rs @@ -0,0 +1,295 @@ +#[allow(unused)] +use pac::adc::vals::{Adcaldif, Difsel, Exten}; +use pac::adccommon::vals::Presc; + +use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime}; +use crate::time::Hertz; +use crate::{pac, Peripheral}; + +/// Default VREF voltage used for sample conversion to millivolts. +pub const VREF_DEFAULT_MV: u32 = 3300; +/// VREF voltage used for factory calibration of VREFINTCAL register. +pub const VREF_CALIB_MV: u32 = 3300; + +/// Max single ADC operation clock frequency +#[cfg(stm32g4)] +const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(60); +#[cfg(stm32h7)] +const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(50); + +#[cfg(stm32g4)] +const VREF_CHANNEL: u8 = 18; +#[cfg(stm32g4)] +const TEMP_CHANNEL: u8 = 16; + +#[cfg(stm32h7)] +const VREF_CHANNEL: u8 = 19; +#[cfg(stm32h7)] +const TEMP_CHANNEL: u8 = 18; + +// TODO this should be 14 for H7a/b/35 +const VBAT_CHANNEL: u8 = 17; + +// NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs +/// Internal voltage reference channel. +pub struct VrefInt; +impl<T: Instance> AdcChannel<T> for VrefInt {} +impl<T: Instance> super::SealedAdcChannel<T> for VrefInt { + fn channel(&self) -> u8 { + VREF_CHANNEL + } +} + +/// Internal temperature channel. +pub struct Temperature; +impl<T: Instance> AdcChannel<T> for Temperature {} +impl<T: Instance> super::SealedAdcChannel<T> for Temperature { + fn channel(&self) -> u8 { + TEMP_CHANNEL + } +} + +/// Internal battery voltage channel. +pub struct Vbat; +impl<T: Instance> AdcChannel<T> for Vbat {} +impl<T: Instance> super::SealedAdcChannel<T> for Vbat { + fn channel(&self) -> u8 { + VBAT_CHANNEL + } +} + +// NOTE (unused): The prescaler enum closely copies the hardware capabilities, +// but high prescaling doesn't make a lot of sense in the current implementation and is ommited. +#[allow(unused)] +enum Prescaler { + NotDivided, + DividedBy2, + DividedBy4, + DividedBy6, + DividedBy8, + DividedBy10, + DividedBy12, + DividedBy16, + DividedBy32, + DividedBy64, + DividedBy128, + DividedBy256, +} + +impl Prescaler { + fn from_ker_ck(frequency: Hertz) -> Self { + let raw_prescaler = frequency.0 / MAX_ADC_CLK_FREQ.0; + match raw_prescaler { + 0 => Self::NotDivided, + 1 => Self::DividedBy2, + 2..=3 => Self::DividedBy4, + 4..=5 => Self::DividedBy6, + 6..=7 => Self::DividedBy8, + 8..=9 => Self::DividedBy10, + 10..=11 => Self::DividedBy12, + _ => unimplemented!(), + } + } + + fn divisor(&self) -> u32 { + match self { + Prescaler::NotDivided => 1, + Prescaler::DividedBy2 => 2, + Prescaler::DividedBy4 => 4, + Prescaler::DividedBy6 => 6, + Prescaler::DividedBy8 => 8, + Prescaler::DividedBy10 => 10, + Prescaler::DividedBy12 => 12, + Prescaler::DividedBy16 => 16, + Prescaler::DividedBy32 => 32, + Prescaler::DividedBy64 => 64, + Prescaler::DividedBy128 => 128, + Prescaler::DividedBy256 => 256, + } + } + + fn presc(&self) -> Presc { + match self { + Prescaler::NotDivided => Presc::DIV1, + Prescaler::DividedBy2 => Presc::DIV2, + Prescaler::DividedBy4 => Presc::DIV4, + Prescaler::DividedBy6 => Presc::DIV6, + Prescaler::DividedBy8 => Presc::DIV8, + Prescaler::DividedBy10 => Presc::DIV10, + Prescaler::DividedBy12 => Presc::DIV12, + Prescaler::DividedBy16 => Presc::DIV16, + Prescaler::DividedBy32 => Presc::DIV32, + Prescaler::DividedBy64 => Presc::DIV64, + Prescaler::DividedBy128 => Presc::DIV128, + Prescaler::DividedBy256 => Presc::DIV256, + } + } +} + +impl<'d, T: Instance> Adc<'d, T> { + /// Create a new ADC driver. + pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { + embassy_hal_internal::into_ref!(adc); + T::enable_and_reset(); + + let prescaler = Prescaler::from_ker_ck(T::frequency()); + + T::common_regs().ccr().modify(|w| w.set_presc(prescaler.presc())); + + let frequency = Hertz(T::frequency().0 / prescaler.divisor()); + info!("ADC frequency set to {} Hz", frequency.0); + + if frequency > MAX_ADC_CLK_FREQ { + panic!("Maximal allowed frequency for the ADC is {} MHz and it varies with different packages, refer to ST docs for more information.", MAX_ADC_CLK_FREQ.0 / 1_000_000 ); + } + + let mut s = Self { + adc, + sample_time: SampleTime::from_bits(0), + }; + s.power_up(); + s.configure_differential_inputs(); + + s.calibrate(); + blocking_delay_us(1); + + s.enable(); + s.configure(); + + s + } + + fn power_up(&mut self) { + T::regs().cr().modify(|reg| { + reg.set_deeppwd(false); + reg.set_advregen(true); + }); + + blocking_delay_us(10); + } + + fn configure_differential_inputs(&mut self) { + T::regs().difsel().modify(|w| { + for n in 0..18 { + w.set_difsel(n, Difsel::SINGLEENDED); + } + }); + } + + fn calibrate(&mut self) { + T::regs().cr().modify(|w| { + w.set_adcaldif(Adcaldif::SINGLEENDED); + }); + + T::regs().cr().modify(|w| w.set_adcal(true)); + + while T::regs().cr().read().adcal() {} + } + + fn enable(&mut self) { + T::regs().isr().write(|w| w.set_adrdy(true)); + T::regs().cr().modify(|w| w.set_aden(true)); + while !T::regs().isr().read().adrdy() {} + T::regs().isr().write(|w| w.set_adrdy(true)); + } + + fn configure(&mut self) { + // single conversion mode, software trigger + T::regs().cfgr().modify(|w| { + w.set_cont(false); + w.set_exten(Exten::DISABLED); + }); + } + + /// Enable reading the voltage reference internal channel. + pub fn enable_vrefint(&self) -> VrefInt { + T::common_regs().ccr().modify(|reg| { + reg.set_vrefen(true); + }); + + VrefInt {} + } + + /// Enable reading the temperature internal channel. + pub fn enable_temperature(&self) -> Temperature { + T::common_regs().ccr().modify(|reg| { + reg.set_vsenseen(true); + }); + + Temperature {} + } + + /// Enable reading the vbat internal channel. + pub fn enable_vbat(&self) -> Vbat { + T::common_regs().ccr().modify(|reg| { + reg.set_vbaten(true); + }); + + Vbat {} + } + + /// Set the ADC sample time. + pub fn set_sample_time(&mut self, sample_time: SampleTime) { + self.sample_time = sample_time; + } + + /// Set the ADC resolution. + pub fn set_resolution(&mut self, resolution: Resolution) { + T::regs().cfgr().modify(|reg| reg.set_res(resolution.into())); + } + + /// Perform a single conversion. + fn convert(&mut self) -> u16 { + T::regs().isr().modify(|reg| { + reg.set_eos(true); + reg.set_eoc(true); + }); + + // Start conversion + T::regs().cr().modify(|reg| { + reg.set_adstart(true); + }); + + while !T::regs().isr().read().eos() { + // spin + } + + T::regs().dr().read().0 as u16 + } + + /// Read an ADC pin. + pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { + channel.setup(); + + self.read_channel(channel.channel()) + } + + fn read_channel(&mut self, channel: u8) -> u16 { + // Configure channel + Self::set_channel_sample_time(channel, self.sample_time); + + #[cfg(stm32h7)] + { + T::regs().cfgr2().modify(|w| w.set_lshift(0)); + T::regs() + .pcsel() + .write(|w| w.set_pcsel(channel as _, Pcsel::PRESELECTED)); + } + + T::regs().sqr1().write(|reg| { + reg.set_sq(0, channel); + reg.set_l(0); + }); + + self.convert() + } + + fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { + let sample_time = sample_time.into(); + if ch <= 9 { + T::regs().smpr().modify(|reg| reg.set_smp(ch as _, sample_time)); + } else { + T::regs().smpr2().modify(|reg| reg.set_smp((ch - 10) as _, sample_time)); + } + } +} diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index ead2357ce..040ee9c53 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs @@ -10,10 +10,13 @@ #[cfg_attr(adc_v1, path = "v1.rs")] #[cfg_attr(adc_l0, path = "v1.rs")] #[cfg_attr(adc_v2, path = "v2.rs")] -#[cfg_attr(any(adc_v3, adc_g0, adc_h5), path = "v3.rs")] +#[cfg_attr(any(adc_v3, adc_g0, adc_h5, adc_u0), path = "v3.rs")] #[cfg_attr(adc_v4, path = "v4.rs")] +#[cfg_attr(adc_g4, path = "g4.rs")] mod _version; +use core::marker::PhantomData; + #[allow(unused)] #[cfg(not(adc_f3_v2))] pub use _version::*; @@ -51,43 +54,103 @@ trait SealedInstance { #[allow(unused)] fn regs() -> crate::pac::adc::Adc; #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))] + #[allow(unused)] fn common_regs() -> crate::pac::adccommon::AdcCommon; #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] fn state() -> &'static State; } -pub(crate) trait SealedAdcPin<T: Instance> { - #[cfg(any(adc_v1, adc_l0, adc_v2))] - fn set_as_analog(&mut self) {} +pub(crate) trait SealedAdcChannel<T> { + #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4))] + fn setup(&mut self) {} #[allow(unused)] fn channel(&self) -> u8; } -trait SealedInternalChannel<T> { - #[allow(unused)] - fn channel(&self) -> u8; +/// Performs a busy-wait delay for a specified number of microseconds. +#[allow(unused)] +pub(crate) fn blocking_delay_us(us: u32) { + #[cfg(time)] + embassy_time::block_for(embassy_time::Duration::from_micros(us)); + #[cfg(not(time))] + { + let freq = unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 as u64; + let us = us as u64; + let cycles = freq * us / 1_000_000; + cortex_m::asm::delay(cycles as u32); + } } /// ADC instance. -#[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5)))] +#[cfg(not(any( + adc_f1, + adc_v1, + adc_l0, + adc_v2, + adc_v3, + adc_v4, + adc_g4, + adc_f3, + adc_f3_v1_1, + adc_g0, + adc_u0, + adc_h5 +)))] #[allow(private_bounds)] pub trait Instance: SealedInstance + crate::Peripheral<P = Self> { type Interrupt: crate::interrupt::typelevel::Interrupt; } /// ADC instance. -#[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5))] +#[cfg(any( + adc_f1, + adc_v1, + adc_l0, + adc_v2, + adc_v3, + adc_v4, + adc_g4, + adc_f3, + adc_f3_v1_1, + adc_g0, + adc_u0, + adc_h5 +))] #[allow(private_bounds)] pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral { type Interrupt: crate::interrupt::typelevel::Interrupt; } -/// ADC pin. +/// ADC channel. #[allow(private_bounds)] -pub trait AdcPin<T: Instance>: SealedAdcPin<T> {} -/// ADC internal channel. -#[allow(private_bounds)] -pub trait InternalChannel<T>: SealedInternalChannel<T> {} +pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized { + #[allow(unused_mut)] + fn degrade_adc(mut self) -> AnyAdcChannel<T> { + #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4))] + self.setup(); + + AnyAdcChannel { + channel: self.channel(), + _phantom: PhantomData, + } + } +} + +/// A type-erased channel for a given ADC instance. +/// +/// This is useful in scenarios where you need the ADC channels to have the same type, such as +/// storing them in an array. +pub struct AnyAdcChannel<T> { + channel: u8, + _phantom: PhantomData<T>, +} + +impl<T: Instance> AdcChannel<T> for AnyAdcChannel<T> {} +impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> { + fn channel(&self) -> u8 { + self.channel + } +} foreach_adc!( ($inst:ident, $common_inst:ident, $clock:ident) => { @@ -116,11 +179,10 @@ foreach_adc!( macro_rules! impl_adc_pin { ($inst:ident, $pin:ident, $ch:expr) => { - impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {} - - impl crate::adc::SealedAdcPin<peripherals::$inst> for crate::peripherals::$pin { - #[cfg(any(adc_v1, adc_l0, adc_v2))] - fn set_as_analog(&mut self) { + impl crate::adc::AdcChannel<peripherals::$inst> for crate::peripherals::$pin {} + impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::peripherals::$pin { + #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4))] + fn setup(&mut self) { <Self as crate::gpio::SealedPin>::set_as_analog(self); } diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs index e9b46be80..090790c39 100644 --- a/embassy-stm32/src/adc/v1.rs +++ b/embassy-stm32/src/adc/v1.rs @@ -3,13 +3,13 @@ use core::marker::PhantomData; use core::task::Poll; use embassy_hal_internal::into_ref; -use embedded_hal_02::blocking::delay::DelayUs; #[cfg(adc_l0)] use stm32_metapac::adc::vals::Ckmode; -use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; +use super::blocking_delay_us; +use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; use crate::interrupt::typelevel::Interrupt; -use crate::peripherals::ADC; +use crate::peripherals::ADC1; use crate::{interrupt, Peripheral}; pub const VDDA_CALIB_MV: u32 = 3300; @@ -36,26 +36,26 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl pub struct Vbat; #[cfg(not(adc_l0))] -impl AdcPin<ADC> for Vbat {} +impl AdcChannel<ADC1> for Vbat {} #[cfg(not(adc_l0))] -impl super::SealedAdcPin<ADC> for Vbat { +impl super::SealedAdcChannel<ADC1> for Vbat { fn channel(&self) -> u8 { 18 } } pub struct Vref; -impl AdcPin<ADC> for Vref {} -impl super::SealedAdcPin<ADC> for Vref { +impl AdcChannel<ADC1> for Vref {} +impl super::SealedAdcChannel<ADC1> for Vref { fn channel(&self) -> u8 { 17 } } pub struct Temperature; -impl AdcPin<ADC> for Temperature {} -impl super::SealedAdcPin<ADC> for Temperature { +impl AdcChannel<ADC1> for Temperature {} +impl super::SealedAdcChannel<ADC1> for Temperature { fn channel(&self) -> u8 { 16 } @@ -65,7 +65,6 @@ impl<'d, T: Instance> Adc<'d, T> { pub fn new( adc: impl Peripheral<P = T> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, - delay: &mut impl DelayUs<u32>, ) -> Self { into_ref!(adc); T::enable_and_reset(); @@ -74,7 +73,7 @@ impl<'d, T: Instance> Adc<'d, T> { // // Table 57. ADC characteristics // tstab = 14 * 1/fadc - delay.delay_us(1); + blocking_delay_us(1); // set default PCKL/2 on L0s because HSI is disabled in the default clock config #[cfg(adc_l0)] @@ -114,7 +113,7 @@ impl<'d, T: Instance> Adc<'d, T> { } #[cfg(not(adc_l0))] - pub fn enable_vbat(&self, _delay: &mut impl DelayUs<u32>) -> Vbat { + pub fn enable_vbat(&self) -> Vbat { // SMP must be ≥ 56 ADC clock cycles when using HSI14. // // 6.3.20 Vbat monitoring characteristics @@ -123,22 +122,22 @@ impl<'d, T: Instance> Adc<'d, T> { Vbat } - pub fn enable_vref(&self, delay: &mut impl DelayUs<u32>) -> Vref { + pub fn enable_vref(&self) -> Vref { // Table 28. Embedded internal reference voltage // tstart = 10μs T::regs().ccr().modify(|reg| reg.set_vrefen(true)); - delay.delay_us(10); + blocking_delay_us(10); Vref } - pub fn enable_temperature(&self, delay: &mut impl DelayUs<u32>) -> Temperature { + pub fn enable_temperature(&self) -> Temperature { // SMP must be ≥ 56 ADC clock cycles when using HSI14. // // 6.3.19 Temperature sensor characteristics // tstart ≤ 10μs // ts_temp ≥ 4μs T::regs().ccr().modify(|reg| reg.set_tsen(true)); - delay.delay_us(10); + blocking_delay_us(10); Temperature } @@ -156,12 +155,12 @@ impl<'d, T: Instance> Adc<'d, T> { T::regs().cfgr2().modify(|reg| reg.set_ckmode(ckmode)); } - pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { - let channel = pin.channel(); - pin.set_as_analog(); + pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { + let ch_num = channel.channel(); + channel.setup(); // A.7.5 Single conversion sequence code example - Software trigger - T::regs().chselr().write(|reg| reg.set_chselx(channel as usize, true)); + T::regs().chselr().write(|reg| reg.set_chselx(ch_num as usize, true)); self.convert().await } diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs index a43eb72db..033108195 100644 --- a/embassy-stm32/src/adc/v2.rs +++ b/embassy-stm32/src/adc/v2.rs @@ -1,7 +1,7 @@ use embassy_hal_internal::into_ref; -use embedded_hal_02::blocking::delay::DelayUs; -use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; +use super::blocking_delay_us; +use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; use crate::peripherals::ADC1; use crate::time::Hertz; use crate::Peripheral; @@ -11,12 +11,9 @@ pub const VREF_DEFAULT_MV: u32 = 3300; /// VREF voltage used for factory calibration of VREFINTCAL register. pub const VREF_CALIB_MV: u32 = 3300; -/// ADC turn-on time -pub const ADC_POWERUP_TIME_US: u32 = 3; - pub struct VrefInt; -impl AdcPin<ADC1> for VrefInt {} -impl super::SealedAdcPin<ADC1> for VrefInt { +impl AdcChannel<ADC1> for VrefInt {} +impl super::SealedAdcChannel<ADC1> for VrefInt { fn channel(&self) -> u8 { 17 } @@ -30,8 +27,8 @@ impl VrefInt { } pub struct Temperature; -impl AdcPin<ADC1> for Temperature {} -impl super::SealedAdcPin<ADC1> for Temperature { +impl AdcChannel<ADC1> for Temperature {} +impl super::SealedAdcChannel<ADC1> for Temperature { fn channel(&self) -> u8 { cfg_if::cfg_if! { if #[cfg(any(stm32f2, stm32f40, stm32f41))] { @@ -51,8 +48,8 @@ impl Temperature { } pub struct Vbat; -impl AdcPin<ADC1> for Vbat {} -impl super::SealedAdcPin<ADC1> for Vbat { +impl AdcChannel<ADC1> for Vbat {} +impl super::SealedAdcChannel<ADC1> for Vbat { fn channel(&self) -> u8 { 18 } @@ -97,7 +94,7 @@ impl<'d, T> Adc<'d, T> where T: Instance, { - pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { + pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { into_ref!(adc); T::enable_and_reset(); @@ -107,7 +104,7 @@ where reg.set_adon(true); }); - delay.delay_us(ADC_POWERUP_TIME_US); + blocking_delay_us(3); Self { adc, @@ -178,11 +175,11 @@ where T::regs().dr().read().0 as u16 } - pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { - pin.set_as_analog(); + pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { + channel.setup(); // Configure ADC - let channel = pin.channel(); + let channel = channel.channel(); // Select channel T::regs().sqr3().write(|reg| reg.set_sq(0, channel)); diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index e25630be2..be857f4dd 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs @@ -1,8 +1,8 @@ use cfg_if::cfg_if; use embassy_hal_internal::into_ref; -use embedded_hal_02::blocking::delay::DelayUs; -use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; +use super::blocking_delay_us; +use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; use crate::Peripheral; /// Default VREF voltage used for sample conversion to millivolts. @@ -11,14 +11,16 @@ pub const VREF_DEFAULT_MV: u32 = 3300; pub const VREF_CALIB_MV: u32 = 3000; pub struct VrefInt; -impl<T: Instance> AdcPin<T> for VrefInt {} -impl<T: Instance> super::SealedAdcPin<T> for VrefInt { +impl<T: Instance> AdcChannel<T> for VrefInt {} +impl<T: Instance> super::SealedAdcChannel<T> for VrefInt { fn channel(&self) -> u8 { cfg_if! { if #[cfg(adc_g0)] { let val = 13; } else if #[cfg(adc_h5)] { let val = 17; + } else if #[cfg(adc_u0)] { + let val = 12; } else { let val = 0; } @@ -28,14 +30,16 @@ impl<T: Instance> super::SealedAdcPin<T> for VrefInt { } pub struct Temperature; -impl<T: Instance> AdcPin<T> for Temperature {} -impl<T: Instance> super::SealedAdcPin<T> for Temperature { +impl<T: Instance> AdcChannel<T> for Temperature {} +impl<T: Instance> super::SealedAdcChannel<T> for Temperature { fn channel(&self) -> u8 { cfg_if! { if #[cfg(adc_g0)] { let val = 12; } else if #[cfg(adc_h5)] { let val = 16; + } else if #[cfg(adc_u0)] { + let val = 11; } else { let val = 17; } @@ -45,14 +49,16 @@ impl<T: Instance> super::SealedAdcPin<T> for Temperature { } pub struct Vbat; -impl<T: Instance> AdcPin<T> for Vbat {} -impl<T: Instance> super::SealedAdcPin<T> for Vbat { +impl<T: Instance> AdcChannel<T> for Vbat {} +impl<T: Instance> super::SealedAdcChannel<T> for Vbat { fn channel(&self) -> u8 { cfg_if! { if #[cfg(adc_g0)] { let val = 14; } else if #[cfg(adc_h5)] { let val = 2; + } else if #[cfg(adc_h5)] { + let val = 13; } else { let val = 18; } @@ -64,8 +70,8 @@ impl<T: Instance> super::SealedAdcPin<T> for Vbat { cfg_if! { if #[cfg(adc_h5)] { pub struct VddCore; - impl<T: Instance> AdcPin<T> for VddCore {} - impl<T: Instance> super::SealedAdcPin<T> for VddCore { + impl<T: Instance> AdcChannel<T> for VddCore {} + impl<T: Instance> super::SealedAdcChannel<T> for VddCore { fn channel(&self) -> u8 { 6 } @@ -73,22 +79,34 @@ cfg_if! { } } +cfg_if! { + if #[cfg(adc_u0)] { + pub struct DacOut; + impl<T: Instance> AdcChannel<T> for DacOut {} + impl<T: Instance> super::SealedAdcChannel<T> for DacOut { + fn channel(&self) -> u8 { + 19 + } + } + } +} + impl<'d, T: Instance> Adc<'d, T> { - pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { + pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { into_ref!(adc); T::enable_and_reset(); T::regs().cr().modify(|reg| { - #[cfg(not(adc_g0))] + #[cfg(not(any(adc_g0, adc_u0)))] reg.set_deeppwd(false); reg.set_advregen(true); }); - #[cfg(adc_g0)] + #[cfg(any(adc_g0, adc_u0))] T::regs().cfgr1().modify(|reg| { reg.set_chselrmod(false); }); - delay.delay_us(20); + blocking_delay_us(20); T::regs().cr().modify(|reg| { reg.set_adcal(true); @@ -98,7 +116,7 @@ impl<'d, T: Instance> Adc<'d, T> { // spin } - delay.delay_us(1); + blocking_delay_us(1); Self { adc, @@ -106,28 +124,26 @@ impl<'d, T: Instance> Adc<'d, T> { } } - pub fn enable_vrefint(&self, delay: &mut impl DelayUs<u32>) -> VrefInt { - #[cfg(not(adc_g0))] + pub fn enable_vrefint(&self) -> VrefInt { + #[cfg(not(any(adc_g0, adc_u0)))] T::common_regs().ccr().modify(|reg| { reg.set_vrefen(true); }); - #[cfg(adc_g0)] + #[cfg(any(adc_g0, adc_u0))] T::regs().ccr().modify(|reg| { reg.set_vrefen(true); }); // "Table 24. Embedded internal voltage reference" states that it takes a maximum of 12 us - // to stabilize the internal voltage reference, we wait a little more. - // TODO: delay 15us - //cortex_m::asm::delay(20_000_000); - delay.delay_us(15); + // to stabilize the internal voltage reference. + blocking_delay_us(15); VrefInt {} } pub fn enable_temperature(&self) -> Temperature { cfg_if! { - if #[cfg(adc_g0)] { + if #[cfg(any(adc_g0, adc_u0))] { T::regs().ccr().modify(|reg| { reg.set_tsen(true); }); @@ -147,7 +163,7 @@ impl<'d, T: Instance> Adc<'d, T> { pub fn enable_vbat(&self) -> Vbat { cfg_if! { - if #[cfg(adc_g0)] { + if #[cfg(any(adc_g0, adc_u0))] { T::regs().ccr().modify(|reg| { reg.set_vbaten(true); }); @@ -170,9 +186,9 @@ impl<'d, T: Instance> Adc<'d, T> { } pub fn set_resolution(&mut self, resolution: Resolution) { - #[cfg(not(adc_g0))] + #[cfg(not(any(adc_g0, adc_u0)))] T::regs().cfgr().modify(|reg| reg.set_res(resolution.into())); - #[cfg(adc_g0)] + #[cfg(any(adc_g0, adc_u0))] T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into())); } @@ -204,7 +220,7 @@ impl<'d, T: Instance> Adc<'d, T> { T::regs().dr().read().0 as u16 } - pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { + pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { // Make sure bits are off while T::regs().cr().read().addis() { // spin @@ -225,18 +241,18 @@ impl<'d, T: Instance> Adc<'d, T> { // RM0492, RM0481, etc. // "This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected." #[cfg(adc_h5)] - if pin.channel() == 0 { + if channel.channel() == 0 { T::regs().or().modify(|reg| reg.set_op0(true)); } // Configure channel - Self::set_channel_sample_time(pin.channel(), self.sample_time); + Self::set_channel_sample_time(channel.channel(), self.sample_time); // Select channel - #[cfg(not(adc_g0))] - T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel())); - #[cfg(adc_g0)] - T::regs().chselr().write(|reg| reg.set_chsel(1 << pin.channel())); + #[cfg(not(any(adc_g0, adc_u0)))] + T::regs().sqr1().write(|reg| reg.set_sq(0, channel.channel())); + #[cfg(any(adc_g0, adc_u0))] + T::regs().chselr().write(|reg| reg.set_chsel(1 << channel.channel())); // Some models are affected by an erratum: // If we perform conversions slower than 1 kHz, the first read ADC value can be @@ -254,7 +270,7 @@ impl<'d, T: Instance> Adc<'d, T> { // RM0492, RM0481, etc. // "This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected." #[cfg(adc_h5)] - if pin.channel() == 0 { + if channel.channel() == 0 { T::regs().or().modify(|reg| reg.set_op0(false)); } @@ -263,7 +279,7 @@ impl<'d, T: Instance> Adc<'d, T> { fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) { cfg_if! { - if #[cfg(adc_g0)] { + if #[cfg(any(adc_g0, adc_u0))] { T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.into())); } else if #[cfg(adc_h5)] { match _ch { diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs index 1ae25bea2..f564114c2 100644 --- a/embassy-stm32/src/adc/v4.rs +++ b/embassy-stm32/src/adc/v4.rs @@ -1,9 +1,8 @@ -use embedded_hal_02::blocking::delay::DelayUs; #[allow(unused)] use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel}; use pac::adccommon::vals::Presc; -use super::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; +use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime}; use crate::time::Hertz; use crate::{pac, Peripheral}; @@ -34,8 +33,8 @@ const VBAT_CHANNEL: u8 = 17; // NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs /// Internal voltage reference channel. pub struct VrefInt; -impl<T: Instance> InternalChannel<T> for VrefInt {} -impl<T: Instance> super::SealedInternalChannel<T> for VrefInt { +impl<T: Instance> AdcChannel<T> for VrefInt {} +impl<T: Instance> super::SealedAdcChannel<T> for VrefInt { fn channel(&self) -> u8 { VREF_CHANNEL } @@ -43,8 +42,8 @@ impl<T: Instance> super::SealedInternalChannel<T> for VrefInt { /// Internal temperature channel. pub struct Temperature; -impl<T: Instance> InternalChannel<T> for Temperature {} -impl<T: Instance> super::SealedInternalChannel<T> for Temperature { +impl<T: Instance> AdcChannel<T> for Temperature {} +impl<T: Instance> super::SealedAdcChannel<T> for Temperature { fn channel(&self) -> u8 { TEMP_CHANNEL } @@ -52,8 +51,8 @@ impl<T: Instance> super::SealedInternalChannel<T> for Temperature { /// Internal battery voltage channel. pub struct Vbat; -impl<T: Instance> InternalChannel<T> for Vbat {} -impl<T: Instance> super::SealedInternalChannel<T> for Vbat { +impl<T: Instance> AdcChannel<T> for Vbat {} +impl<T: Instance> super::SealedAdcChannel<T> for Vbat { fn channel(&self) -> u8 { VBAT_CHANNEL } @@ -129,7 +128,7 @@ impl Prescaler { impl<'d, T: Instance> Adc<'d, T> { /// Create a new ADC driver. - pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self { + pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { embassy_hal_internal::into_ref!(adc); T::enable_and_reset(); @@ -161,11 +160,11 @@ impl<'d, T: Instance> Adc<'d, T> { adc, sample_time: SampleTime::from_bits(0), }; - s.power_up(delay); + s.power_up(); s.configure_differential_inputs(); s.calibrate(); - delay.delay_us(1); + blocking_delay_us(1); s.enable(); s.configure(); @@ -173,13 +172,13 @@ impl<'d, T: Instance> Adc<'d, T> { s } - fn power_up(&mut self, delay: &mut impl DelayUs<u16>) { + fn power_up(&mut self) { T::regs().cr().modify(|reg| { reg.set_deeppwd(false); reg.set_advregen(true); }); - delay.delay_us(10); + blocking_delay_us(10); } fn configure_differential_inputs(&mut self) { @@ -272,19 +271,10 @@ impl<'d, T: Instance> Adc<'d, T> { T::regs().dr().read().0 as u16 } - /// Read an ADC pin. - pub fn read<P>(&mut self, pin: &mut P) -> u16 - where - P: AdcPin<T>, - P: crate::gpio::Pin, - { - pin.set_as_analog(); + /// Read an ADC channel. + pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { + channel.setup(); - self.read_channel(pin.channel()) - } - - /// Read an ADC internal channel. - pub fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 { self.read_channel(channel.channel()) } diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs index 65fd0e9c2..0ac4cdab6 100644 --- a/embassy-stm32/src/can/bxcan/mod.rs +++ b/embassy-stm32/src/can/bxcan/mod.rs @@ -67,12 +67,23 @@ pub struct SceInterruptHandler<T: Instance> { impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterruptHandler<T> { unsafe fn on_interrupt() { - // info!("sce irq"); + info!("sce irq"); let msr = T::regs().msr(); let msr_val = msr.read(); - if msr_val.erri() { - msr.modify(|v| v.set_erri(true)); + if msr_val.slaki() { + msr.modify(|m| m.set_slaki(true)); + T::state().err_waker.wake(); + } else if msr_val.erri() { + info!("Error interrupt"); + // Disable the interrupt, but don't acknowledge the error, so that it can be + // forwarded off the the bus message consumer. If we don't provide some way for + // downstream code to determine that it has already provided this bus error instance + // to the bus message consumer, we are doomed to re-provide a single error instance for + // an indefinite amount of time. + let ier = T::regs().ier(); + ier.modify(|i| i.set_errie(false)); + T::state().err_waker.wake(); } } @@ -122,7 +133,7 @@ impl<T: Instance> CanConfig<'_, T> { self } - /// Enables or disables automatic retransmission of messages. + /// Enables or disables automatic retransmission of frames. /// /// If this is enabled, the CAN peripheral will automatically try to retransmit each frame /// until it can be sent. Otherwise, it will try only once to send each frame. @@ -180,6 +191,10 @@ impl<'d, T: Instance> Can<'d, T> { w.set_fmpie(0, true); w.set_fmpie(1, true); w.set_tmeie(true); + w.set_bofie(true); + w.set_epvie(true); + w.set_ewgie(true); + w.set_lecie(true); }); T::regs().mcr().write(|w| { @@ -239,6 +254,67 @@ impl<'d, T: Instance> Can<'d, T> { } } + /// Enables or disables the peripheral from automatically wakeup when a SOF is detected on the bus + /// while the peripheral is in sleep mode + pub fn set_automatic_wakeup(&mut self, enabled: bool) { + Registers(T::regs()).set_automatic_wakeup(enabled); + } + + /// Manually wake the peripheral from sleep mode. + /// + /// Waking the peripheral manually does not trigger a wake-up interrupt. + /// This will wait until the peripheral has acknowledged it has awoken from sleep mode + pub fn wakeup(&mut self) { + Registers(T::regs()).wakeup() + } + + /// Check if the peripheral is currently in sleep mode + pub fn is_sleeping(&self) -> bool { + T::regs().msr().read().slak() + } + + /// Put the peripheral in sleep mode + /// + /// When the peripherial is in sleep mode, messages can still be queued for transmission + /// and any previously received messages can be read from the receive FIFOs, however + /// no messages will be transmitted and no additional messages will be received. + /// + /// If the peripheral has automatic wakeup enabled, when a Start-of-Frame is detected + /// the peripheral will automatically wake and receive the incoming message. + pub async fn sleep(&mut self) { + T::regs().ier().modify(|i| i.set_slkie(true)); + T::regs().mcr().modify(|m| m.set_sleep(true)); + + poll_fn(|cx| { + T::state().err_waker.register(cx.waker()); + if self.is_sleeping() { + Poll::Ready(()) + } else { + Poll::Pending + } + }) + .await; + + T::regs().ier().modify(|i| i.set_slkie(false)); + } + + /// Enable FIFO scheduling of outgoing frames. + /// + /// If this is enabled, frames will be transmitted in the order that they are passed to + /// [`write()`][Self::write] or [`try_write()`][Self::try_write()]. + /// + /// If this is disabled, frames are transmitted in order of priority. + /// + /// FIFO scheduling is disabled by default. + pub fn set_tx_fifo_scheduling(&mut self, enabled: bool) { + Registers(T::regs()).set_tx_fifo_scheduling(enabled) + } + + /// Checks if FIFO scheduling of outgoing frames is enabled. + pub fn tx_fifo_scheduling_enabled(&self) -> bool { + Registers(T::regs()).tx_fifo_scheduling_enabled() + } + /// Queues the message to be sent. /// /// If the TX queue is full, this will wait until there is space, therefore exerting backpressure. @@ -248,7 +324,13 @@ impl<'d, T: Instance> Can<'d, T> { /// Attempts to transmit a frame without blocking. /// - /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. + /// Returns [Err(TryWriteError::Full)] if the frame can not be queued for transmission now. + /// + /// If FIFO scheduling is enabled, any empty mailbox will be used. + /// + /// Otherwise, the frame will only be accepted if there is no frame with the same priority already queued. + /// This is done to work around a hardware limitation that could lead to out-of-order delivery + /// of frames with the same priority. pub fn try_write(&mut self, frame: &Frame) -> Result<TransmitStatus, TryWriteError> { self.split().0.try_write(frame) } @@ -259,6 +341,11 @@ impl<'d, T: Instance> Can<'d, T> { } /// Waits until any of the transmit mailboxes become empty + /// + /// Note that [`Self::try_write()`] may fail with [`TryWriteError::Full`], + /// even after the future returned by this function completes. + /// This will happen if FIFO scheduling of outgoing frames is not enabled, + /// and a frame with equal priority is already queued for transmission. pub async fn flush_any(&self) { CanTx::<T>::flush_any_inner().await } @@ -406,7 +493,13 @@ impl<'d, T: Instance> CanTx<'d, T> { /// Attempts to transmit a frame without blocking. /// - /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. + /// Returns [Err(TryWriteError::Full)] if the frame can not be queued for transmission now. + /// + /// If FIFO scheduling is enabled, any empty mailbox will be used. + /// + /// Otherwise, the frame will only be accepted if there is no frame with the same priority already queued. + /// This is done to work around a hardware limitation that could lead to out-of-order delivery + /// of frames with the same priority. pub fn try_write(&mut self, frame: &Frame) -> Result<TransmitStatus, TryWriteError> { Registers(T::regs()).transmit(frame).map_err(|_| TryWriteError::Full) } @@ -446,6 +539,11 @@ impl<'d, T: Instance> CanTx<'d, T> { } /// Waits until any of the transmit mailboxes become empty + /// + /// Note that [`Self::try_write()`] may fail with [`TryWriteError::Full`], + /// even after the future returned by this function completes. + /// This will happen if FIFO scheduling of outgoing frames is not enabled, + /// and a frame with equal priority is already queued for transmission. pub async fn flush_any(&self) { Self::flush_any_inner().await } diff --git a/embassy-stm32/src/can/bxcan/registers.rs b/embassy-stm32/src/can/bxcan/registers.rs index 732567797..ad27e0744 100644 --- a/embassy-stm32/src/can/bxcan/registers.rs +++ b/embassy-stm32/src/can/bxcan/registers.rs @@ -145,7 +145,21 @@ impl Registers { } pub fn curr_error(&self) -> Option<BusError> { - let err = { self.0.esr().read() }; + if !self.0.msr().read().erri() { + // This ensures that once a single error instance has + // been acknowledged and forwared to the bus message consumer + // we don't continue to re-forward the same error occurrance for an + // in-definite amount of time. + return None; + } + + // Since we have not already acknowledge the error, and the interrupt was + // disabled in the ISR, we will acknowledge the current error and re-enable the interrupt + // so futher errors are captured + self.0.msr().modify(|m| m.set_erri(true)); + self.0.ier().modify(|i| i.set_errie(true)); + + let err = self.0.esr().read(); if err.boff() { return Some(BusError::BusOff); } else if err.epvf() { @@ -167,46 +181,85 @@ impl Registers { None } + /// Enables or disables FIFO scheduling of outgoing mailboxes. + /// + /// If this is enabled, mailboxes are scheduled based on the time when the transmit request bit of the mailbox was set. + /// + /// If this is disabled, mailboxes are scheduled based on the priority of the frame in the mailbox. + pub fn set_tx_fifo_scheduling(&mut self, enabled: bool) { + self.0.mcr().modify(|w| w.set_txfp(enabled)) + } + + /// Checks if FIFO scheduling of outgoing mailboxes is enabled. + pub fn tx_fifo_scheduling_enabled(&self) -> bool { + self.0.mcr().read().txfp() + } + /// Puts a CAN frame in a transmit mailbox for transmission on the bus. /// - /// Frames are transmitted to the bus based on their priority (see [`FramePriority`]). - /// Transmit order is preserved for frames with identical priority. + /// The behavior of this function depends on wheter or not FIFO scheduling is enabled. + /// See [`Self::set_tx_fifo_scheduling()`] and [`Self::tx_fifo_scheduling_enabled()`]. + /// + /// # Priority based scheduling + /// + /// If FIFO scheduling is disabled, frames are transmitted to the bus based on their + /// priority (see [`FramePriority`]). Transmit order is preserved for frames with identical + /// priority. /// /// If all transmit mailboxes are full, and `frame` has a higher priority than the /// lowest-priority message in the transmit mailboxes, transmission of the enqueued frame is /// cancelled and `frame` is enqueued instead. The frame that was replaced is returned as /// [`TransmitStatus::dequeued_frame`]. + /// + /// # FIFO scheduling + /// + /// If FIFO scheduling is enabled, frames are transmitted in the order that they are passed to this function. + /// + /// If all transmit mailboxes are full, this function returns [`nb::Error::WouldBlock`]. pub fn transmit(&mut self, frame: &Frame) -> nb::Result<TransmitStatus, Infallible> { + // Check if FIFO scheduling is enabled. + let fifo_scheduling = self.0.mcr().read().txfp(); + // Get the index of the next free mailbox or the one with the lowest priority. let tsr = self.0.tsr().read(); let idx = tsr.code() as usize; let frame_is_pending = !tsr.tme(0) || !tsr.tme(1) || !tsr.tme(2); - let pending_frame = if frame_is_pending { - // High priority frames are transmitted first by the mailbox system. - // Frames with identical identifier shall be transmitted in FIFO order. - // The controller schedules pending frames of same priority based on the - // mailbox index instead. As a workaround check all pending mailboxes - // and only accept higher priority frames. + let all_frames_are_pending = !tsr.tme(0) && !tsr.tme(1) && !tsr.tme(2); + + let pending_frame; + if fifo_scheduling && all_frames_are_pending { + // FIFO scheduling is enabled and all mailboxes are full. + // We will not drop a lower priority frame, we just report WouldBlock. + return Err(nb::Error::WouldBlock); + } else if !fifo_scheduling && frame_is_pending { + // Priority scheduling is enabled and alteast one mailbox is full. + // + // In this mode, the peripheral transmits high priority frames first. + // Frames with identical priority should be transmitted in FIFO order, + // but the controller schedules pending frames of same priority based on the + // mailbox index. As a workaround check all pending mailboxes and only accept + // frames with a different priority. self.check_priority(0, frame.id().into())?; self.check_priority(1, frame.id().into())?; self.check_priority(2, frame.id().into())?; - let all_frames_are_pending = !tsr.tme(0) && !tsr.tme(1) && !tsr.tme(2); if all_frames_are_pending { // No free mailbox is available. This can only happen when three frames with // ascending priority (descending IDs) were requested for transmission and all // of them are blocked by bus traffic with even higher priority. // To prevent a priority inversion abort and replace the lowest priority frame. - self.read_pending_mailbox(idx) + pending_frame = self.read_pending_mailbox(idx); } else { // There was a free mailbox. - None + pending_frame = None; } } else { - // All mailboxes are available: Send frame without performing any checks. - None - }; + // Either we have FIFO scheduling and at-least one free mailbox, + // or we have priority scheduling and all mailboxes are free. + // No further checks are needed. + pending_frame = None + } self.write_mailbox(idx, frame); @@ -223,18 +276,16 @@ impl Registers { } /// Returns `Ok` when the mailbox is free or if it contains pending frame with a - /// lower priority (higher ID) than the identifier `id`. + /// different priority from the identifier `id`. fn check_priority(&self, idx: usize, id: IdReg) -> nb::Result<(), Infallible> { // Read the pending frame's id to check its priority. assert!(idx < 3); let tir = &self.0.tx(idx).tir().read(); - //let tir = &can.tx[idx].tir.read(); // Check the priority by comparing the identifiers. But first make sure the // frame has not finished the transmission (`TXRQ` == 0) in the meantime. - if tir.txrq() && id <= IdReg::from_register(tir.0) { - // There's a mailbox whose priority is higher or equal - // the priority of the new frame. + if tir.txrq() && id == IdReg::from_register(tir.0) { + // There's a mailbox whose priority is equal to the priority of the new frame. return Err(nb::Error::WouldBlock); } diff --git a/embassy-stm32/src/can/enums.rs b/embassy-stm32/src/can/enums.rs index 4d89c84d1..a5cca424d 100644 --- a/embassy-stm32/src/can/enums.rs +++ b/embassy-stm32/src/can/enums.rs @@ -29,6 +29,24 @@ pub enum BusError { BusWarning, } +/// Bus error modes. +/// +/// Contrary to the `BusError` enum which also includes last-seen acute protocol +/// errors, this enum includes only the mutually exclusive bus error modes. +#[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum BusErrorMode { + /// Error active mode (default). Controller will transmit an active error + /// frame upon protocol error. + ErrorActive, + /// Error passive mode. An error counter exceeded 127. Controller will + /// transmit a passive error frame upon protocol error. + ErrorPassive, + /// Bus off mode. The transmit error counter exceeded 255. Controller is not + /// participating in bus traffic. + BusOff, +} + /// Frame Create Errors #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] diff --git a/embassy-stm32/src/can/fd/peripheral.rs b/embassy-stm32/src/can/fd/peripheral.rs index e32f19d91..9cd5f0785 100644 --- a/embassy-stm32/src/can/fd/peripheral.rs +++ b/embassy-stm32/src/can/fd/peripheral.rs @@ -30,10 +30,10 @@ impl Registers { &mut self.msg_ram_mut().transmit.tbsa[bufidx] } pub fn msg_ram_mut(&self) -> &mut RegisterBlock { - #[cfg(stm32h7)] + #[cfg(can_fdcan_h7)] let ptr = self.msgram.ram(self.msg_ram_offset / 4).as_ptr() as *mut RegisterBlock; - #[cfg(not(stm32h7))] + #[cfg(not(can_fdcan_h7))] let ptr = self.msgram.as_ptr() as *mut RegisterBlock; unsafe { &mut (*ptr) } @@ -105,7 +105,7 @@ impl Registers { return Some(BusError::BusWarning); } else { cfg_if! { - if #[cfg(stm32h7)] { + if #[cfg(can_fdcan_h7)] { let lec = err.lec(); } else { let lec = err.lec().to_bits(); @@ -334,14 +334,14 @@ impl Registers { // set extended filters list size to 8 // REQUIRED: we use the memory map as if these settings are set // instead of re-calculating them. - #[cfg(not(stm32h7))] + #[cfg(not(can_fdcan_h7))] { self.regs.rxgfc().modify(|w| { w.set_lss(crate::can::fd::message_ram::STANDARD_FILTER_MAX); w.set_lse(crate::can::fd::message_ram::EXTENDED_FILTER_MAX); }); } - #[cfg(stm32h7)] + #[cfg(can_fdcan_h7)] { self.regs .sidfc() @@ -354,11 +354,11 @@ impl Registers { self.configure_msg_ram(); // Enable timestamping - #[cfg(not(stm32h7))] + #[cfg(not(can_fdcan_h7))] self.regs .tscc() .write(|w| w.set_tss(stm32_metapac::can::vals::Tss::INCREMENT)); - #[cfg(stm32h7)] + #[cfg(can_fdcan_h7)] self.regs.tscc().write(|w| w.set_tss(0x01)); // this isn't really documented in the reference manual @@ -368,6 +368,7 @@ impl Registers { w.set_rfne(0, true); // Rx Fifo 0 New Msg w.set_rfne(1, true); // Rx Fifo 1 New Msg w.set_tce(true); // Tx Complete + w.set_boe(true); // Bus-Off Status Changed }); self.regs.ile().modify(|w| { w.set_eint0(true); // Interrupt Line 0 @@ -490,9 +491,9 @@ impl Registers { self.regs.cccr().modify(|w| { w.set_fdoe(fdoe); - #[cfg(stm32h7)] + #[cfg(can_fdcan_h7)] w.set_bse(brse); - #[cfg(not(stm32h7))] + #[cfg(not(can_fdcan_h7))] w.set_brse(brse); }); } @@ -507,14 +508,14 @@ impl Registers { #[inline] #[allow(unused)] pub fn set_timestamp_counter_source(&mut self, select: TimestampSource) { - #[cfg(stm32h7)] + #[cfg(can_fdcan_h7)] let (tcp, tss) = match select { TimestampSource::None => (0, 0), TimestampSource::Prescaler(p) => (p as u8, 1), TimestampSource::FromTIM3 => (0, 2), }; - #[cfg(not(stm32h7))] + #[cfg(not(can_fdcan_h7))] let (tcp, tss) = match select { TimestampSource::None => (0, stm32_metapac::can::vals::Tss::ZERO), TimestampSource::Prescaler(p) => (p as u8, stm32_metapac::can::vals::Tss::INCREMENT), @@ -527,7 +528,7 @@ impl Registers { }); } - #[cfg(not(stm32h7))] + #[cfg(not(can_fdcan_h7))] /// Configures the global filter settings #[inline] pub fn set_global_filter(&mut self, filter: GlobalFilter) { @@ -550,7 +551,7 @@ impl Registers { }); } - #[cfg(stm32h7)] + #[cfg(can_fdcan_h7)] /// Configures the global filter settings #[inline] pub fn set_global_filter(&mut self, filter: GlobalFilter) { @@ -574,10 +575,10 @@ impl Registers { }); } - #[cfg(not(stm32h7))] + #[cfg(not(can_fdcan_h7))] fn configure_msg_ram(&mut self) {} - #[cfg(stm32h7)] + #[cfg(can_fdcan_h7)] fn configure_msg_ram(&mut self) { let r = self.regs; diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index e31821ca2..81ceb06aa 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs @@ -44,53 +44,51 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup let ir = regs.ir().read(); - { - if ir.tc() { - regs.ir().write(|w| w.set_tc(true)); - } - if ir.tefn() { - regs.ir().write(|w| w.set_tefn(true)); - } - - match &T::state().tx_mode { - TxMode::NonBuffered(waker) => waker.wake(), - TxMode::ClassicBuffered(buf) => { - if !T::registers().tx_queue_is_full() { - match buf.tx_receiver.try_receive() { - Ok(frame) => { - _ = T::registers().write(&frame); - } - Err(_) => {} - } - } - } - TxMode::FdBuffered(buf) => { - if !T::registers().tx_queue_is_full() { - match buf.tx_receiver.try_receive() { - Ok(frame) => { - _ = T::registers().write(&frame); - } - Err(_) => {} - } - } - } - } + if ir.tc() { + regs.ir().write(|w| w.set_tc(true)); + } + if ir.tefn() { + regs.ir().write(|w| w.set_tefn(true)); } - if ir.ped() || ir.pea() { - regs.ir().write(|w| { - w.set_ped(true); - w.set_pea(true); - }); + match &T::state().tx_mode { + TxMode::NonBuffered(waker) => waker.wake(), + TxMode::ClassicBuffered(buf) => { + if !T::registers().tx_queue_is_full() { + match buf.tx_receiver.try_receive() { + Ok(frame) => { + _ = T::registers().write(&frame); + } + Err(_) => {} + } + } + } + TxMode::FdBuffered(buf) => { + if !T::registers().tx_queue_is_full() { + match buf.tx_receiver.try_receive() { + Ok(frame) => { + _ = T::registers().write(&frame); + } + Err(_) => {} + } + } + } } if ir.rfn(0) { T::state().rx_mode.on_interrupt::<T>(0); } - if ir.rfn(1) { T::state().rx_mode.on_interrupt::<T>(1); } + + if ir.bo() { + regs.ir().write(|w| w.set_bo(true)); + if regs.psr().read().bo() { + // Initiate bus-off recovery sequence by resetting CCCR.INIT + regs.cccr().modify(|w| w.set_init(false)); + } + } } } @@ -148,6 +146,7 @@ pub struct CanConfigurator<'d, T: Instance> { config: crate::can::fd::config::FdCanConfig, /// Reference to internals. instance: FdcanInstance<'d, T>, + properties: Properties<T>, } fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransmissionConfig) -> u64 { @@ -201,9 +200,15 @@ impl<'d, T: Instance> CanConfigurator<'d, T> { Self { config, instance: FdcanInstance(peri), + properties: Properties::new(), } } + /// Get driver properties + pub fn properties(&self) -> &Properties<T> { + &self.properties + } + /// Get configuration pub fn config(&self) -> crate::can::fd::config::FdCanConfig { return self.config; @@ -242,32 +247,6 @@ impl<'d, T: Instance> CanConfigurator<'d, T> { self.config = self.config.set_data_bit_timing(nbtr); } - /// Set an Standard Address CAN filter into slot 'id' - #[inline] - pub fn set_standard_filter(&mut self, slot: StandardFilterSlot, filter: StandardFilter) { - T::registers().msg_ram_mut().filters.flssa[slot as usize].activate(filter); - } - - /// Set an array of Standard Address CAN filters and overwrite the current set - pub fn set_standard_filters(&mut self, filters: &[StandardFilter; STANDARD_FILTER_MAX as usize]) { - for (i, f) in filters.iter().enumerate() { - T::registers().msg_ram_mut().filters.flssa[i].activate(*f); - } - } - - /// Set an Extended Address CAN filter into slot 'id' - #[inline] - pub fn set_extended_filter(&mut self, slot: ExtendedFilterSlot, filter: ExtendedFilter) { - T::registers().msg_ram_mut().filters.flesa[slot as usize].activate(filter); - } - - /// Set an array of Extended Address CAN filters and overwrite the current set - pub fn set_extended_filters(&mut self, filters: &[ExtendedFilter; EXTENDED_FILTER_MAX as usize]) { - for (i, f) in filters.iter().enumerate() { - T::registers().msg_ram_mut().filters.flesa[i].activate(*f); - } - } - /// Start in mode. pub fn start(self, mode: OperatingMode) -> Can<'d, T> { let ns_per_timer_tick = calc_ns_per_timer_tick::<T>(self.config.frame_transmit); @@ -279,6 +258,7 @@ impl<'d, T: Instance> CanConfigurator<'d, T> { config: self.config, instance: self.instance, _mode: mode, + properties: self.properties, }; ret } @@ -305,9 +285,15 @@ pub struct Can<'d, T: Instance> { /// Reference to internals. instance: FdcanInstance<'d, T>, _mode: OperatingMode, + properties: Properties<T>, } impl<'d, T: Instance> Can<'d, T> { + /// Get driver properties + pub fn properties(&self) -> &Properties<T> { + &self.properties + } + /// Flush one of the TX mailboxes. pub async fn flush(&self, idx: usize) { poll_fn(|cx| { @@ -352,8 +338,8 @@ impl<'d, T: Instance> Can<'d, T> { T::state().rx_mode.read_fd::<T>().await } - /// Split instance into separate Tx(write) and Rx(read) portions - pub fn split(self) -> (CanTx<'d, T>, CanRx<'d, T>) { + /// Split instance into separate portions: Tx(write), Rx(read), common properties + pub fn split(self) -> (CanTx<'d, T>, CanRx<'d, T>, Properties<T>) { ( CanTx { config: self.config, @@ -365,6 +351,7 @@ impl<'d, T: Instance> Can<'d, T> { _instance2: T::regs(), _mode: self._mode, }, + self.properties, ) } @@ -375,6 +362,7 @@ impl<'d, T: Instance> Can<'d, T> { //_instance2: T::regs(), instance: tx._instance, _mode: rx._mode, + properties: Properties::new(), } } @@ -410,6 +398,7 @@ pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_S _mode: OperatingMode, tx_buf: &'static TxBuf<TX_BUF_SIZE>, rx_buf: &'static RxBuf<RX_BUF_SIZE>, + properties: Properties<T>, } impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> @@ -428,10 +417,16 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> _mode, tx_buf, rx_buf, + properties: Properties::new(), } .setup() } + /// Get driver properties + pub fn properties(&self) -> &Properties<T> { + &self.properties + } + fn setup(self) -> Self { // We don't want interrupts being processed while we change modes. critical_section::with(|_| unsafe { @@ -496,6 +491,7 @@ pub struct BufferedCanFd<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF _mode: OperatingMode, tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, + properties: Properties<T>, } /// Sender that can be used for sending CAN frames. @@ -544,10 +540,16 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> _mode, tx_buf, rx_buf, + properties: Properties::new(), } .setup() } + /// Get driver properties + pub fn properties(&self) -> &Properties<T> { + &self.properties + } + fn setup(self) -> Self { // We don't want interrupts being processed while we change modes. critical_section::with(|_| unsafe { @@ -806,6 +808,71 @@ impl TxMode { } } +/// Common driver properties, including filters and error counters +pub struct Properties<T> { + // phantom pointer to ensure !Sync + instance: PhantomData<*const T>, +} + +impl<T: Instance> Properties<T> { + fn new() -> Self { + Self { + instance: Default::default(), + } + } + + /// Set a standard address CAN filter in the specified slot in FDCAN memory. + #[inline] + pub fn set_standard_filter(&self, slot: StandardFilterSlot, filter: StandardFilter) { + T::registers().msg_ram_mut().filters.flssa[slot as usize].activate(filter); + } + + /// Set the full array of standard address CAN filters in FDCAN memory. + /// Overwrites all standard address filters in memory. + pub fn set_standard_filters(&self, filters: &[StandardFilter; STANDARD_FILTER_MAX as usize]) { + for (i, f) in filters.iter().enumerate() { + T::registers().msg_ram_mut().filters.flssa[i].activate(*f); + } + } + + /// Set an extended address CAN filter in the specified slot in FDCAN memory. + #[inline] + pub fn set_extended_filter(&self, slot: ExtendedFilterSlot, filter: ExtendedFilter) { + T::registers().msg_ram_mut().filters.flesa[slot as usize].activate(filter); + } + + /// Set the full array of extended address CAN filters in FDCAN memory. + /// Overwrites all extended address filters in memory. + pub fn set_extended_filters(&self, filters: &[ExtendedFilter; EXTENDED_FILTER_MAX as usize]) { + for (i, f) in filters.iter().enumerate() { + T::registers().msg_ram_mut().filters.flesa[i].activate(*f); + } + } + + /// Get the CAN RX error counter + pub fn rx_error_count(&self) -> u8 { + T::regs().ecr().read().rec() + } + + /// Get the CAN TX error counter + pub fn tx_error_count(&self) -> u8 { + T::regs().ecr().read().tec() + } + + /// Get the current bus error mode + pub fn bus_error_mode(&self) -> BusErrorMode { + // This read will clear LEC and DLEC. This is not ideal, but protocol + // error reporting in this driver should have a big ol' FIXME on it + // anyway! + let psr = T::regs().psr().read(); + match (psr.bo(), psr.ep()) { + (false, false) => BusErrorMode::ErrorActive, + (false, true) => BusErrorMode::ErrorPassive, + (true, _) => BusErrorMode::BusOff, + } + } +} + struct State { pub rx_mode: RxMode, pub tx_mode: TxMode, @@ -908,7 +975,7 @@ macro_rules! impl_fdcan { }; } -#[cfg(not(stm32h7))] +#[cfg(not(can_fdcan_h7))] foreach_peripheral!( (can, FDCAN) => { impl_fdcan!(FDCAN, FDCANRAM); }; (can, FDCAN1) => { impl_fdcan!(FDCAN1, FDCANRAM1); }; @@ -916,7 +983,7 @@ foreach_peripheral!( (can, FDCAN3) => { impl_fdcan!(FDCAN3, FDCANRAM3); }; ); -#[cfg(stm32h7)] +#[cfg(can_fdcan_h7)] foreach_peripheral!( (can, FDCAN1) => { impl_fdcan!(FDCAN1, FDCANRAM, 0x0000); }; (can, FDCAN2) => { impl_fdcan!(FDCAN2, FDCANRAM, 0x0C00); }; diff --git a/embassy-stm32/src/cordic/mod.rs b/embassy-stm32/src/cordic/mod.rs index 9ac10e714..29b11735e 100644 --- a/embassy-stm32/src/cordic/mod.rs +++ b/embassy-stm32/src/cordic/mod.rs @@ -47,6 +47,7 @@ trait SealedInstance { } /// Enable global interrupt + #[allow(unused)] fn enable_irq(&self) { Self::regs().csr().modify(|v| v.set_ien(true)) } diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs index f8909d438..e8e0270af 100644 --- a/embassy-stm32/src/crc/v1.rs +++ b/embassy-stm32/src/crc/v1.rs @@ -32,6 +32,9 @@ impl<'d> Crc<'d> { /// Feeds a word to the peripheral and returns the current CRC value pub fn feed_word(&mut self, word: u32) -> u32 { // write a single byte to the device, and return the result + #[cfg(not(crc_v1))] + PAC_CRC.dr32().write_value(word); + #[cfg(crc_v1)] PAC_CRC.dr().write_value(word); self.read() } @@ -39,6 +42,9 @@ impl<'d> Crc<'d> { /// Feed a slice of words to the peripheral and return the result. pub fn feed_words(&mut self, words: &[u32]) -> u32 { for word in words { + #[cfg(not(crc_v1))] + PAC_CRC.dr32().write_value(*word); + #[cfg(crc_v1)] PAC_CRC.dr().write_value(*word); } @@ -46,6 +52,12 @@ impl<'d> Crc<'d> { } /// Read the CRC result value. + #[cfg(not(crc_v1))] + pub fn read(&self) -> u32 { + PAC_CRC.dr32().read() + } + /// Read the CRC result value. + #[cfg(crc_v1)] pub fn read(&self) -> u32 { PAC_CRC.dr().read() } diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs index 46f5ea1be..ad7c79f12 100644 --- a/embassy-stm32/src/crc/v2v3.rs +++ b/embassy-stm32/src/crc/v2v3.rs @@ -13,6 +13,8 @@ pub struct Crc<'d> { } /// CRC configuration errlr +#[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ConfigError { /// The selected polynomial is invalid. InvalidPolynomial, @@ -136,7 +138,7 @@ impl<'d> Crc<'d> { /// Feeds a byte into the CRC peripheral. Returns the computed checksum. pub fn feed_byte(&mut self, byte: u8) -> u32 { PAC_CRC.dr8().write_value(byte); - PAC_CRC.dr().read() + PAC_CRC.dr32().read() } /// Feeds an slice of bytes into the CRC peripheral. Returns the computed checksum. @@ -144,30 +146,30 @@ impl<'d> Crc<'d> { for byte in bytes { PAC_CRC.dr8().write_value(*byte); } - PAC_CRC.dr().read() + PAC_CRC.dr32().read() } /// Feeds a halfword into the CRC peripheral. Returns the computed checksum. pub fn feed_halfword(&mut self, halfword: u16) -> u32 { PAC_CRC.dr16().write_value(halfword); - PAC_CRC.dr().read() + PAC_CRC.dr32().read() } /// Feeds an slice of halfwords into the CRC peripheral. Returns the computed checksum. pub fn feed_halfwords(&mut self, halfwords: &[u16]) -> u32 { for halfword in halfwords { PAC_CRC.dr16().write_value(*halfword); } - PAC_CRC.dr().read() + PAC_CRC.dr32().read() } /// Feeds a words into the CRC peripheral. Returns the computed checksum. pub fn feed_word(&mut self, word: u32) -> u32 { - PAC_CRC.dr().write_value(word as u32); - PAC_CRC.dr().read() + PAC_CRC.dr32().write_value(word as u32); + PAC_CRC.dr32().read() } /// Feeds an slice of words into the CRC peripheral. Returns the computed checksum. pub fn feed_words(&mut self, words: &[u32]) -> u32 { for word in words { - PAC_CRC.dr().write_value(*word as u32); + PAC_CRC.dr32().write_value(*word as u32); } - PAC_CRC.dr().read() + PAC_CRC.dr32().read() } } diff --git a/embassy-stm32/src/cryp/mod.rs b/embassy-stm32/src/cryp/mod.rs index 18b5ec918..f19c94fda 100644 --- a/embassy-stm32/src/cryp/mod.rs +++ b/embassy-stm32/src/cryp/mod.rs @@ -1,5 +1,5 @@ //! Crypto Accelerator (CRYP) -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] use core::cmp::min; use core::marker::PhantomData; use core::ptr; @@ -7,7 +7,7 @@ use core::ptr; use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; -use crate::dma::{NoDma, Priority, Transfer, TransferOptions}; +use crate::dma::{NoDma, Transfer, TransferOptions}; use crate::interrupt::typelevel::Interrupt; use crate::{interrupt, pac, peripherals, Peripheral}; @@ -147,7 +147,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for TdesEcb<'c, KEY_SIZE> { { p.cr().modify(|w| w.set_algomode(0)); } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] { p.cr().modify(|w| w.set_algomode0(0)); p.cr().modify(|w| w.set_algomode3(false)); @@ -189,7 +189,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for TdesCbc<'c, KEY_SIZE> { { p.cr().modify(|w| w.set_algomode(1)); } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] { p.cr().modify(|w| w.set_algomode0(1)); p.cr().modify(|w| w.set_algomode3(false)); @@ -231,7 +231,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for DesEcb<'c, KEY_SIZE> { { p.cr().modify(|w| w.set_algomode(2)); } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] { p.cr().modify(|w| w.set_algomode0(2)); p.cr().modify(|w| w.set_algomode3(false)); @@ -272,7 +272,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for DesCbc<'c, KEY_SIZE> { { p.cr().modify(|w| w.set_algomode(3)); } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] { p.cr().modify(|w| w.set_algomode0(3)); p.cr().modify(|w| w.set_algomode3(false)); @@ -313,7 +313,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesEcb<'c, KEY_SIZE> { { p.cr().modify(|w| w.set_algomode(7)); } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] { p.cr().modify(|w| w.set_algomode0(7)); p.cr().modify(|w| w.set_algomode3(false)); @@ -327,7 +327,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesEcb<'c, KEY_SIZE> { { p.cr().modify(|w| w.set_algomode(2)); } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] { p.cr().modify(|w| w.set_algomode0(2)); p.cr().modify(|w| w.set_algomode3(false)); @@ -370,7 +370,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesCbc<'c, KEY_SIZE> { { p.cr().modify(|w| w.set_algomode(7)); } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] { p.cr().modify(|w| w.set_algomode0(7)); p.cr().modify(|w| w.set_algomode3(false)); @@ -384,7 +384,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesCbc<'c, KEY_SIZE> { { p.cr().modify(|w| w.set_algomode(5)); } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] { p.cr().modify(|w| w.set_algomode0(5)); p.cr().modify(|w| w.set_algomode3(false)); @@ -426,7 +426,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesCtr<'c, KEY_SIZE> { { p.cr().modify(|w| w.set_algomode(6)); } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] { p.cr().modify(|w| w.set_algomode0(6)); p.cr().modify(|w| w.set_algomode3(false)); @@ -439,14 +439,14 @@ impl<'c> CipherSized for AesCtr<'c, { 192 / 8 }> {} impl<'c> CipherSized for AesCtr<'c, { 256 / 8 }> {} impl<'c, const KEY_SIZE: usize> IVSized for AesCtr<'c, KEY_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] ///AES-GCM Cipher Mode pub struct AesGcm<'c, const KEY_SIZE: usize> { iv: [u8; 16], key: &'c [u8; KEY_SIZE], } -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize> AesGcm<'c, KEY_SIZE> { /// Constucts a new AES-GCM cipher for a cryptographic operation. pub fn new(key: &'c [u8; KEY_SIZE], iv: &'c [u8; 12]) -> Self { @@ -457,7 +457,7 @@ impl<'c, const KEY_SIZE: usize> AesGcm<'c, KEY_SIZE> { } } -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> { const BLOCK_SIZE: usize = AES_BLOCK_SIZE; @@ -504,7 +504,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> { [0; 4] } - #[cfg(cryp_v3)] + #[cfg(any(cryp_v3, cryp_v4))] fn pre_final(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] { //Handle special GCM partial block process. p.cr().modify(|w| w.set_npblb(padding_len as u8)); @@ -573,25 +573,25 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> { } } -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c> CipherSized for AesGcm<'c, { 128 / 8 }> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c> CipherSized for AesGcm<'c, { 192 / 8 }> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c> CipherSized for AesGcm<'c, { 256 / 8 }> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize> CipherAuthenticated<16> for AesGcm<'c, KEY_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize> IVSized for AesGcm<'c, KEY_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] /// AES-GMAC Cipher Mode pub struct AesGmac<'c, const KEY_SIZE: usize> { iv: [u8; 16], key: &'c [u8; KEY_SIZE], } -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize> AesGmac<'c, KEY_SIZE> { /// Constructs a new AES-GMAC cipher for a cryptographic operation. pub fn new(key: &'c [u8; KEY_SIZE], iv: &'c [u8; 12]) -> Self { @@ -602,7 +602,7 @@ impl<'c, const KEY_SIZE: usize> AesGmac<'c, KEY_SIZE> { } } -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> { const BLOCK_SIZE: usize = AES_BLOCK_SIZE; @@ -649,7 +649,7 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> { [0; 4] } - #[cfg(cryp_v3)] + #[cfg(any(cryp_v3, cryp_v4))] fn pre_final(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] { //Handle special GCM partial block process. p.cr().modify(|w| w.set_npblb(padding_len as u8)); @@ -716,18 +716,18 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> { } } -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c> CipherSized for AesGmac<'c, { 128 / 8 }> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c> CipherSized for AesGmac<'c, { 192 / 8 }> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c> CipherSized for AesGmac<'c, { 256 / 8 }> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize> CipherAuthenticated<16> for AesGmac<'c, KEY_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize> IVSized for AesGmac<'c, KEY_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] /// AES-CCM Cipher Mode pub struct AesCcm<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> { key: &'c [u8; KEY_SIZE], @@ -737,7 +737,7 @@ pub struct AesCcm<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZ ctr: [u8; 16], } -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> AesCcm<'c, KEY_SIZE, TAG_SIZE, IV_SIZE> { /// Constructs a new AES-CCM cipher for a cryptographic operation. pub fn new(key: &'c [u8; KEY_SIZE], iv: &'c [u8; IV_SIZE], aad_len: usize, payload_len: usize) -> Self { @@ -801,7 +801,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Aes } } -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cipher<'c> for AesCcm<'c, KEY_SIZE, TAG_SIZE, IV_SIZE> { @@ -865,7 +865,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip return temp1; } - #[cfg(cryp_v3)] + #[cfg(any(cryp_v3, cryp_v4))] fn pre_final(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] { //Handle special GCM partial block process. p.cr().modify(|w| w.set_npblb(padding_len as u8)); @@ -950,39 +950,39 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip } } -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const TAG_SIZE: usize, const IV_SIZE: usize> CipherSized for AesCcm<'c, { 128 / 8 }, TAG_SIZE, IV_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const TAG_SIZE: usize, const IV_SIZE: usize> CipherSized for AesCcm<'c, { 192 / 8 }, TAG_SIZE, IV_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const TAG_SIZE: usize, const IV_SIZE: usize> CipherSized for AesCcm<'c, { 256 / 8 }, TAG_SIZE, IV_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<4> for AesCcm<'c, KEY_SIZE, 4, IV_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<6> for AesCcm<'c, KEY_SIZE, 6, IV_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<8> for AesCcm<'c, KEY_SIZE, 8, IV_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<10> for AesCcm<'c, KEY_SIZE, 10, IV_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<12> for AesCcm<'c, KEY_SIZE, 12, IV_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<14> for AesCcm<'c, KEY_SIZE, 14, IV_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const IV_SIZE: usize> CipherAuthenticated<16> for AesCcm<'c, KEY_SIZE, 16, IV_SIZE> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 7> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 8> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 9> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 10> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 11> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 12> {} -#[cfg(any(cryp_v2, cryp_v3))] +#[cfg(any(cryp_v2, cryp_v3, cryp_v4))] impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize> IVSized for AesCcm<'c, KEY_SIZE, TAG_SIZE, 13> {} #[allow(dead_code)] @@ -1205,7 +1205,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { ctx } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] /// Controls the header phase of cipher processing. /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC. /// All additional associated data (AAD) must be supplied to this function prior to starting the payload phase with `payload_blocking`. @@ -1302,7 +1302,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { self.store_context(ctx); } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] /// Controls the header phase of cipher processing. /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC. /// All additional associated data (AAD) must be supplied to this function prior to starting the payload phase with `payload`. @@ -1420,7 +1420,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { if !ctx.aad_complete && ctx.header_len > 0 { panic!("Additional associated data must be processed first!"); } else if !ctx.aad_complete { - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] { ctx.aad_complete = true; T::regs().cr().modify(|w| w.set_crypen(false)); @@ -1512,7 +1512,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { if !ctx.aad_complete && ctx.header_len > 0 { panic!("Additional associated data must be processed first!"); } else if !ctx.aad_complete { - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] { ctx.aad_complete = true; T::regs().cr().modify(|w| w.set_crypen(false)); @@ -1585,7 +1585,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { self.store_context(ctx); } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] /// Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC. /// Called after the all data has been encrypted/decrypted by `payload`. pub fn finish_blocking< @@ -1614,7 +1614,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { payloadlen1.swap_bytes(), payloadlen2.swap_bytes(), ]; - #[cfg(cryp_v3)] + #[cfg(any(cryp_v3, cryp_v4))] let footer: [u32; 4] = [headerlen1, headerlen2, payloadlen1, payloadlen2]; self.write_words_blocking(C::BLOCK_SIZE, &footer); @@ -1631,7 +1631,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { tag } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] // Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC. /// Called after the all data has been encrypted/decrypted by `payload`. pub async fn finish< @@ -1664,7 +1664,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { payloadlen1.swap_bytes(), payloadlen2.swap_bytes(), ]; - #[cfg(cryp_v3)] + #[cfg(any(cryp_v3, cryp_v4))] let footer: [u32; 4] = [headerlen1, headerlen2, payloadlen1, payloadlen2]; let write = Self::write_words(&mut self.indma, C::BLOCK_SIZE, &footer); @@ -1735,7 +1735,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { ctx.iv[2] = T::regs().init(1).ivlr().read(); ctx.iv[3] = T::regs().init(1).ivrr().read(); - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] for i in 0..8 { ctx.csgcmccm[i] = T::regs().csgcmccmr(i).read(); ctx.csgcm[i] = T::regs().csgcmr(i).read(); @@ -1750,7 +1750,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { T::regs().init(1).ivlr().write_value(ctx.iv[2]); T::regs().init(1).ivrr().write_value(ctx.iv[3]); - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] for i in 0..8 { T::regs().csgcmccmr(i).write_value(ctx.csgcmccm[i]); T::regs().csgcmr(i).write_value(ctx.csgcm[i]); @@ -1797,7 +1797,8 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { let num_words = blocks.len() / 4; let src_ptr = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words); let options = TransferOptions { - priority: Priority::High, + #[cfg(not(gpdma))] + priority: crate::dma::Priority::High, ..Default::default() }; let dma_transfer = unsafe { Transfer::new_write_raw(dma, dma_request, src_ptr, dst_ptr, options) }; @@ -1806,7 +1807,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { dma_transfer.await; } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] fn write_words_blocking(&self, block_size: usize, blocks: &[u32]) { assert_eq!((blocks.len() * 4) % block_size, 0); let mut byte_counter: usize = 0; @@ -1820,7 +1821,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { } } - #[cfg(any(cryp_v2, cryp_v3))] + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] async fn write_words(dma: &mut PeripheralRef<'_, DmaIn>, block_size: usize, blocks: &[u32]) where DmaIn: crate::cryp::DmaIn<T>, @@ -1836,7 +1837,8 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { let num_words = blocks.len(); let src_ptr = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words); let options = TransferOptions { - priority: Priority::High, + #[cfg(not(gpdma))] + priority: crate::dma::Priority::High, ..Default::default() }; let dma_transfer = unsafe { Transfer::new_write_raw(dma, dma_request, src_ptr, dst_ptr, options) }; @@ -1875,7 +1877,8 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { let num_words = blocks.len() / 4; let dst_ptr = ptr::slice_from_raw_parts_mut(blocks.as_mut_ptr().cast(), num_words); let options = TransferOptions { - priority: Priority::VeryHigh, + #[cfg(not(gpdma))] + priority: crate::dma::Priority::VeryHigh, ..Default::default() }; let dma_transfer = unsafe { Transfer::new_read_raw(dma, dma_request, src_ptr, dst_ptr, options) }; diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index acfed8356..8a748ad72 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -118,7 +118,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { /// /// If you're not using DMA, pass [`dma::NoDma`] for the `dma` argument. /// - /// The channel is enabled on creation and begins to drive the output pin. + /// The channel is enabled on creation and begin to drive the output pin. /// Note that some methods, such as `set_trigger()` and `set_mode()`, will /// disable the channel; you must re-enable it with `enable()`. /// @@ -368,7 +368,7 @@ impl<'d, T: Instance, const N: u8, DMA> Drop for DacChannel<'d, T, N, DMA> { /// /// ```ignore /// // Pins may need to be changed for your specific device. -/// let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC, NoDma, NoDma, p.PA4, p.PA5).split(); +/// let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, NoDma, NoDma, p.PA4, p.PA5).split(); /// ``` pub struct Dac<'d, T: Instance, DMACh1 = NoDma, DMACh2 = NoDma> { ch1: DacChannel<'d, T, 1, DMACh1>, @@ -382,7 +382,7 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { /// call `split()` to obtain separate `DacChannel`s, or use methods on `Dac` to use /// the two channels together. /// - /// The channels are enabled on creation and begins to drive their output pins. + /// The channels are enabled on creation and begin to drive their output pins. /// Note that some methods, such as `set_trigger()` and `set_mode()`, will /// disable the channel; you must re-enable them with `enable()`. /// @@ -398,19 +398,28 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2); pin_ch1.set_as_analog(); pin_ch2.set_as_analog(); + // Enable twice to increment the DAC refcount for each channel. T::enable_and_reset(); T::enable_and_reset(); - Self { - ch1: DacCh1 { - phantom: PhantomData, - dma: dma_ch1, - }, - ch2: DacCh2 { - phantom: PhantomData, - dma: dma_ch2, - }, - } + + let mut ch1 = DacCh1 { + phantom: PhantomData, + dma: dma_ch1, + }; + #[cfg(any(dac_v5, dac_v6, dac_v7))] + ch1.set_hfsel(); + ch1.enable(); + + let mut ch2 = DacCh2 { + phantom: PhantomData, + dma: dma_ch2, + }; + #[cfg(any(dac_v5, dac_v6, dac_v7))] + ch2.set_hfsel(); + ch2.enable(); + + Self { ch1, ch2 } } /// Create a new `Dac` instance where the external output pins are not used, @@ -437,16 +446,26 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { // Enable twice to increment the DAC refcount for each channel. T::enable_and_reset(); T::enable_and_reset(); - Self { - ch1: DacCh1 { - phantom: PhantomData, - dma: dma_ch1, - }, - ch2: DacCh2 { - phantom: PhantomData, - dma: dma_ch2, - }, - } + + let mut ch1 = DacCh1 { + phantom: PhantomData, + dma: dma_ch1, + }; + #[cfg(any(dac_v5, dac_v6, dac_v7))] + ch1.set_hfsel(); + ch1.set_mode(Mode::NormalInternalUnbuffered); + ch1.enable(); + + let mut ch2 = DacCh2 { + phantom: PhantomData, + dma: dma_ch2, + }; + #[cfg(any(dac_v5, dac_v6, dac_v7))] + ch2.set_hfsel(); + ch2.set_mode(Mode::NormalInternalUnbuffered); + ch2.enable(); + + Self { ch1, ch2 } } /// Split this `Dac` into separate channels. diff --git a/embassy-stm32/src/dac/tsel.rs b/embassy-stm32/src/dac/tsel.rs index 22d8d3dfa..1877954b9 100644 --- a/embassy-stm32/src/dac/tsel.rs +++ b/embassy-stm32/src/dac/tsel.rs @@ -235,6 +235,23 @@ pub enum TriggerSel { Exti9 = 13, } +/// Trigger selection for U0. +#[cfg(stm32u0)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Software = 0, + Tim1 = 1, + Tim2 = 2, + Tim3 = 3, + Tim6 = 5, + Tim7 = 6, + Tim15 = 8, + Lptim1 = 11, + Lptim2 = 12, + Exti9 = 14, +} + /// Trigger selection for G4. #[cfg(stm32g4)] #[derive(Debug, Copy, Clone, Eq, PartialEq)] diff --git a/embassy-stm32/src/dma/dmamux.rs b/embassy-stm32/src/dma/dmamux.rs index dc7cd3a66..1585b30d4 100644 --- a/embassy-stm32/src/dma/dmamux.rs +++ b/embassy-stm32/src/dma/dmamux.rs @@ -19,30 +19,6 @@ pub(crate) fn configure_dmamux(info: &DmamuxInfo, request: u8) { }); } -pub(crate) trait SealedMuxChannel {} - -/// DMAMUX1 instance. -pub struct DMAMUX1; -/// DMAMUX2 instance. -#[cfg(stm32h7)] -pub struct DMAMUX2; - -/// DMAMUX channel trait. -#[allow(private_bounds)] -pub trait MuxChannel: SealedMuxChannel { - /// DMAMUX instance this channel is on. - type Mux; -} - -macro_rules! dmamux_channel_impl { - ($channel_peri:ident, $dmamux:ident) => { - impl crate::dma::SealedMuxChannel for crate::peripherals::$channel_peri {} - impl crate::dma::MuxChannel for crate::peripherals::$channel_peri { - type Mux = crate::dma::$dmamux; - } - }; -} - /// safety: must be called only once pub(crate) unsafe fn init(_cs: critical_section::CriticalSection) { crate::_generated::init_dmamux(); diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs index ef03970ef..a3717e67b 100644 --- a/embassy-stm32/src/dma/gpdma.rs +++ b/embassy-stm32/src/dma/gpdma.rs @@ -32,7 +32,7 @@ impl Default for TransferOptions { } } -impl From<WordSize> for vals::ChTr1Dw { +impl From<WordSize> for vals::Dw { fn from(raw: WordSize) -> Self { match raw { WordSize::OneByte => Self::BYTE, @@ -235,8 +235,8 @@ impl<'a> Transfer<'a> { }); ch.tr2().write(|w| { w.set_dreq(match dir { - Dir::MemoryToPeripheral => vals::ChTr2Dreq::DESTINATIONPERIPHERAL, - Dir::PeripheralToMemory => vals::ChTr2Dreq::SOURCEPERIPHERAL, + Dir::MemoryToPeripheral => vals::Dreq::DESTINATIONPERIPHERAL, + Dir::PeripheralToMemory => vals::Dreq::SOURCEPERIPHERAL, }); w.set_reqsel(request); }); diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index 7e3681469..3f5687a62 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs @@ -14,7 +14,10 @@ pub use gpdma::*; #[cfg(dmamux)] mod dmamux; #[cfg(dmamux)] -pub use dmamux::*; +pub(crate) use dmamux::*; + +mod util; +pub(crate) use util::*; pub(crate) mod ringbuffer; pub mod word; diff --git a/embassy-stm32/src/dma/util.rs b/embassy-stm32/src/dma/util.rs new file mode 100644 index 000000000..962ea2501 --- /dev/null +++ b/embassy-stm32/src/dma/util.rs @@ -0,0 +1,60 @@ +use embassy_hal_internal::PeripheralRef; + +use super::word::Word; +use super::{AnyChannel, Request, Transfer, TransferOptions}; + +/// Convenience wrapper, contains a channel and a request number. +/// +/// Commonly used in peripheral drivers that own DMA channels. +pub(crate) struct ChannelAndRequest<'d> { + pub channel: PeripheralRef<'d, AnyChannel>, + pub request: Request, +} + +impl<'d> ChannelAndRequest<'d> { + pub unsafe fn read<'a, W: Word>( + &'a mut self, + peri_addr: *mut W, + buf: &'a mut [W], + options: TransferOptions, + ) -> Transfer<'a> { + Transfer::new_read(&mut self.channel, self.request, peri_addr, buf, options) + } + + pub unsafe fn read_raw<'a, W: Word>( + &'a mut self, + peri_addr: *mut W, + buf: *mut [W], + options: TransferOptions, + ) -> Transfer<'a> { + Transfer::new_read_raw(&mut self.channel, self.request, peri_addr, buf, options) + } + + pub unsafe fn write<'a, W: Word>( + &'a mut self, + buf: &'a [W], + peri_addr: *mut W, + options: TransferOptions, + ) -> Transfer<'a> { + Transfer::new_write(&mut self.channel, self.request, buf, peri_addr, options) + } + + pub unsafe fn write_raw<'a, W: Word>( + &'a mut self, + buf: *const [W], + peri_addr: *mut W, + options: TransferOptions, + ) -> Transfer<'a> { + Transfer::new_write_raw(&mut self.channel, self.request, buf, peri_addr, options) + } + + pub unsafe fn write_repeated<'a, W: Word>( + &'a mut self, + repeated: &'a W, + count: usize, + peri_addr: *mut W, + options: TransferOptions, + ) -> Transfer<'a> { + Transfer::new_write_repeated(&mut self.channel, self.request, repeated, count, peri_addr, options) + } +} diff --git a/embassy-stm32/src/dsihost.rs b/embassy-stm32/src/dsihost.rs new file mode 100644 index 000000000..f1c737fdc --- /dev/null +++ b/embassy-stm32/src/dsihost.rs @@ -0,0 +1,429 @@ +//! DSI HOST + +use core::marker::PhantomData; + +use embassy_hal_internal::{into_ref, PeripheralRef}; + +//use crate::gpio::{AnyPin, SealedPin}; +use crate::gpio::{AFType, AnyPin, Pull, Speed}; +use crate::rcc::RccPeripheral; +use crate::{peripherals, Peripheral}; + +/// Performs a busy-wait delay for a specified number of microseconds. +pub fn blocking_delay_ms(ms: u32) { + #[cfg(time)] + embassy_time::block_for(embassy_time::Duration::from_millis(ms)); + #[cfg(not(time))] + cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 1_000 * ms); +} + +/// PacketTypes extracted from CubeMX +#[repr(u8)] +#[allow(dead_code)] +pub enum PacketType { + /// DCS short write, no parameters + DcsShortPktWriteP0, + /// DCS short write, one parameter + DcsShortPktWriteP1, + /// Generic short write, no parameters + GenShortPktWriteP0, + /// Generic short write, one parameter + GenShortPktWriteP1, + /// Generic short write, two parameters + GenShortPktWriteP2, + /// DCS long write + DcsLongPktWrite, + /// Generic long write + GenLongPktWrite, + /// DCS short read + DcsShortPktRead(u8), + /// Generic short read, no parameters + GenShortPktReadP0, + /// Generic short read, one parameter + GenShortPktReadP1(u8), + /// Generic short read, two parameters + GenShortPktReadP2(u8, u8), + /// Used to set the maximum return packet size for reading data + MaxReturnPktSize, +} + +impl From<PacketType> for u8 { + fn from(packet_type: PacketType) -> u8 { + match packet_type { + PacketType::DcsShortPktWriteP0 => 0x05, + PacketType::DcsShortPktWriteP1 => 0x15, + PacketType::GenShortPktWriteP0 => 0x03, + PacketType::GenShortPktWriteP1 => 0x13, + PacketType::GenShortPktWriteP2 => 0x23, + PacketType::DcsLongPktWrite => 0x39, + PacketType::GenLongPktWrite => 0x29, + PacketType::DcsShortPktRead(_) => 0x06, + PacketType::GenShortPktReadP0 => 0x04, + PacketType::GenShortPktReadP1(_) => 0x14, + PacketType::GenShortPktReadP2(_, _) => 0x24, + PacketType::MaxReturnPktSize => 0x37, + } + } +} + +/// DSIHOST driver. +pub struct DsiHost<'d, T: Instance> { + _peri: PhantomData<&'d mut T>, + _te: PeripheralRef<'d, AnyPin>, +} + +impl<'d, T: Instance> DsiHost<'d, T> { + /// Note: Full-Duplex modes are not supported at this time + pub fn new(_peri: impl Peripheral<P = T> + 'd, te: impl Peripheral<P = impl TePin<T>> + 'd) -> Self { + into_ref!(te); + + T::enable_and_reset(); + + // Set Tearing Enable pin according to CubeMx example + te.set_as_af_pull(te.af_num(), AFType::OutputPushPull, Pull::None); + te.set_speed(Speed::Low); + /* + T::regs().wcr().modify(|w| { + w.set_dsien(true); + }); + */ + Self { + _peri: PhantomData, + _te: te.map_into(), + } + } + + /// Get the DSIHOST hardware version. Found in the reference manual for comparison. + pub fn get_version(&self) -> u32 { + T::regs().vr().read().version() + } + + /// Set the enable bit in the control register and assert that it has been enabled + pub fn enable(&mut self) { + T::regs().cr().modify(|w| w.set_en(true)); + assert!(T::regs().cr().read().en()) + } + + /// Unset the enable bit in the control register and assert that it has been disabled + pub fn disable(&mut self) { + T::regs().cr().modify(|w| w.set_en(false)); + assert!(!T::regs().cr().read().en()) + } + + /// Set the DSI enable bit in the wrapper control register and assert that it has been enabled + pub fn enable_wrapper_dsi(&mut self) { + T::regs().wcr().modify(|w| w.set_dsien(true)); + assert!(T::regs().wcr().read().dsien()) + } + + /// Unset the DSI enable bit in the wrapper control register and assert that it has been disabled + pub fn disable_wrapper_dsi(&mut self) { + T::regs().wcr().modify(|w| w.set_dsien(false)); + assert!(!T::regs().wcr().read().dsien()) + } + + /// DCS or Generic short/long write command + pub fn write_cmd(&mut self, channel_id: u8, address: u8, data: &[u8]) -> Result<(), Error> { + assert!(data.len() > 0); + + if data.len() == 1 { + self.short_write(channel_id, PacketType::DcsShortPktWriteP1, address, data[0]) + } else { + self.long_write( + channel_id, + PacketType::DcsLongPktWrite, // FIXME: This might be a generic long packet, as well... + address, + data, + ) + } + } + + fn short_write(&mut self, channel_id: u8, packet_type: PacketType, param1: u8, param2: u8) -> Result<(), Error> { + #[cfg(feature = "defmt")] + defmt::debug!("short_write: BEGIN wait for command fifo empty"); + + // Wait for Command FIFO empty + self.wait_command_fifo_empty()?; + #[cfg(feature = "defmt")] + defmt::debug!("short_write: END wait for command fifo empty"); + + // Configure the packet to send a short DCS command with 0 or 1 parameters + // Update the DSI packet header with new information + self.config_packet_header(channel_id, packet_type, param1, param2); + + self.wait_command_fifo_empty()?; + + let status = T::regs().isr1().read().0; + if status != 0 { + error!("ISR1 after short_write(): {:b}", status); + } + Ok(()) + } + + fn config_packet_header(&mut self, channel_id: u8, packet_type: PacketType, param1: u8, param2: u8) { + T::regs().ghcr().write(|w| { + w.set_dt(packet_type.into()); + w.set_vcid(channel_id); + w.set_wclsb(param1); + w.set_wcmsb(param2); + }); + } + + /// Write long DCS or long Generic command. + /// + /// `params` is expected to contain at least 2 elements. Use [`short_write`] for a single element. + fn long_write(&mut self, channel_id: u8, packet_type: PacketType, address: u8, data: &[u8]) -> Result<(), Error> { + // Must be a long packet if we do the long write, obviously. + assert!(matches!( + packet_type, + PacketType::DcsLongPktWrite | PacketType::GenLongPktWrite + )); + + // params needs to have at least 2 elements, otherwise short_write should be used + assert!(data.len() >= 2); + + #[cfg(feature = "defmt")] + defmt::debug!("long_write: BEGIN wait for command fifo empty"); + + self.wait_command_fifo_empty()?; + + #[cfg(feature = "defmt")] + defmt::debug!("long_write: DONE wait for command fifo empty"); + + // Note: CubeMX example "NbParams" is always one LESS than params.len() + // DCS code (last element of params) must be on payload byte 1 and if we have only 2 more params, + // then they must go into data2 and data3 + T::regs().gpdr().write(|w| { + // data[2] may or may not exist. + if let Some(x) = data.get(2) { + w.set_data4(*x); + } + // data[0] and [1] have to exist if long_write is called. + w.set_data3(data[1]); + w.set_data2(data[0]); + + // DCS Code + w.set_data1(address); + }); + + self.wait_command_fifo_empty()?; + + // These steps are only necessary if more than 1x 4 bytes need to go into the FIFO + if data.len() >= 4 { + // Generate an iterator that iterates over chunks of exactly 4 bytes + let iter = data[3..data.len()].chunks_exact(4); + // Obtain remainder before consuming iter + let remainder = iter.remainder(); + + // Keep filling the buffer with remaining data + for param in iter { + self.wait_command_fifo_not_full()?; + T::regs().gpdr().write(|w| { + w.set_data4(param[3]); + w.set_data3(param[2]); + w.set_data2(param[1]); + w.set_data1(param[0]); + }); + + self.wait_command_fifo_empty().unwrap(); + } + + // If the remaining data was not devisible by 4 we get a remainder + if remainder.len() >= 1 { + self.wait_command_fifo_not_full()?; + T::regs().gpdr().write(|w| { + if let Some(x) = remainder.get(2) { + w.set_data3(*x); + } + if let Some(x) = remainder.get(1) { + w.set_data2(*x); + } + w.set_data1(remainder[0]); + }); + self.wait_command_fifo_empty().unwrap(); + } + } + // Configure the packet to send a long DCS command + self.config_packet_header( + channel_id, + packet_type, + ((data.len() + 1) & 0x00FF) as u8, // +1 to account for address byte + (((data.len() + 1) & 0xFF00) >> 8) as u8, // +1 to account for address byte + ); + + self.wait_command_fifo_empty()?; + + let status = T::regs().isr1().read().0; + if status != 0 { + error!("ISR1 after long_write(): {:b}", status); + } + Ok(()) + } + + /// Read DSI Register + pub fn read( + &mut self, + channel_id: u8, + packet_type: PacketType, + read_size: u16, + data: &mut [u8], + ) -> Result<(), Error> { + if data.len() != read_size as usize { + return Err(Error::InvalidReadSize); + } + + // Set the maximum return packet size + self.short_write( + channel_id, + PacketType::MaxReturnPktSize, + (read_size & 0xFF) as u8, + ((read_size & 0xFF00) >> 8) as u8, + )?; + + // Set the packet header according to the packet_type + use PacketType::*; + match packet_type { + DcsShortPktRead(cmd) => self.config_packet_header(channel_id, packet_type, cmd, 0), + GenShortPktReadP0 => self.config_packet_header(channel_id, packet_type, 0, 0), + GenShortPktReadP1(param1) => self.config_packet_header(channel_id, packet_type, param1, 0), + GenShortPktReadP2(param1, param2) => self.config_packet_header(channel_id, packet_type, param1, param2), + _ => return Err(Error::InvalidPacketType), + } + + self.wait_read_not_busy()?; + + // Obtain chunks of 32-bit so the entire FIFO data register can be read + for bytes in data.chunks_exact_mut(4) { + self.wait_payload_read_fifo_not_empty()?; + + // Only perform a single read on the entire register to avoid unintended side-effects + let gpdr = T::regs().gpdr().read(); + bytes[0] = gpdr.data1(); + bytes[1] = gpdr.data2(); + bytes[2] = gpdr.data3(); + bytes[3] = gpdr.data4(); + } + + // Collect the remaining chunks and read the corresponding number of bytes from the FIFO + let remainder = data.chunks_exact_mut(4).into_remainder(); + if !remainder.is_empty() { + self.wait_payload_read_fifo_not_empty()?; + // Only perform a single read on the entire register to avoid unintended side-effects + let gpdr = T::regs().gpdr().read(); + if let Some(x) = remainder.get_mut(0) { + *x = gpdr.data1() + } + if let Some(x) = remainder.get_mut(1) { + *x = gpdr.data2() + } + if let Some(x) = remainder.get_mut(2) { + *x = gpdr.data3() + } + } + + /* + // Used this to check whether there are read errors. Does not seem like it. + if !self.read_busy() { + defmt::debug!("Read not busy!"); + if self.packet_size_error() { + return Err(Error::ReadError); + } + } + */ + Ok(()) + } + + fn wait_command_fifo_empty(&self) -> Result<(), Error> { + for _ in 1..1000 { + // Wait for Command FIFO empty + if T::regs().gpsr().read().cmdfe() { + return Ok(()); + } + blocking_delay_ms(1); + } + Err(Error::FifoTimeout) + } + + fn wait_command_fifo_not_full(&self) -> Result<(), Error> { + for _ in 1..1000 { + // Wait for Command FIFO not empty + if !T::regs().gpsr().read().cmdff() { + return Ok(()); + } + blocking_delay_ms(1); + } + Err(Error::FifoTimeout) + } + + fn wait_read_not_busy(&self) -> Result<(), Error> { + for _ in 1..1000 { + // Wait for read not busy + if !self.read_busy() { + return Ok(()); + } + blocking_delay_ms(1); + } + Err(Error::ReadTimeout) + } + + fn wait_payload_read_fifo_not_empty(&self) -> Result<(), Error> { + for _ in 1..1000 { + // Wait for payload read FIFO not empty + if !T::regs().gpsr().read().prdfe() { + return Ok(()); + } + blocking_delay_ms(1); + } + Err(Error::FifoTimeout) + } + + fn _packet_size_error(&self) -> bool { + T::regs().isr1().read().pse() + } + + fn read_busy(&self) -> bool { + T::regs().gpsr().read().rcb() + } +} + +/// Possible Error Types for DSI HOST +#[non_exhaustive] +#[derive(Debug)] +pub enum Error { + /// Waiting for FIFO empty flag timed out + FifoTimeout, + /// The specified `PacketType` is invalid for the selected operation + InvalidPacketType, + /// Provided read size does not match the read buffer length + InvalidReadSize, + /// Error during read + ReadError, + /// Read operation timed out + ReadTimeout, +} + +impl<'d, T: Instance> Drop for DsiHost<'d, T> { + fn drop(&mut self) {} +} + +trait SealedInstance: crate::rcc::SealedRccPeripheral { + fn regs() -> &'static crate::pac::dsihost::Dsihost; +} + +/// DSI instance trait. +#[allow(private_bounds)] +pub trait Instance: SealedInstance + RccPeripheral + 'static {} + +pin_trait!(TePin, Instance); + +foreach_peripheral!( + (dsihost, $inst:ident) => { + impl crate::dsihost::SealedInstance for peripherals::$inst { + fn regs() -> &'static crate::pac::dsihost::Dsihost { + &crate::pac::$inst + } + } + + impl crate::dsihost::Instance for peripherals::$inst {} + }; +); diff --git a/embassy-stm32/src/eth/generic_smi.rs b/embassy-stm32/src/eth/generic_smi.rs index 9c26e90f1..3b43051f4 100644 --- a/embassy-stm32/src/eth/generic_smi.rs +++ b/embassy-stm32/src/eth/generic_smi.rs @@ -1,10 +1,11 @@ //! Generic SMI Ethernet PHY +use core::task::Context; + #[cfg(feature = "time")] use embassy_time::{Duration, Timer}; -use futures::task::Context; #[cfg(feature = "time")] -use futures::FutureExt; +use futures_util::FutureExt; use super::{StationManagement, PHY}; diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index c6e015022..a19aa42cf 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs @@ -4,6 +4,7 @@ use core::marker::PhantomData; use core::sync::atomic::{fence, Ordering}; use embassy_hal_internal::{into_ref, PeripheralRef}; +use stm32_metapac::syscfg::vals::EthSelPhy; pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; use super::*; @@ -80,31 +81,15 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { phy: P, mac_addr: [u8; 6], ) -> Self { - // Enable the necessary Clocks - #[cfg(not(rcc_h5))] + // Enable the necessary clocks critical_section::with(|_| { - crate::pac::RCC.ahb1enr().modify(|w| { - w.set_eth1macen(true); - w.set_eth1txen(true); - w.set_eth1rxen(true); - }); - - crate::pac::SYSCFG.pmcr().modify(|w| w.set_epis(0b100)); - }); - - #[cfg(rcc_h5)] - critical_section::with(|_| { - crate::pac::RCC.apb3enr().modify(|w| w.set_sbsen(true)); - crate::pac::RCC.ahb1enr().modify(|w| { w.set_ethen(true); w.set_ethtxen(true); w.set_ethrxen(true); }); - crate::pac::SYSCFG - .pmcr() - .modify(|w| w.set_eth_sel_phy(crate::pac::syscfg::vals::EthSelPhy::B_0X4)); + crate::pac::SYSCFG.pmcr().modify(|w| w.set_eth_sel_phy(EthSelPhy::RMII)); }); into_ref!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); @@ -147,32 +132,17 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { phy: P, mac_addr: [u8; 6], ) -> Self { - // Enable necessary clocks. - #[cfg(not(rcc_h5))] + // Enable the necessary clocks critical_section::with(|_| { - crate::pac::RCC.ahb1enr().modify(|w| { - w.set_eth1macen(true); - w.set_eth1txen(true); - w.set_eth1rxen(true); - }); - - crate::pac::SYSCFG.pmcr().modify(|w| w.set_epis(0b000)); - }); - - #[cfg(rcc_h5)] - critical_section::with(|_| { - crate::pac::RCC.apb3enr().modify(|w| w.set_sbsen(true)); - crate::pac::RCC.ahb1enr().modify(|w| { w.set_ethen(true); w.set_ethtxen(true); w.set_ethrxen(true); }); - // TODO: This is for RMII - what would MII need here? crate::pac::SYSCFG .pmcr() - .modify(|w| w.set_eth_sel_phy(crate::pac::syscfg::vals::EthSelPhy::B_0X4)); + .modify(|w| w.set_eth_sel_phy(EthSelPhy::MII_GMII)); }); into_ref!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en); diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 8d5dae436..224d51b84 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -27,11 +27,11 @@ fn cpu_regs() -> pac::exti::Exti { EXTI } -#[cfg(not(any(exti_c0, exti_g0, exti_l5, gpio_v1, exti_u5, exti_h5, exti_h50)))] +#[cfg(not(any(exti_c0, exti_g0, exti_u0, exti_l5, gpio_v1, exti_u5, exti_h5, exti_h50)))] fn exticr_regs() -> pac::syscfg::Syscfg { pac::SYSCFG } -#[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))] +#[cfg(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50))] fn exticr_regs() -> pac::exti::Exti { EXTI } @@ -44,9 +44,9 @@ unsafe fn on_irq() { #[cfg(feature = "low-power")] crate::low_power::on_wakeup_irq(); - #[cfg(not(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50)))] + #[cfg(not(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50)))] let bits = EXTI.pr(0).read().0; - #[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))] + #[cfg(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50))] let bits = EXTI.rpr(0).read().0 | EXTI.fpr(0).read().0; // We don't handle or change any EXTI lines above 16. @@ -61,9 +61,9 @@ unsafe fn on_irq() { } // Clear pending - #[cfg(not(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50)))] + #[cfg(not(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50)))] EXTI.pr(0).write_value(Lines(bits)); - #[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))] + #[cfg(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50))] { EXTI.rpr(0).write_value(Lines(bits)); EXTI.fpr(0).write_value(Lines(bits)); @@ -241,9 +241,9 @@ impl<'a> ExtiInputFuture<'a> { EXTI.ftsr(0).modify(|w| w.set_line(pin, falling)); // clear pending bit - #[cfg(not(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50)))] + #[cfg(not(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50)))] EXTI.pr(0).write(|w| w.set_line(pin, true)); - #[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))] + #[cfg(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50))] { EXTI.rpr(0).write(|w| w.set_line(pin, true)); EXTI.fpr(0).write(|w| w.set_line(pin, true)); diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 00e61f2d2..2634fba37 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs @@ -16,7 +16,7 @@ mod alt_regions { use embassy_hal_internal::PeripheralRef; use stm32_metapac::FLASH_SIZE; - use crate::_generated::flash_regions::{OTPRegion, BANK1_REGION1, BANK1_REGION2, BANK1_REGION3, OTP_REGION}; + use crate::_generated::flash_regions::{BANK1_REGION1, BANK1_REGION2, BANK1_REGION3}; use crate::flash::{asynch, Async, Bank1Region1, Bank1Region2, Blocking, Error, Flash, FlashBank, FlashRegion}; use crate::peripherals::FLASH; @@ -62,7 +62,6 @@ mod alt_regions { pub bank2_region1: AltBank2Region1<'d, MODE>, pub bank2_region2: AltBank2Region2<'d, MODE>, pub bank2_region3: AltBank2Region3<'d, MODE>, - pub otp_region: OTPRegion<'d, MODE>, } impl<'d> Flash<'d> { @@ -79,7 +78,6 @@ mod alt_regions { bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }, PhantomData), bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }, PhantomData), bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }, PhantomData), - otp_region: OTPRegion(&OTP_REGION, unsafe { p.clone_unchecked() }, PhantomData), } } @@ -96,7 +94,6 @@ mod alt_regions { bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }, PhantomData), bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }, PhantomData), bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }, PhantomData), - otp_region: OTPRegion(&OTP_REGION, unsafe { p.clone_unchecked() }, PhantomData), } } } @@ -341,10 +338,9 @@ pub(crate) fn clear_all_err() { } pub(crate) async fn wait_ready() -> Result<(), Error> { + use core::future::poll_fn; use core::task::Poll; - use futures::future::poll_fn; - poll_fn(|cx| { WAKER.register(cx.waker()); diff --git a/embassy-stm32/src/flash/h50.rs b/embassy-stm32/src/flash/h50.rs index db05bef5d..56ea7a421 100644 --- a/embassy-stm32/src/flash/h50.rs +++ b/embassy-stm32/src/flash/h50.rs @@ -55,17 +55,18 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) } pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), Error> { - assert!(sector.bank != FlashBank::Otp); assert!(sector.index_in_bank < 8); while busy() {} interrupt::free(|_| { pac::FLASH.nscr().modify(|w| { - w.set_bksel(match sector.bank { - FlashBank::Bank1 => Bksel::B_0X0, - FlashBank::Bank2 => Bksel::B_0X1, - _ => unreachable!(), + // BKSEL ignores SWAP_BANK, so we must take it into account here + w.set_bksel(match (sector.bank, banks_swapped()) { + (FlashBank::Bank1, false) => Bksel::BANK1, + (FlashBank::Bank2, true) => Bksel::BANK1, + (FlashBank::Bank2, false) => Bksel::BANK2, + (FlashBank::Bank1, true) => Bksel::BANK2, }); w.set_snb(sector.index_in_bank); w.set_ser(true); @@ -113,6 +114,47 @@ pub(crate) unsafe fn clear_all_err() { }) } +/// Get the current SWAP_BANK option. +/// +/// This value is only loaded on system or power-on reset. `perform_bank_swap()` +/// will not reflect here. +pub fn banks_swapped() -> bool { + pac::FLASH.optcr().read().swap_bank() +} + +/// Logical, persistent swap of flash banks 1 and 2. +/// +/// This allows the application to write a new firmware blob into bank 2, then +/// swap the banks and perform a reset, loading the new firmware. +/// +/// Swap does not take effect until system or power-on reset. +/// +/// PLEASE READ THE REFERENCE MANUAL - there are nuances to this feature. For +/// instance, erase commands and interrupt enables which take a flash bank as a +/// parameter ignore the swap! +pub fn perform_bank_swap() { + while busy() {} + + unsafe { + clear_all_err(); + } + + // unlock OPTLOCK + pac::FLASH.optkeyr().write(|w| *w = 0x0819_2A3B); + pac::FLASH.optkeyr().write(|w| *w = 0x4C5D_6E7F); + while pac::FLASH.optcr().read().optlock() {} + + // toggle SWAP_BANK option + pac::FLASH.optsr_prg().modify(|w| w.set_swap_bank(!banks_swapped())); + + // load option bytes + pac::FLASH.optcr().modify(|w| w.set_optstrt(true)); + while pac::FLASH.optcr().read().optstrt() {} + + // re-lock OPTLOCK + pac::FLASH.optcr().modify(|w| w.set_optlock(true)); +} + fn sr_busy(sr: Nssr) -> bool { // Note: RM0492 sometimes incorrectly refers to WBNE as NSWBNE sr.bsy() || sr.dbne() || sr.wbne() diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs index 1d8031e82..8c6ca2471 100644 --- a/embassy-stm32/src/flash/mod.rs +++ b/embassy-stm32/src/flash/mod.rs @@ -89,8 +89,6 @@ pub enum FlashBank { Bank1 = 0, /// Bank 2 Bank2 = 1, - /// OTP region - Otp, } #[cfg_attr(any(flash_l0, flash_l1, flash_l4, flash_wl, flash_wb), path = "l.rs")] @@ -103,10 +101,11 @@ pub enum FlashBank { #[cfg_attr(flash_h7ab, path = "h7.rs")] #[cfg_attr(flash_u5, path = "u5.rs")] #[cfg_attr(flash_h50, path = "h50.rs")] +#[cfg_attr(flash_u0, path = "u0.rs")] #[cfg_attr( not(any( flash_l0, flash_l1, flash_l4, flash_wl, flash_wb, flash_f0, flash_f1, flash_f3, flash_f4, flash_f7, flash_g0, - flash_g4, flash_h7, flash_h7ab, flash_u5, flash_h50 + flash_g4, flash_h7, flash_h7ab, flash_u5, flash_h50, flash_u0 )), path = "other.rs" )] diff --git a/embassy-stm32/src/flash/u0.rs b/embassy-stm32/src/flash/u0.rs new file mode 100644 index 000000000..dfc5a2f76 --- /dev/null +++ b/embassy-stm32/src/flash/u0.rs @@ -0,0 +1,96 @@ +use core::ptr::write_volatile; +use core::sync::atomic::{fence, Ordering}; + +use cortex_m::interrupt; + +use super::{FlashRegion, FlashSector, FLASH_REGIONS, WRITE_SIZE}; +use crate::flash::Error; +use crate::pac; + +pub(crate) const fn is_default_layout() -> bool { + true +} + +pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] { + &FLASH_REGIONS +} + +pub(crate) unsafe fn lock() { + pac::FLASH.cr().modify(|w| w.set_lock(true)); +} +pub(crate) unsafe fn unlock() { + // Wait, while the memory interface is busy. + while pac::FLASH.sr().read().bsy1() {} + + // Unlock flash + if pac::FLASH.cr().read().lock() { + pac::FLASH.keyr().write(|w| w.set_key(0x4567_0123)); + pac::FLASH.keyr().write(|w| w.set_key(0xCDEF_89AB)); + } +} + +pub(crate) unsafe fn enable_blocking_write() { + assert_eq!(0, WRITE_SIZE % 4); + pac::FLASH.cr().write(|w| w.set_pg(true)); +} + +pub(crate) unsafe fn disable_blocking_write() { + pac::FLASH.cr().write(|w| w.set_pg(false)); +} + +pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { + let mut address = start_address; + for val in buf.chunks(4) { + write_volatile(address as *mut u32, u32::from_le_bytes(val.try_into().unwrap())); + address += val.len() as u32; + + // prevents parallelism errors + fence(Ordering::SeqCst); + } + + wait_ready_blocking() +} + +pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), Error> { + let idx = (sector.start - super::FLASH_BASE as u32) / super::BANK1_REGION.erase_size as u32; + while pac::FLASH.sr().read().bsy1() {} + clear_all_err(); + + interrupt::free(|_| { + pac::FLASH.cr().modify(|w| { + w.set_per(true); + w.set_pnb(idx as u8); + w.set_strt(true); + }); + }); + + let ret: Result<(), Error> = wait_ready_blocking(); + pac::FLASH.cr().modify(|w| w.set_per(false)); + ret +} + +pub(crate) unsafe fn wait_ready_blocking() -> Result<(), Error> { + while pac::FLASH.sr().read().bsy1() {} + + let sr = pac::FLASH.sr().read(); + + if sr.progerr() { + return Err(Error::Prog); + } + + if sr.wrperr() { + return Err(Error::Protected); + } + + if sr.pgaerr() { + return Err(Error::Unaligned); + } + + Ok(()) +} + +pub(crate) unsafe fn clear_all_err() { + // read and write back the same value. + // This clears all "write 1 to clear" bits. + pac::FLASH.sr().modify(|_| {}); +} diff --git a/embassy-stm32/src/flash/u5.rs b/embassy-stm32/src/flash/u5.rs index 580c490da..ddd4d73ff 100644 --- a/embassy-stm32/src/flash/u5.rs +++ b/embassy-stm32/src/flash/u5.rs @@ -14,26 +14,43 @@ pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] { } pub(crate) unsafe fn lock() { + #[cfg(feature = "trustzone-secure")] pac::FLASH.seccr().modify(|w| w.set_lock(true)); + #[cfg(not(feature = "trustzone-secure"))] + pac::FLASH.nscr().modify(|w| w.set_lock(true)); } pub(crate) unsafe fn unlock() { + #[cfg(feature = "trustzone-secure")] if pac::FLASH.seccr().read().lock() { pac::FLASH.seckeyr().write_value(0x4567_0123); pac::FLASH.seckeyr().write_value(0xCDEF_89AB); } + #[cfg(not(feature = "trustzone-secure"))] + if pac::FLASH.nscr().read().lock() { + pac::FLASH.nskeyr().write_value(0x4567_0123); + pac::FLASH.nskeyr().write_value(0xCDEF_89AB); + } } pub(crate) unsafe fn enable_blocking_write() { assert_eq!(0, WRITE_SIZE % 4); + #[cfg(feature = "trustzone-secure")] pac::FLASH.seccr().write(|w| { w.set_pg(pac::flash::vals::SeccrPg::B_0X1); }); + #[cfg(not(feature = "trustzone-secure"))] + pac::FLASH.nscr().write(|w| { + w.set_pg(pac::flash::vals::NscrPg::B_0X1); + }); } pub(crate) unsafe fn disable_blocking_write() { + #[cfg(feature = "trustzone-secure")] pac::FLASH.seccr().write(|w| w.set_pg(pac::flash::vals::SeccrPg::B_0X0)); + #[cfg(not(feature = "trustzone-secure"))] + pac::FLASH.nscr().write(|w| w.set_pg(pac::flash::vals::NscrPg::B_0X0)); } pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { @@ -50,19 +67,35 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) } pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), Error> { + #[cfg(feature = "trustzone-secure")] pac::FLASH.seccr().modify(|w| { w.set_per(pac::flash::vals::SeccrPer::B_0X1); w.set_pnb(sector.index_in_bank) }); + #[cfg(not(feature = "trustzone-secure"))] + pac::FLASH.nscr().modify(|w| { + w.set_per(pac::flash::vals::NscrPer::B_0X1); + w.set_pnb(sector.index_in_bank) + }); + #[cfg(feature = "trustzone-secure")] pac::FLASH.seccr().modify(|w| { w.set_strt(true); }); + #[cfg(not(feature = "trustzone-secure"))] + pac::FLASH.nscr().modify(|w| { + w.set_strt(true); + }); let ret: Result<(), Error> = blocking_wait_ready(); + #[cfg(feature = "trustzone-secure")] pac::FLASH .seccr() .modify(|w| w.set_per(pac::flash::vals::SeccrPer::B_0X0)); + #[cfg(not(feature = "trustzone-secure"))] + pac::FLASH + .nscr() + .modify(|w| w.set_per(pac::flash::vals::NscrPer::B_0X0)); clear_all_err(); ret } @@ -70,12 +103,18 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E pub(crate) unsafe fn clear_all_err() { // read and write back the same value. // This clears all "write 1 to clear" bits. + #[cfg(feature = "trustzone-secure")] pac::FLASH.secsr().modify(|_| {}); + #[cfg(not(feature = "trustzone-secure"))] + pac::FLASH.nssr().modify(|_| {}); } unsafe fn blocking_wait_ready() -> Result<(), Error> { loop { + #[cfg(feature = "trustzone-secure")] let sr = pac::FLASH.secsr().read(); + #[cfg(not(feature = "trustzone-secure"))] + let sr = pac::FLASH.nssr().read(); if !sr.bsy() { if sr.pgserr() { diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 214813a42..d60a857ef 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -128,6 +128,15 @@ impl<'d> Flex<'d> { }); } + /// Put the pin into analog mode + /// + /// This mode is used by ADC and COMP but usually there is no need to set this manually + /// as the mode change is handled by the driver. + #[inline] + pub fn set_as_analog(&mut self) { + self.pin.set_as_analog(); + } + /// Put the pin into AF mode, unchecked. /// /// This puts the pin into the AF mode, with the requested number, pull and speed. This is @@ -661,6 +670,11 @@ pub(crate) trait SealedPin { self.set_as_analog(); } + /// Sets the speed of the output pin. + /// + /// This should never be called for AFType::Input on the STM32F1 series, since MODE and + /// CNF bits are not independent. If the CNF bits are altered afterwards as well, this + /// will put the pin into output mode. #[inline] fn set_speed(&self, speed: Speed) { let pin = self._pin() as usize; @@ -676,6 +690,38 @@ pub(crate) trait SealedPin { #[cfg(gpio_v2)] self.block().ospeedr().modify(|w| w.set_ospeedr(pin, speed.into())); } + + /// Get the pull-up configuration. + #[inline] + fn pull(&self) -> Pull { + critical_section::with(|_| { + let r = self.block(); + let n = self._pin() as usize; + #[cfg(gpio_v1)] + { + let crlh = if n < 8 { 0 } else { 1 }; + match r.cr(crlh).read().mode(n % 8) { + vals::Mode::INPUT => match r.cr(crlh).read().cnf_in(n % 8) { + vals::CnfIn::PULL => match r.odr().read().odr(n) { + vals::Odr::LOW => Pull::Down, + vals::Odr::HIGH => Pull::Up, + }, + _ => Pull::None, + }, + _ => Pull::None, + } + } + #[cfg(gpio_v2)] + { + match r.pupdr().read().pupdr(n) { + vals::Pupdr::FLOATING => Pull::None, + vals::Pupdr::PULLDOWN => Pull::Down, + vals::Pupdr::PULLUP => Pull::Up, + vals::Pupdr::_RESERVED_3 => Pull::None, + } + } + }) + } } /// GPIO pin trait. diff --git a/embassy-stm32/src/hsem/mod.rs b/embassy-stm32/src/hsem/mod.rs new file mode 100644 index 000000000..b77a3415b --- /dev/null +++ b/embassy-stm32/src/hsem/mod.rs @@ -0,0 +1,182 @@ +//! Hardware Semaphore (HSEM) + +// TODO: This code works for all HSEM implemenations except for the STM32WBA52/4/5xx MCUs. +// Those MCUs have a different HSEM implementation (Secure semaphore lock support, +// Privileged / unprivileged semaphore lock support, Semaphore lock protection via semaphore attribute), +// which is not yet supported by this code. +use embassy_hal_internal::{into_ref, PeripheralRef}; + +use crate::rcc::RccPeripheral; +use crate::{pac, Peripheral}; + +/// HSEM error. +#[derive(Debug)] +pub enum HsemError { + /// Locking the semaphore failed. + LockFailed, +} + +/// CPU core. +/// The enum values are identical to the bus master IDs / core Ids defined for each +/// chip family (i.e. stm32h747 see rm0399 table 95) +#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] +#[repr(u8)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum CoreId { + #[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))] + /// Cortex-M7, core 1. + Core0 = 0x3, + + #[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))] + /// Cortex-M4, core 2. + Core1 = 0x1, + + #[cfg(not(any(stm32h745, stm32h747, stm32h755, stm32h757)))] + /// Cortex-M4, core 1 + Core0 = 0x4, + + #[cfg(any(stm32wb, stm32wl))] + /// Cortex-M0+, core 2. + Core1 = 0x8, +} + +/// Get the current core id +/// This code assume that it is only executed on a Cortex-M M0+, M4 or M7 core. +#[inline(always)] +pub fn get_current_coreid() -> CoreId { + let cpuid = unsafe { cortex_m::peripheral::CPUID::PTR.read_volatile().base.read() }; + match cpuid & 0x000000F0 { + #[cfg(any(stm32wb, stm32wl))] + 0x0 => CoreId::Core1, + + #[cfg(not(any(stm32h745, stm32h747, stm32h755, stm32h757)))] + 0x4 => CoreId::Core0, + + #[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))] + 0x4 => CoreId::Core1, + + #[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))] + 0x7 => CoreId::Core0, + _ => panic!("Unknown Cortex-M core"), + } +} + +/// Translates the core ID to an index into the interrupt registers. +#[inline(always)] +fn core_id_to_index(core: CoreId) -> usize { + match core { + CoreId::Core0 => 0, + #[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757, stm32wb, stm32wl))] + CoreId::Core1 => 1, + } +} + +/// HSEM driver +pub struct HardwareSemaphore<'d, T: Instance> { + _peri: PeripheralRef<'d, T>, +} + +impl<'d, T: Instance> HardwareSemaphore<'d, T> { + /// Creates a new HardwareSemaphore instance. + pub fn new(peripheral: impl Peripheral<P = T> + 'd) -> Self { + into_ref!(peripheral); + HardwareSemaphore { _peri: peripheral } + } + + /// Locks the semaphore. + /// The 2-step lock procedure consists in a write to lock the semaphore, followed by a read to + /// check if the lock has been successful, carried out from the HSEM_Rx register. + pub fn two_step_lock(&mut self, sem_id: u8, process_id: u8) -> Result<(), HsemError> { + T::regs().r(sem_id as usize).write(|w| { + w.set_procid(process_id); + w.set_coreid(get_current_coreid() as u8); + w.set_lock(true); + }); + let reg = T::regs().r(sem_id as usize).read(); + match ( + reg.lock(), + reg.coreid() == get_current_coreid() as u8, + reg.procid() == process_id, + ) { + (true, true, true) => Ok(()), + _ => Err(HsemError::LockFailed), + } + } + + /// Locks the semaphore. + /// The 1-step procedure consists in a read to lock and check the semaphore in a single step, + /// carried out from the HSEM_RLRx register. + pub fn one_step_lock(&mut self, sem_id: u8) -> Result<(), HsemError> { + let reg = T::regs().rlr(sem_id as usize).read(); + match (reg.lock(), reg.coreid() == get_current_coreid() as u8, reg.procid()) { + (false, true, 0) => Ok(()), + _ => Err(HsemError::LockFailed), + } + } + + /// Unlocks the semaphore. + /// Unlocking a semaphore is a protected process, to prevent accidental clearing by a AHB bus + /// core ID or by a process not having the semaphore lock right. + pub fn unlock(&mut self, sem_id: u8, process_id: u8) { + T::regs().r(sem_id as usize).write(|w| { + w.set_procid(process_id); + w.set_coreid(get_current_coreid() as u8); + w.set_lock(false); + }); + } + + /// Unlocks all semaphores. + /// All semaphores locked by a COREID can be unlocked at once by using the HSEM_CR + /// register. Write COREID and correct KEY value in HSEM_CR. All locked semaphores with a + /// matching COREID are unlocked, and may generate an interrupt when enabled. + pub fn unlock_all(&mut self, key: u16, core_id: u8) { + T::regs().cr().write(|w| { + w.set_key(key); + w.set_coreid(core_id); + }); + } + + /// Checks if the semaphore is locked. + pub fn is_semaphore_locked(&self, sem_id: u8) -> bool { + T::regs().r(sem_id as usize).read().lock() + } + + /// Sets the clear (unlock) key + pub fn set_clear_key(&mut self, key: u16) { + T::regs().keyr().modify(|w| w.set_key(key)); + } + + /// Gets the clear (unlock) key + pub fn get_clear_key(&mut self) -> u16 { + T::regs().keyr().read().key() + } + + /// Sets the interrupt enable bit for the semaphore. + pub fn enable_interrupt(&mut self, core_id: CoreId, sem_x: usize, enable: bool) { + T::regs() + .ier(core_id_to_index(core_id)) + .modify(|w| w.set_ise(sem_x, enable)); + } + + /// Clears the interrupt flag for the semaphore. + pub fn clear_interrupt(&mut self, core_id: CoreId, sem_x: usize) { + T::regs() + .icr(core_id_to_index(core_id)) + .write(|w| w.set_isc(sem_x, false)); + } +} + +trait SealedInstance { + fn regs() -> pac::hsem::Hsem; +} + +/// HSEM instance trait. +#[allow(private_bounds)] +pub trait Instance: SealedInstance + RccPeripheral + Send + 'static {} + +impl SealedInstance for crate::peripherals::HSEM { + fn regs() -> crate::pac::hsem::Hsem { + crate::pac::HSEM + } +} +impl Instance for crate::peripherals::HSEM {} diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index a46061d54..ef5fd0972 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -2,21 +2,23 @@ #![macro_use] #[cfg_attr(i2c_v1, path = "v1.rs")] -#[cfg_attr(i2c_v2, path = "v2.rs")] +#[cfg_attr(any(i2c_v2, i2c_v3), path = "v2.rs")] mod _version; use core::future::Future; use core::iter; use core::marker::PhantomData; -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::{into_ref, Peripheral}; use embassy_sync::waitqueue::AtomicWaker; #[cfg(feature = "time")] use embassy_time::{Duration, Instant}; -use crate::dma::NoDma; +use crate::dma::ChannelAndRequest; use crate::gpio::{AFType, Pull}; use crate::interrupt::typelevel::Interrupt; +use crate::mode::{Async, Blocking, Mode}; +use crate::rcc::{ClockEnableBit, SealedRccPeripheral}; use crate::time::Hertz; use crate::{interrupt, peripherals}; @@ -71,31 +73,60 @@ impl Default for Config { } /// I2C driver. -pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> { - _peri: PeripheralRef<'d, T>, - #[allow(dead_code)] - tx_dma: PeripheralRef<'d, TXDMA>, - #[allow(dead_code)] - rx_dma: PeripheralRef<'d, RXDMA>, +pub struct I2c<'d, M: Mode> { + info: &'static Info, + state: &'static State, + kernel_clock: Hertz, + tx_dma: Option<ChannelAndRequest<'d>>, + rx_dma: Option<ChannelAndRequest<'d>>, #[cfg(feature = "time")] timeout: Duration, + _phantom: PhantomData<M>, } -impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { +impl<'d> I2c<'d, Async> { /// Create a new I2C driver. - pub fn new( + pub fn new<T: Instance>( peri: impl Peripheral<P = T> + 'd, scl: impl Peripheral<P = impl SclPin<T>> + 'd, sda: impl Peripheral<P = impl SdaPin<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::EventInterrupt, EventInterruptHandler<T>> + interrupt::typelevel::Binding<T::ErrorInterrupt, ErrorInterruptHandler<T>> + 'd, - tx_dma: impl Peripheral<P = TXDMA> + 'd, - rx_dma: impl Peripheral<P = RXDMA> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, + rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, freq: Hertz, config: Config, ) -> Self { - into_ref!(peri, scl, sda, tx_dma, rx_dma); + Self::new_inner(peri, scl, sda, new_dma!(tx_dma), new_dma!(rx_dma), freq, config) + } +} + +impl<'d> I2c<'d, Blocking> { + /// Create a new blocking I2C driver. + pub fn new_blocking<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + scl: impl Peripheral<P = impl SclPin<T>> + 'd, + sda: impl Peripheral<P = impl SdaPin<T>> + 'd, + freq: Hertz, + config: Config, + ) -> Self { + Self::new_inner(peri, scl, sda, None, None, freq, config) + } +} + +impl<'d, M: Mode> I2c<'d, M> { + /// Create a new I2C driver. + fn new_inner<T: Instance>( + _peri: impl Peripheral<P = T> + 'd, + scl: impl Peripheral<P = impl SclPin<T>> + 'd, + sda: impl Peripheral<P = impl SdaPin<T>> + 'd, + tx_dma: Option<ChannelAndRequest<'d>>, + rx_dma: Option<ChannelAndRequest<'d>>, + freq: Hertz, + config: Config, + ) -> Self { + into_ref!(scl, sda); T::enable_and_reset(); @@ -120,11 +151,14 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { unsafe { T::ErrorInterrupt::enable() }; let mut this = Self { - _peri: peri, + info: T::info(), + state: T::state(), + kernel_clock: T::frequency(), tx_dma, rx_dma, #[cfg(feature = "time")] timeout: config.timeout, + _phantom: PhantomData, }; this.init(freq, config); @@ -162,7 +196,7 @@ impl Timeout { fn with<R>(self, fut: impl Future<Output = Result<R, Error>>) -> impl Future<Output = Result<R, Error>> { #[cfg(feature = "time")] { - use futures::FutureExt; + use futures_util::FutureExt; embassy_futures::select::select(embassy_time::Timer::at(self.deadline), fut).map(|r| match r { embassy_futures::select::Either::First(_) => Err(Error::Timeout), @@ -188,19 +222,14 @@ impl State { } } -trait SealedInstance: crate::rcc::RccPeripheral { - fn regs() -> crate::pac::i2c::I2c; - fn state() -> &'static State; +struct Info { + regs: crate::pac::i2c::I2c, + pub(crate) enable_bit: ClockEnableBit, } -/// I2C peripheral instance -#[allow(private_bounds)] -pub trait Instance: SealedInstance + 'static { - /// Event interrupt for this instance - type EventInterrupt: interrupt::typelevel::Interrupt; - /// Error interrupt for this instance - type ErrorInterrupt: interrupt::typelevel::Interrupt; -} +peri_trait!( + irqs: [EventInterrupt, ErrorInterrupt], +); pin_trait!(SclPin, Instance); pin_trait!(SdaPin, Instance); @@ -231,11 +260,15 @@ impl<T: Instance> interrupt::typelevel::Handler<T::ErrorInterrupt> for ErrorInte foreach_peripheral!( (i2c, $inst:ident) => { + #[allow(private_interfaces)] impl SealedInstance for peripherals::$inst { - fn regs() -> crate::pac::i2c::I2c { - crate::pac::$inst + fn info() -> &'static Info { + static INFO: Info = Info{ + regs: crate::pac::$inst, + enable_bit: crate::peripherals::$inst::ENABLE_BIT, + }; + &INFO } - fn state() -> &'static State { static STATE: State = State::new(); &STATE @@ -249,7 +282,7 @@ foreach_peripheral!( }; ); -impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> { +impl<'d, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d, M> { type Error = Error; fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { @@ -257,7 +290,7 @@ impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> { } } -impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Write for I2c<'d, T> { +impl<'d, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d, M> { type Error = Error; fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { @@ -265,7 +298,7 @@ impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Write for I2c<'d, T> { } } -impl<'d, T: Instance> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T> { +impl<'d, M: Mode> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, M> { type Error = Error; fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { @@ -289,11 +322,11 @@ impl embedded_hal_1::i2c::Error for Error { } } -impl<'d, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for I2c<'d, T, TXDMA, RXDMA> { +impl<'d, M: Mode> embedded_hal_1::i2c::ErrorType for I2c<'d, M> { type Error = Error; } -impl<'d, T: Instance> embedded_hal_1::i2c::I2c for I2c<'d, T, NoDma, NoDma> { +impl<'d, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, M> { fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { self.blocking_read(address, read) } @@ -315,7 +348,7 @@ impl<'d, T: Instance> embedded_hal_1::i2c::I2c for I2c<'d, T, NoDma, NoDma> { } } -impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_async::i2c::I2c for I2c<'d, T, TXDMA, RXDMA> { +impl<'d> embedded_hal_async::i2c::I2c for I2c<'d, Async> { async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { self.read(address, read).await } diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index d45c48b24..0269e53aa 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs @@ -13,7 +13,7 @@ use embassy_hal_internal::drop::OnDrop; use embedded_hal_1::i2c::Operation; use super::*; -use crate::dma::Transfer; +use crate::mode::Mode as PeriMode; use crate::pac::i2c; // /!\ /!\ @@ -28,7 +28,7 @@ use crate::pac::i2c; // There's some more details there, and we might have a fix for you. But please let us know if you // hit a case like this! pub unsafe fn on_interrupt<T: Instance>() { - let regs = T::regs(); + let regs = T::info().regs; // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of // other stuff, so we wake the task on every interrupt. T::state().waker.wake(); @@ -41,39 +41,65 @@ pub unsafe fn on_interrupt<T: Instance>() { }); } -impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { +impl<'d, M: PeriMode> I2c<'d, M> { pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { - T::regs().cr1().modify(|reg| { + self.info.regs.cr1().modify(|reg| { reg.set_pe(false); //reg.set_anfoff(false); }); - let timings = Timings::new(T::frequency(), freq); + // Errata: "Start cannot be generated after a misplaced Stop" + // + // > If a master generates a misplaced Stop on the bus (bus error) + // > while the microcontroller I2C peripheral attempts to switch to + // > Master mode by setting the START bit, the Start condition is + // > not properly generated. + // + // This also can occur with falsely detected STOP events, for example + // if the SDA line is shorted to low. + // + // The workaround for this is to trigger the SWRST line AFTER power is + // enabled, AFTER PE is disabled and BEFORE making any other configuration. + // + // It COULD be possible to apply this workaround at runtime, instead of + // only on initialization, however this would require detecting the timeout + // or BUSY lockup condition, and re-configuring the peripheral after reset. + // + // This presents as an ~infinite hang on read or write, as the START condition + // is never generated, meaning the start event is never generated. + self.info.regs.cr1().modify(|reg| { + reg.set_swrst(true); + }); + self.info.regs.cr1().modify(|reg| { + reg.set_swrst(false); + }); - T::regs().cr2().modify(|reg| { + let timings = Timings::new(self.kernel_clock, freq); + + self.info.regs.cr2().modify(|reg| { reg.set_freq(timings.freq); }); - T::regs().ccr().modify(|reg| { + self.info.regs.ccr().modify(|reg| { reg.set_f_s(timings.mode.f_s()); reg.set_duty(timings.duty.duty()); reg.set_ccr(timings.ccr); }); - T::regs().trise().modify(|reg| { + self.info.regs.trise().modify(|reg| { reg.set_trise(timings.trise); }); - T::regs().cr1().modify(|reg| { + self.info.regs.cr1().modify(|reg| { reg.set_pe(true); }); } - fn check_and_clear_error_flags() -> Result<i2c::regs::Sr1, Error> { + fn check_and_clear_error_flags(info: &'static Info) -> Result<i2c::regs::Sr1, Error> { // Note that flags should only be cleared once they have been registered. If flags are // cleared otherwise, there may be an inherent race condition and flags may be missed. - let sr1 = T::regs().sr1().read(); + let sr1 = info.regs.sr1().read(); if sr1.timeout() { - T::regs().sr1().write(|reg| { + info.regs.sr1().write(|reg| { reg.0 = !0; reg.set_timeout(false); }); @@ -81,7 +107,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } if sr1.pecerr() { - T::regs().sr1().write(|reg| { + info.regs.sr1().write(|reg| { reg.0 = !0; reg.set_pecerr(false); }); @@ -89,7 +115,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } if sr1.ovr() { - T::regs().sr1().write(|reg| { + info.regs.sr1().write(|reg| { reg.0 = !0; reg.set_ovr(false); }); @@ -97,7 +123,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } if sr1.af() { - T::regs().sr1().write(|reg| { + info.regs.sr1().write(|reg| { reg.0 = !0; reg.set_af(false); }); @@ -105,7 +131,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } if sr1.arlo() { - T::regs().sr1().write(|reg| { + info.regs.sr1().write(|reg| { reg.0 = !0; reg.set_arlo(false); }); @@ -115,7 +141,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // The errata indicates that BERR may be incorrectly detected. It recommends ignoring and // clearing the BERR bit instead. if sr1.berr() { - T::regs().sr1().write(|reg| { + info.regs.sr1().write(|reg| { reg.0 = !0; reg.set_berr(false); }); @@ -128,32 +154,32 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { if frame.send_start() { // Send a START condition - T::regs().cr1().modify(|reg| { + self.info.regs.cr1().modify(|reg| { reg.set_start(true); }); // Wait until START condition was generated - while !Self::check_and_clear_error_flags()?.start() { + while !Self::check_and_clear_error_flags(self.info)?.start() { timeout.check()?; } // Check if we were the ones to generate START - if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() { + if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() { return Err(Error::Arbitration); } // Set up current address we're trying to talk to - T::regs().dr().write(|reg| reg.set_dr(addr << 1)); + self.info.regs.dr().write(|reg| reg.set_dr(addr << 1)); // Wait until address was sent // Wait for the address to be acknowledged // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set. - while !Self::check_and_clear_error_flags()?.addr() { + while !Self::check_and_clear_error_flags(self.info)?.addr() { timeout.check()?; } // Clear condition by reading SR2 - let _ = T::regs().sr2().read(); + let _ = self.info.regs.sr2().read(); } // Send bytes @@ -163,7 +189,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { if frame.send_stop() { // Send a STOP condition - T::regs().cr1().modify(|reg| reg.set_stop(true)); + self.info.regs.cr1().modify(|reg| reg.set_stop(true)); } // Fallthrough is success @@ -174,18 +200,18 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Wait until we're ready for sending while { // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set. - !Self::check_and_clear_error_flags()?.txe() + !Self::check_and_clear_error_flags(self.info)?.txe() } { timeout.check()?; } // Push out a byte of data - T::regs().dr().write(|reg| reg.set_dr(byte)); + self.info.regs.dr().write(|reg| reg.set_dr(byte)); // Wait until byte is transferred while { // Check for any potential error conditions. - !Self::check_and_clear_error_flags()?.btf() + !Self::check_and_clear_error_flags(self.info)?.btf() } { timeout.check()?; } @@ -196,14 +222,14 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { fn recv_byte(&self, timeout: Timeout) -> Result<u8, Error> { while { // Check for any potential error conditions. - Self::check_and_clear_error_flags()?; + Self::check_and_clear_error_flags(self.info)?; - !T::regs().sr1().read().rxne() + !self.info.regs.sr1().read().rxne() } { timeout.check()?; } - let value = T::regs().dr().read().dr(); + let value = self.info.regs.dr().read().dr(); Ok(value) } @@ -220,32 +246,32 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { if frame.send_start() { // Send a START condition and set ACK bit - T::regs().cr1().modify(|reg| { + self.info.regs.cr1().modify(|reg| { reg.set_start(true); reg.set_ack(true); }); // Wait until START condition was generated - while !Self::check_and_clear_error_flags()?.start() { + while !Self::check_and_clear_error_flags(self.info)?.start() { timeout.check()?; } // Check if we were the ones to generate START - if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() { + if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() { return Err(Error::Arbitration); } // Set up current address we're trying to talk to - T::regs().dr().write(|reg| reg.set_dr((addr << 1) + 1)); + self.info.regs.dr().write(|reg| reg.set_dr((addr << 1) + 1)); // Wait until address was sent // Wait for the address to be acknowledged - while !Self::check_and_clear_error_flags()?.addr() { + while !Self::check_and_clear_error_flags(self.info)?.addr() { timeout.check()?; } // Clear condition by reading SR2 - let _ = T::regs().sr2().read(); + let _ = self.info.regs.sr2().read(); } // Receive bytes into buffer @@ -254,7 +280,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } // Prepare to send NACK then STOP after next byte - T::regs().cr1().modify(|reg| { + self.info.regs.cr1().modify(|reg| { if frame.send_nack() { reg.set_ack(false); } @@ -320,18 +346,17 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Async #[inline] // pretty sure this should always be inlined - fn enable_interrupts() -> () { - T::regs().cr2().modify(|w| { + fn enable_interrupts(info: &'static Info) -> () { + info.regs.cr2().modify(|w| { w.set_iterren(true); w.set_itevten(true); }); } +} - async fn write_frame(&mut self, address: u8, write: &[u8], frame: FrameOptions) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma<T>, - { - T::regs().cr2().modify(|w| { +impl<'d> I2c<'d, Async> { + async fn write_frame(&mut self, address: u8, write: &[u8], frame: FrameOptions) -> Result<(), Error> { + self.info.regs.cr2().modify(|w| { // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for // reception. w.set_itbufen(false); @@ -345,33 +370,31 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Sentinel to disable transfer when an error occurs or future is canceled. // TODO: Generate STOP condition on cancel? let on_drop = OnDrop::new(|| { - T::regs().cr2().modify(|w| { + self.info.regs.cr2().modify(|w| { w.set_dmaen(false); w.set_iterren(false); w.set_itevten(false); }) }); - let state = T::state(); - if frame.send_start() { // Send a START condition - T::regs().cr1().modify(|reg| { + self.info.regs.cr1().modify(|reg| { reg.set_start(true); }); // Wait until START condition was generated poll_fn(|cx| { - state.waker.register(cx.waker()); + self.state.waker.register(cx.waker()); - match Self::check_and_clear_error_flags() { + match Self::check_and_clear_error_flags(self.info) { Err(e) => Poll::Ready(Err(e)), Ok(sr1) => { if sr1.start() { Poll::Ready(Ok(())) } else { // When pending, (re-)enable interrupts to wake us up. - Self::enable_interrupts(); + Self::enable_interrupts(self.info); Poll::Pending } } @@ -380,25 +403,25 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { .await?; // Check if we were the ones to generate START - if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() { + if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() { return Err(Error::Arbitration); } // Set up current address we're trying to talk to - T::regs().dr().write(|reg| reg.set_dr(address << 1)); + self.info.regs.dr().write(|reg| reg.set_dr(address << 1)); // Wait for the address to be acknowledged poll_fn(|cx| { - state.waker.register(cx.waker()); + self.state.waker.register(cx.waker()); - match Self::check_and_clear_error_flags() { + match Self::check_and_clear_error_flags(self.info) { Err(e) => Poll::Ready(Err(e)), Ok(sr1) => { if sr1.addr() { Poll::Ready(Ok(())) } else { // When pending, (re-)enable interrupts to wake us up. - Self::enable_interrupts(); + Self::enable_interrupts(self.info); Poll::Pending } } @@ -407,28 +430,26 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { .await?; // Clear condition by reading SR2 - T::regs().sr2().read(); + self.info.regs.sr2().read(); } let dma_transfer = unsafe { // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved to // this address from the memory after each TxE event. - let dst = T::regs().dr().as_ptr() as *mut u8; + let dst = self.info.regs.dr().as_ptr() as *mut u8; - let ch = &mut self.tx_dma; - let request = ch.request(); - Transfer::new_write(ch, request, write, dst, Default::default()) + self.tx_dma.as_mut().unwrap().write(write, dst, Default::default()) }; // Wait for bytes to be sent, or an error to occur. let poll_error = poll_fn(|cx| { - state.waker.register(cx.waker()); + self.state.waker.register(cx.waker()); - match Self::check_and_clear_error_flags() { + match Self::check_and_clear_error_flags(self.info) { Err(e) => Poll::Ready(Err::<(), Error>(e)), Ok(_) => { // When pending, (re-)enable interrupts to wake us up. - Self::enable_interrupts(); + Self::enable_interrupts(self.info); Poll::Pending } } @@ -440,7 +461,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { _ => Ok(()), }?; - T::regs().cr2().modify(|w| { + self.info.regs.cr2().modify(|w| { w.set_dmaen(false); }); @@ -450,16 +471,16 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // 18.3.8 “Master transmitter: In the interrupt routine after the EOT interrupt, disable DMA // requests then wait for a BTF event before programming the Stop condition.” poll_fn(|cx| { - state.waker.register(cx.waker()); + self.state.waker.register(cx.waker()); - match Self::check_and_clear_error_flags() { + match Self::check_and_clear_error_flags(self.info) { Err(e) => Poll::Ready(Err(e)), Ok(sr1) => { if sr1.btf() { Poll::Ready(Ok(())) } else { // When pending, (re-)enable interrupts to wake us up. - Self::enable_interrupts(); + Self::enable_interrupts(self.info); Poll::Pending } } @@ -467,7 +488,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { }) .await?; - T::regs().cr1().modify(|w| { + self.info.regs.cr1().modify(|w| { w.set_stop(true); }); } @@ -479,10 +500,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } /// Write. - pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma<T>, - { + pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { self.write_frame(address, write, FrameOptions::FirstAndLastFrame) .await?; @@ -490,20 +508,14 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } /// Read. - pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> - where - RXDMA: crate::i2c::RxDma<T>, - { + pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { self.read_frame(address, buffer, FrameOptions::FirstAndLastFrame) .await?; Ok(()) } - async fn read_frame(&mut self, address: u8, buffer: &mut [u8], frame: FrameOptions) -> Result<(), Error> - where - RXDMA: crate::i2c::RxDma<T>, - { + async fn read_frame(&mut self, address: u8, buffer: &mut [u8], frame: FrameOptions) -> Result<(), Error> { if buffer.is_empty() { return Err(Error::Overrun); } @@ -511,7 +523,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Some branches below depend on whether the buffer contains only a single byte. let single_byte = buffer.len() == 1; - T::regs().cr2().modify(|w| { + self.info.regs.cr2().modify(|w| { // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for // reception. w.set_itbufen(false); @@ -527,34 +539,32 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Sentinel to disable transfer when an error occurs or future is canceled. // TODO: Generate STOP condition on cancel? let on_drop = OnDrop::new(|| { - T::regs().cr2().modify(|w| { + self.info.regs.cr2().modify(|w| { w.set_dmaen(false); w.set_iterren(false); w.set_itevten(false); }) }); - let state = T::state(); - if frame.send_start() { // Send a START condition and set ACK bit - T::regs().cr1().modify(|reg| { + self.info.regs.cr1().modify(|reg| { reg.set_start(true); reg.set_ack(true); }); // Wait until START condition was generated poll_fn(|cx| { - state.waker.register(cx.waker()); + self.state.waker.register(cx.waker()); - match Self::check_and_clear_error_flags() { + match Self::check_and_clear_error_flags(self.info) { Err(e) => Poll::Ready(Err(e)), Ok(sr1) => { if sr1.start() { Poll::Ready(Ok(())) } else { // When pending, (re-)enable interrupts to wake us up. - Self::enable_interrupts(); + Self::enable_interrupts(self.info); Poll::Pending } } @@ -563,25 +573,25 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { .await?; // Check if we were the ones to generate START - if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() { + if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() { return Err(Error::Arbitration); } // Set up current address we're trying to talk to - T::regs().dr().write(|reg| reg.set_dr((address << 1) + 1)); + self.info.regs.dr().write(|reg| reg.set_dr((address << 1) + 1)); // Wait for the address to be acknowledged poll_fn(|cx| { - state.waker.register(cx.waker()); + self.state.waker.register(cx.waker()); - match Self::check_and_clear_error_flags() { + match Self::check_and_clear_error_flags(self.info) { Err(e) => Poll::Ready(Err(e)), Ok(sr1) => { if sr1.addr() { Poll::Ready(Ok(())) } else { // When pending, (re-)enable interrupts to wake us up. - Self::enable_interrupts(); + Self::enable_interrupts(self.info); Poll::Pending } } @@ -592,18 +602,18 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // 18.3.8: When a single byte must be received: the NACK must be programmed during EV6 // event, i.e. program ACK=0 when ADDR=1, before clearing ADDR flag. if frame.send_nack() && single_byte { - T::regs().cr1().modify(|w| { + self.info.regs.cr1().modify(|w| { w.set_ack(false); }); } // Clear condition by reading SR2 - T::regs().sr2().read(); + self.info.regs.sr2().read(); } else { // Before starting reception of single byte (but without START condition, i.e. in case // of continued frame), program NACK to emit at end of this byte. if frame.send_nack() && single_byte { - T::regs().cr1().modify(|w| { + self.info.regs.cr1().modify(|w| { w.set_ack(false); }); } @@ -613,7 +623,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // condition either after clearing ADDR flag, or in the DMA Transfer Complete interrupt // routine. if frame.send_stop() && single_byte { - T::regs().cr1().modify(|w| { + self.info.regs.cr1().modify(|w| { w.set_stop(true); }); } @@ -621,22 +631,20 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { let dma_transfer = unsafe { // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved // from this address from the memory after each RxE event. - let src = T::regs().dr().as_ptr() as *mut u8; + let src = self.info.regs.dr().as_ptr() as *mut u8; - let ch = &mut self.rx_dma; - let request = ch.request(); - Transfer::new_read(ch, request, src, buffer, Default::default()) + self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) }; // Wait for bytes to be received, or an error to occur. let poll_error = poll_fn(|cx| { - state.waker.register(cx.waker()); + self.state.waker.register(cx.waker()); - match Self::check_and_clear_error_flags() { + match Self::check_and_clear_error_flags(self.info) { Err(e) => Poll::Ready(Err::<(), Error>(e)), _ => { // When pending, (re-)enable interrupts to wake us up. - Self::enable_interrupts(); + Self::enable_interrupts(self.info); Poll::Pending } } @@ -647,12 +655,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { _ => Ok(()), }?; - T::regs().cr2().modify(|w| { + self.info.regs.cr2().modify(|w| { w.set_dmaen(false); }); if frame.send_stop() && !single_byte { - T::regs().cr1().modify(|w| { + self.info.regs.cr1().modify(|w| { w.set_stop(true); }); } @@ -664,11 +672,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } /// Write, restart, read. - pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> - where - RXDMA: crate::i2c::RxDma<T>, - TXDMA: crate::i2c::TxDma<T>, - { + pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { // Check empty read buffer before starting transaction. Otherwise, we would not generate the // stop condition below. if read.is_empty() { @@ -684,11 +688,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { /// Consecutive operations of same type are merged. See [transaction contract] for details. /// /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction - pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> - where - RXDMA: crate::i2c::RxDma<T>, - TXDMA: crate::i2c::TxDma<T>, - { + pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { for (op, frame) in operation_frames(operations)? { match op { Operation::Read(read) => self.read_frame(addr, read, frame).await?, @@ -700,9 +700,9 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } } -impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> { +impl<'d, M: PeriMode> Drop for I2c<'d, M> { fn drop(&mut self) { - T::disable(); + self.info.enable_bit.disable() } } @@ -806,20 +806,20 @@ impl Timings { } } -impl<'d, T: Instance> SetConfig for I2c<'d, T> { +impl<'d, M: PeriMode> SetConfig for I2c<'d, M> { type Config = Hertz; type ConfigError = (); fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - let timings = Timings::new(T::frequency(), *config); - T::regs().cr2().modify(|reg| { + let timings = Timings::new(self.kernel_clock, *config); + self.info.regs.cr2().modify(|reg| { reg.set_freq(timings.freq); }); - T::regs().ccr().modify(|reg| { + self.info.regs.ccr().modify(|reg| { reg.set_f_s(timings.mode.f_s()); reg.set_duty(timings.duty.duty()); reg.set_ccr(timings.ccr); }); - T::regs().trise().modify(|reg| { + self.info.regs.trise().modify(|reg| { reg.set_trise(timings.trise); }); diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index da3b0ee30..aa6daf786 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -7,11 +7,10 @@ use embassy_hal_internal::drop::OnDrop; use embedded_hal_1::i2c::Operation; use super::*; -use crate::dma::Transfer; use crate::pac::i2c; pub(crate) unsafe fn on_interrupt<T: Instance>() { - let regs = T::regs(); + let regs = T::info().regs; let isr = regs.isr().read(); if isr.tcr() || isr.tc() { @@ -24,16 +23,16 @@ pub(crate) unsafe fn on_interrupt<T: Instance>() { }); } -impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { +impl<'d, M: Mode> I2c<'d, M> { pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { - T::regs().cr1().modify(|reg| { + self.info.regs.cr1().modify(|reg| { reg.set_pe(false); reg.set_anfoff(false); }); - let timings = Timings::new(T::frequency(), freq.into()); + let timings = Timings::new(self.kernel_clock, freq.into()); - T::regs().timingr().write(|reg| { + self.info.regs.timingr().write(|reg| { reg.set_presc(timings.prescale); reg.set_scll(timings.scll); reg.set_sclh(timings.sclh); @@ -41,16 +40,17 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { reg.set_scldel(timings.scldel); }); - T::regs().cr1().modify(|reg| { + self.info.regs.cr1().modify(|reg| { reg.set_pe(true); }); } fn master_stop(&mut self) { - T::regs().cr2().write(|w| w.set_stop(true)); + self.info.regs.cr2().write(|w| w.set_stop(true)); } fn master_read( + info: &'static Info, address: u8, length: usize, stop: Stop, @@ -64,7 +64,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Wait for any previous address sequence to end // automatically. This could be up to 50% of a bus // cycle (ie. up to 0.5/freq) - while T::regs().cr2().read().start() { + while info.regs.cr2().read().start() { timeout.check()?; } } @@ -79,7 +79,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { i2c::vals::Reload::COMPLETED }; - T::regs().cr2().modify(|w| { + info.regs.cr2().modify(|w| { w.set_sadd((address << 1 | 0) as u16); w.set_add10(i2c::vals::Addmode::BIT7); w.set_dir(i2c::vals::Dir::READ); @@ -92,13 +92,20 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { Ok(()) } - fn master_write(address: u8, length: usize, stop: Stop, reload: bool, timeout: Timeout) -> Result<(), Error> { + fn master_write( + info: &'static Info, + address: u8, + length: usize, + stop: Stop, + reload: bool, + timeout: Timeout, + ) -> Result<(), Error> { assert!(length < 256); // Wait for any previous address sequence to end // automatically. This could be up to 50% of a bus // cycle (ie. up to 0.5/freq) - while T::regs().cr2().read().start() { + while info.regs.cr2().read().start() { timeout.check()?; } @@ -111,7 +118,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Set START and prepare to send `bytes`. The // START bit can be set even if the bus is BUSY or // I2C is in slave mode. - T::regs().cr2().modify(|w| { + info.regs.cr2().modify(|w| { w.set_sadd((address << 1 | 0) as u16); w.set_add10(i2c::vals::Addmode::BIT7); w.set_dir(i2c::vals::Dir::WRITE); @@ -124,10 +131,10 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { Ok(()) } - fn master_continue(length: usize, reload: bool, timeout: Timeout) -> Result<(), Error> { + fn master_continue(info: &'static Info, length: usize, reload: bool, timeout: Timeout) -> Result<(), Error> { assert!(length < 256 && length > 0); - while !T::regs().isr().read().tcr() { + while !info.regs.isr().read().tcr() { timeout.check()?; } @@ -137,7 +144,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { i2c::vals::Reload::COMPLETED }; - T::regs().cr2().modify(|w| { + info.regs.cr2().modify(|w| { w.set_nbytes(length as u8); w.set_reload(reload); }); @@ -146,27 +153,27 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } fn flush_txdr(&self) { - if T::regs().isr().read().txis() { - T::regs().txdr().write(|w| w.set_txdata(0)); + if self.info.regs.isr().read().txis() { + self.info.regs.txdr().write(|w| w.set_txdata(0)); } - if !T::regs().isr().read().txe() { - T::regs().isr().modify(|w| w.set_txe(true)) + if !self.info.regs.isr().read().txe() { + self.info.regs.isr().modify(|w| w.set_txe(true)) } } fn wait_txe(&self, timeout: Timeout) -> Result<(), Error> { loop { - let isr = T::regs().isr().read(); + let isr = self.info.regs.isr().read(); if isr.txe() { return Ok(()); } else if isr.berr() { - T::regs().icr().write(|reg| reg.set_berrcf(true)); + self.info.regs.icr().write(|reg| reg.set_berrcf(true)); return Err(Error::Bus); } else if isr.arlo() { - T::regs().icr().write(|reg| reg.set_arlocf(true)); + self.info.regs.icr().write(|reg| reg.set_arlocf(true)); return Err(Error::Arbitration); } else if isr.nackf() { - T::regs().icr().write(|reg| reg.set_nackcf(true)); + self.info.regs.icr().write(|reg| reg.set_nackcf(true)); self.flush_txdr(); return Err(Error::Nack); } @@ -177,17 +184,17 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { fn wait_rxne(&self, timeout: Timeout) -> Result<(), Error> { loop { - let isr = T::regs().isr().read(); + let isr = self.info.regs.isr().read(); if isr.rxne() { return Ok(()); } else if isr.berr() { - T::regs().icr().write(|reg| reg.set_berrcf(true)); + self.info.regs.icr().write(|reg| reg.set_berrcf(true)); return Err(Error::Bus); } else if isr.arlo() { - T::regs().icr().write(|reg| reg.set_arlocf(true)); + self.info.regs.icr().write(|reg| reg.set_arlocf(true)); return Err(Error::Arbitration); } else if isr.nackf() { - T::regs().icr().write(|reg| reg.set_nackcf(true)); + self.info.regs.icr().write(|reg| reg.set_nackcf(true)); self.flush_txdr(); return Err(Error::Nack); } @@ -198,17 +205,17 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { fn wait_tc(&self, timeout: Timeout) -> Result<(), Error> { loop { - let isr = T::regs().isr().read(); + let isr = self.info.regs.isr().read(); if isr.tc() { return Ok(()); } else if isr.berr() { - T::regs().icr().write(|reg| reg.set_berrcf(true)); + self.info.regs.icr().write(|reg| reg.set_berrcf(true)); return Err(Error::Bus); } else if isr.arlo() { - T::regs().icr().write(|reg| reg.set_arlocf(true)); + self.info.regs.icr().write(|reg| reg.set_arlocf(true)); return Err(Error::Arbitration); } else if isr.nackf() { - T::regs().icr().write(|reg| reg.set_nackcf(true)); + self.info.regs.icr().write(|reg| reg.set_nackcf(true)); self.flush_txdr(); return Err(Error::Nack); } @@ -227,6 +234,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { let last_chunk_idx = total_chunks.saturating_sub(1); Self::master_read( + self.info, address, read.len().min(255), Stop::Automatic, @@ -237,14 +245,14 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { for (number, chunk) in read.chunks_mut(255).enumerate() { if number != 0 { - Self::master_continue(chunk.len(), number != last_chunk_idx, timeout)?; + Self::master_continue(self.info, chunk.len(), number != last_chunk_idx, timeout)?; } for byte in chunk { // Wait until we have received something self.wait_rxne(timeout)?; - *byte = T::regs().rxdr().read().rxdata(); + *byte = self.info.regs.rxdr().read().rxdata(); } } Ok(()) @@ -263,6 +271,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // // ST SAD+W if let Err(err) = Self::master_write( + self.info, address, write.len().min(255), Stop::Software, @@ -277,7 +286,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { for (number, chunk) in write.chunks(255).enumerate() { if number != 0 { - Self::master_continue(chunk.len(), number != last_chunk_idx, timeout)?; + Self::master_continue(self.info, chunk.len(), number != last_chunk_idx, timeout)?; } for byte in chunk { @@ -291,7 +300,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { return Err(err); } - T::regs().txdr().write(|w| w.set_txdata(*byte)); + self.info.regs.txdr().write(|w| w.set_txdata(*byte)); } } // Wait until the write finishes @@ -302,276 +311,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { result } - async fn write_dma_internal( - &mut self, - address: u8, - write: &[u8], - first_slice: bool, - last_slice: bool, - timeout: Timeout, - ) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma<T>, - { - let total_len = write.len(); - - let dma_transfer = unsafe { - let regs = T::regs(); - regs.cr1().modify(|w| { - w.set_txdmaen(true); - if first_slice { - w.set_tcie(true); - } - }); - let dst = regs.txdr().as_ptr() as *mut u8; - - let ch = &mut self.tx_dma; - let request = ch.request(); - Transfer::new_write(ch, request, write, dst, Default::default()) - }; - - let state = T::state(); - let mut remaining_len = total_len; - - let on_drop = OnDrop::new(|| { - let regs = T::regs(); - regs.cr1().modify(|w| { - if last_slice { - w.set_txdmaen(false); - } - w.set_tcie(false); - }) - }); - - poll_fn(|cx| { - state.waker.register(cx.waker()); - - let isr = T::regs().isr().read(); - if remaining_len == total_len { - if first_slice { - Self::master_write( - address, - total_len.min(255), - Stop::Software, - (total_len > 255) || !last_slice, - timeout, - )?; - } else { - Self::master_continue(total_len.min(255), (total_len > 255) || !last_slice, timeout)?; - T::regs().cr1().modify(|w| w.set_tcie(true)); - } - } else if !(isr.tcr() || isr.tc()) { - // poll_fn was woken without an interrupt present - return Poll::Pending; - } else if remaining_len == 0 { - return Poll::Ready(Ok(())); - } else { - let last_piece = (remaining_len <= 255) && last_slice; - - if let Err(e) = Self::master_continue(remaining_len.min(255), !last_piece, timeout) { - return Poll::Ready(Err(e)); - } - T::regs().cr1().modify(|w| w.set_tcie(true)); - } - - remaining_len = remaining_len.saturating_sub(255); - Poll::Pending - }) - .await?; - - dma_transfer.await; - - if last_slice { - // This should be done already - self.wait_tc(timeout)?; - self.master_stop(); - } - - drop(on_drop); - - Ok(()) - } - - async fn read_dma_internal( - &mut self, - address: u8, - buffer: &mut [u8], - restart: bool, - timeout: Timeout, - ) -> Result<(), Error> - where - RXDMA: crate::i2c::RxDma<T>, - { - let total_len = buffer.len(); - - let dma_transfer = unsafe { - let regs = T::regs(); - regs.cr1().modify(|w| { - w.set_rxdmaen(true); - w.set_tcie(true); - }); - let src = regs.rxdr().as_ptr() as *mut u8; - - let ch = &mut self.rx_dma; - let request = ch.request(); - Transfer::new_read(ch, request, src, buffer, Default::default()) - }; - - let state = T::state(); - let mut remaining_len = total_len; - - let on_drop = OnDrop::new(|| { - let regs = T::regs(); - regs.cr1().modify(|w| { - w.set_rxdmaen(false); - w.set_tcie(false); - }) - }); - - poll_fn(|cx| { - state.waker.register(cx.waker()); - - let isr = T::regs().isr().read(); - if remaining_len == total_len { - Self::master_read( - address, - total_len.min(255), - Stop::Software, - total_len > 255, - restart, - timeout, - )?; - } else if !(isr.tcr() || isr.tc()) { - // poll_fn was woken without an interrupt present - return Poll::Pending; - } else if remaining_len == 0 { - return Poll::Ready(Ok(())); - } else { - let last_piece = remaining_len <= 255; - - if let Err(e) = Self::master_continue(remaining_len.min(255), !last_piece, timeout) { - return Poll::Ready(Err(e)); - } - T::regs().cr1().modify(|w| w.set_tcie(true)); - } - - remaining_len = remaining_len.saturating_sub(255); - Poll::Pending - }) - .await?; - - dma_transfer.await; - - // This should be done already - self.wait_tc(timeout)?; - self.master_stop(); - - drop(on_drop); - - Ok(()) - } - - // ========================= - // Async public API - - /// Write. - pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma<T>, - { - let timeout = self.timeout(); - if write.is_empty() { - self.write_internal(address, write, true, timeout) - } else { - timeout - .with(self.write_dma_internal(address, write, true, true, timeout)) - .await - } - } - - /// Write multiple buffers. - /// - /// The buffers are concatenated in a single write transaction. - pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma<T>, - { - let timeout = self.timeout(); - - if write.is_empty() { - return Err(Error::ZeroLengthTransfer); - } - let mut iter = write.iter(); - - let mut first = true; - let mut current = iter.next(); - while let Some(c) = current { - let next = iter.next(); - let is_last = next.is_none(); - - let fut = self.write_dma_internal(address, c, first, is_last, timeout); - timeout.with(fut).await?; - first = false; - current = next; - } - Ok(()) - } - - /// Read. - pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> - where - RXDMA: crate::i2c::RxDma<T>, - { - let timeout = self.timeout(); - - if buffer.is_empty() { - self.read_internal(address, buffer, false, timeout) - } else { - let fut = self.read_dma_internal(address, buffer, false, timeout); - timeout.with(fut).await - } - } - - /// Write, restart, read. - pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> - where - TXDMA: super::TxDma<T>, - RXDMA: super::RxDma<T>, - { - let timeout = self.timeout(); - - if write.is_empty() { - self.write_internal(address, write, false, timeout)?; - } else { - let fut = self.write_dma_internal(address, write, true, true, timeout); - timeout.with(fut).await?; - } - - if read.is_empty() { - self.read_internal(address, read, true, timeout)?; - } else { - let fut = self.read_dma_internal(address, read, true, timeout); - timeout.with(fut).await?; - } - - Ok(()) - } - - /// Transaction with operations. - /// - /// Consecutive operations of same type are merged. See [transaction contract] for details. - /// - /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction - pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> - where - RXDMA: crate::i2c::RxDma<T>, - TXDMA: crate::i2c::TxDma<T>, - { - let _ = addr; - let _ = operations; - todo!() - } - // ========================= // Blocking public API @@ -619,6 +358,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { let last_slice_index = write.len() - 1; if let Err(err) = Self::master_write( + self.info, address, first_length.min(255), Stop::Software, @@ -641,6 +381,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { if idx != 0 { if let Err(err) = Self::master_continue( + self.info, slice_len.min(255), (idx != last_slice_index) || (slice_len > 255), timeout, @@ -653,6 +394,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { for (number, chunk) in slice.chunks(255).enumerate() { if number != 0 { if let Err(err) = Self::master_continue( + self.info, chunk.len(), (number != last_chunk_idx) || (idx != last_slice_index), timeout, @@ -673,7 +415,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Put byte on the wire //self.i2c.txdr.write(|w| w.txdata().bits(*byte)); - T::regs().txdr().write(|w| w.set_txdata(*byte)); + self.info.regs.txdr().write(|w| w.set_txdata(*byte)); } } } @@ -684,9 +426,254 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } } -impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> { +impl<'d> I2c<'d, Async> { + async fn write_dma_internal( + &mut self, + address: u8, + write: &[u8], + first_slice: bool, + last_slice: bool, + timeout: Timeout, + ) -> Result<(), Error> { + let total_len = write.len(); + + let dma_transfer = unsafe { + let regs = self.info.regs; + regs.cr1().modify(|w| { + w.set_txdmaen(true); + if first_slice { + w.set_tcie(true); + } + }); + let dst = regs.txdr().as_ptr() as *mut u8; + + self.tx_dma.as_mut().unwrap().write(write, dst, Default::default()) + }; + + let mut remaining_len = total_len; + + let on_drop = OnDrop::new(|| { + let regs = self.info.regs; + regs.cr1().modify(|w| { + if last_slice { + w.set_txdmaen(false); + } + w.set_tcie(false); + }) + }); + + poll_fn(|cx| { + self.state.waker.register(cx.waker()); + + let isr = self.info.regs.isr().read(); + if remaining_len == total_len { + if first_slice { + Self::master_write( + self.info, + address, + total_len.min(255), + Stop::Software, + (total_len > 255) || !last_slice, + timeout, + )?; + } else { + Self::master_continue(self.info, total_len.min(255), (total_len > 255) || !last_slice, timeout)?; + self.info.regs.cr1().modify(|w| w.set_tcie(true)); + } + } else if !(isr.tcr() || isr.tc()) { + // poll_fn was woken without an interrupt present + return Poll::Pending; + } else if remaining_len == 0 { + return Poll::Ready(Ok(())); + } else { + let last_piece = (remaining_len <= 255) && last_slice; + + if let Err(e) = Self::master_continue(self.info, remaining_len.min(255), !last_piece, timeout) { + return Poll::Ready(Err(e)); + } + self.info.regs.cr1().modify(|w| w.set_tcie(true)); + } + + remaining_len = remaining_len.saturating_sub(255); + Poll::Pending + }) + .await?; + + dma_transfer.await; + + if last_slice { + // This should be done already + self.wait_tc(timeout)?; + self.master_stop(); + } + + drop(on_drop); + + Ok(()) + } + + async fn read_dma_internal( + &mut self, + address: u8, + buffer: &mut [u8], + restart: bool, + timeout: Timeout, + ) -> Result<(), Error> { + let total_len = buffer.len(); + + let dma_transfer = unsafe { + let regs = self.info.regs; + regs.cr1().modify(|w| { + w.set_rxdmaen(true); + w.set_tcie(true); + }); + let src = regs.rxdr().as_ptr() as *mut u8; + + self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) + }; + + let mut remaining_len = total_len; + + let on_drop = OnDrop::new(|| { + let regs = self.info.regs; + regs.cr1().modify(|w| { + w.set_rxdmaen(false); + w.set_tcie(false); + }) + }); + + poll_fn(|cx| { + self.state.waker.register(cx.waker()); + + let isr = self.info.regs.isr().read(); + if remaining_len == total_len { + Self::master_read( + self.info, + address, + total_len.min(255), + Stop::Software, + total_len > 255, + restart, + timeout, + )?; + } else if !(isr.tcr() || isr.tc()) { + // poll_fn was woken without an interrupt present + return Poll::Pending; + } else if remaining_len == 0 { + return Poll::Ready(Ok(())); + } else { + let last_piece = remaining_len <= 255; + + if let Err(e) = Self::master_continue(self.info, remaining_len.min(255), !last_piece, timeout) { + return Poll::Ready(Err(e)); + } + self.info.regs.cr1().modify(|w| w.set_tcie(true)); + } + + remaining_len = remaining_len.saturating_sub(255); + Poll::Pending + }) + .await?; + + dma_transfer.await; + + // This should be done already + self.wait_tc(timeout)?; + self.master_stop(); + + drop(on_drop); + + Ok(()) + } + + // ========================= + // Async public API + + /// Write. + pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { + let timeout = self.timeout(); + if write.is_empty() { + self.write_internal(address, write, true, timeout) + } else { + timeout + .with(self.write_dma_internal(address, write, true, true, timeout)) + .await + } + } + + /// Write multiple buffers. + /// + /// The buffers are concatenated in a single write transaction. + pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> { + let timeout = self.timeout(); + + if write.is_empty() { + return Err(Error::ZeroLengthTransfer); + } + let mut iter = write.iter(); + + let mut first = true; + let mut current = iter.next(); + while let Some(c) = current { + let next = iter.next(); + let is_last = next.is_none(); + + let fut = self.write_dma_internal(address, c, first, is_last, timeout); + timeout.with(fut).await?; + first = false; + current = next; + } + Ok(()) + } + + /// Read. + pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { + let timeout = self.timeout(); + + if buffer.is_empty() { + self.read_internal(address, buffer, false, timeout) + } else { + let fut = self.read_dma_internal(address, buffer, false, timeout); + timeout.with(fut).await + } + } + + /// Write, restart, read. + pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { + let timeout = self.timeout(); + + if write.is_empty() { + self.write_internal(address, write, false, timeout)?; + } else { + let fut = self.write_dma_internal(address, write, true, true, timeout); + timeout.with(fut).await?; + } + + if read.is_empty() { + self.read_internal(address, read, true, timeout)?; + } else { + let fut = self.read_dma_internal(address, read, true, timeout); + timeout.with(fut).await?; + } + + Ok(()) + } + + /// Transaction with operations. + /// + /// Consecutive operations of same type are merged. See [transaction contract] for details. + /// + /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction + pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { + let _ = addr; + let _ = operations; + todo!() + } +} + +impl<'d, M: Mode> Drop for I2c<'d, M> { fn drop(&mut self) { - T::disable(); + self.info.enable_bit.disable(); } } @@ -814,12 +801,12 @@ impl Timings { } } -impl<'d, T: Instance> SetConfig for I2c<'d, T> { +impl<'d, M: Mode> SetConfig for I2c<'d, M> { type Config = Hertz; type ConfigError = (); fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - let timings = Timings::new(T::frequency(), *config); - T::regs().timingr().write(|reg| { + let timings = Timings::new(self.kernel_clock, *config); + self.info.regs.timingr().write(|reg| { reg.set_presc(timings.prescale); reg.set_scll(timings.scll); reg.set_sclh(timings.sclh); diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs index c5a606b21..c78810a38 100644 --- a/embassy-stm32/src/i2s.rs +++ b/embassy-stm32/src/i2s.rs @@ -2,6 +2,7 @@ use embassy_hal_internal::into_ref; use crate::gpio::{AFType, AnyPin, SealedPin}; +use crate::mode::Async; use crate::pac::spi::vals; use crate::spi::{Config as SpiConfig, *}; use crate::time::Hertz; @@ -152,24 +153,24 @@ impl Default for Config { } /// I2S driver. -pub struct I2S<'d, T: Instance, Tx, Rx> { - _peri: Spi<'d, T, Tx, Rx>, +pub struct I2S<'d> { + _peri: Spi<'d, Async>, sd: Option<PeripheralRef<'d, AnyPin>>, ws: Option<PeripheralRef<'d, AnyPin>>, ck: Option<PeripheralRef<'d, AnyPin>>, mck: Option<PeripheralRef<'d, AnyPin>>, } -impl<'d, T: Instance, Tx, Rx> I2S<'d, T, Tx, Rx> { +impl<'d> I2S<'d> { /// Note: Full-Duplex modes are not supported at this time - pub fn new( + pub fn new<T: Instance>( peri: impl Peripheral<P = T> + 'd, sd: impl Peripheral<P = impl MosiPin<T>> + 'd, ws: impl Peripheral<P = impl WsPin<T>> + 'd, ck: impl Peripheral<P = impl CkPin<T>> + 'd, mck: impl Peripheral<P = impl MckPin<T>> + 'd, - txdma: impl Peripheral<P = Tx> + 'd, - rxdma: impl Peripheral<P = Rx> + 'd, + txdma: impl Peripheral<P = impl TxDma<T>> + 'd, + rxdma: impl Peripheral<P = impl RxDma<T>> + 'd, freq: Hertz, config: Config, ) -> Self { @@ -207,7 +208,7 @@ impl<'d, T: Instance, Tx, Rx> I2S<'d, T, Tx, Rx> { // rate to reach the proper audio sample frequency. The ODD bit in the SPI_I2SPR // register also has to be defined. - T::REGS.i2spr().modify(|w| { + spi.info.regs.i2spr().modify(|w| { w.set_i2sdiv(div); w.set_odd(match odd { true => Odd::ODD, @@ -234,7 +235,7 @@ impl<'d, T: Instance, Tx, Rx> I2S<'d, T, Tx, Rx> { // 5. The I2SE bit in SPI_I2SCFGR register must be set. - T::REGS.i2scfgr().modify(|w| { + spi.info.regs.i2scfgr().modify(|w| { w.set_ckpol(config.clock_polarity.ckpol()); w.set_i2smod(true); @@ -265,24 +266,17 @@ impl<'d, T: Instance, Tx, Rx> I2S<'d, T, Tx, Rx> { } /// Write audio data. - pub async fn write<W: Word>(&mut self, data: &[W]) -> Result<(), Error> - where - Tx: TxDma<T>, - { + pub async fn write<W: Word>(&mut self, data: &[W]) -> Result<(), Error> { self._peri.write(data).await } /// Read audio data. - pub async fn read<W: Word>(&mut self, data: &mut [W]) -> Result<(), Error> - where - Tx: TxDma<T>, - Rx: RxDma<T>, - { + pub async fn read<W: Word>(&mut self, data: &mut [W]) -> Result<(), Error> { self._peri.read(data).await } } -impl<'d, T: Instance, Tx, Rx> Drop for I2S<'d, T, Tx, Rx> { +impl<'d> Drop for I2S<'d> { fn drop(&mut self) { self.sd.as_ref().map(|x| x.set_as_disconnected()); self.ws.as_ref().map(|x| x.set_as_disconnected()); diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index ea17f8477..81ee60c1c 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -2,7 +2,7 @@ #![allow(async_fn_in_trait)] #![cfg_attr( docsrs, - doc = "<div style='padding:30px;background:#810;color:#fff;text-align:center;'><p>You might want to <a href='https://docs.embassy.dev/embassy-stm32'>browse the `embassy-stm32` documentation on the Embassy website</a> instead.</p><p>The documentation here on `docs.rs` is built for a single chip only (STM32H755 in particular), while on the Embassy website you can pick your exact chip from the top menu. Available peripherals and their APIs change depending on the chip.</p></div>\n\n" + doc = "<div style='padding:30px;background:#810;color:#fff;text-align:center;'><p>You might want to <a href='https://docs.embassy.dev/embassy-stm32'>browse the `embassy-stm32` documentation on the Embassy website</a> instead.</p><p>The documentation here on `docs.rs` is built for a single chip only (stm32h7, stm32h7rs55 in particular), while on the Embassy website you can pick your exact chip from the top menu. Available peripherals and their APIs change depending on the chip.</p></div>\n\n" )] #![doc = include_str!("../README.md")] #![warn(missing_docs)] @@ -15,8 +15,31 @@ mod fmt; include!(concat!(env!("OUT_DIR"), "/_macros.rs")); // Utilities +mod macros; pub mod time; -mod traits; +/// Operating modes for peripherals. +pub mod mode { + trait SealedMode {} + + /// Operating mode for a peripheral. + #[allow(private_bounds)] + pub trait Mode: SealedMode {} + + macro_rules! impl_mode { + ($name:ident) => { + impl SealedMode for $name {} + impl Mode for $name {} + }; + } + + /// Blocking mode. + pub struct Blocking; + /// Async mode. + pub struct Async; + + impl_mode!(Blocking); + impl_mode!(Async); +} // Always-present hardware pub mod dma; @@ -43,6 +66,8 @@ pub mod cryp; pub mod dac; #[cfg(dcmi)] pub mod dcmi; +#[cfg(dsihost)] +pub mod dsihost; #[cfg(eth)] pub mod eth; #[cfg(feature = "exti")] @@ -54,6 +79,8 @@ pub mod fmc; pub mod hash; #[cfg(hrtim)] pub mod hrtim; +#[cfg(hsem)] +pub mod hsem; #[cfg(i2c)] pub mod i2c; #[cfg(all(spi_v1, rcc_f4))] @@ -62,6 +89,8 @@ pub mod i2s; pub mod ipcc; #[cfg(feature = "low-power")] pub mod low_power; +#[cfg(ltdc)] +pub mod ltdc; #[cfg(opamp)] pub mod opamp; #[cfg(octospi)] @@ -78,6 +107,8 @@ pub mod sai; pub mod sdmmc; #[cfg(spi)] pub mod spi; +#[cfg(tsc)] +pub mod tsc; #[cfg(ucpd)] pub mod ucpd; #[cfg(uid)] @@ -280,9 +311,9 @@ pub fn init(config: Config) -> Peripherals { #[cfg(not(any(stm32f1, stm32wb, stm32wl)))] peripherals::SYSCFG::enable_and_reset_with_cs(cs); - #[cfg(not(any(stm32h5, stm32h7, stm32wb, stm32wl)))] + #[cfg(not(any(stm32h5, stm32h7, stm32h7rs, stm32wb, stm32wl)))] peripherals::PWR::enable_and_reset_with_cs(cs); - #[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7)))] + #[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7, stm32h7rs)))] peripherals::FLASH::enable_and_reset_with_cs(cs); // Enable the VDDIO2 power supply on chips that have it. diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index 4c3d288fd..604bdf416 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs @@ -10,14 +10,14 @@ //! exceptions to this rule: //! //! * `GPIO` -//! * `RCC` +//! * `RTC` //! //! Since entering and leaving low-power modes typically incurs a significant latency, the //! low-power executor will only attempt to enter when the next timer event is at least //! [`time_driver::MIN_STOP_PAUSE`] in the future. //! //! Currently there is no macro analogous to `embassy_executor::main` for this executor; -//! consequently one must define their entrypoint manually. Moveover, you must relinquish control +//! consequently one must define their entrypoint manually. Moreover, you must relinquish control //! of the `RTC` peripheral to the executor. This will typically look like //! //! ```rust,no_run @@ -99,7 +99,7 @@ pub fn stop_ready(stop_mode: StopMode) -> bool { } } -/// Available stop modes. +/// Available Stop modes. #[non_exhaustive] #[derive(PartialEq)] pub enum StopMode { @@ -183,6 +183,12 @@ impl Executor { fn configure_stop(&mut self, stop_mode: StopMode) { #[cfg(stm32l5)] crate::pac::PWR.cr1().modify(|m| m.set_lpms(stop_mode.into())); + #[cfg(stm32h5)] + crate::pac::PWR.pmcr().modify(|v| { + use crate::pac::pwr::vals; + v.set_lpms(vals::Lpms::STOP); + v.set_svos(vals::Svos::SCALE3); + }); } fn configure_pwr(&mut self) { @@ -191,21 +197,26 @@ impl Executor { compiler_fence(Ordering::SeqCst); let stop_mode = self.stop_mode(); + if stop_mode.is_none() { trace!("low power: not ready to stop"); - } else if self.time_driver.pause_time().is_err() { - trace!("low power: failed to pause time"); - } else { - let stop_mode = stop_mode.unwrap(); - match stop_mode { - StopMode::Stop1 => trace!("low power: stop 1"), - StopMode::Stop2 => trace!("low power: stop 2"), - } - self.configure_stop(stop_mode); - - #[cfg(not(feature = "low-power-debug-with-sleep"))] - self.scb.set_sleepdeep(); + return; } + + if self.time_driver.pause_time().is_err() { + trace!("low power: failed to pause time"); + return; + } + + let stop_mode = stop_mode.unwrap(); + match stop_mode { + StopMode::Stop1 => trace!("low power: stop 1"), + StopMode::Stop2 => trace!("low power: stop 2"), + } + self.configure_stop(stop_mode); + + #[cfg(not(feature = "low-power-debug-with-sleep"))] + self.scb.set_sleepdeep(); } /// Run the executor. diff --git a/embassy-stm32/src/ltdc.rs b/embassy-stm32/src/ltdc.rs new file mode 100644 index 000000000..0cc8a0557 --- /dev/null +++ b/embassy-stm32/src/ltdc.rs @@ -0,0 +1,142 @@ +//! LTDC +use core::marker::PhantomData; + +use crate::rcc::RccPeripheral; +use crate::{peripherals, Peripheral}; + +/// LTDC driver. +pub struct Ltdc<'d, T: Instance> { + _peri: PhantomData<&'d mut T>, +} + +impl<'d, T: Instance> Ltdc<'d, T> { + /// Note: Full-Duplex modes are not supported at this time + pub fn new( + _peri: impl Peripheral<P = T> + 'd, + /* + clk: impl Peripheral<P = impl ClkPin<T>> + 'd, + hsync: impl Peripheral<P = impl HsyncPin<T>> + 'd, + vsync: impl Peripheral<P = impl VsyncPin<T>> + 'd, + b0: impl Peripheral<P = impl B0Pin<T>> + 'd, + b1: impl Peripheral<P = impl B1Pin<T>> + 'd, + b2: impl Peripheral<P = impl B2Pin<T>> + 'd, + b3: impl Peripheral<P = impl B3Pin<T>> + 'd, + b4: impl Peripheral<P = impl B4Pin<T>> + 'd, + b5: impl Peripheral<P = impl B5Pin<T>> + 'd, + b6: impl Peripheral<P = impl B6Pin<T>> + 'd, + b7: impl Peripheral<P = impl B7Pin<T>> + 'd, + g0: impl Peripheral<P = impl G0Pin<T>> + 'd, + g1: impl Peripheral<P = impl G1Pin<T>> + 'd, + g2: impl Peripheral<P = impl G2Pin<T>> + 'd, + g3: impl Peripheral<P = impl G3Pin<T>> + 'd, + g4: impl Peripheral<P = impl G4Pin<T>> + 'd, + g5: impl Peripheral<P = impl G5Pin<T>> + 'd, + g6: impl Peripheral<P = impl G6Pin<T>> + 'd, + g7: impl Peripheral<P = impl G7Pin<T>> + 'd, + r0: impl Peripheral<P = impl R0Pin<T>> + 'd, + r1: impl Peripheral<P = impl R1Pin<T>> + 'd, + r2: impl Peripheral<P = impl R2Pin<T>> + 'd, + r3: impl Peripheral<P = impl R3Pin<T>> + 'd, + r4: impl Peripheral<P = impl R4Pin<T>> + 'd, + r5: impl Peripheral<P = impl R5Pin<T>> + 'd, + r6: impl Peripheral<P = impl R6Pin<T>> + 'd, + r7: impl Peripheral<P = impl R7Pin<T>> + 'd, + */ + ) -> Self { + //into_ref!(clk); + + critical_section::with(|_cs| { + // RM says the pllsaidivr should only be changed when pllsai is off. But this could have other unintended side effects. So let's just give it a try like this. + // According to the debugger, this bit gets set, anyway. + #[cfg(stm32f7)] + stm32_metapac::RCC + .dckcfgr1() + .modify(|w| w.set_pllsaidivr(stm32_metapac::rcc::vals::Pllsaidivr::DIV2)); + + // It is set to RCC_PLLSAIDIVR_2 in ST's BSP example for the STM32469I-DISCO. + #[cfg(not(any(stm32f7, stm32u5)))] + stm32_metapac::RCC + .dckcfgr() + .modify(|w| w.set_pllsaidivr(stm32_metapac::rcc::vals::Pllsaidivr::DIV2)); + }); + + T::enable_and_reset(); + + //new_pin!(clk, AFType::OutputPushPull, Speed::VeryHigh, Pull::None); + + // Set Tearing Enable pin according to CubeMx example + //te.set_as_af_pull(te.af_num(), AFType::OutputPushPull, Pull::None); + //te.set_speed(Speed::Low); + /* + T::regs().wcr().modify(|w| { + w.set_dsien(true); + }); + */ + Self { _peri: PhantomData } + } + + /// Set the enable bit in the control register and assert that it has been enabled + pub fn enable(&mut self) { + T::regs().gcr().modify(|w| w.set_ltdcen(true)); + assert!(T::regs().gcr().read().ltdcen()) + } + + /// Unset the enable bit in the control register and assert that it has been disabled + pub fn disable(&mut self) { + T::regs().gcr().modify(|w| w.set_ltdcen(false)); + assert!(!T::regs().gcr().read().ltdcen()) + } +} + +impl<'d, T: Instance> Drop for Ltdc<'d, T> { + fn drop(&mut self) {} +} + +trait SealedInstance: crate::rcc::SealedRccPeripheral { + fn regs() -> &'static crate::pac::ltdc::Ltdc; +} + +/// DSI instance trait. +#[allow(private_bounds)] +pub trait Instance: SealedInstance + RccPeripheral + 'static {} + +pin_trait!(ClkPin, Instance); +pin_trait!(HsyncPin, Instance); +pin_trait!(VsyncPin, Instance); +pin_trait!(DePin, Instance); +pin_trait!(R0Pin, Instance); +pin_trait!(R1Pin, Instance); +pin_trait!(R2Pin, Instance); +pin_trait!(R3Pin, Instance); +pin_trait!(R4Pin, Instance); +pin_trait!(R5Pin, Instance); +pin_trait!(R6Pin, Instance); +pin_trait!(R7Pin, Instance); +pin_trait!(G0Pin, Instance); +pin_trait!(G1Pin, Instance); +pin_trait!(G2Pin, Instance); +pin_trait!(G3Pin, Instance); +pin_trait!(G4Pin, Instance); +pin_trait!(G5Pin, Instance); +pin_trait!(G6Pin, Instance); +pin_trait!(G7Pin, Instance); +pin_trait!(B0Pin, Instance); +pin_trait!(B1Pin, Instance); +pin_trait!(B2Pin, Instance); +pin_trait!(B3Pin, Instance); +pin_trait!(B4Pin, Instance); +pin_trait!(B5Pin, Instance); +pin_trait!(B6Pin, Instance); +pin_trait!(B7Pin, Instance); + +foreach_peripheral!( + (ltdc, $inst:ident) => { + impl crate::ltdc::SealedInstance for peripherals::$inst { + fn regs() -> &'static crate::pac::ltdc::Ltdc { + &crate::pac::$inst + } + } + + impl crate::ltdc::Instance for peripherals::$inst {} + }; +); diff --git a/embassy-stm32/src/macros.rs b/embassy-stm32/src/macros.rs new file mode 100644 index 000000000..dcd25cbe9 --- /dev/null +++ b/embassy-stm32/src/macros.rs @@ -0,0 +1,119 @@ +#![macro_use] + +macro_rules! peri_trait { + ( + $(irqs: [$($irq:ident),*],)? + ) => { + #[allow(private_interfaces)] + pub(crate) trait SealedInstance { + #[allow(unused)] + fn info() -> &'static Info; + #[allow(unused)] + fn state() -> &'static State; + } + + /// Peripheral instance trait. + #[allow(private_bounds)] + pub trait Instance: crate::Peripheral<P = Self> + SealedInstance + crate::rcc::RccPeripheral { + $($( + /// Interrupt for this peripheral. + type $irq: crate::interrupt::typelevel::Interrupt; + )*)? + } + }; +} + +macro_rules! peri_trait_impl { + ($instance:ident, $info:expr) => { + #[allow(private_interfaces)] + impl SealedInstance for crate::peripherals::$instance { + fn info() -> &'static Info { + static INFO: Info = $info; + &INFO + } + fn state() -> &'static State { + static STATE: State = State::new(); + &STATE + } + } + impl Instance for crate::peripherals::$instance {} + }; +} + +macro_rules! pin_trait { + ($signal:ident, $instance:path $(, $mode:path)?) => { + #[doc = concat!(stringify!($signal), " pin trait")] + pub trait $signal<T: $instance $(, M: $mode)?>: crate::gpio::Pin { + #[doc = concat!("Get the AF number needed to use this pin as ", stringify!($signal))] + fn af_num(&self) -> u8; + } + }; +} + +macro_rules! pin_trait_impl { + (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $pin:ident, $af:expr) => { + impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$pin { + fn af_num(&self) -> u8 { + $af + } + } + }; +} + +// ==================== + +macro_rules! dma_trait { + ($signal:ident, $instance:path$(, $mode:path)?) => { + #[doc = concat!(stringify!($signal), " DMA request trait")] + pub trait $signal<T: $instance $(, M: $mode)?>: crate::dma::Channel { + #[doc = concat!("Get the DMA request number needed to use this channel as", stringify!($signal))] + /// Note: in some chips, ST calls this the "channel", and calls channels "streams". + /// `embassy-stm32` always uses the "channel" and "request number" names. + fn request(&self) -> crate::dma::Request; + } + }; +} + +#[allow(unused)] +macro_rules! dma_trait_impl { + (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $channel:ident, $request:expr) => { + impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$channel { + fn request(&self) -> crate::dma::Request { + $request + } + } + }; +} + +macro_rules! new_dma { + ($name:ident) => {{ + let dma = $name.into_ref(); + let request = dma.request(); + Some(crate::dma::ChannelAndRequest { + channel: dma.map_into(), + request, + }) + }}; +} + +macro_rules! new_pin { + ($name:ident, $aftype:expr) => {{ + new_pin!($name, $aftype, crate::gpio::Speed::Medium, crate::gpio::Pull::None) + }}; + ($name:ident, $aftype:expr, $speed:expr) => { + new_pin!($name, $aftype, $speed, crate::gpio::Pull::None) + }; + ($name:ident, $aftype:expr, $speed:expr, $pull:expr) => {{ + let pin = $name.into_ref(); + pin.set_as_af_pull(pin.af_num(), $aftype, $pull); + // Do not call set_speed on AFType::Input, as MODE and CNF bits are not independent + // for gpio_v1 + match $aftype { + crate::gpio::AFType::Input => {} + _ => { + pin.set_speed($speed); + } + }; + Some(pin.map_into()) + }}; +} diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs index a3b4352c0..487902959 100644 --- a/embassy-stm32/src/opamp.rs +++ b/embassy-stm32/src/opamp.rs @@ -198,7 +198,7 @@ macro_rules! impl_opamp_external_output { ($inst:ident, $adc:ident, $ch:expr) => { foreach_adc!( ($adc, $common_inst:ident, $adc_clock:ident) => { - impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc> + impl<'d> crate::adc::SealedAdcChannel<crate::peripherals::$adc> for OpAmpOutput<'d, crate::peripherals::$inst> { fn channel(&self) -> u8 { @@ -206,7 +206,7 @@ macro_rules! impl_opamp_external_output { } } - impl<'d> crate::adc::AdcPin<crate::peripherals::$adc> + impl<'d> crate::adc::AdcChannel<crate::peripherals::$adc> for OpAmpOutput<'d, crate::peripherals::$inst> { } @@ -244,7 +244,7 @@ macro_rules! impl_opamp_internal_output { ($inst:ident, $adc:ident, $ch:expr) => { foreach_adc!( ($adc, $common_inst:ident, $adc_clock:ident) => { - impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc> + impl<'d> crate::adc::SealedAdcChannel<crate::peripherals::$adc> for OpAmpInternalOutput<'d, crate::peripherals::$inst> { fn channel(&self) -> u8 { @@ -252,7 +252,7 @@ macro_rules! impl_opamp_internal_output { } } - impl<'d> crate::adc::AdcPin<crate::peripherals::$adc> + impl<'d> crate::adc::AdcChannel<crate::peripherals::$adc> for OpAmpInternalOutput<'d, crate::peripherals::$inst> { } diff --git a/embassy-stm32/src/ospi/mod.rs b/embassy-stm32/src/ospi/mod.rs index 398c3298f..536da4ca0 100644 --- a/embassy-stm32/src/ospi/mod.rs +++ b/embassy-stm32/src/ospi/mod.rs @@ -5,13 +5,16 @@ pub mod enums; +use core::marker::PhantomData; + use embassy_embedded_hal::{GetConfig, SetConfig}; use embassy_hal_internal::{into_ref, PeripheralRef}; pub use enums::*; use stm32_metapac::octospi::vals::{PhaseMode, SizeInBits}; -use crate::dma::{word, Transfer}; -use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _}; +use crate::dma::{word, ChannelAndRequest}; +use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; +use crate::mode::{Async, Blocking, Mode as PeriMode}; use crate::pac::octospi::{vals, Octospi as Regs}; use crate::rcc::RccPeripheral; use crate::{peripherals, Peripheral}; @@ -154,7 +157,7 @@ pub enum OspiError { } /// OSPI driver. -pub struct Ospi<'d, T: Instance, Dma> { +pub struct Ospi<'d, T: Instance, M: PeriMode> { _peri: PeripheralRef<'d, T>, sck: Option<PeripheralRef<'d, AnyPin>>, d0: Option<PeripheralRef<'d, AnyPin>>, @@ -167,259 +170,13 @@ pub struct Ospi<'d, T: Instance, Dma> { d7: Option<PeripheralRef<'d, AnyPin>>, nss: Option<PeripheralRef<'d, AnyPin>>, dqs: Option<PeripheralRef<'d, AnyPin>>, - dma: PeripheralRef<'d, Dma>, + dma: Option<ChannelAndRequest<'d>>, + _phantom: PhantomData<M>, config: Config, width: OspiWidth, } -impl<'d, T: Instance, Dma> Ospi<'d, T, Dma> { - /// Create new OSPI driver for a single spi external chip - pub fn new_singlespi( - peri: impl Peripheral<P = T> + 'd, - sck: impl Peripheral<P = impl SckPin<T>> + 'd, - d0: impl Peripheral<P = impl D0Pin<T>> + 'd, - d1: impl Peripheral<P = impl D1Pin<T>> + 'd, - nss: impl Peripheral<P = impl NSSPin<T>> + 'd, - dma: impl Peripheral<P = Dma> + 'd, - config: Config, - ) -> Self { - into_ref!(peri, sck, d0, d1, nss); - - sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None); - sck.set_speed(crate::gpio::Speed::VeryHigh); - nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up); - nss.set_speed(crate::gpio::Speed::VeryHigh); - d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None); - d0.set_speed(crate::gpio::Speed::VeryHigh); - d1.set_as_af_pull(d1.af_num(), AFType::Input, Pull::None); - d1.set_speed(crate::gpio::Speed::VeryHigh); - - Self::new_inner( - peri, - Some(d0.map_into()), - Some(d1.map_into()), - None, - None, - None, - None, - None, - None, - Some(sck.map_into()), - Some(nss.map_into()), - None, - dma, - config, - OspiWidth::SING, - false, - ) - } - - /// Create new OSPI driver for a dualspi external chip - pub fn new_dualspi( - peri: impl Peripheral<P = T> + 'd, - sck: impl Peripheral<P = impl SckPin<T>> + 'd, - d0: impl Peripheral<P = impl D0Pin<T>> + 'd, - d1: impl Peripheral<P = impl D1Pin<T>> + 'd, - nss: impl Peripheral<P = impl NSSPin<T>> + 'd, - dma: impl Peripheral<P = Dma> + 'd, - config: Config, - ) -> Self { - into_ref!(peri, sck, d0, d1, nss); - - sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None); - sck.set_speed(crate::gpio::Speed::VeryHigh); - nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up); - nss.set_speed(crate::gpio::Speed::VeryHigh); - d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None); - d0.set_speed(crate::gpio::Speed::VeryHigh); - d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::None); - d1.set_speed(crate::gpio::Speed::VeryHigh); - - Self::new_inner( - peri, - Some(d0.map_into()), - Some(d1.map_into()), - None, - None, - None, - None, - None, - None, - Some(sck.map_into()), - Some(nss.map_into()), - None, - dma, - config, - OspiWidth::DUAL, - false, - ) - } - - /// Create new OSPI driver for a quadspi external chip - pub fn new_quadspi( - peri: impl Peripheral<P = T> + 'd, - sck: impl Peripheral<P = impl SckPin<T>> + 'd, - d0: impl Peripheral<P = impl D0Pin<T>> + 'd, - d1: impl Peripheral<P = impl D1Pin<T>> + 'd, - d2: impl Peripheral<P = impl D2Pin<T>> + 'd, - d3: impl Peripheral<P = impl D3Pin<T>> + 'd, - nss: impl Peripheral<P = impl NSSPin<T>> + 'd, - dma: impl Peripheral<P = Dma> + 'd, - config: Config, - ) -> Self { - into_ref!(peri, sck, d0, d1, d2, d3, nss); - - sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None); - sck.set_speed(crate::gpio::Speed::VeryHigh); - nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up); - nss.set_speed(crate::gpio::Speed::VeryHigh); - d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None); - d0.set_speed(crate::gpio::Speed::VeryHigh); - d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::None); - d1.set_speed(crate::gpio::Speed::VeryHigh); - d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::None); - d2.set_speed(crate::gpio::Speed::VeryHigh); - d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::None); - d3.set_speed(crate::gpio::Speed::VeryHigh); - - Self::new_inner( - peri, - Some(d0.map_into()), - Some(d1.map_into()), - Some(d2.map_into()), - Some(d3.map_into()), - None, - None, - None, - None, - Some(sck.map_into()), - Some(nss.map_into()), - None, - dma, - config, - OspiWidth::QUAD, - false, - ) - } - - /// Create new OSPI driver for two quadspi external chips - pub fn new_dualquadspi( - peri: impl Peripheral<P = T> + 'd, - sck: impl Peripheral<P = impl SckPin<T>> + 'd, - d0: impl Peripheral<P = impl D0Pin<T>> + 'd, - d1: impl Peripheral<P = impl D1Pin<T>> + 'd, - d2: impl Peripheral<P = impl D2Pin<T>> + 'd, - d3: impl Peripheral<P = impl D3Pin<T>> + 'd, - d4: impl Peripheral<P = impl D4Pin<T>> + 'd, - d5: impl Peripheral<P = impl D5Pin<T>> + 'd, - d6: impl Peripheral<P = impl D6Pin<T>> + 'd, - d7: impl Peripheral<P = impl D7Pin<T>> + 'd, - nss: impl Peripheral<P = impl NSSPin<T>> + 'd, - dma: impl Peripheral<P = Dma> + 'd, - config: Config, - ) -> Self { - into_ref!(peri, sck, d0, d1, d2, d3, d4, d5, d6, d7, nss); - - sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None); - sck.set_speed(crate::gpio::Speed::VeryHigh); - nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up); - nss.set_speed(crate::gpio::Speed::VeryHigh); - d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None); - d0.set_speed(crate::gpio::Speed::VeryHigh); - d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::None); - d1.set_speed(crate::gpio::Speed::VeryHigh); - d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::None); - d2.set_speed(crate::gpio::Speed::VeryHigh); - d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::None); - d3.set_speed(crate::gpio::Speed::VeryHigh); - d4.set_as_af_pull(d4.af_num(), AFType::OutputPushPull, Pull::None); - d4.set_speed(crate::gpio::Speed::VeryHigh); - d5.set_as_af_pull(d5.af_num(), AFType::OutputPushPull, Pull::None); - d5.set_speed(crate::gpio::Speed::VeryHigh); - d6.set_as_af_pull(d6.af_num(), AFType::OutputPushPull, Pull::None); - d6.set_speed(crate::gpio::Speed::VeryHigh); - d7.set_as_af_pull(d7.af_num(), AFType::OutputPushPull, Pull::None); - d7.set_speed(crate::gpio::Speed::VeryHigh); - - Self::new_inner( - peri, - Some(d0.map_into()), - Some(d1.map_into()), - Some(d2.map_into()), - Some(d3.map_into()), - Some(d4.map_into()), - Some(d5.map_into()), - Some(d6.map_into()), - Some(d7.map_into()), - Some(sck.map_into()), - Some(nss.map_into()), - None, - dma, - config, - OspiWidth::QUAD, - true, - ) - } - - /// Create new OSPI driver for octospi external chips - pub fn new_octospi( - peri: impl Peripheral<P = T> + 'd, - sck: impl Peripheral<P = impl SckPin<T>> + 'd, - d0: impl Peripheral<P = impl D0Pin<T>> + 'd, - d1: impl Peripheral<P = impl D1Pin<T>> + 'd, - d2: impl Peripheral<P = impl D2Pin<T>> + 'd, - d3: impl Peripheral<P = impl D3Pin<T>> + 'd, - d4: impl Peripheral<P = impl D4Pin<T>> + 'd, - d5: impl Peripheral<P = impl D5Pin<T>> + 'd, - d6: impl Peripheral<P = impl D6Pin<T>> + 'd, - d7: impl Peripheral<P = impl D7Pin<T>> + 'd, - nss: impl Peripheral<P = impl NSSPin<T>> + 'd, - dma: impl Peripheral<P = Dma> + 'd, - config: Config, - ) -> Self { - into_ref!(peri, sck, d0, d1, d2, d3, d4, d5, d6, d7, nss); - - sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None); - sck.set_speed(crate::gpio::Speed::VeryHigh); - nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up); - nss.set_speed(crate::gpio::Speed::VeryHigh); - d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None); - d0.set_speed(crate::gpio::Speed::VeryHigh); - d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::None); - d1.set_speed(crate::gpio::Speed::VeryHigh); - d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::None); - d2.set_speed(crate::gpio::Speed::VeryHigh); - d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::None); - d3.set_speed(crate::gpio::Speed::VeryHigh); - d4.set_as_af_pull(d4.af_num(), AFType::OutputPushPull, Pull::None); - d4.set_speed(crate::gpio::Speed::VeryHigh); - d5.set_as_af_pull(d5.af_num(), AFType::OutputPushPull, Pull::None); - d5.set_speed(crate::gpio::Speed::VeryHigh); - d6.set_as_af_pull(d6.af_num(), AFType::OutputPushPull, Pull::None); - d6.set_speed(crate::gpio::Speed::VeryHigh); - d7.set_as_af_pull(d7.af_num(), AFType::OutputPushPull, Pull::None); - d7.set_speed(crate::gpio::Speed::VeryHigh); - - Self::new_inner( - peri, - Some(d0.map_into()), - Some(d1.map_into()), - Some(d2.map_into()), - Some(d3.map_into()), - Some(d4.map_into()), - Some(d5.map_into()), - Some(d6.map_into()), - Some(d7.map_into()), - Some(sck.map_into()), - Some(nss.map_into()), - None, - dma, - config, - OspiWidth::OCTO, - false, - ) - } - +impl<'d, T: Instance, M: PeriMode> Ospi<'d, T, M> { fn new_inner( peri: impl Peripheral<P = T> + 'd, d0: Option<PeripheralRef<'d, AnyPin>>, @@ -433,12 +190,12 @@ impl<'d, T: Instance, Dma> Ospi<'d, T, Dma> { sck: Option<PeripheralRef<'d, AnyPin>>, nss: Option<PeripheralRef<'d, AnyPin>>, dqs: Option<PeripheralRef<'d, AnyPin>>, - dma: impl Peripheral<P = Dma> + 'd, + dma: Option<ChannelAndRequest<'d>>, config: Config, width: OspiWidth, dual_quad: bool, ) -> Self { - into_ref!(peri, dma); + into_ref!(peri); // System configuration T::enable_and_reset(); @@ -519,6 +276,7 @@ impl<'d, T: Instance, Dma> Ospi<'d, T, Dma> { nss, dqs, dma, + _phantom: PhantomData, config, width, } @@ -702,170 +460,6 @@ impl<'d, T: Instance, Dma> Ospi<'d, T, Dma> { Ok(()) } - /// Blocking read with DMA transfer - pub fn blocking_read_dma<W: Word>(&mut self, buf: &mut [W], transaction: TransferConfig) -> Result<(), OspiError> - where - Dma: OctoDma<T>, - { - if buf.is_empty() { - return Err(OspiError::EmptyBuffer); - } - - // Wait for peripheral to be free - while T::REGS.sr().read().busy() {} - - self.configure_command(&transaction, Some(buf.len()))?; - - let current_address = T::REGS.ar().read().address(); - let current_instruction = T::REGS.ir().read().instruction(); - - // For a indirect read transaction, the transaction begins when the instruction/address is set - T::REGS.cr().modify(|v| v.set_fmode(vals::FunctionalMode::INDIRECTREAD)); - if T::REGS.ccr().read().admode() == vals::PhaseMode::NONE { - T::REGS.ir().write(|v| v.set_instruction(current_instruction)); - } else { - T::REGS.ar().write(|v| v.set_address(current_address)); - } - - let request = self.dma.request(); - let transfer = unsafe { - Transfer::new_read( - &mut self.dma, - request, - T::REGS.dr().as_ptr() as *mut W, - buf, - Default::default(), - ) - }; - - T::REGS.cr().modify(|w| w.set_dmaen(true)); - - transfer.blocking_wait(); - - finish_dma(T::REGS); - - Ok(()) - } - - /// Blocking write with DMA transfer - pub fn blocking_write_dma<W: Word>(&mut self, buf: &[W], transaction: TransferConfig) -> Result<(), OspiError> - where - Dma: OctoDma<T>, - { - if buf.is_empty() { - return Err(OspiError::EmptyBuffer); - } - - // Wait for peripheral to be free - while T::REGS.sr().read().busy() {} - - self.configure_command(&transaction, Some(buf.len()))?; - T::REGS - .cr() - .modify(|v| v.set_fmode(vals::FunctionalMode::INDIRECTWRITE)); - - let request = self.dma.request(); - let transfer = unsafe { - Transfer::new_write( - &mut self.dma, - request, - buf, - T::REGS.dr().as_ptr() as *mut W, - Default::default(), - ) - }; - - T::REGS.cr().modify(|w| w.set_dmaen(true)); - - transfer.blocking_wait(); - - finish_dma(T::REGS); - - Ok(()) - } - - /// Asynchronous read from external device - pub async fn read<W: Word>(&mut self, buf: &mut [W], transaction: TransferConfig) -> Result<(), OspiError> - where - Dma: OctoDma<T>, - { - if buf.is_empty() { - return Err(OspiError::EmptyBuffer); - } - - // Wait for peripheral to be free - while T::REGS.sr().read().busy() {} - - self.configure_command(&transaction, Some(buf.len()))?; - - let current_address = T::REGS.ar().read().address(); - let current_instruction = T::REGS.ir().read().instruction(); - - // For a indirect read transaction, the transaction begins when the instruction/address is set - T::REGS.cr().modify(|v| v.set_fmode(vals::FunctionalMode::INDIRECTREAD)); - if T::REGS.ccr().read().admode() == vals::PhaseMode::NONE { - T::REGS.ir().write(|v| v.set_instruction(current_instruction)); - } else { - T::REGS.ar().write(|v| v.set_address(current_address)); - } - - let request = self.dma.request(); - let transfer = unsafe { - Transfer::new_read( - &mut self.dma, - request, - T::REGS.dr().as_ptr() as *mut W, - buf, - Default::default(), - ) - }; - - T::REGS.cr().modify(|w| w.set_dmaen(true)); - - transfer.await; - - finish_dma(T::REGS); - - Ok(()) - } - - /// Asynchronous write to external device - pub async fn write<W: Word>(&mut self, buf: &[W], transaction: TransferConfig) -> Result<(), OspiError> - where - Dma: OctoDma<T>, - { - if buf.is_empty() { - return Err(OspiError::EmptyBuffer); - } - - // Wait for peripheral to be free - while T::REGS.sr().read().busy() {} - - self.configure_command(&transaction, Some(buf.len()))?; - T::REGS - .cr() - .modify(|v| v.set_fmode(vals::FunctionalMode::INDIRECTWRITE)); - - let request = self.dma.request(); - let transfer = unsafe { - Transfer::new_write( - &mut self.dma, - request, - buf, - T::REGS.dr().as_ptr() as *mut W, - Default::default(), - ) - }; - - T::REGS.cr().modify(|w| w.set_dmaen(true)); - - transfer.await; - - finish_dma(T::REGS); - - Ok(()) - } - /// Set new bus configuration pub fn set_config(&mut self, config: &Config) { // Wait for busy flag to clear @@ -942,7 +536,470 @@ impl<'d, T: Instance, Dma> Ospi<'d, T, Dma> { } } -impl<'d, T: Instance, Dma> Drop for Ospi<'d, T, Dma> { +impl<'d, T: Instance> Ospi<'d, T, Blocking> { + /// Create new blocking OSPI driver for a single spi external chip + pub fn new_blocking_singlespi( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + d0: impl Peripheral<P = impl D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl D1Pin<T>> + 'd, + nss: impl Peripheral<P = impl NSSPin<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::Input, Speed::VeryHigh), + None, + None, + None, + None, + None, + None, + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + None, + None, + config, + OspiWidth::SING, + false, + ) + } + + /// Create new blocking OSPI driver for a dualspi external chip + pub fn new_blocking_dualspi( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + d0: impl Peripheral<P = impl D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl D1Pin<T>> + 'd, + nss: impl Peripheral<P = impl NSSPin<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + None, + None, + None, + None, + None, + None, + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + None, + None, + config, + OspiWidth::DUAL, + false, + ) + } + + /// Create new blocking OSPI driver for a quadspi external chip + pub fn new_blocking_quadspi( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + d0: impl Peripheral<P = impl D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl D1Pin<T>> + 'd, + d2: impl Peripheral<P = impl D2Pin<T>> + 'd, + d3: impl Peripheral<P = impl D3Pin<T>> + 'd, + nss: impl Peripheral<P = impl NSSPin<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), + None, + None, + None, + None, + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + None, + None, + config, + OspiWidth::QUAD, + false, + ) + } + + /// Create new blocking OSPI driver for two quadspi external chips + pub fn new_blocking_dualquadspi( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + d0: impl Peripheral<P = impl D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl D1Pin<T>> + 'd, + d2: impl Peripheral<P = impl D2Pin<T>> + 'd, + d3: impl Peripheral<P = impl D3Pin<T>> + 'd, + d4: impl Peripheral<P = impl D4Pin<T>> + 'd, + d5: impl Peripheral<P = impl D5Pin<T>> + 'd, + d6: impl Peripheral<P = impl D6Pin<T>> + 'd, + d7: impl Peripheral<P = impl D7Pin<T>> + 'd, + nss: impl Peripheral<P = impl NSSPin<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d4, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d5, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d6, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d7, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + None, + None, + config, + OspiWidth::QUAD, + true, + ) + } + + /// Create new blocking OSPI driver for octospi external chips + pub fn new_blocking_octospi( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + d0: impl Peripheral<P = impl D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl D1Pin<T>> + 'd, + d2: impl Peripheral<P = impl D2Pin<T>> + 'd, + d3: impl Peripheral<P = impl D3Pin<T>> + 'd, + d4: impl Peripheral<P = impl D4Pin<T>> + 'd, + d5: impl Peripheral<P = impl D5Pin<T>> + 'd, + d6: impl Peripheral<P = impl D6Pin<T>> + 'd, + d7: impl Peripheral<P = impl D7Pin<T>> + 'd, + nss: impl Peripheral<P = impl NSSPin<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d4, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d5, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d6, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d7, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + None, + None, + config, + OspiWidth::OCTO, + false, + ) + } +} + +impl<'d, T: Instance> Ospi<'d, T, Async> { + /// Create new blocking OSPI driver for a single spi external chip + pub fn new_singlespi( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + d0: impl Peripheral<P = impl D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl D1Pin<T>> + 'd, + nss: impl Peripheral<P = impl NSSPin<T>> + 'd, + dma: impl Peripheral<P = impl OctoDma<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::Input, Speed::VeryHigh), + None, + None, + None, + None, + None, + None, + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + None, + new_dma!(dma), + config, + OspiWidth::SING, + false, + ) + } + + /// Create new blocking OSPI driver for a dualspi external chip + pub fn new_dualspi( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + d0: impl Peripheral<P = impl D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl D1Pin<T>> + 'd, + nss: impl Peripheral<P = impl NSSPin<T>> + 'd, + dma: impl Peripheral<P = impl OctoDma<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + None, + None, + None, + None, + None, + None, + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + None, + new_dma!(dma), + config, + OspiWidth::DUAL, + false, + ) + } + + /// Create new blocking OSPI driver for a quadspi external chip + pub fn new_quadspi( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + d0: impl Peripheral<P = impl D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl D1Pin<T>> + 'd, + d2: impl Peripheral<P = impl D2Pin<T>> + 'd, + d3: impl Peripheral<P = impl D3Pin<T>> + 'd, + nss: impl Peripheral<P = impl NSSPin<T>> + 'd, + dma: impl Peripheral<P = impl OctoDma<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), + None, + None, + None, + None, + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + None, + new_dma!(dma), + config, + OspiWidth::QUAD, + false, + ) + } + + /// Create new blocking OSPI driver for two quadspi external chips + pub fn new_dualquadspi( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + d0: impl Peripheral<P = impl D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl D1Pin<T>> + 'd, + d2: impl Peripheral<P = impl D2Pin<T>> + 'd, + d3: impl Peripheral<P = impl D3Pin<T>> + 'd, + d4: impl Peripheral<P = impl D4Pin<T>> + 'd, + d5: impl Peripheral<P = impl D5Pin<T>> + 'd, + d6: impl Peripheral<P = impl D6Pin<T>> + 'd, + d7: impl Peripheral<P = impl D7Pin<T>> + 'd, + nss: impl Peripheral<P = impl NSSPin<T>> + 'd, + dma: impl Peripheral<P = impl OctoDma<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d4, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d5, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d6, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d7, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + None, + new_dma!(dma), + config, + OspiWidth::QUAD, + true, + ) + } + + /// Create new blocking OSPI driver for octospi external chips + pub fn new_octospi( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + d0: impl Peripheral<P = impl D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl D1Pin<T>> + 'd, + d2: impl Peripheral<P = impl D2Pin<T>> + 'd, + d3: impl Peripheral<P = impl D3Pin<T>> + 'd, + d4: impl Peripheral<P = impl D4Pin<T>> + 'd, + d5: impl Peripheral<P = impl D5Pin<T>> + 'd, + d6: impl Peripheral<P = impl D6Pin<T>> + 'd, + d7: impl Peripheral<P = impl D7Pin<T>> + 'd, + nss: impl Peripheral<P = impl NSSPin<T>> + 'd, + dma: impl Peripheral<P = impl OctoDma<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d4, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d5, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d6, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d7, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + None, + new_dma!(dma), + config, + OspiWidth::OCTO, + false, + ) + } + + /// Blocking read with DMA transfer + pub fn blocking_read_dma<W: Word>(&mut self, buf: &mut [W], transaction: TransferConfig) -> Result<(), OspiError> { + if buf.is_empty() { + return Err(OspiError::EmptyBuffer); + } + + // Wait for peripheral to be free + while T::REGS.sr().read().busy() {} + + self.configure_command(&transaction, Some(buf.len()))?; + + let current_address = T::REGS.ar().read().address(); + let current_instruction = T::REGS.ir().read().instruction(); + + // For a indirect read transaction, the transaction begins when the instruction/address is set + T::REGS.cr().modify(|v| v.set_fmode(vals::FunctionalMode::INDIRECTREAD)); + if T::REGS.ccr().read().admode() == vals::PhaseMode::NONE { + T::REGS.ir().write(|v| v.set_instruction(current_instruction)); + } else { + T::REGS.ar().write(|v| v.set_address(current_address)); + } + + let transfer = unsafe { + self.dma + .as_mut() + .unwrap() + .read(T::REGS.dr().as_ptr() as *mut W, buf, Default::default()) + }; + + T::REGS.cr().modify(|w| w.set_dmaen(true)); + + transfer.blocking_wait(); + + finish_dma(T::REGS); + + Ok(()) + } + + /// Blocking write with DMA transfer + pub fn blocking_write_dma<W: Word>(&mut self, buf: &[W], transaction: TransferConfig) -> Result<(), OspiError> { + if buf.is_empty() { + return Err(OspiError::EmptyBuffer); + } + + // Wait for peripheral to be free + while T::REGS.sr().read().busy() {} + + self.configure_command(&transaction, Some(buf.len()))?; + T::REGS + .cr() + .modify(|v| v.set_fmode(vals::FunctionalMode::INDIRECTWRITE)); + + let transfer = unsafe { + self.dma + .as_mut() + .unwrap() + .write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default()) + }; + + T::REGS.cr().modify(|w| w.set_dmaen(true)); + + transfer.blocking_wait(); + + finish_dma(T::REGS); + + Ok(()) + } + + /// Asynchronous read from external device + pub async fn read<W: Word>(&mut self, buf: &mut [W], transaction: TransferConfig) -> Result<(), OspiError> { + if buf.is_empty() { + return Err(OspiError::EmptyBuffer); + } + + // Wait for peripheral to be free + while T::REGS.sr().read().busy() {} + + self.configure_command(&transaction, Some(buf.len()))?; + + let current_address = T::REGS.ar().read().address(); + let current_instruction = T::REGS.ir().read().instruction(); + + // For a indirect read transaction, the transaction begins when the instruction/address is set + T::REGS.cr().modify(|v| v.set_fmode(vals::FunctionalMode::INDIRECTREAD)); + if T::REGS.ccr().read().admode() == vals::PhaseMode::NONE { + T::REGS.ir().write(|v| v.set_instruction(current_instruction)); + } else { + T::REGS.ar().write(|v| v.set_address(current_address)); + } + + let transfer = unsafe { + self.dma + .as_mut() + .unwrap() + .read(T::REGS.dr().as_ptr() as *mut W, buf, Default::default()) + }; + + T::REGS.cr().modify(|w| w.set_dmaen(true)); + + transfer.await; + + finish_dma(T::REGS); + + Ok(()) + } + + /// Asynchronous write to external device + pub async fn write<W: Word>(&mut self, buf: &[W], transaction: TransferConfig) -> Result<(), OspiError> { + if buf.is_empty() { + return Err(OspiError::EmptyBuffer); + } + + // Wait for peripheral to be free + while T::REGS.sr().read().busy() {} + + self.configure_command(&transaction, Some(buf.len()))?; + T::REGS + .cr() + .modify(|v| v.set_fmode(vals::FunctionalMode::INDIRECTWRITE)); + + let transfer = unsafe { + self.dma + .as_mut() + .unwrap() + .write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default()) + }; + + T::REGS.cr().modify(|w| w.set_dmaen(true)); + + transfer.await; + + finish_dma(T::REGS); + + Ok(()) + } +} + +impl<'d, T: Instance, M: PeriMode> Drop for Ospi<'d, T, M> { fn drop(&mut self) { self.sck.as_ref().map(|x| x.set_as_disconnected()); self.d0.as_ref().map(|x| x.set_as_disconnected()); @@ -969,17 +1026,6 @@ fn finish_dma(regs: Regs) { }); } -trait RegsExt { - fn dr_ptr<W>(&self) -> *mut W; -} - -impl RegsExt for Regs { - fn dr_ptr<W>(&self) -> *mut W { - let dr = self.dr(); - dr.as_ptr() as *mut W - } -} - pub(crate) trait SealedInstance { const REGS: Regs; } @@ -1016,7 +1062,7 @@ foreach_peripheral!( }; ); -impl<'d, T: Instance, Dma> SetConfig for Ospi<'d, T, Dma> { +impl<'d, T: Instance, M: PeriMode> SetConfig for Ospi<'d, T, M> { type Config = Config; type ConfigError = (); fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { @@ -1025,7 +1071,7 @@ impl<'d, T: Instance, Dma> SetConfig for Ospi<'d, T, Dma> { } } -impl<'d, T: Instance, Dma> GetConfig for Ospi<'d, T, Dma> { +impl<'d, T: Instance, M: PeriMode> GetConfig for Ospi<'d, T, M> { type Config = Config; fn get_config(&self) -> Self::Config { self.get_config() diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 0a4b4f074..a82e93b5b 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -4,11 +4,14 @@ pub mod enums; +use core::marker::PhantomData; + use embassy_hal_internal::{into_ref, PeripheralRef}; use enums::*; -use crate::dma::Transfer; -use crate::gpio::{AFType, AnyPin, Pull}; +use crate::dma::ChannelAndRequest; +use crate::gpio::{AFType, AnyPin, Pull, Speed}; +use crate::mode::{Async, Blocking, Mode as PeriMode}; use crate::pac::quadspi::Quadspi as Regs; use crate::rcc::RccPeripheral; use crate::{peripherals, Peripheral}; @@ -71,7 +74,7 @@ impl Default for Config { /// QSPI driver. #[allow(dead_code)] -pub struct Qspi<'d, T: Instance, Dma> { +pub struct Qspi<'d, T: Instance, M: PeriMode> { _peri: PeripheralRef<'d, T>, sck: Option<PeripheralRef<'d, AnyPin>>, d0: Option<PeripheralRef<'d, AnyPin>>, @@ -79,93 +82,12 @@ pub struct Qspi<'d, T: Instance, Dma> { d2: Option<PeripheralRef<'d, AnyPin>>, d3: Option<PeripheralRef<'d, AnyPin>>, nss: Option<PeripheralRef<'d, AnyPin>>, - dma: PeripheralRef<'d, Dma>, + dma: Option<ChannelAndRequest<'d>>, + _phantom: PhantomData<M>, config: Config, } -impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { - /// Create a new QSPI driver for bank 1. - pub fn new_bk1( - peri: impl Peripheral<P = T> + 'd, - d0: impl Peripheral<P = impl BK1D0Pin<T>> + 'd, - d1: impl Peripheral<P = impl BK1D1Pin<T>> + 'd, - d2: impl Peripheral<P = impl BK1D2Pin<T>> + 'd, - d3: impl Peripheral<P = impl BK1D3Pin<T>> + 'd, - sck: impl Peripheral<P = impl SckPin<T>> + 'd, - nss: impl Peripheral<P = impl BK1NSSPin<T>> + 'd, - dma: impl Peripheral<P = Dma> + 'd, - config: Config, - ) -> Self { - into_ref!(peri, d0, d1, d2, d3, sck, nss); - - sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None); - sck.set_speed(crate::gpio::Speed::VeryHigh); - nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up); - nss.set_speed(crate::gpio::Speed::VeryHigh); - d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None); - d0.set_speed(crate::gpio::Speed::VeryHigh); - d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::None); - d1.set_speed(crate::gpio::Speed::VeryHigh); - d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::None); - d2.set_speed(crate::gpio::Speed::VeryHigh); - d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::None); - d3.set_speed(crate::gpio::Speed::VeryHigh); - - Self::new_inner( - peri, - Some(d0.map_into()), - Some(d1.map_into()), - Some(d2.map_into()), - Some(d3.map_into()), - Some(sck.map_into()), - Some(nss.map_into()), - dma, - config, - FlashSelection::Flash1, - ) - } - - /// Create a new QSPI driver for bank 2. - pub fn new_bk2( - peri: impl Peripheral<P = T> + 'd, - d0: impl Peripheral<P = impl BK2D0Pin<T>> + 'd, - d1: impl Peripheral<P = impl BK2D1Pin<T>> + 'd, - d2: impl Peripheral<P = impl BK2D2Pin<T>> + 'd, - d3: impl Peripheral<P = impl BK2D3Pin<T>> + 'd, - sck: impl Peripheral<P = impl SckPin<T>> + 'd, - nss: impl Peripheral<P = impl BK2NSSPin<T>> + 'd, - dma: impl Peripheral<P = Dma> + 'd, - config: Config, - ) -> Self { - into_ref!(peri, d0, d1, d2, d3, sck, nss); - - sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None); - sck.set_speed(crate::gpio::Speed::VeryHigh); - nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up); - nss.set_speed(crate::gpio::Speed::VeryHigh); - d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None); - d0.set_speed(crate::gpio::Speed::VeryHigh); - d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::None); - d1.set_speed(crate::gpio::Speed::VeryHigh); - d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::None); - d2.set_speed(crate::gpio::Speed::VeryHigh); - d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::None); - d3.set_speed(crate::gpio::Speed::VeryHigh); - - Self::new_inner( - peri, - Some(d0.map_into()), - Some(d1.map_into()), - Some(d2.map_into()), - Some(d3.map_into()), - Some(sck.map_into()), - Some(nss.map_into()), - dma, - config, - FlashSelection::Flash2, - ) - } - +impl<'d, T: Instance, M: PeriMode> Qspi<'d, T, M> { fn new_inner( peri: impl Peripheral<P = T> + 'd, d0: Option<PeripheralRef<'d, AnyPin>>, @@ -174,11 +96,11 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { d3: Option<PeripheralRef<'d, AnyPin>>, sck: Option<PeripheralRef<'d, AnyPin>>, nss: Option<PeripheralRef<'d, AnyPin>>, - dma: impl Peripheral<P = Dma> + 'd, + dma: Option<ChannelAndRequest<'d>>, config: Config, fsel: FlashSelection, ) -> Self { - into_ref!(peri, dma); + into_ref!(peri); T::enable_and_reset(); @@ -220,6 +142,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { d3, nss, dma, + _phantom: PhantomData, config, } } @@ -278,68 +201,6 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { T::REGS.fcr().modify(|v| v.set_ctcf(true)); } - /// Blocking read data, using DMA. - pub fn blocking_read_dma(&mut self, buf: &mut [u8], transaction: TransferConfig) - where - Dma: QuadDma<T>, - { - self.setup_transaction(QspiMode::IndirectWrite, &transaction, Some(buf.len())); - - T::REGS.ccr().modify(|v| { - v.set_fmode(QspiMode::IndirectRead.into()); - }); - let current_ar = T::REGS.ar().read().address(); - T::REGS.ar().write(|v| { - v.set_address(current_ar); - }); - - let request = self.dma.request(); - let transfer = unsafe { - Transfer::new_read( - &mut self.dma, - request, - T::REGS.dr().as_ptr() as *mut u8, - buf, - Default::default(), - ) - }; - - // STM32H7 does not have dmaen - #[cfg(not(stm32h7))] - T::REGS.cr().modify(|v| v.set_dmaen(true)); - - transfer.blocking_wait(); - } - - /// Blocking write data, using DMA. - pub fn blocking_write_dma(&mut self, buf: &[u8], transaction: TransferConfig) - where - Dma: QuadDma<T>, - { - self.setup_transaction(QspiMode::IndirectWrite, &transaction, Some(buf.len())); - - T::REGS.ccr().modify(|v| { - v.set_fmode(QspiMode::IndirectWrite.into()); - }); - - let request = self.dma.request(); - let transfer = unsafe { - Transfer::new_write( - &mut self.dma, - request, - buf, - T::REGS.dr().as_ptr() as *mut u8, - Default::default(), - ) - }; - - // STM32H7 does not have dmaen - #[cfg(not(stm32h7))] - T::REGS.cr().modify(|v| v.set_dmaen(true)); - - transfer.blocking_wait(); - } - fn setup_transaction(&mut self, fmode: QspiMode, transaction: &TransferConfig, data_len: Option<usize>) { T::REGS.fcr().modify(|v| { v.set_csmf(true); @@ -373,6 +234,160 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { } } +impl<'d, T: Instance> Qspi<'d, T, Blocking> { + /// Create a new QSPI driver for bank 1, in blocking mode. + pub fn new_blocking_bank1( + peri: impl Peripheral<P = T> + 'd, + d0: impl Peripheral<P = impl BK1D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl BK1D1Pin<T>> + 'd, + d2: impl Peripheral<P = impl BK1D2Pin<T>> + 'd, + d3: impl Peripheral<P = impl BK1D3Pin<T>> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + nss: impl Peripheral<P = impl BK1NSSPin<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + None, + config, + FlashSelection::Flash1, + ) + } + + /// Create a new QSPI driver for bank 2, in blocking mode. + pub fn new_blocking_bank2( + peri: impl Peripheral<P = T> + 'd, + d0: impl Peripheral<P = impl BK2D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl BK2D1Pin<T>> + 'd, + d2: impl Peripheral<P = impl BK2D2Pin<T>> + 'd, + d3: impl Peripheral<P = impl BK2D3Pin<T>> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + nss: impl Peripheral<P = impl BK2NSSPin<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + None, + config, + FlashSelection::Flash2, + ) + } +} + +impl<'d, T: Instance> Qspi<'d, T, Async> { + /// Create a new QSPI driver for bank 1. + pub fn new_bank1( + peri: impl Peripheral<P = T> + 'd, + d0: impl Peripheral<P = impl BK1D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl BK1D1Pin<T>> + 'd, + d2: impl Peripheral<P = impl BK1D2Pin<T>> + 'd, + d3: impl Peripheral<P = impl BK1D3Pin<T>> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + nss: impl Peripheral<P = impl BK1NSSPin<T>> + 'd, + dma: impl Peripheral<P = impl QuadDma<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_dma!(dma), + config, + FlashSelection::Flash1, + ) + } + + /// Create a new QSPI driver for bank 2. + pub fn new_bank2( + peri: impl Peripheral<P = T> + 'd, + d0: impl Peripheral<P = impl BK2D0Pin<T>> + 'd, + d1: impl Peripheral<P = impl BK2D1Pin<T>> + 'd, + d2: impl Peripheral<P = impl BK2D2Pin<T>> + 'd, + d3: impl Peripheral<P = impl BK2D3Pin<T>> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + nss: impl Peripheral<P = impl BK2NSSPin<T>> + 'd, + dma: impl Peripheral<P = impl QuadDma<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_dma!(dma), + config, + FlashSelection::Flash2, + ) + } + + /// Blocking read data, using DMA. + pub fn blocking_read_dma(&mut self, buf: &mut [u8], transaction: TransferConfig) { + self.setup_transaction(QspiMode::IndirectWrite, &transaction, Some(buf.len())); + + T::REGS.ccr().modify(|v| { + v.set_fmode(QspiMode::IndirectRead.into()); + }); + let current_ar = T::REGS.ar().read().address(); + T::REGS.ar().write(|v| { + v.set_address(current_ar); + }); + + let transfer = unsafe { + self.dma + .as_mut() + .unwrap() + .read(T::REGS.dr().as_ptr() as *mut u8, buf, Default::default()) + }; + + // STM32H7 does not have dmaen + #[cfg(not(stm32h7))] + T::REGS.cr().modify(|v| v.set_dmaen(true)); + + transfer.blocking_wait(); + } + + /// Blocking write data, using DMA. + pub fn blocking_write_dma(&mut self, buf: &[u8], transaction: TransferConfig) { + self.setup_transaction(QspiMode::IndirectWrite, &transaction, Some(buf.len())); + + T::REGS.ccr().modify(|v| { + v.set_fmode(QspiMode::IndirectWrite.into()); + }); + + let transfer = unsafe { + self.dma + .as_mut() + .unwrap() + .write(buf, T::REGS.dr().as_ptr() as *mut u8, Default::default()) + }; + + // STM32H7 does not have dmaen + #[cfg(not(stm32h7))] + T::REGS.cr().modify(|v| v.set_dmaen(true)); + + transfer.blocking_wait(); + } +} + trait SealedInstance { const REGS: Regs; } diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index 54d3c662b..f3ac4fdbe 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs @@ -198,7 +198,7 @@ impl LsConfig { } // If not OK, reset backup domain and configure it. - #[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1, stm32h5, stm32c0)))] + #[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1, stm32h5, stm32h7rs, stm32c0)))] { bdcr().modify(|w| w.set_bdrst(true)); bdcr().modify(|w| w.set_bdrst(false)); @@ -210,11 +210,12 @@ impl LsConfig { // letting half our RAM go magically *poof*. // STM32H503CB/EB/KB/RB device errata - 2.2.8 SRAM2 unduly erased upon a backup domain reset // STM32H562xx/563xx/573xx device errata - 2.2.14 SRAM2 is erased when the backup domain is reset - //#[cfg(any(stm32h5))] - //{ - // bdcr().modify(|w| w.set_vswrst(true)); - // bdcr().modify(|w| w.set_vswrst(false)); - //} + //#[cfg(any(stm32h5, stm32h7rs))] + #[cfg(any(stm32h7rs))] + { + bdcr().modify(|w| w.set_vswrst(true)); + bdcr().modify(|w| w.set_vswrst(false)); + } #[cfg(any(stm32c0, stm32l0))] { bdcr().modify(|w| w.set_rtcrst(true)); diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index 349f978c5..5adf37941 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs @@ -76,25 +76,29 @@ impl Default for Config { } pub(crate) unsafe fn init(config: Config) { + // Turn on the HSI + match config.hsi { + None => RCC.cr().modify(|w| w.set_hsion(true)), + Some(hsi) => RCC.cr().modify(|w| { + w.set_hsidiv(hsi.sys_div); + w.set_hsikerdiv(hsi.ker_div); + w.set_hsion(true); + }), + } + while !RCC.cr().read().hsirdy() {} + + // Use the HSI clock as system clock during the actual clock setup + RCC.cfgr().modify(|w| w.set_sw(Sysclk::HSISYS)); + while RCC.cfgr().read().sws() != Sysclk::HSISYS {} + // Configure HSI let (hsi, hsisys, hsiker) = match config.hsi { - None => { - RCC.cr().modify(|w| w.set_hsion(false)); - (None, None, None) - } - Some(hsi) => { - RCC.cr().modify(|w| { - w.set_hsidiv(hsi.sys_div); - w.set_hsikerdiv(hsi.ker_div); - w.set_hsion(true); - }); - while !RCC.cr().read().hsirdy() {} - ( - Some(HSI_FREQ), - Some(HSI_FREQ / hsi.sys_div), - Some(HSI_FREQ / hsi.ker_div), - ) - } + None => (None, None, None), + Some(hsi) => ( + Some(HSI_FREQ), + Some(HSI_FREQ / hsi.sys_div), + Some(HSI_FREQ / hsi.ker_div), + ), }; // Configure HSE @@ -150,6 +154,12 @@ pub(crate) unsafe fn init(config: Config) { w.set_hpre(config.ahb_pre); w.set_ppre(config.apb1_pre); }); + while RCC.cfgr().read().sws() != config.sys {} + + // Disable HSI if not used + if config.hsi.is_none() { + RCC.cr().modify(|w| w.set_hsion(false)); + } let rtc = config.ls.init(); diff --git a/embassy-stm32/src/rcc/f013.rs b/embassy-stm32/src/rcc/f013.rs index 215f8a3d2..0946287ea 100644 --- a/embassy-stm32/src/rcc/f013.rs +++ b/embassy-stm32/src/rcc/f013.rs @@ -135,17 +135,18 @@ impl Default for Config { /// Initialize and Set the clock frequencies pub(crate) unsafe fn init(config: Config) { + // Turn on the HSI + RCC.cr().modify(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} + + // Use the HSI clock as system clock during the actual clock setup + RCC.cfgr().modify(|w| w.set_sw(Sysclk::HSI)); + while RCC.cfgr().read().sws() != Sysclk::HSI {} + // Configure HSI let hsi = match config.hsi { - false => { - RCC.cr().modify(|w| w.set_hsion(false)); - None - } - true => { - RCC.cr().modify(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - Some(HSI_FREQ) - } + false => None, + true => Some(HSI_FREQ), }; // Configure HSE @@ -297,56 +298,73 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| w.set_sw(config.sys)); while RCC.cfgr().read().sws() != config.sys {} + // Disable HSI if not used + if !config.hsi { + RCC.cr().modify(|w| w.set_hsion(false)); + } + let rtc = config.ls.init(); + // TODO: all this ADC stuff should probably go into the ADC module, not here. + // Most STM32s manage ADC clocks in a similar way with ADCx_COMMON. #[cfg(all(stm32f3, not(rcc_f37)))] use crate::pac::adccommon::vals::Ckmode; #[cfg(all(stm32f3, not(rcc_f37)))] - let adc = match config.adc { - AdcClockSource::Pll(adcpres) => { - RCC.cfgr2().modify(|w| w.set_adc12pres(adcpres)); - crate::pac::ADC_COMMON - .ccr() - .modify(|w| w.set_ckmode(Ckmode::ASYNCHRONOUS)); + let adc = { + #[cfg(peri_adc1_common)] + let common = crate::pac::ADC1_COMMON; + #[cfg(peri_adc12_common)] + let common = crate::pac::ADC12_COMMON; - unwrap!(pll) / adcpres - } - AdcClockSource::Hclk(adcpres) => { - assert!(!(adcpres == AdcHclkPrescaler::Div1 && config.ahb_pre != AHBPrescaler::DIV1)); + match config.adc { + AdcClockSource::Pll(adcpres) => { + RCC.cfgr2().modify(|w| w.set_adc12pres(adcpres)); + common.ccr().modify(|w| w.set_ckmode(Ckmode::ASYNCHRONOUS)); - let (div, ckmode) = match adcpres { - AdcHclkPrescaler::Div1 => (1u32, Ckmode::SYNCDIV1), - AdcHclkPrescaler::Div2 => (2u32, Ckmode::SYNCDIV2), - AdcHclkPrescaler::Div4 => (4u32, Ckmode::SYNCDIV4), - }; - crate::pac::ADC_COMMON.ccr().modify(|w| w.set_ckmode(ckmode)); + unwrap!(pll) / adcpres + } + AdcClockSource::Hclk(adcpres) => { + assert!(!(adcpres == AdcHclkPrescaler::Div1 && config.ahb_pre != AHBPrescaler::DIV1)); - hclk / div + let (div, ckmode) = match adcpres { + AdcHclkPrescaler::Div1 => (1u32, Ckmode::SYNCDIV1), + AdcHclkPrescaler::Div2 => (2u32, Ckmode::SYNCDIV2), + AdcHclkPrescaler::Div4 => (4u32, Ckmode::SYNCDIV4), + }; + common.ccr().modify(|w| w.set_ckmode(ckmode)); + + hclk / div + } } }; #[cfg(all(stm32f3, not(rcc_f37), adc3_common))] - let adc34 = match config.adc34 { - AdcClockSource::Pll(adcpres) => { - RCC.cfgr2().modify(|w| w.set_adc34pres(adcpres)); - crate::pac::ADC3_COMMON - .ccr() - .modify(|w| w.set_ckmode(Ckmode::ASYNCHRONOUS)); + let adc34 = { + #[cfg(peri_adc3_common)] + let common = crate::pac::ADC3_COMMON; + #[cfg(peri_adc34_common)] + let common = crate::pac::ADC34_COMMON; - unwrap!(pll) / adcpres - } - AdcClockSource::Hclk(adcpres) => { - assert!(!(adcpres == AdcHclkPrescaler::Div1 && config.ahb_pre != AHBPrescaler::DIV1)); + match config.adc34 { + AdcClockSource::Pll(adcpres) => { + RCC.cfgr2().modify(|w| w.set_adc34pres(adcpres)); + common.ccr().modify(|w| w.set_ckmode(Ckmode::ASYNCHRONOUS)); - let (div, ckmode) = match adcpres { - AdcHclkPrescaler::Div1 => (1u32, Ckmode::SYNCDIV1), - AdcHclkPrescaler::Div2 => (2u32, Ckmode::SYNCDIV2), - AdcHclkPrescaler::Div4 => (4u32, Ckmode::SYNCDIV4), - }; - crate::pac::ADC3_COMMON.ccr().modify(|w| w.set_ckmode(ckmode)); + unwrap!(pll) / adcpres + } + AdcClockSource::Hclk(adcpres) => { + assert!(!(adcpres == AdcHclkPrescaler::Div1 && config.ahb_pre != AHBPrescaler::DIV1)); - hclk / div + let (div, ckmode) = match adcpres { + AdcHclkPrescaler::Div1 => (1u32, Ckmode::SYNCDIV1), + AdcHclkPrescaler::Div2 => (2u32, Ckmode::SYNCDIV2), + AdcHclkPrescaler::Div4 => (4u32, Ckmode::SYNCDIV4), + }; + common.ccr().modify(|w| w.set_ckmode(ckmode)); + + hclk / div + } } }; diff --git a/embassy-stm32/src/rcc/f247.rs b/embassy-stm32/src/rcc/f247.rs index 7b252870c..61f687d30 100644 --- a/embassy-stm32/src/rcc/f247.rs +++ b/embassy-stm32/src/rcc/f247.rs @@ -146,17 +146,18 @@ pub(crate) unsafe fn init(config: Config) { while !PWR.csr1().read().odswrdy() {} } + // Turn on the HSI + RCC.cr().modify(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} + + // Use the HSI clock as system clock during the actual clock setup + RCC.cfgr().modify(|w| w.set_sw(Sysclk::HSI)); + while RCC.cfgr().read().sws() != Sysclk::HSI {} + // Configure HSI let hsi = match config.hsi { - false => { - RCC.cr().modify(|w| w.set_hsion(false)); - None - } - true => { - RCC.cr().modify(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - Some(HSI_FREQ) - } + false => None, + true => Some(HSI_FREQ), }; // Configure HSE @@ -260,6 +261,11 @@ pub(crate) unsafe fn init(config: Config) { }); while RCC.cfgr().read().sws() != config.sys {} + // Disable HSI if not used + if !config.hsi { + RCC.cr().modify(|w| w.set_hsion(false)); + } + config.mux.init(); set_clocks!( @@ -277,6 +283,7 @@ pub(crate) unsafe fn init(config: Config) { pclk2_tim: Some(pclk2_tim), rtc: rtc, pll1_q: pll.q, + pll1_r: pll.r, #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] plli2s1_p: plli2s.p, @@ -296,6 +303,9 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(not(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7)))] pllsai1_q: None, + #[cfg(dsihost)] + dsi_phy: None, // DSI PLL clock not supported, don't call `RccPeripheral::frequency()` in the drivers + hsi_div488: hsi.map(|hsi| hsi/488u32), hsi_hse: None, afif: None, diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index ea4422ccc..c2fa0ca39 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -116,17 +116,18 @@ pub struct PllFreq { } pub(crate) unsafe fn init(config: Config) { + // Turn on the HSI + RCC.cr().modify(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} + + // Use the HSI clock as system clock during the actual clock setup + RCC.cfgr().modify(|w| w.set_sw(Sysclk::HSI)); + while RCC.cfgr().read().sws() != Sysclk::HSI {} + // Configure HSI let hsi = match config.hsi { - false => { - RCC.cr().modify(|w| w.set_hsion(false)); - None - } - true => { - RCC.cr().modify(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - Some(HSI_FREQ) - } + false => None, + true => Some(HSI_FREQ), }; // Configure HSE @@ -259,6 +260,12 @@ pub(crate) unsafe fn init(config: Config) { w.set_hpre(config.ahb_pre); w.set_ppre(config.apb1_pre); }); + while RCC.cfgr().read().sws() != config.sys {} + + // Disable HSI if not used + if !config.hsi { + RCC.cr().modify(|w| w.set_hsion(false)); + } if config.low_power_run { assert!(sys <= Hertz(2_000_000)); diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index cd2d2a8a2..c261c0fed 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -117,17 +117,18 @@ pub struct PllFreq { } pub(crate) unsafe fn init(config: Config) { + // Turn on the HSI + RCC.cr().modify(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} + + // Use the HSI clock as system clock during the actual clock setup + RCC.cfgr().modify(|w| w.set_sw(Sysclk::HSI)); + while RCC.cfgr().read().sws() != Sysclk::HSI {} + // Configure HSI let hsi = match config.hsi { - false => { - RCC.cr().modify(|w| w.set_hsion(false)); - None - } - true => { - RCC.cr().modify(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - Some(HSI_FREQ) - } + false => None, + true => Some(HSI_FREQ), }; // Configure HSE @@ -285,6 +286,12 @@ pub(crate) unsafe fn init(config: Config) { w.set_ppre1(config.apb1_pre); w.set_ppre2(config.apb2_pre); }); + while RCC.cfgr().read().sws() != config.sys {} + + // Disable HSI if not used + if !config.hsi { + RCC.cr().modify(|w| w.set_hsion(false)); + } if config.low_power_run { assert!(sys <= Hertz(2_000_000)); diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 1949fc891..e3c7dd158 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -1,7 +1,6 @@ use core::ops::RangeInclusive; use crate::pac; -use crate::pac::pwr::vals::Vos; pub use crate::pac::rcc::vals::{ Hsidiv as HSIPrescaler, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul, Pllsrc as PllSource, Sw as Sysclk, }; @@ -22,9 +21,12 @@ const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(128_000_000)..=Hertz(560_000 const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(192_000_000)..=Hertz(836_000_000); #[cfg(any(pwr_h7rm0399, pwr_h7rm0433))] const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(192_000_000)..=Hertz(960_000_000); +#[cfg(any(stm32h7rs))] +const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(384_000_000)..=Hertz(1672_000_000); pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; +#[cfg(any(stm32h5, stm32h7))] #[derive(Clone, Copy, Eq, PartialEq)] pub enum VoltageScale { Scale0, @@ -32,6 +34,8 @@ pub enum VoltageScale { Scale2, Scale3, } +#[cfg(any(stm32h7rs))] +pub use crate::pac::pwr::vals::Vos as VoltageScale; #[derive(Clone, Copy, Eq, PartialEq)] pub enum HseMode { @@ -40,7 +44,7 @@ pub enum HseMode { /// external analog clock (low swing) (HSEBYP=1, HSEEXT=0) Bypass, /// external digital clock (full swing) (HSEBYP=1, HSEEXT=1) - #[cfg(any(rcc_h5, rcc_h50))] + #[cfg(any(rcc_h5, rcc_h50, rcc_h7rs))] BypassDigital, } @@ -65,8 +69,8 @@ pub struct Pll { /// PLL P division factor. If None, PLL P output is disabled. /// On PLL1, it must be even for most series (in particular, - /// it cannot be 1 in series other than STM32H723/733, - /// STM32H725/735 and STM32H730.) + /// it cannot be 1 in series other than stm32h7, stm32h7rs23/733, + /// stm32h7, stm32h7rs25/735 and stm32h7, stm32h7rs30.) pub divp: Option<PllDiv>, /// PLL Q division factor. If None, PLL Q output is disabled. pub divq: Option<PllDiv>, @@ -115,7 +119,7 @@ impl From<TimerPrescaler> for Timpre { /// Power supply configuration /// See RM0433 Rev 4 7.4 -#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] +#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))] #[derive(PartialEq)] pub enum SupplyConfig { /// Default power supply configuration. @@ -164,8 +168,15 @@ pub enum SupplyConfig { /// SMPS step-down converter voltage output level. /// This is only used in certain power supply configurations: /// SMPSLDO, SMPSExternalLDO, SMPSExternalLDOBypass. -#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] -pub use pac::pwr::vals::Sdlevel as SMPSSupplyVoltage; +#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] +pub enum SMPSSupplyVoltage { + /// 1.8v + V1_8, + /// 2.5v + #[cfg(not(pwr_h7rs))] + V2_5, +} /// Configuration of the core clocks #[non_exhaustive] @@ -178,22 +189,26 @@ pub struct Config { pub pll1: Option<Pll>, pub pll2: Option<Pll>, - #[cfg(any(rcc_h5, stm32h7))] + #[cfg(any(rcc_h5, stm32h7, stm32h7rs))] pub pll3: Option<Pll>, + #[cfg(any(stm32h7, stm32h7rs))] pub d1c_pre: AHBPrescaler, pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, + #[cfg(not(stm32h7rs))] pub apb3_pre: APBPrescaler, - #[cfg(stm32h7)] + #[cfg(any(stm32h7, stm32h7rs))] pub apb4_pre: APBPrescaler, + #[cfg(stm32h7rs)] + pub apb5_pre: APBPrescaler, pub timer_prescaler: TimerPrescaler, pub voltage_scale: VoltageScale, pub ls: super::LsConfig, - #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] + #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))] pub supply_config: SupplyConfig, /// Per-peripheral kernel clock selection muxes @@ -210,23 +225,30 @@ impl Default for Config { sys: Sysclk::HSI, pll1: None, pll2: None, - #[cfg(any(rcc_h5, stm32h7))] + #[cfg(any(rcc_h5, stm32h7, stm32h7rs))] pll3: None, + #[cfg(any(stm32h7, stm32h7rs))] d1c_pre: AHBPrescaler::DIV1, ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, + #[cfg(not(stm32h7rs))] apb3_pre: APBPrescaler::DIV1, - #[cfg(stm32h7)] + #[cfg(any(stm32h7, stm32h7rs))] apb4_pre: APBPrescaler::DIV1, + #[cfg(stm32h7rs)] + apb5_pre: APBPrescaler::DIV1, timer_prescaler: TimerPrescaler::DefaultX2, + #[cfg(not(rcc_h7rs))] voltage_scale: VoltageScale::Scale0, + #[cfg(rcc_h7rs)] + voltage_scale: VoltageScale::HIGH, ls: Default::default(), - #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] - supply_config: SupplyConfig::Default, + #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))] + supply_config: SupplyConfig::LDO, mux: Default::default(), } @@ -234,24 +256,30 @@ impl Default for Config { } pub(crate) unsafe fn init(config: Config) { + #[cfg(any(stm32h7))] + let pwr_reg = PWR.cr3(); + #[cfg(any(stm32h7rs))] + let pwr_reg = PWR.csr2(); + // NB. The lower bytes of CR3 can only be written once after // POR, and must be written with a valid combination. Refer to // RM0433 Rev 7 6.8.4. This is partially enforced by dropping // `self` at the end of this method, but of course we cannot // know what happened between the previous POR and here. #[cfg(pwr_h7rm0433)] - PWR.cr3().modify(|w| { + pwr_reg.modify(|w| { w.set_scuen(true); w.set_ldoen(true); w.set_bypass(false); }); - #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] + #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))] { + use pac::pwr::vals::Sdlevel; match config.supply_config { SupplyConfig::Default => { - PWR.cr3().modify(|w| { - w.set_sdlevel(SMPSSupplyVoltage::RESET); + pwr_reg.modify(|w| { + w.set_sdlevel(Sdlevel::RESET); w.set_sdexthp(false); w.set_sden(true); w.set_ldoen(true); @@ -259,25 +287,30 @@ pub(crate) unsafe fn init(config: Config) { }); } SupplyConfig::LDO => { - PWR.cr3().modify(|w| { + pwr_reg.modify(|w| { w.set_sden(false); w.set_ldoen(true); w.set_bypass(false); }); } SupplyConfig::DirectSMPS => { - PWR.cr3().modify(|w| { + pwr_reg.modify(|w| { w.set_sdexthp(false); w.set_sden(true); w.set_ldoen(false); w.set_bypass(false); }); } - SupplyConfig::SMPSLDO(smps_supply_voltage) - | SupplyConfig::SMPSExternalLDO(smps_supply_voltage) - | SupplyConfig::SMPSExternalLDOBypass(smps_supply_voltage) => { - PWR.cr3().modify(|w| { - w.set_sdlevel(smps_supply_voltage); + SupplyConfig::SMPSLDO(sdlevel) + | SupplyConfig::SMPSExternalLDO(sdlevel) + | SupplyConfig::SMPSExternalLDOBypass(sdlevel) => { + let sdlevel = match sdlevel { + SMPSSupplyVoltage::V1_8 => Sdlevel::V1_8, + #[cfg(not(pwr_h7rs))] + SMPSSupplyVoltage::V2_5 => Sdlevel::V2_5, + }; + pwr_reg.modify(|w| { + w.set_sdlevel(sdlevel); w.set_sdexthp(matches!( config.supply_config, SupplyConfig::SMPSExternalLDO(_) | SupplyConfig::SMPSExternalLDOBypass(_) @@ -291,7 +324,7 @@ pub(crate) unsafe fn init(config: Config) { }); } SupplyConfig::SMPSDisabledLDOBypass => { - PWR.cr3().modify(|w| { + pwr_reg.modify(|w| { w.set_sden(false); w.set_ldoen(false); w.set_bypass(true); @@ -305,43 +338,49 @@ pub(crate) unsafe fn init(config: Config) { // in the D3CR.VOS and CR3.SDLEVEL fields. By default after reset // VOS = Scale 3, so check that the voltage on the VCAP pins = // 1.0V. - #[cfg(any(pwr_h7rm0433, pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))] + #[cfg(any(stm32h7))] while !PWR.csr1().read().actvosrdy() {} + #[cfg(any(stm32h7rs))] + while !PWR.sr1().read().actvosrdy() {} // Configure voltage scale. #[cfg(any(pwr_h5, pwr_h50))] { PWR.voscr().modify(|w| { w.set_vos(match config.voltage_scale { - VoltageScale::Scale0 => Vos::SCALE0, - VoltageScale::Scale1 => Vos::SCALE1, - VoltageScale::Scale2 => Vos::SCALE2, - VoltageScale::Scale3 => Vos::SCALE3, + VoltageScale::Scale0 => crate::pac::pwr::vals::Vos::SCALE0, + VoltageScale::Scale1 => crate::pac::pwr::vals::Vos::SCALE1, + VoltageScale::Scale2 => crate::pac::pwr::vals::Vos::SCALE2, + VoltageScale::Scale3 => crate::pac::pwr::vals::Vos::SCALE3, }) }); while !PWR.vossr().read().vosrdy() {} } - #[cfg(syscfg_h7)] { // in chips without the overdrive bit, we can go from any scale to any scale directly. PWR.d3cr().modify(|w| { w.set_vos(match config.voltage_scale { - VoltageScale::Scale0 => Vos::SCALE0, - VoltageScale::Scale1 => Vos::SCALE1, - VoltageScale::Scale2 => Vos::SCALE2, - VoltageScale::Scale3 => Vos::SCALE3, + VoltageScale::Scale0 => crate::pac::pwr::vals::Vos::SCALE0, + VoltageScale::Scale1 => crate::pac::pwr::vals::Vos::SCALE1, + VoltageScale::Scale2 => crate::pac::pwr::vals::Vos::SCALE2, + VoltageScale::Scale3 => crate::pac::pwr::vals::Vos::SCALE3, }) }); while !PWR.d3cr().read().vosrdy() {} } + #[cfg(pwr_h7rs)] + { + PWR.csr4().modify(|w| w.set_vos(config.voltage_scale)); + while !PWR.csr4().read().vosrdy() {} + } #[cfg(syscfg_h7od)] { match config.voltage_scale { VoltageScale::Scale0 => { // to go to scale0, we must go to Scale1 first... - PWR.d3cr().modify(|w| w.set_vos(Vos::SCALE1)); + PWR.d3cr().modify(|w| w.set_vos(crate::pac::pwr::vals::Vos::SCALE1)); while !PWR.d3cr().read().vosrdy() {} // Then enable overdrive. @@ -353,9 +392,9 @@ pub(crate) unsafe fn init(config: Config) { PWR.d3cr().modify(|w| { w.set_vos(match config.voltage_scale { VoltageScale::Scale0 => unreachable!(), - VoltageScale::Scale1 => Vos::SCALE1, - VoltageScale::Scale2 => Vos::SCALE2, - VoltageScale::Scale3 => Vos::SCALE3, + VoltageScale::Scale1 => crate::pac::pwr::vals::Vos::SCALE1, + VoltageScale::Scale2 => crate::pac::pwr::vals::Vos::SCALE2, + VoltageScale::Scale3 => crate::pac::pwr::vals::Vos::SCALE3, }) }); while !PWR.d3cr().read().vosrdy() {} @@ -363,20 +402,24 @@ pub(crate) unsafe fn init(config: Config) { } } + // Turn on the HSI + match config.hsi { + None => RCC.cr().modify(|w| w.set_hsion(true)), + Some(hsidiv) => RCC.cr().modify(|w| { + w.set_hsidiv(hsidiv); + w.set_hsion(true); + }), + } + while !RCC.cr().read().hsirdy() {} + + // Use the HSI clock as system clock during the actual clock setup + RCC.cfgr().modify(|w| w.set_sw(Sysclk::HSI)); + while RCC.cfgr().read().sws() != Sysclk::HSI {} + // Configure HSI let hsi = match config.hsi { - None => { - RCC.cr().modify(|w| w.set_hsion(false)); - None - } - Some(hsidiv) => { - RCC.cr().modify(|w| { - w.set_hsidiv(hsidiv); - w.set_hsion(true); - }); - while !RCC.cr().read().hsirdy() {} - Some(HSI_FREQ / hsidiv) - } + None => None, + Some(hsidiv) => Some(HSI_FREQ / hsidiv), }; // Configure HSE @@ -388,7 +431,7 @@ pub(crate) unsafe fn init(config: Config) { Some(hse) => { RCC.cr().modify(|w| { w.set_hsebyp(hse.mode != HseMode::Oscillator); - #[cfg(any(rcc_h5, rcc_h50))] + #[cfg(any(rcc_h5, rcc_h50, rcc_h7rs))] w.set_hseext(match hse.mode { HseMode::Oscillator | HseMode::Bypass => pac::rcc::vals::Hseext::ANALOG, HseMode::BypassDigital => pac::rcc::vals::Hseext::DIGITAL, @@ -414,7 +457,7 @@ pub(crate) unsafe fn init(config: Config) { }; // H7 has shared PLLSRC, check it's equal in all PLLs. - #[cfg(stm32h7)] + #[cfg(any(stm32h7, stm32h7rs))] { let plls = [&config.pll1, &config.pll2, &config.pll3]; if !super::util::all_equal(plls.into_iter().flatten().map(|p| p.source)) { @@ -426,7 +469,7 @@ pub(crate) unsafe fn init(config: Config) { let pll_input = PllInput { csi, hse, hsi }; let pll1 = init_pll(0, config.pll1, &pll_input); let pll2 = init_pll(1, config.pll2, &pll_input); - #[cfg(any(rcc_h5, stm32h7))] + #[cfg(any(rcc_h5, stm32h7, stm32h7rs))] let pll3 = init_pll(2, config.pll3, &pll_input); // Configure sysclk @@ -474,8 +517,13 @@ pub(crate) unsafe fn init(config: Config) { VoltageScale::Scale2 => (Hertz(300_000_000), Hertz(150_000_000), Hertz(75_000_000)), VoltageScale::Scale3 => (Hertz(200_000_000), Hertz(100_000_000), Hertz(50_000_000)), }; + #[cfg(stm32h7rs)] + let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale { + VoltageScale::HIGH => (Hertz(600_000_000), Hertz(300_000_000), Hertz(150_000_000)), + VoltageScale::LOW => (Hertz(400_000_000), Hertz(200_000_000), Hertz(100_000_000)), + }; - #[cfg(stm32h7)] + #[cfg(any(stm32h7, stm32h7rs))] let hclk = { let d1cpre_clk = sys / config.d1c_pre; assert!(d1cpre_clk <= d1cpre_clk_max); @@ -491,12 +539,18 @@ pub(crate) unsafe fn init(config: Config) { let apb2 = hclk / config.apb2_pre; let apb2_tim = apb_div_tim(&config.apb2_pre, hclk, config.timer_prescaler); assert!(apb2 <= pclk_max); + #[cfg(not(stm32h7rs))] let apb3 = hclk / config.apb3_pre; + #[cfg(not(stm32h7rs))] assert!(apb3 <= pclk_max); - #[cfg(stm32h7)] + #[cfg(any(stm32h7, stm32h7rs))] let apb4 = hclk / config.apb4_pre; - #[cfg(stm32h7)] + #[cfg(any(stm32h7, stm32h7rs))] assert!(apb4 <= pclk_max); + #[cfg(stm32h7rs)] + let apb5 = hclk / config.apb5_pre; + #[cfg(stm32h7rs)] + assert!(apb5 <= pclk_max); flash_setup(hclk, config.voltage_scale); @@ -520,6 +574,25 @@ pub(crate) unsafe fn init(config: Config) { w.set_d3ppre(config.apb4_pre); }); } + #[cfg(stm32h7rs)] + { + RCC.cdcfgr().write(|w| { + w.set_cpre(config.d1c_pre); + }); + while RCC.cdcfgr().read().cpre() != config.d1c_pre {} + + RCC.bmcfgr().write(|w| { + w.set_bmpre(config.ahb_pre); + }); + while RCC.bmcfgr().read().bmpre() != config.ahb_pre {} + + RCC.apbcfgr().modify(|w| { + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); + w.set_ppre4(config.apb4_pre); + w.set_ppre5(config.apb5_pre); + }); + } #[cfg(stm32h5)] { // Set hpre @@ -539,8 +612,13 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| w.set_sw(config.sys)); while RCC.cfgr().read().sws() != config.sys {} + // Disable HSI if not used + if config.hsi.is_none() { + RCC.cr().modify(|w| w.set_hsion(false)); + } + // IO compensation cell - Requires CSI clock and SYSCFG - #[cfg(stm32h7)] // TODO h5 + #[cfg(any(stm32h7))] // TODO h5, h7rs if csi.is_some() { // Enable the compensation cell, using back-bias voltage code // provide by the cell. @@ -551,7 +629,7 @@ pub(crate) unsafe fn init(config: Config) { w.set_hslv(false); }) }); - while !pac::SYSCFG.cccsr().read().ready() {} + while !pac::SYSCFG.cccsr().read().rdy() {} } config.mux.init(); @@ -562,11 +640,17 @@ pub(crate) unsafe fn init(config: Config) { hclk2: Some(hclk), hclk3: Some(hclk), hclk4: Some(hclk), + #[cfg(stm32h7rs)] + hclk5: Some(hclk), pclk1: Some(apb1), pclk2: Some(apb2), + #[cfg(not(stm32h7rs))] pclk3: Some(apb3), - #[cfg(stm32h7)] + #[cfg(any(stm32h7, stm32h7rs))] pclk4: Some(apb4), + #[cfg(stm32h7rs)] + pclk5: Some(apb5), + pclk1_tim: Some(apb1_tim), pclk2_tim: Some(apb2_tim), rtc: rtc, @@ -584,11 +668,15 @@ pub(crate) unsafe fn init(config: Config) { pll2_p: pll2.p, pll2_q: pll2.q, pll2_r: pll2.r, - #[cfg(any(rcc_h5, stm32h7))] + #[cfg(stm32h7rs)] + pll2_s: None, // TODO + #[cfg(stm32h7rs)] + pll2_t: None, // TODO + #[cfg(any(rcc_h5, stm32h7, stm32h7rs))] pll3_p: pll3.p, - #[cfg(any(rcc_h5, stm32h7))] + #[cfg(any(rcc_h5, stm32h7, stm32h7rs))] pll3_q: pll3.q, - #[cfg(any(rcc_h5, stm32h7))] + #[cfg(any(rcc_h5, stm32h7, stm32h7rs))] pll3_r: pll3.r, #[cfg(rcc_h50)] @@ -598,9 +686,18 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(rcc_h50)] pll3_r: None, + #[cfg(dsihost)] + dsi_phy: None, // DSI PLL clock not supported, don't call `RccPeripheral::frequency()` in the drivers + #[cfg(stm32h5)] audioclk: None, i2s_ckin: None, + #[cfg(stm32h7rs)] + spdifrx_symb: None, // TODO + #[cfg(stm32h7rs)] + clk48mohci: None, // TODO + #[cfg(stm32h7rs)] + usb: None, // TODO ); } @@ -625,7 +722,7 @@ fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput { while RCC.cr().read().pllrdy(num) {} // "To save power when PLL1 is not used, the value of PLL1M must be set to 0."" - #[cfg(stm32h7)] + #[cfg(any(stm32h7, stm32h7rs))] RCC.pllckselr().write(|w| w.set_divm(num, PllPreDiv::from_bits(0))); #[cfg(stm32h5)] RCC.pllcfgr(num).write(|w| w.set_divm(PllPreDiv::from_bits(0))); @@ -694,7 +791,7 @@ fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput { w.set_pllren(r.is_some()); }); - #[cfg(stm32h7)] + #[cfg(any(stm32h7, stm32h7rs))] { RCC.pllckselr().modify(|w| { w.set_divm(num, config.prediv); @@ -848,6 +945,26 @@ fn flash_setup(clk: Hertz, vos: VoltageScale) { (VoltageScale::Scale3, ..=88) => (3, 1), _ => unreachable!(), }; + #[cfg(flash_h7rs)] + let (latency, wrhighfreq) = match (vos, clk.0) { + // VOS high range VCORE 1.30V - 1.40V + (VoltageScale::HIGH, ..=40_000_000) => (0, 0), + (VoltageScale::HIGH, ..=80_000_000) => (1, 0), + (VoltageScale::HIGH, ..=120_000_000) => (2, 1), + (VoltageScale::HIGH, ..=160_000_000) => (3, 1), + (VoltageScale::HIGH, ..=200_000_000) => (4, 2), + (VoltageScale::HIGH, ..=240_000_000) => (5, 2), + (VoltageScale::HIGH, ..=280_000_000) => (6, 3), + (VoltageScale::HIGH, ..=320_000_000) => (7, 3), + // VOS low range VCORE 1.15V - 1.26V + (VoltageScale::LOW, ..=36_000_000) => (0, 0), + (VoltageScale::LOW, ..=72_000_000) => (1, 0), + (VoltageScale::LOW, ..=108_000_000) => (2, 1), + (VoltageScale::LOW, ..=144_000_000) => (3, 1), + (VoltageScale::LOW, ..=180_000_000) => (4, 2), + (VoltageScale::LOW, ..=216_000_000) => (5, 2), + _ => unreachable!(), + }; debug!("flash: latency={} wrhighfreq={}", latency, wrhighfreq); diff --git a/embassy-stm32/src/rcc/hsi48.rs b/embassy-stm32/src/rcc/hsi48.rs index 6f0d7b379..da81abc34 100644 --- a/embassy-stm32/src/rcc/hsi48.rs +++ b/embassy-stm32/src/rcc/hsi48.rs @@ -33,9 +33,9 @@ pub(crate) fn init_hsi48(config: Hsi48Config) -> Hertz { }); // Enable HSI48 - #[cfg(not(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32u5, stm32wba, stm32f0)))] + #[cfg(not(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32h7rs, stm32u5, stm32wba, stm32f0)))] let r = RCC.crrcr(); - #[cfg(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32u5, stm32wba))] + #[cfg(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32h7rs, stm32u5, stm32wba))] let r = RCC.cr(); #[cfg(any(stm32f0))] let r = RCC.cr2(); diff --git a/embassy-stm32/src/rcc/l.rs b/embassy-stm32/src/rcc/l.rs index 9079ddd41..e9266c65b 100644 --- a/embassy-stm32/src/rcc/l.rs +++ b/embassy-stm32/src/rcc/l.rs @@ -49,6 +49,7 @@ pub struct Config { pub sys: Sysclk, pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, + #[cfg(not(stm32u0))] pub apb2_pre: APBPrescaler, #[cfg(any(stm32wl5x, stm32wb))] pub core2_ahb_pre: AHBPrescaler, @@ -75,6 +76,7 @@ impl Default for Config { sys: Sysclk::MSI, ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, + #[cfg(not(stm32u0))] apb2_pre: APBPrescaler::DIV1, #[cfg(any(stm32wl5x, stm32wb))] core2_ahb_pre: AHBPrescaler::DIV1, @@ -130,7 +132,7 @@ pub const WPAN_DEFAULT: Config = Config { }; fn msi_enable(range: MSIRange) { - #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl, stm32u0))] RCC.cr().modify(|w| { #[cfg(not(stm32wb))] w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); @@ -157,6 +159,13 @@ pub(crate) unsafe fn init(config: Config) { while RCC.cfgr().read().sws() != Sysclk::MSI {} } + #[cfg(stm32wl)] + { + // Set max latency + FLASH.acr().modify(|w| w.set_prften(true)); + FLASH.acr().modify(|w| w.set_latency(2)); + } + // Set voltage scale #[cfg(any(stm32l0, stm32l1))] { @@ -240,7 +249,7 @@ pub(crate) unsafe fn init(config: Config) { let pll_input = PllInput { hse, hsi, - #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl, stm32u0))] msi, }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); @@ -254,6 +263,10 @@ pub(crate) unsafe fn init(config: Config) { Sysclk::HSI => hsi.unwrap(), Sysclk::MSI => msi.unwrap(), Sysclk::PLL1_R => pll.r.unwrap(), + #[cfg(stm32u0)] + Sysclk::LSI | Sysclk::LSE => todo!(), + #[cfg(stm32u0)] + Sysclk::_RESERVED_6 | Sysclk::_RESERVED_7 => unreachable!(), }; #[cfg(rcc_l4plus)] @@ -263,6 +276,7 @@ pub(crate) unsafe fn init(config: Config) { let hclk1 = sys_clk / config.ahb_pre; let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre); + #[cfg(not(stm32u0))] let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); #[cfg(any(stm32l4, stm32l5, stm32wlex))] let hclk2 = hclk1; @@ -315,6 +329,13 @@ pub(crate) unsafe fn init(config: Config) { ..=64_000_000 => 3, _ => 4, }; + #[cfg(stm32u0)] + let latency = match hclk1.0 { + // VOS RANGE1, others TODO. + ..=24_000_000 => 0, + ..=48_000_000 => 1, + _ => 2, + }; #[cfg(stm32l1)] FLASH.acr().write(|w| w.set_acc64(true)); @@ -326,7 +347,11 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| { w.set_sw(config.sys); w.set_hpre(config.ahb_pre); + #[cfg(stm32u0)] + w.set_ppre(config.apb1_pre); + #[cfg(not(stm32u0))] w.set_ppre1(config.apb1_pre); + #[cfg(not(stm32u0))] w.set_ppre2(config.apb2_pre); }); while RCC.cfgr().read().sws() != config.sys {} @@ -353,8 +378,10 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] hclk3: Some(hclk3), pclk1: Some(pclk1), + #[cfg(not(stm32u0))] pclk2: Some(pclk2), pclk1_tim: Some(pclk1_tim), + #[cfg(not(stm32u0))] pclk2_tim: Some(pclk2_tim), #[cfg(stm32wl)] pclk3: Some(hclk3), @@ -393,6 +420,9 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] pllsai2_r: pllsai2.r, + #[cfg(dsihost)] + dsi_phy: None, // DSI PLL clock not supported, don't call `RccPeripheral::frequency()` in the drivers + rtc: rtc, // TODO @@ -408,7 +438,7 @@ fn msirange_to_hertz(range: MSIRange) -> Hertz { Hertz(32_768 * (1 << (range as u8 + 1))) } -#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] +#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl, stm32u0))] fn msirange_to_hertz(range: MSIRange) -> Hertz { match range { MSIRange::RANGE100K => Hertz(100_000), @@ -521,7 +551,7 @@ mod pll { } } -#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] +#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl, stm32u0))] mod pll { use super::{pll_enable, PllInstance}; pub use crate::pac::rcc::vals::{ diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs index d8604e07e..40e963466 100644 --- a/embassy-stm32/src/rcc/mco.rs +++ b/embassy-stm32/src/rcc/mco.rs @@ -5,9 +5,31 @@ use embassy_hal_internal::into_ref; use crate::gpio::{AFType, Speed}; #[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))] pub use crate::pac::rcc::vals::Mcopre as McoPrescaler; -#[cfg(not(any(rcc_f2, rcc_f410, rcc_f4, rcc_f7, rcc_h50, rcc_h5, rcc_h7ab, rcc_h7rm0433, rcc_h7)))] +#[cfg(not(any( + rcc_f2, + rcc_f410, + rcc_f4, + rcc_f7, + rcc_h50, + rcc_h5, + rcc_h7ab, + rcc_h7rm0433, + rcc_h7, + rcc_h7rs +)))] pub use crate::pac::rcc::vals::Mcosel as McoSource; -#[cfg(any(rcc_f2, rcc_f410, rcc_f4, rcc_f7, rcc_h50, rcc_h5, rcc_h7ab, rcc_h7rm0433, rcc_h7))] +#[cfg(any( + rcc_f2, + rcc_f410, + rcc_f4, + rcc_f7, + rcc_h50, + rcc_h5, + rcc_h7ab, + rcc_h7rm0433, + rcc_h7, + rcc_h7rs +))] pub use crate::pac::rcc::vals::{Mco1sel as Mco1Source, Mco2sel as Mco2Source}; use crate::pac::RCC; use crate::{peripherals, Peripheral}; @@ -52,7 +74,7 @@ macro_rules! impl_peri { }; } -#[cfg(any(rcc_c0, rcc_g0))] +#[cfg(any(rcc_c0, rcc_g0, rcc_u0))] #[allow(unused_imports)] use self::{McoSource as Mco1Source, McoSource as Mco2Source}; diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index c328344aa..28816256c 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -24,13 +24,14 @@ pub use hsi48::*; #[cfg_attr(stm32c0, path = "c0.rs")] #[cfg_attr(stm32g0, path = "g0.rs")] #[cfg_attr(stm32g4, path = "g4.rs")] -#[cfg_attr(any(stm32h5, stm32h7), path = "h.rs")] -#[cfg_attr(any(stm32l0, stm32l1, stm32l4, stm32l5, stm32wb, stm32wl), path = "l.rs")] +#[cfg_attr(any(stm32h5, stm32h7, stm32h7rs), path = "h.rs")] +#[cfg_attr(any(stm32l0, stm32l1, stm32l4, stm32l5, stm32wb, stm32wl, stm32u0), path = "l.rs")] #[cfg_attr(stm32u5, path = "u5.rs")] #[cfg_attr(stm32wba, path = "wba.rs")] mod _version; pub use _version::*; +use stm32_metapac::RCC; pub use crate::_generated::{mux, Clocks}; use crate::time::Hertz; @@ -66,7 +67,9 @@ pub(crate) unsafe fn get_freqs() -> &'static Clocks { } pub(crate) trait SealedRccPeripheral { - fn frequency() -> crate::time::Hertz; + const ENABLE_BIT: ClockEnableBit; + + fn frequency() -> Hertz; fn enable_and_reset_with_cs(cs: CriticalSection); fn disable_with_cs(cs: CriticalSection); @@ -119,3 +122,67 @@ mod util { pub fn frequency<T: RccPeripheral>() -> Hertz { T::frequency() } + +/// Enables and resets peripheral `T`. +/// +/// # Safety +/// +/// Peripheral must not be in use. +pub unsafe fn enable_and_reset<T: RccPeripheral>() { + T::enable_and_reset(); +} + +/// Disables peripheral `T`. +/// +/// # Safety +/// +/// Peripheral must not be in use. +pub unsafe fn disable<T: RccPeripheral>() { + T::disable(); +} + +/// Struct representing some clock enable bit (xxxENR.xxEN), only known at runtime. +#[derive(Clone, Copy)] +pub(crate) struct ClockEnableBit { + /// offset in 32bit words of the xxxENR register into the RCC register block. + offset: u8, + /// bit within the register (0..=31) + bit: u8, +} + +impl ClockEnableBit { + /// Safety: offset+bit must correspond to a valid xxxEN bit. + pub(crate) const unsafe fn new(offset: u8, bit: u8) -> Self { + Self { offset, bit } + } + + fn ptr(self) -> *mut u32 { + unsafe { (RCC.as_ptr() as *mut u32).add(self.offset as _) } + } + + #[allow(unused)] + pub(crate) fn enable_with_cs(self, _cs: CriticalSection) { + let p = self.ptr(); + unsafe { + let val = p.read_volatile(); + p.write_volatile(val | 1u32 << self.bit); + } + } + + pub(crate) fn disable_with_cs(self, _cs: CriticalSection) { + let p = self.ptr(); + unsafe { + let val = p.read_volatile(); + p.write_volatile(val & !(1u32 << self.bit)); + } + } + + #[allow(unused)] + pub(crate) fn enable(self) { + critical_section::with(|cs| self.enable_with_cs(cs)) + } + + pub(crate) fn disable(self) { + critical_section::with(|cs| self.disable_with_cs(cs)) + } +} diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index 9533e16c4..d6331f512 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -289,6 +289,9 @@ pub(crate) unsafe fn init(config: Config) { pll3_q: pll3.q, pll3_r: pll3.r, + #[cfg(dsihost)] + dsi_phy: None, // DSI PLL clock not supported, don't call `RccPeripheral::frequency()` in the drivers + // TODO audioclk: None, hsi48_div_2: None, diff --git a/embassy-stm32/src/rtc/datetime.rs b/embassy-stm32/src/rtc/datetime.rs index bab8cf4a3..77d89293d 100644 --- a/embassy-stm32/src/rtc/datetime.rs +++ b/embassy-stm32/src/rtc/datetime.rs @@ -148,9 +148,9 @@ impl DateTime { ) -> Result<Self, Error> { if year > 4095 { Err(Error::InvalidYear) - } else if month < 1 || month > 12 { + } else if !(1..=12).contains(&month) { Err(Error::InvalidMonth) - } else if day < 1 || day > 31 { + } else if !(1..=31).contains(&day) { Err(Error::InvalidDay) } else if hour > 23 { Err(Error::InvalidHour) diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 00abe9356..b12a0db66 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -42,7 +42,7 @@ pub(crate) enum WakeupPrescaler { Div16 = 16, } -#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4, stm32l5, stm32g0))] +#[cfg(any(stm32f4, stm32l0, stm32g4, stm32l5, stm32wb, stm32h5, stm32g0))] impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel { fn from(val: WakeupPrescaler) -> Self { use crate::pac::rtc::vals::Wucksel; @@ -56,7 +56,7 @@ impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel { } } -#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4, stm32l5, stm32g0))] +#[cfg(any(stm32f4, stm32l0, stm32g4, stm32l5, stm32wb, stm32h5, stm32g0))] impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler { fn from(val: crate::pac::rtc::vals::Wucksel) -> Self { use crate::pac::rtc::vals::Wucksel; @@ -81,8 +81,7 @@ impl WakeupPrescaler { WakeupPrescaler::Div16, ] .iter() - .skip_while(|psc| **psc as u32 <= val) - .next() + .find(|psc| **psc as u32 > val) .unwrap_or(&WakeupPrescaler::Div16) } } @@ -159,7 +158,7 @@ impl RtcTimeProvider { } } - return Err(RtcError::ReadFailure); + Err(RtcError::ReadFailure) } } @@ -190,7 +189,7 @@ impl Default for RtcConfig { } /// Calibration cycle period. -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Default, Copy, Clone, Debug, PartialEq)] #[repr(u8)] pub enum RtcCalibrationCyclePeriod { /// 8-second calibration period @@ -198,15 +197,10 @@ pub enum RtcCalibrationCyclePeriod { /// 16-second calibration period Seconds16, /// 32-second calibration period + #[default] Seconds32, } -impl Default for RtcCalibrationCyclePeriod { - fn default() -> Self { - RtcCalibrationCyclePeriod::Seconds32 - } -} - impl Rtc { /// Create a new RTC instance. pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { @@ -254,13 +248,13 @@ impl Rtc { /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range. pub fn set_datetime(&mut self, t: DateTime) -> Result<(), RtcError> { self.write(true, |rtc| { - let (ht, hu) = byte_to_bcd2(t.hour() as u8); - let (mnt, mnu) = byte_to_bcd2(t.minute() as u8); - let (st, su) = byte_to_bcd2(t.second() as u8); + let (ht, hu) = byte_to_bcd2(t.hour()); + let (mnt, mnu) = byte_to_bcd2(t.minute()); + let (st, su) = byte_to_bcd2(t.second()); - let (dt, du) = byte_to_bcd2(t.day() as u8); - let (mt, mu) = byte_to_bcd2(t.month() as u8); - let yr = t.year() as u16; + let (dt, du) = byte_to_bcd2(t.day()); + let (mt, mu) = byte_to_bcd2(t.month()); + let yr = t.year(); let yr_offset = (yr - 2000_u16) as u8; let (yt, yu) = byte_to_bcd2(yr_offset); @@ -338,7 +332,7 @@ impl Rtc { } #[cfg(feature = "low-power")] - /// start the wakeup alarm and wtih a duration that is as close to but less than + /// start the wakeup alarm and with a duration that is as close to but less than /// the requested duration, and record the instant the wakeup alarm was started pub(crate) fn start_wakeup_alarm( &self, @@ -422,20 +416,15 @@ impl Rtc { #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))] regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR)); - #[cfg(all(stm32g0))] - crate::pac::EXTI - .rpr(0) - .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); - #[cfg(all(not(stm32g0), not(stm32l5)))] + // Check RM for EXTI and/or NVIC section, "Event event input mapping" or "EXTI interrupt/event mapping" or something similar, + // there is a table for every "Event input" / "EXTI Line". + // If you find the EXTI line related to "RTC wakeup" marks as "Configurable" (not "Direct"), + // then write 1 to related field of Pending Register, to clean it's pending state. + #[cfg(any(exti_v1, stm32h7, stm32wb))] crate::pac::EXTI .pr(0) .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); - #[cfg(stm32l5)] - crate::pac::EXTI - .fpr(0) - .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); - <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend(); }); } @@ -465,7 +454,7 @@ pub(crate) fn byte_to_bcd2(byte: u8) -> (u8, u8) { value -= 10; } - (bcd_high, ((bcd_high << 4) | value) as u8) + (bcd_high, ((bcd_high << 4) | value)) } pub(crate) fn bcd2_to_byte(bcd: (u8, u8)) -> u8 { diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs index 8a78d16e1..e51e09e7c 100644 --- a/embassy-stm32/src/rtc/v3.rs +++ b/embassy-stm32/src/rtc/v3.rs @@ -50,7 +50,7 @@ impl super::Rtc { clock_drift = Self::RTC_CALR_MAX_PPM; } - clock_drift = clock_drift / Self::RTC_CALR_RESOLUTION_PPM; + clock_drift /= Self::RTC_CALR_RESOLUTION_PPM; self.write(false, |rtc| { rtc.calr().write(|w| { @@ -129,29 +129,25 @@ impl super::Rtc { impl SealedInstance for crate::peripherals::RTC { const BACKUP_REGISTER_COUNT: usize = 32; - #[cfg(all(feature = "low-power", stm32g4))] - const EXTI_WAKEUP_LINE: usize = 20; - - #[cfg(all(feature = "low-power", stm32g0))] - const EXTI_WAKEUP_LINE: usize = 19; - - #[cfg(all(feature = "low-power", stm32g0))] - type WakeupInterrupt = crate::interrupt::typelevel::RTC_TAMP; - - #[cfg(all(feature = "low-power", stm32g4))] - type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP; - - #[cfg(all(feature = "low-power", stm32l5))] - const EXTI_WAKEUP_LINE: usize = 17; - - #[cfg(all(feature = "low-power", stm32l5))] - type WakeupInterrupt = crate::interrupt::typelevel::RTC; + #[cfg(feature = "low-power")] + cfg_if::cfg_if!( + if #[cfg(stm32g4)] { + const EXTI_WAKEUP_LINE: usize = 20; + type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP; + } else if #[cfg(stm32g0)] { + const EXTI_WAKEUP_LINE: usize = 19; + type WakeupInterrupt = crate::interrupt::typelevel::RTC_TAMP; + } else if #[cfg(any(stm32l5, stm32h5))] { + const EXTI_WAKEUP_LINE: usize = 17; + type WakeupInterrupt = crate::interrupt::typelevel::RTC; + } + ); fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> { #[allow(clippy::if_same_then_else)] if register < Self::BACKUP_REGISTER_COUNT { //Some(rtc.bkpr()[register].read().bits()) - None // RTC3 backup registers come from the TAMP peripe=heral, not RTC. Not() even in the L412 PAC + None // RTC3 backup registers come from the TAMP peripheral, not RTC. Not() even in the L412 PAC } else { None } @@ -159,7 +155,7 @@ impl SealedInstance for crate::peripherals::RTC { fn write_backup_register(_rtc: &Rtc, register: usize, _value: u32) { if register < Self::BACKUP_REGISTER_COUNT { - // RTC3 backup registers come from the TAMP peripe=heral, not RTC. Not() even in the L412 PAC + // RTC3 backup registers come from the TAMP peripheral, not RTC. Not() even in the L412 PAC //self.rtc.bkpr()[register].write(|w| w.bits(value)) } } diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 0b38c4288..5fc8691ac 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -1,19 +1,21 @@ //! Serial Peripheral Interface (SPI) #![macro_use] +use core::marker::PhantomData; use core::ptr; use embassy_embedded_hal::SetConfig; use embassy_futures::join::join; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::PeripheralRef; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; -use crate::dma::{slice_ptr_parts, word, Transfer}; -use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _}; +use crate::dma::{slice_ptr_parts, word, ChannelAndRequest}; +use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; +use crate::mode::{Async, Blocking, Mode as PeriMode}; use crate::pac::spi::{regs, vals, Spi as Regs}; -use crate::rcc::RccPeripheral; +use crate::rcc::{ClockEnableBit, SealedRccPeripheral}; use crate::time::Hertz; -use crate::{peripherals, Peripheral}; +use crate::Peripheral; /// SPI error. #[derive(Debug, PartialEq, Eq)] @@ -48,6 +50,11 @@ pub struct Config { pub bit_order: BitOrder, /// Clock frequency. pub frequency: Hertz, + /// Enable internal pullup on MISO. + /// + /// There are some ICs that require a pull-up on the MISO pin for some applications. + /// If you are unsure, you probably don't need this. + pub miso_pull: Pull, } impl Default for Config { @@ -56,6 +63,7 @@ impl Default for Config { mode: MODE_0, bit_order: BitOrder::MsbFirst, frequency: Hertz(1_000_000), + miso_pull: Pull::None, } } } @@ -81,167 +89,40 @@ impl Config { BitOrder::MsbFirst => vals::Lsbfirst::MSBFIRST, } } -} + fn sck_pull_mode(&self) -> Pull { + match self.mode.polarity { + Polarity::IdleLow => Pull::Down, + Polarity::IdleHigh => Pull::Up, + } + } +} /// SPI driver. -pub struct Spi<'d, T: Instance, Tx, Rx> { - _peri: PeripheralRef<'d, T>, +pub struct Spi<'d, M: PeriMode> { + pub(crate) info: &'static Info, + kernel_clock: Hertz, sck: Option<PeripheralRef<'d, AnyPin>>, mosi: Option<PeripheralRef<'d, AnyPin>>, miso: Option<PeripheralRef<'d, AnyPin>>, - txdma: PeripheralRef<'d, Tx>, - rxdma: PeripheralRef<'d, Rx>, + tx_dma: Option<ChannelAndRequest<'d>>, + rx_dma: Option<ChannelAndRequest<'d>>, + _phantom: PhantomData<M>, current_word_size: word_impl::Config, } -impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { - /// Create a new SPI driver. - pub fn new( - peri: impl Peripheral<P = T> + 'd, - sck: impl Peripheral<P = impl SckPin<T>> + 'd, - mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, - miso: impl Peripheral<P = impl MisoPin<T>> + 'd, - txdma: impl Peripheral<P = Tx> + 'd, - rxdma: impl Peripheral<P = Rx> + 'd, - config: Config, - ) -> Self { - into_ref!(peri, sck, mosi, miso); - - let sck_pull_mode = match config.mode.polarity { - Polarity::IdleLow => Pull::Down, - Polarity::IdleHigh => Pull::Up, - }; - - sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, sck_pull_mode); - sck.set_speed(crate::gpio::Speed::VeryHigh); - mosi.set_as_af(mosi.af_num(), AFType::OutputPushPull); - mosi.set_speed(crate::gpio::Speed::VeryHigh); - miso.set_as_af(miso.af_num(), AFType::Input); - miso.set_speed(crate::gpio::Speed::VeryHigh); - - Self::new_inner( - peri, - Some(sck.map_into()), - Some(mosi.map_into()), - Some(miso.map_into()), - txdma, - rxdma, - config, - ) - } - - /// Create a new SPI driver, in RX-only mode (only MISO pin, no MOSI). - pub fn new_rxonly( - peri: impl Peripheral<P = T> + 'd, - sck: impl Peripheral<P = impl SckPin<T>> + 'd, - miso: impl Peripheral<P = impl MisoPin<T>> + 'd, - txdma: impl Peripheral<P = Tx> + 'd, // TODO remove - rxdma: impl Peripheral<P = Rx> + 'd, - config: Config, - ) -> Self { - into_ref!(sck, miso); - sck.set_as_af(sck.af_num(), AFType::OutputPushPull); - sck.set_speed(crate::gpio::Speed::VeryHigh); - miso.set_as_af(miso.af_num(), AFType::Input); - miso.set_speed(crate::gpio::Speed::VeryHigh); - - Self::new_inner( - peri, - Some(sck.map_into()), - None, - Some(miso.map_into()), - txdma, - rxdma, - config, - ) - } - - /// Create a new SPI driver, in TX-only mode (only MOSI pin, no MISO). - pub fn new_txonly( - peri: impl Peripheral<P = T> + 'd, - sck: impl Peripheral<P = impl SckPin<T>> + 'd, - mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, - txdma: impl Peripheral<P = Tx> + 'd, - rxdma: impl Peripheral<P = Rx> + 'd, // TODO remove - config: Config, - ) -> Self { - into_ref!(sck, mosi); - sck.set_as_af(sck.af_num(), AFType::OutputPushPull); - sck.set_speed(crate::gpio::Speed::VeryHigh); - mosi.set_as_af(mosi.af_num(), AFType::OutputPushPull); - mosi.set_speed(crate::gpio::Speed::VeryHigh); - - Self::new_inner( - peri, - Some(sck.map_into()), - Some(mosi.map_into()), - None, - txdma, - rxdma, - config, - ) - } - - /// Create a new SPI driver, in TX-only mode, without SCK pin. - /// - /// This can be useful for bit-banging non-SPI protocols. - pub fn new_txonly_nosck( - peri: impl Peripheral<P = T> + 'd, - mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, - txdma: impl Peripheral<P = Tx> + 'd, - rxdma: impl Peripheral<P = Rx> + 'd, // TODO: remove - config: Config, - ) -> Self { - into_ref!(mosi); - mosi.set_as_af_pull(mosi.af_num(), AFType::OutputPushPull, Pull::Down); - mosi.set_speed(crate::gpio::Speed::Medium); - - Self::new_inner(peri, None, Some(mosi.map_into()), None, txdma, rxdma, config) - } - - #[cfg(stm32wl)] - /// Useful for on chip peripherals like SUBGHZ which are hardwired. - pub fn new_subghz( - peri: impl Peripheral<P = T> + 'd, - txdma: impl Peripheral<P = Tx> + 'd, - rxdma: impl Peripheral<P = Rx> + 'd, - ) -> Self { - // see RM0453 rev 1 section 7.2.13 page 291 - // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two. - // The SUBGHZSPI_SCK clock maximum speed must not exceed 16 MHz. - let pclk3_freq = <peripherals::SUBGHZSPI as crate::rcc::SealedRccPeripheral>::frequency().0; - let freq = Hertz(core::cmp::min(pclk3_freq / 2, 16_000_000)); - let mut config = Config::default(); - config.mode = MODE_0; - config.bit_order = BitOrder::MsbFirst; - config.frequency = freq; - Self::new_inner(peri, None, None, None, txdma, rxdma, config) - } - - #[allow(dead_code)] - pub(crate) fn new_internal( - peri: impl Peripheral<P = T> + 'd, - txdma: impl Peripheral<P = Tx> + 'd, - rxdma: impl Peripheral<P = Rx> + 'd, - config: Config, - ) -> Self { - Self::new_inner(peri, None, None, None, txdma, rxdma, config) - } - - fn new_inner( - peri: impl Peripheral<P = T> + 'd, +impl<'d, M: PeriMode> Spi<'d, M> { + fn new_inner<T: Instance>( + _peri: impl Peripheral<P = T> + 'd, sck: Option<PeripheralRef<'d, AnyPin>>, mosi: Option<PeripheralRef<'d, AnyPin>>, miso: Option<PeripheralRef<'d, AnyPin>>, - txdma: impl Peripheral<P = Tx> + 'd, - rxdma: impl Peripheral<P = Rx> + 'd, + tx_dma: Option<ChannelAndRequest<'d>>, + rx_dma: Option<ChannelAndRequest<'d>>, config: Config, ) -> Self { - into_ref!(peri, txdma, rxdma); - - let pclk = T::frequency(); - let freq = config.frequency; - let br = compute_baud_rate(pclk, freq); + let regs = T::info().regs; + let kernel_clock = T::frequency(); + let br = compute_baud_rate(kernel_clock, config.frequency); let cpha = config.raw_phase(); let cpol = config.raw_polarity(); @@ -252,10 +133,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { #[cfg(any(spi_v1, spi_f1))] { - T::REGS.cr2().modify(|w| { + regs.cr2().modify(|w| { w.set_ssoe(false); }); - T::REGS.cr1().modify(|w| { + regs.cr1().modify(|w| { w.set_cpha(cpha); w.set_cpol(cpol); @@ -275,13 +156,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } #[cfg(spi_v2)] { - T::REGS.cr2().modify(|w| { + regs.cr2().modify(|w| { let (ds, frxth) = <u8 as SealedWord>::CONFIG; w.set_frxth(frxth); w.set_ds(ds); w.set_ssoe(false); }); - T::REGS.cr1().modify(|w| { + regs.cr1().modify(|w| { w.set_cpha(cpha); w.set_cpol(cpol); @@ -297,8 +178,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } #[cfg(any(spi_v3, spi_v4, spi_v5))] { - T::REGS.ifcr().write(|w| w.0 = 0xffff_ffff); - T::REGS.cfg2().modify(|w| { + regs.ifcr().write(|w| w.0 = 0xffff_ffff); + regs.cfg2().modify(|w| { //w.set_ssoe(true); w.set_ssoe(false); w.set_cpha(cpha); @@ -313,29 +194,31 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { w.set_afcntr(true); w.set_ssiop(vals::Ssiop::ACTIVEHIGH); }); - T::REGS.cfg1().modify(|w| { + regs.cfg1().modify(|w| { w.set_crcen(false); w.set_mbr(br); w.set_dsize(<u8 as SealedWord>::CONFIG); w.set_fthlv(vals::Fthlv::ONEFRAME); }); - T::REGS.cr2().modify(|w| { + regs.cr2().modify(|w| { w.set_tsize(0); }); - T::REGS.cr1().modify(|w| { + regs.cr1().modify(|w| { w.set_ssi(false); w.set_spe(true); }); } Self { - _peri: peri, + info: T::info(), + kernel_clock, sck, mosi, miso, - txdma, - rxdma, + tx_dma, + rx_dma, current_word_size: <u8 as SealedWord>::CONFIG, + _phantom: PhantomData, } } @@ -346,12 +229,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let lsbfirst = config.raw_byte_order(); - let pclk = T::frequency(); - let freq = config.frequency; - let br = compute_baud_rate(pclk, freq); + let br = compute_baud_rate(self.kernel_clock, config.frequency); #[cfg(any(spi_v1, spi_f1, spi_v2))] - T::REGS.cr1().modify(|w| { + self.info.regs.cr1().modify(|w| { w.set_cpha(cpha); w.set_cpol(cpol); w.set_br(br); @@ -360,12 +241,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { #[cfg(any(spi_v3, spi_v4, spi_v5))] { - T::REGS.cfg2().modify(|w| { + self.info.regs.cfg2().modify(|w| { w.set_cpha(cpha); w.set_cpol(cpol); w.set_lsbfirst(lsbfirst); }); - T::REGS.cfg1().modify(|w| { + self.info.regs.cfg1().modify(|w| { w.set_mbr(br); }); } @@ -375,11 +256,11 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { /// Get current SPI configuration. pub fn get_current_config(&self) -> Config { #[cfg(any(spi_v1, spi_f1, spi_v2))] - let cfg = T::REGS.cr1().read(); + let cfg = self.info.regs.cr1().read(); #[cfg(any(spi_v3, spi_v4, spi_v5))] - let cfg = T::REGS.cfg2().read(); + let cfg = self.info.regs.cfg2().read(); #[cfg(any(spi_v3, spi_v4, spi_v5))] - let cfg1 = T::REGS.cfg1().read(); + let cfg1 = self.info.regs.cfg1().read(); let polarity = if cfg.cpol() == vals::Cpol::IDLELOW { Polarity::IdleLow @@ -398,18 +279,23 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { BitOrder::MsbFirst }; + let miso_pull = match &self.miso { + None => Pull::None, + Some(pin) => pin.pull(), + }; + #[cfg(any(spi_v1, spi_f1, spi_v2))] let br = cfg.br(); #[cfg(any(spi_v3, spi_v4, spi_v5))] let br = cfg1.mbr(); - let pclk = T::frequency(); - let frequency = compute_frequency(pclk, br); + let frequency = compute_frequency(self.kernel_clock, br); Config { mode: Mode { polarity, phase }, bit_order, frequency, + miso_pull, } } @@ -420,40 +306,40 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { #[cfg(any(spi_v1, spi_f1))] { - T::REGS.cr1().modify(|reg| { + self.info.regs.cr1().modify(|reg| { reg.set_spe(false); reg.set_dff(word_size) }); - T::REGS.cr1().modify(|reg| { + self.info.regs.cr1().modify(|reg| { reg.set_spe(true); }); } #[cfg(spi_v2)] { - T::REGS.cr1().modify(|w| { + self.info.regs.cr1().modify(|w| { w.set_spe(false); }); - T::REGS.cr2().modify(|w| { + self.info.regs.cr2().modify(|w| { w.set_frxth(word_size.1); w.set_ds(word_size.0); }); - T::REGS.cr1().modify(|w| { + self.info.regs.cr1().modify(|w| { w.set_spe(true); }); } #[cfg(any(spi_v3, spi_v4, spi_v5))] { - T::REGS.cr1().modify(|w| { + self.info.regs.cr1().modify(|w| { w.set_csusp(true); }); - while T::REGS.sr().read().eot() {} - T::REGS.cr1().modify(|w| { + while self.info.regs.sr().read().eot() {} + self.info.regs.cr1().modify(|w| { w.set_spe(false); }); - T::REGS.cfg1().modify(|w| { + self.info.regs.cfg1().modify(|w| { w.set_dsize(word_size); }); - T::REGS.cr1().modify(|w| { + self.info.regs.cr1().modify(|w| { w.set_csusp(false); w.set_spe(true); }); @@ -462,187 +348,24 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { self.current_word_size = word_size; } - /// SPI write, using DMA. - pub async fn write<W: Word>(&mut self, data: &[W]) -> Result<(), Error> - where - Tx: TxDma<T>, - { - if data.is_empty() { - return Ok(()); - } - - self.set_word_size(W::CONFIG); - T::REGS.cr1().modify(|w| { - w.set_spe(false); - }); - - let tx_request = self.txdma.request(); - let tx_dst = T::REGS.tx_ptr(); - let tx_f = unsafe { Transfer::new_write(&mut self.txdma, tx_request, data, tx_dst, Default::default()) }; - - set_txdmaen(T::REGS, true); - T::REGS.cr1().modify(|w| { - w.set_spe(true); - }); - #[cfg(any(spi_v3, spi_v4, spi_v5))] - T::REGS.cr1().modify(|w| { - w.set_cstart(true); - }); - - tx_f.await; - - finish_dma(T::REGS); - - Ok(()) - } - - /// SPI read, using DMA. - pub async fn read<W: Word>(&mut self, data: &mut [W]) -> Result<(), Error> - where - Tx: TxDma<T>, - Rx: RxDma<T>, - { - if data.is_empty() { - return Ok(()); - } - - self.set_word_size(W::CONFIG); - T::REGS.cr1().modify(|w| { - w.set_spe(false); - }); - - // SPIv3 clears rxfifo on SPE=0 - #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] - flush_rx_fifo(T::REGS); - - set_rxdmaen(T::REGS, true); - - let clock_byte_count = data.len(); - - let rx_request = self.rxdma.request(); - let rx_src = T::REGS.rx_ptr(); - let rx_f = unsafe { Transfer::new_read(&mut self.rxdma, rx_request, rx_src, data, Default::default()) }; - - let tx_request = self.txdma.request(); - let tx_dst = T::REGS.tx_ptr(); - let clock_byte = 0x00u8; - let tx_f = unsafe { - Transfer::new_write_repeated( - &mut self.txdma, - tx_request, - &clock_byte, - clock_byte_count, - tx_dst, - Default::default(), - ) - }; - - set_txdmaen(T::REGS, true); - T::REGS.cr1().modify(|w| { - w.set_spe(true); - }); - #[cfg(any(spi_v3, spi_v4, spi_v5))] - T::REGS.cr1().modify(|w| { - w.set_cstart(true); - }); - - join(tx_f, rx_f).await; - - finish_dma(T::REGS); - - Ok(()) - } - - async fn transfer_inner<W: Word>(&mut self, read: *mut [W], write: *const [W]) -> Result<(), Error> - where - Tx: TxDma<T>, - Rx: RxDma<T>, - { - let (_, rx_len) = slice_ptr_parts(read); - let (_, tx_len) = slice_ptr_parts(write); - assert_eq!(rx_len, tx_len); - if rx_len == 0 { - return Ok(()); - } - - self.set_word_size(W::CONFIG); - T::REGS.cr1().modify(|w| { - w.set_spe(false); - }); - - // SPIv3 clears rxfifo on SPE=0 - #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] - flush_rx_fifo(T::REGS); - - set_rxdmaen(T::REGS, true); - - let rx_request = self.rxdma.request(); - let rx_src = T::REGS.rx_ptr(); - let rx_f = unsafe { Transfer::new_read_raw(&mut self.rxdma, rx_request, rx_src, read, Default::default()) }; - - let tx_request = self.txdma.request(); - let tx_dst = T::REGS.tx_ptr(); - let tx_f = unsafe { Transfer::new_write_raw(&mut self.txdma, tx_request, write, tx_dst, Default::default()) }; - - set_txdmaen(T::REGS, true); - T::REGS.cr1().modify(|w| { - w.set_spe(true); - }); - #[cfg(any(spi_v3, spi_v4, spi_v5))] - T::REGS.cr1().modify(|w| { - w.set_cstart(true); - }); - - join(tx_f, rx_f).await; - - finish_dma(T::REGS); - - Ok(()) - } - - /// Bidirectional transfer, using DMA. - /// - /// This transfers both buffers at the same time, so it is NOT equivalent to `write` followed by `read`. - /// - /// The transfer runs for `max(read.len(), write.len())` bytes. If `read` is shorter extra bytes are ignored. - /// If `write` is shorter it is padded with zero bytes. - pub async fn transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> - where - Tx: TxDma<T>, - Rx: RxDma<T>, - { - self.transfer_inner(read, write).await - } - - /// In-place bidirectional transfer, using DMA. - /// - /// This writes the contents of `data` on MOSI, and puts the received data on MISO in `data`, at the same time. - pub async fn transfer_in_place<W: Word>(&mut self, data: &mut [W]) -> Result<(), Error> - where - Tx: TxDma<T>, - Rx: RxDma<T>, - { - self.transfer_inner(data, data).await - } - /// Blocking write. pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> { - T::REGS.cr1().modify(|w| w.set_spe(true)); - flush_rx_fifo(T::REGS); + self.info.regs.cr1().modify(|w| w.set_spe(true)); + flush_rx_fifo(self.info.regs); self.set_word_size(W::CONFIG); for word in words.iter() { - let _ = transfer_word(T::REGS, *word)?; + let _ = transfer_word(self.info.regs, *word)?; } Ok(()) } /// Blocking read. pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { - T::REGS.cr1().modify(|w| w.set_spe(true)); - flush_rx_fifo(T::REGS); + self.info.regs.cr1().modify(|w| w.set_spe(true)); + flush_rx_fifo(self.info.regs); self.set_word_size(W::CONFIG); for word in words.iter_mut() { - *word = transfer_word(T::REGS, W::default())?; + *word = transfer_word(self.info.regs, W::default())?; } Ok(()) } @@ -651,11 +374,11 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { /// /// This writes the contents of `data` on MOSI, and puts the received data on MISO in `data`, at the same time. pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { - T::REGS.cr1().modify(|w| w.set_spe(true)); - flush_rx_fifo(T::REGS); + self.info.regs.cr1().modify(|w| w.set_spe(true)); + flush_rx_fifo(self.info.regs); self.set_word_size(W::CONFIG); for word in words.iter_mut() { - *word = transfer_word(T::REGS, *word)?; + *word = transfer_word(self.info.regs, *word)?; } Ok(()) } @@ -667,13 +390,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { /// The transfer runs for `max(read.len(), write.len())` bytes. If `read` is shorter extra bytes are ignored. /// If `write` is shorter it is padded with zero bytes. pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { - T::REGS.cr1().modify(|w| w.set_spe(true)); - flush_rx_fifo(T::REGS); + self.info.regs.cr1().modify(|w| w.set_spe(true)); + flush_rx_fifo(self.info.regs); self.set_word_size(W::CONFIG); let len = read.len().max(write.len()); for i in 0..len { let wb = write.get(i).copied().unwrap_or_default(); - let rb = transfer_word(T::REGS, wb)?; + let rb = transfer_word(self.info.regs, wb)?; if let Some(r) = read.get_mut(i) { *r = rb; } @@ -682,13 +405,340 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } } -impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { +impl<'d> Spi<'d, Blocking> { + /// Create a new blocking SPI driver. + pub fn new_blocking<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, + miso: impl Peripheral<P = impl MisoPin<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), + new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(miso, AFType::Input, Speed::VeryHigh, config.miso_pull), + None, + None, + config, + ) + } + + /// Create a new blocking SPI driver, in RX-only mode (only MISO pin, no MOSI). + pub fn new_blocking_rxonly<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + miso: impl Peripheral<P = impl MisoPin<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), + None, + new_pin!(miso, AFType::Input, Speed::VeryHigh, config.miso_pull), + None, + None, + config, + ) + } + + /// Create a new blocking SPI driver, in TX-only mode (only MOSI pin, no MISO). + pub fn new_blocking_txonly<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), + new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), + None, + None, + None, + config, + ) + } + + /// Create a new SPI driver, in TX-only mode, without SCK pin. + /// + /// This can be useful for bit-banging non-SPI protocols. + pub fn new_blocking_txonly_nosck<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + None, + new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), + None, + None, + None, + config, + ) + } +} + +impl<'d> Spi<'d, Async> { + /// Create a new SPI driver. + pub fn new<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, + miso: impl Peripheral<P = impl MisoPin<T>> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, + rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), + new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(miso, AFType::Input, Speed::VeryHigh), + new_dma!(tx_dma), + new_dma!(rx_dma), + config, + ) + } + + /// Create a new SPI driver, in RX-only mode (only MISO pin, no MOSI). + pub fn new_rxonly<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + miso: impl Peripheral<P = impl MisoPin<T>> + 'd, + rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), + None, + new_pin!(miso, AFType::Input, Speed::VeryHigh), + None, + new_dma!(rx_dma), + config, + ) + } + + /// Create a new SPI driver, in TX-only mode (only MOSI pin, no MISO). + pub fn new_txonly<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + sck: impl Peripheral<P = impl SckPin<T>> + 'd, + mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), + new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), + None, + new_dma!(tx_dma), + None, + config, + ) + } + + /// Create a new SPI driver, in TX-only mode, without SCK pin. + /// + /// This can be useful for bit-banging non-SPI protocols. + pub fn new_txonly_nosck<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner( + peri, + None, + new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), + None, + new_dma!(tx_dma), + None, + config, + ) + } + + #[cfg(stm32wl)] + /// Useful for on chip peripherals like SUBGHZ which are hardwired. + pub fn new_subghz<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, + rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, + ) -> Self { + // see RM0453 rev 1 section 7.2.13 page 291 + // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two. + // The SUBGHZSPI_SCK clock maximum speed must not exceed 16 MHz. + let pclk3_freq = <crate::peripherals::SUBGHZSPI as crate::rcc::SealedRccPeripheral>::frequency().0; + let freq = Hertz(core::cmp::min(pclk3_freq / 2, 16_000_000)); + let mut config = Config::default(); + config.mode = MODE_0; + config.bit_order = BitOrder::MsbFirst; + config.frequency = freq; + + Self::new_inner(peri, None, None, None, new_dma!(tx_dma), new_dma!(rx_dma), config) + } + + #[allow(dead_code)] + pub(crate) fn new_internal<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, + rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, + config: Config, + ) -> Self { + Self::new_inner(peri, None, None, None, new_dma!(tx_dma), new_dma!(rx_dma), config) + } + + /// SPI write, using DMA. + pub async fn write<W: Word>(&mut self, data: &[W]) -> Result<(), Error> { + if data.is_empty() { + return Ok(()); + } + + self.set_word_size(W::CONFIG); + self.info.regs.cr1().modify(|w| { + w.set_spe(false); + }); + + let tx_dst = self.info.regs.tx_ptr(); + let tx_f = unsafe { self.tx_dma.as_mut().unwrap().write(data, tx_dst, Default::default()) }; + + set_txdmaen(self.info.regs, true); + self.info.regs.cr1().modify(|w| { + w.set_spe(true); + }); + #[cfg(any(spi_v3, spi_v4, spi_v5))] + self.info.regs.cr1().modify(|w| { + w.set_cstart(true); + }); + + tx_f.await; + + finish_dma(self.info.regs); + + Ok(()) + } + + /// SPI read, using DMA. + pub async fn read<W: Word>(&mut self, data: &mut [W]) -> Result<(), Error> { + if data.is_empty() { + return Ok(()); + } + + self.set_word_size(W::CONFIG); + self.info.regs.cr1().modify(|w| { + w.set_spe(false); + }); + + // SPIv3 clears rxfifo on SPE=0 + #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] + flush_rx_fifo(self.info.regs); + + set_rxdmaen(self.info.regs, true); + + let clock_byte_count = data.len(); + + let rx_src = self.info.regs.rx_ptr(); + let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read(rx_src, data, Default::default()) }; + + let tx_dst = self.info.regs.tx_ptr(); + let clock_byte = 0x00u8; + let tx_f = unsafe { + self.tx_dma + .as_mut() + .unwrap() + .write_repeated(&clock_byte, clock_byte_count, tx_dst, Default::default()) + }; + + set_txdmaen(self.info.regs, true); + self.info.regs.cr1().modify(|w| { + w.set_spe(true); + }); + #[cfg(any(spi_v3, spi_v4, spi_v5))] + self.info.regs.cr1().modify(|w| { + w.set_cstart(true); + }); + + join(tx_f, rx_f).await; + + finish_dma(self.info.regs); + + Ok(()) + } + + async fn transfer_inner<W: Word>(&mut self, read: *mut [W], write: *const [W]) -> Result<(), Error> { + let (_, rx_len) = slice_ptr_parts(read); + let (_, tx_len) = slice_ptr_parts(write); + assert_eq!(rx_len, tx_len); + if rx_len == 0 { + return Ok(()); + } + + self.set_word_size(W::CONFIG); + self.info.regs.cr1().modify(|w| { + w.set_spe(false); + }); + + // SPIv3 clears rxfifo on SPE=0 + #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] + flush_rx_fifo(self.info.regs); + + set_rxdmaen(self.info.regs, true); + + let rx_src = self.info.regs.rx_ptr(); + let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) }; + + let tx_dst = self.info.regs.tx_ptr(); + let tx_f = unsafe { + self.tx_dma + .as_mut() + .unwrap() + .write_raw(write, tx_dst, Default::default()) + }; + + set_txdmaen(self.info.regs, true); + self.info.regs.cr1().modify(|w| { + w.set_spe(true); + }); + #[cfg(any(spi_v3, spi_v4, spi_v5))] + self.info.regs.cr1().modify(|w| { + w.set_cstart(true); + }); + + join(tx_f, rx_f).await; + + finish_dma(self.info.regs); + + Ok(()) + } + + /// Bidirectional transfer, using DMA. + /// + /// This transfers both buffers at the same time, so it is NOT equivalent to `write` followed by `read`. + /// + /// The transfer runs for `max(read.len(), write.len())` bytes. If `read` is shorter extra bytes are ignored. + /// If `write` is shorter it is padded with zero bytes. + pub async fn transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { + self.transfer_inner(read, write).await + } + + /// In-place bidirectional transfer, using DMA. + /// + /// This writes the contents of `data` on MOSI, and puts the received data on MISO in `data`, at the same time. + pub async fn transfer_in_place<W: Word>(&mut self, data: &mut [W]) -> Result<(), Error> { + self.transfer_inner(data, data).await + } +} + +impl<'d, M: PeriMode> Drop for Spi<'d, M> { fn drop(&mut self) { self.sck.as_ref().map(|x| x.set_as_disconnected()); self.mosi.as_ref().map(|x| x.set_as_disconnected()); self.miso.as_ref().map(|x| x.set_as_disconnected()); - T::disable(); + self.info.enable_bit.disable(); } } @@ -697,8 +747,8 @@ use vals::Br; #[cfg(any(spi_v3, spi_v4, spi_v5))] use vals::Mbr as Br; -fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> Br { - let val = match clocks.0 / freq.0 { +fn compute_baud_rate(kernel_clock: Hertz, freq: Hertz) -> Br { + let val = match kernel_clock.0 / freq.0 { 0 => panic!("You are trying to reach a frequency higher than the clock"), 1..=2 => 0b000, 3..=5 => 0b001, @@ -713,7 +763,7 @@ fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> Br { Br::from_bits(val) } -fn compute_frequency(clocks: Hertz, br: Br) -> Hertz { +fn compute_frequency(kernel_clock: Hertz, br: Br) -> Hertz { let div: u16 = match br { Br::DIV2 => 2, Br::DIV4 => 4, @@ -725,7 +775,7 @@ fn compute_frequency(clocks: Hertz, br: Br) -> Hertz { Br::DIV256 => 256, }; - clocks / div + kernel_clock / div } trait RegsExt { @@ -735,18 +785,22 @@ trait RegsExt { impl RegsExt for Regs { fn tx_ptr<W>(&self) -> *mut W { - #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] + #[cfg(any(spi_v1, spi_f1))] let dr = self.dr(); + #[cfg(spi_v2)] + let dr = self.dr16(); #[cfg(any(spi_v3, spi_v4, spi_v5))] - let dr = self.txdr(); + let dr = self.txdr32(); dr.as_ptr() as *mut W } fn rx_ptr<W>(&self) -> *mut W { - #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] + #[cfg(any(spi_v1, spi_f1))] let dr = self.dr(); + #[cfg(spi_v2)] + let dr = self.dr16(); #[cfg(any(spi_v3, spi_v4, spi_v5))] - let dr = self.rxdr(); + let dr = self.rxdr32(); dr.as_ptr() as *mut W } } @@ -815,11 +869,14 @@ fn spin_until_rx_ready(regs: Regs) -> Result<(), Error> { fn flush_rx_fifo(regs: Regs) { #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] while regs.sr().read().rxne() { + #[cfg(not(spi_v2))] let _ = regs.dr().read(); + #[cfg(spi_v2)] + let _ = regs.dr16().read(); } #[cfg(any(spi_v3, spi_v4, spi_v5))] while regs.sr().read().rxp() { - let _ = regs.rxdr().read(); + let _ = regs.rxdr32().read(); } } @@ -893,7 +950,7 @@ fn transfer_word<W: Word>(regs: Regs, tx_word: W) -> Result<W, Error> { // some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289 macro_rules! impl_blocking { ($w:ident) => { - impl<'d, T: Instance, Tx, Rx> embedded_hal_02::blocking::spi::Write<$w> for Spi<'d, T, Tx, Rx> { + impl<'d, M: PeriMode> embedded_hal_02::blocking::spi::Write<$w> for Spi<'d, M> { type Error = Error; fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> { @@ -901,7 +958,7 @@ macro_rules! impl_blocking { } } - impl<'d, T: Instance, Tx, Rx> embedded_hal_02::blocking::spi::Transfer<$w> for Spi<'d, T, Tx, Rx> { + impl<'d, M: PeriMode> embedded_hal_02::blocking::spi::Transfer<$w> for Spi<'d, M> { type Error = Error; fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> { @@ -915,11 +972,11 @@ macro_rules! impl_blocking { impl_blocking!(u8); impl_blocking!(u16); -impl<'d, T: Instance, Tx, Rx> embedded_hal_1::spi::ErrorType for Spi<'d, T, Tx, Rx> { +impl<'d, M: PeriMode> embedded_hal_1::spi::ErrorType for Spi<'d, M> { type Error = Error; } -impl<'d, T: Instance, W: Word, Tx, Rx> embedded_hal_1::spi::SpiBus<W> for Spi<'d, T, Tx, Rx> { +impl<'d, W: Word, M: PeriMode> embedded_hal_1::spi::SpiBus<W> for Spi<'d, M> { fn flush(&mut self) -> Result<(), Self::Error> { Ok(()) } @@ -952,7 +1009,7 @@ impl embedded_hal_1::spi::Error for Error { } } -impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>, W: Word> embedded_hal_async::spi::SpiBus<W> for Spi<'d, T, Tx, Rx> { +impl<'d, W: Word> embedded_hal_async::spi::SpiBus<W> for Spi<'d, Async> { async fn flush(&mut self) -> Result<(), Self::Error> { Ok(()) } @@ -974,10 +1031,6 @@ impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>, W: Word> embedded_hal_async::s } } -pub(crate) trait SealedInstance { - const REGS: Regs; -} - trait SealedWord { const CONFIG: word_impl::Config; } @@ -1063,9 +1116,20 @@ mod word_impl { impl_word!(u32, 32 - 1); } -/// SPI instance trait. -#[allow(private_bounds)] -pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} +pub(crate) struct Info { + pub(crate) regs: Regs, + pub(crate) enable_bit: ClockEnableBit, +} + +struct State {} + +impl State { + const fn new() -> Self { + Self {} + } +} + +peri_trait!(); pin_trait!(SckPin, Instance); pin_trait!(MosiPin, Instance); @@ -1079,15 +1143,14 @@ dma_trait!(TxDma, Instance); foreach_peripheral!( (spi, $inst:ident) => { - impl SealedInstance for peripherals::$inst { - const REGS: Regs = crate::pac::$inst; - } - - impl Instance for peripherals::$inst {} + peri_trait_impl!($inst, Info { + regs: crate::pac::$inst, + enable_bit: crate::peripherals::$inst::ENABLE_BIT, + }); }; ); -impl<'d, T: Instance, Tx, Rx> SetConfig for Spi<'d, T, Tx, Rx> { +impl<'d, M: PeriMode> SetConfig for Spi<'d, M> { type Config = Config; type ConfigError = (); fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs new file mode 100644 index 000000000..a1c1486f9 --- /dev/null +++ b/embassy-stm32/src/timer/input_capture.rs @@ -0,0 +1,233 @@ +//! Input capture driver. + +use core::future::Future; +use core::marker::PhantomData; +use core::pin::Pin; +use core::task::{Context, Poll}; + +use embassy_hal_internal::{into_ref, PeripheralRef}; + +use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, Timer}; +use super::{ + CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, + GeneralInstance4Channel, +}; +use crate::gpio::{AFType, AnyPin, Pull}; +use crate::interrupt::typelevel::{Binding, Interrupt}; +use crate::time::Hertz; +use crate::Peripheral; + +/// Channel 1 marker type. +pub enum Ch1 {} +/// Channel 2 marker type. +pub enum Ch2 {} +/// Channel 3 marker type. +pub enum Ch3 {} +/// Channel 4 marker type. +pub enum Ch4 {} + +/// Capture pin wrapper. +/// +/// This wraps a pin to make it usable with capture. +pub struct CapturePin<'d, T, C> { + _pin: PeripheralRef<'d, AnyPin>, + phantom: PhantomData<(T, C)>, +} + +macro_rules! channel_impl { + ($new_chx:ident, $channel:ident, $pin_trait:ident) => { + impl<'d, T: GeneralInstance4Channel> CapturePin<'d, T, $channel> { + #[doc = concat!("Create a new ", stringify!($channel), " capture pin instance.")] + pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, pull_type: Pull) -> Self { + into_ref!(pin); + critical_section::with(|_| { + pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type); + #[cfg(gpio_v2)] + pin.set_speed(crate::gpio::Speed::VeryHigh); + }); + CapturePin { + _pin: pin.map_into(), + phantom: PhantomData, + } + } + } + }; +} + +channel_impl!(new_ch1, Ch1, Channel1Pin); +channel_impl!(new_ch2, Ch2, Channel2Pin); +channel_impl!(new_ch3, Ch3, Channel3Pin); +channel_impl!(new_ch4, Ch4, Channel4Pin); + +/// Input capture driver. +pub struct InputCapture<'d, T: GeneralInstance4Channel> { + inner: Timer<'d, T>, +} + +impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { + /// Create a new input capture driver. + pub fn new( + tim: impl Peripheral<P = T> + 'd, + _ch1: Option<CapturePin<'d, T, Ch1>>, + _ch2: Option<CapturePin<'d, T, Ch2>>, + _ch3: Option<CapturePin<'d, T, Ch3>>, + _ch4: Option<CapturePin<'d, T, Ch4>>, + _irq: impl Binding<T::CaptureCompareInterrupt, CaptureCompareInterruptHandler<T>> + 'd, + freq: Hertz, + counting_mode: CountingMode, + ) -> Self { + Self::new_inner(tim, freq, counting_mode) + } + + fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, counting_mode: CountingMode) -> Self { + let mut this = Self { inner: Timer::new(tim) }; + + this.inner.set_counting_mode(counting_mode); + this.set_tick_freq(freq); + this.inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details + this.inner.start(); + + // enable NVIC interrupt + T::CaptureCompareInterrupt::unpend(); + unsafe { T::CaptureCompareInterrupt::enable() }; + + this + } + + /// Enable the given channel. + pub fn enable(&mut self, channel: Channel) { + self.inner.enable_channel(channel, true); + } + + /// Disable the given channel. + pub fn disable(&mut self, channel: Channel) { + self.inner.enable_channel(channel, false); + } + + /// Check whether given channel is enabled + pub fn is_enabled(&self, channel: Channel) -> bool { + self.inner.get_channel_enable_state(channel) + } + + /// Set tick frequency. + /// + /// Note: when you call this, the max period value changes + pub fn set_tick_freq(&mut self, freq: Hertz) { + let f = freq; + assert!(f.0 > 0); + let timer_f = self.inner.get_clock_frequency(); + + let pclk_ticks_per_timer_period = timer_f / f; + let psc: u16 = unwrap!((pclk_ticks_per_timer_period - 1).try_into()); + + let regs = self.inner.regs_core(); + regs.psc().write_value(psc); + + // Generate an Update Request + regs.egr().write(|r| r.set_ug(true)); + } + + /// Set the input capture mode for a given channel. + pub fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) { + self.inner.set_input_capture_mode(channel, mode); + } + + /// Set input TI selection. + pub fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) { + self.inner.set_input_ti_selection(channel, tisel) + } + + /// Get capture value for a channel. + pub fn get_capture_value(&self, channel: Channel) -> u32 { + self.inner.get_capture_value(channel) + } + + /// Get input interrupt. + pub fn get_input_interrupt(&self, channel: Channel) -> bool { + self.inner.get_input_interrupt(channel) + } + + fn new_future(&self, channel: Channel, mode: InputCaptureMode, tisel: InputTISelection) -> InputCaptureFuture<T> { + self.inner.enable_channel(channel, true); + self.inner.set_input_capture_mode(channel, mode); + self.inner.set_input_ti_selection(channel, tisel); + self.inner.clear_input_interrupt(channel); + self.inner.enable_input_interrupt(channel, true); + + InputCaptureFuture { + channel, + phantom: PhantomData, + } + } + + /// Asynchronously wait until the pin sees a rising edge. + pub async fn wait_for_rising_edge(&mut self, channel: Channel) -> u32 { + self.new_future(channel, InputCaptureMode::Rising, InputTISelection::Normal) + .await + } + + /// Asynchronously wait until the pin sees a falling edge. + pub async fn wait_for_falling_edge(&mut self, channel: Channel) -> u32 { + self.new_future(channel, InputCaptureMode::Falling, InputTISelection::Normal) + .await + } + + /// Asynchronously wait until the pin sees any edge. + pub async fn wait_for_any_edge(&mut self, channel: Channel) -> u32 { + self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Normal) + .await + } + + /// Asynchronously wait until the (alternate) pin sees a rising edge. + pub async fn wait_for_rising_edge_alternate(&mut self, channel: Channel) -> u32 { + self.new_future(channel, InputCaptureMode::Rising, InputTISelection::Alternate) + .await + } + + /// Asynchronously wait until the (alternate) pin sees a falling edge. + pub async fn wait_for_falling_edge_alternate(&mut self, channel: Channel) -> u32 { + self.new_future(channel, InputCaptureMode::Falling, InputTISelection::Alternate) + .await + } + + /// Asynchronously wait until the (alternate) pin sees any edge. + pub async fn wait_for_any_edge_alternate(&mut self, channel: Channel) -> u32 { + self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Alternate) + .await + } +} + +#[must_use = "futures do nothing unless you `.await` or poll them"] +struct InputCaptureFuture<T: GeneralInstance4Channel> { + channel: Channel, + phantom: PhantomData<T>, +} + +impl<T: GeneralInstance4Channel> Drop for InputCaptureFuture<T> { + fn drop(&mut self) { + critical_section::with(|_| { + let regs = unsafe { crate::pac::timer::TimGp16::from_ptr(T::regs()) }; + + // disable interrupt enable + regs.dier().modify(|w| w.set_ccie(self.channel.index(), false)); + }); + } +} + +impl<T: GeneralInstance4Channel> Future for InputCaptureFuture<T> { + type Output = u32; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { + T::state().cc_waker[self.channel.index()].register(cx.waker()); + + let regs = unsafe { crate::pac::timer::TimGp16::from_ptr(T::regs()) }; + + let dier = regs.dier().read(); + if !dier.ccie(self.channel.index()) { + let val = regs.ccr(self.channel.index()).read().0; + Poll::Ready(val) + } else { + Poll::Pending + } + } +} diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs index a5d942314..7f533b75c 100644 --- a/embassy-stm32/src/timer/low_level.rs +++ b/embassy-stm32/src/timer/low_level.rs @@ -257,7 +257,10 @@ impl<'d, T: CoreInstance> Timer<'d, T> { TimerBits::Bits32 => { let pclk_ticks_per_timer_period = (timer_f / f) as u64; let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << 32)).try_into()); - let arr: u32 = unwrap!((pclk_ticks_per_timer_period / (psc as u64 + 1)).try_into()); + let divide_by = pclk_ticks_per_timer_period / (u64::from(psc) + 1); + + // the timer counts `0..=arr`, we want it to count `0..divide_by` + let arr: u32 = unwrap!(u32::try_from(divide_by - 1)); let regs = self.regs_gp32_unchecked(); regs.psc().write_value(psc); @@ -318,6 +321,11 @@ impl<'d, T: CoreInstance> Timer<'d, T> { } } } + + /// Get the clock frequency of the timer (before prescaler is applied). + pub fn get_clock_frequency(&self) -> Hertz { + T::frequency() + } } impl<'d, T: BasicNoCr2Instance> Timer<'d, T> { @@ -440,6 +448,11 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { self.regs_gp16().sr().modify(|r| r.set_ccif(channel.index(), false)); } + /// Get input interrupt. + pub fn get_input_interrupt(&self, channel: Channel) -> bool { + self.regs_gp16().sr().read().ccif(channel.index()) + } + /// Enable input interrupt. pub fn enable_input_interrupt(&self, channel: Channel, enable: bool) { self.regs_gp16().dier().modify(|r| r.set_ccie(channel.index(), enable)); diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 346127005..314b6006b 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -1,7 +1,12 @@ //! Timers, PWM, quadrature decoder. +use core::marker::PhantomData; + +use embassy_sync::waitqueue::AtomicWaker; + #[cfg(not(stm32l0))] pub mod complementary_pwm; +pub mod input_capture; pub mod low_level; pub mod qei; pub mod simple_pwm; @@ -45,8 +50,29 @@ pub enum TimerBits { Bits32, } +struct State { + up_waker: AtomicWaker, + cc_waker: [AtomicWaker; 4], +} + +impl State { + const fn new() -> Self { + const NEW_AW: AtomicWaker = AtomicWaker::new(); + Self { + up_waker: NEW_AW, + cc_waker: [NEW_AW; 4], + } + } +} + +trait SealedInstance: RccPeripheral { + /// Async state for this timer + fn state() -> &'static State; +} + /// Core timer instance. -pub trait CoreInstance: RccPeripheral + 'static { +#[allow(private_bounds)] +pub trait CoreInstance: SealedInstance + 'static { /// Update Interrupt for this timer. type UpdateInterrupt: interrupt::typelevel::Interrupt; @@ -143,6 +169,13 @@ dma_trait!(Ch4Dma, GeneralInstance4Channel); #[allow(unused)] macro_rules! impl_core_timer { ($inst:ident, $bits:expr) => { + impl SealedInstance for crate::peripherals::$inst { + fn state() -> &'static State { + static STATE: State = State::new(); + &STATE + } + } + impl CoreInstance for crate::peripherals::$inst { type UpdateInterrupt = crate::_generated::peripheral_interrupts::$inst::UP; @@ -285,3 +318,63 @@ foreach_interrupt! { impl AdvancedInstance4Channel for crate::peripherals::$inst {} }; } + +/// Update interrupt handler. +pub struct UpdateInterruptHandler<T: CoreInstance> { + _phantom: PhantomData<T>, +} + +impl<T: CoreInstance> interrupt::typelevel::Handler<T::UpdateInterrupt> for UpdateInterruptHandler<T> { + unsafe fn on_interrupt() { + #[cfg(feature = "low-power")] + crate::low_power::on_wakeup_irq(); + + let regs = crate::pac::timer::TimCore::from_ptr(T::regs()); + + // Read TIM interrupt flags. + let sr = regs.sr().read(); + + // Mask relevant interrupts (UIE). + let bits = sr.0 & 0x00000001; + + // Mask all the channels that fired. + regs.dier().modify(|w| w.0 &= !bits); + + // Wake the tasks + if sr.uif() { + T::state().up_waker.wake(); + } + } +} + +/// Capture/Compare interrupt handler. +pub struct CaptureCompareInterruptHandler<T: GeneralInstance1Channel> { + _phantom: PhantomData<T>, +} + +impl<T: GeneralInstance1Channel> interrupt::typelevel::Handler<T::CaptureCompareInterrupt> + for CaptureCompareInterruptHandler<T> +{ + unsafe fn on_interrupt() { + #[cfg(feature = "low-power")] + crate::low_power::on_wakeup_irq(); + + let regs = crate::pac::timer::TimGp16::from_ptr(T::regs()); + + // Read TIM interrupt flags. + let sr = regs.sr().read(); + + // Mask relevant interrupts (CCIE). + let bits = sr.0 & 0x0000001E; + + // Mask all the channels that fired. + regs.dier().modify(|w| w.0 &= !bits); + + // Wake the tasks + for ch in 0..4 { + if sr.ccif(ch) { + T::state().cc_waker[ch].wake(); + } + } + } +} diff --git a/embassy-stm32/src/traits.rs b/embassy-stm32/src/traits.rs deleted file mode 100644 index 13f695821..000000000 --- a/embassy-stm32/src/traits.rs +++ /dev/null @@ -1,71 +0,0 @@ -#![macro_use] - -macro_rules! pin_trait { - ($signal:ident, $instance:path $(, $mode:path)?) => { - #[doc = concat!(stringify!($signal), " pin trait")] - pub trait $signal<T: $instance $(, M: $mode)?>: crate::gpio::Pin { - #[doc = concat!("Get the AF number needed to use this pin as ", stringify!($signal))] - fn af_num(&self) -> u8; - } - }; -} - -macro_rules! pin_trait_impl { - (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $pin:ident, $af:expr) => { - impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$pin { - fn af_num(&self) -> u8 { - $af - } - } - }; -} - -// ==================== - -macro_rules! dma_trait { - ($signal:ident, $instance:path$(, $mode:path)?) => { - #[doc = concat!(stringify!($signal), " DMA request trait")] - pub trait $signal<T: $instance $(, M: $mode)?>: crate::dma::Channel { - #[doc = concat!("Get the DMA request number needed to use this channel as", stringify!($signal))] - /// Note: in some chips, ST calls this the "channel", and calls channels "streams". - /// `embassy-stm32` always uses the "channel" and "request number" names. - fn request(&self) -> crate::dma::Request; - } - }; -} - -#[allow(unused)] -macro_rules! dma_trait_impl { - // DMAMUX - (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {dmamux: $dmamux:ident}, $request:expr) => { - impl<T> crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for T - where - T: crate::dma::Channel + crate::dma::MuxChannel<Mux = crate::dma::$dmamux>, - { - fn request(&self) -> crate::dma::Request { - $request - } - } - }; - - // DMAMUX - (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {dma: $dma:ident}, $request:expr) => { - impl<T> crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for T - where - T: crate::dma::Channel, - { - fn request(&self) -> crate::dma::Request { - $request - } - } - }; - - // DMA/GPDMA, without DMAMUX - (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {channel: $channel:ident}, $request:expr) => { - impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$channel { - fn request(&self) -> crate::dma::Request { - $request - } - } - }; -} diff --git a/embassy-stm32/src/tsc/enums.rs b/embassy-stm32/src/tsc/enums.rs new file mode 100644 index 000000000..0d34a43ec --- /dev/null +++ b/embassy-stm32/src/tsc/enums.rs @@ -0,0 +1,238 @@ +use core::ops::BitOr; + +/// Pin defines +#[allow(missing_docs)] +pub enum TscIOPin { + Group1Io1, + Group1Io2, + Group1Io3, + Group1Io4, + Group2Io1, + Group2Io2, + Group2Io3, + Group2Io4, + Group3Io1, + Group3Io2, + Group3Io3, + Group3Io4, + Group4Io1, + Group4Io2, + Group4Io3, + Group4Io4, + Group5Io1, + Group5Io2, + Group5Io3, + Group5Io4, + Group6Io1, + Group6Io2, + Group6Io3, + Group6Io4, + #[cfg(any(tsc_v2, tsc_v3))] + Group7Io1, + #[cfg(any(tsc_v2, tsc_v3))] + Group7Io2, + #[cfg(any(tsc_v2, tsc_v3))] + Group7Io3, + #[cfg(any(tsc_v2, tsc_v3))] + Group7Io4, + #[cfg(tsc_v3)] + Group8Io1, + #[cfg(tsc_v3)] + Group8Io2, + #[cfg(tsc_v3)] + Group8Io3, + #[cfg(tsc_v3)] + Group8Io4, +} + +impl BitOr<TscIOPin> for u32 { + type Output = u32; + fn bitor(self, rhs: TscIOPin) -> Self::Output { + let rhs: u32 = rhs.into(); + self | rhs + } +} + +impl BitOr<u32> for TscIOPin { + type Output = u32; + fn bitor(self, rhs: u32) -> Self::Output { + let val: u32 = self.into(); + val | rhs + } +} + +impl BitOr for TscIOPin { + type Output = u32; + fn bitor(self, rhs: Self) -> Self::Output { + let val: u32 = self.into(); + let rhs: u32 = rhs.into(); + val | rhs + } +} + +impl Into<u32> for TscIOPin { + fn into(self) -> u32 { + match self { + TscIOPin::Group1Io1 => 0x00000001, + TscIOPin::Group1Io2 => 0x00000002, + TscIOPin::Group1Io3 => 0x00000004, + TscIOPin::Group1Io4 => 0x00000008, + TscIOPin::Group2Io1 => 0x00000010, + TscIOPin::Group2Io2 => 0x00000020, + TscIOPin::Group2Io3 => 0x00000040, + TscIOPin::Group2Io4 => 0x00000080, + TscIOPin::Group3Io1 => 0x00000100, + TscIOPin::Group3Io2 => 0x00000200, + TscIOPin::Group3Io3 => 0x00000400, + TscIOPin::Group3Io4 => 0x00000800, + TscIOPin::Group4Io1 => 0x00001000, + TscIOPin::Group4Io2 => 0x00002000, + TscIOPin::Group4Io3 => 0x00004000, + TscIOPin::Group4Io4 => 0x00008000, + TscIOPin::Group5Io1 => 0x00010000, + TscIOPin::Group5Io2 => 0x00020000, + TscIOPin::Group5Io3 => 0x00040000, + TscIOPin::Group5Io4 => 0x00080000, + TscIOPin::Group6Io1 => 0x00100000, + TscIOPin::Group6Io2 => 0x00200000, + TscIOPin::Group6Io3 => 0x00400000, + TscIOPin::Group6Io4 => 0x00800000, + #[cfg(any(tsc_v2, tsc_v3))] + TscIOPin::Group7Io1 => 0x01000000, + #[cfg(any(tsc_v2, tsc_v3))] + TscIOPin::Group7Io2 => 0x02000000, + #[cfg(any(tsc_v2, tsc_v3))] + TscIOPin::Group7Io3 => 0x04000000, + #[cfg(any(tsc_v2, tsc_v3))] + TscIOPin::Group7Io4 => 0x08000000, + #[cfg(tsc_v3)] + TscIOPin::Group8Io1 => 0x10000000, + #[cfg(tsc_v3)] + TscIOPin::Group8Io2 => 0x20000000, + #[cfg(tsc_v3)] + TscIOPin::Group8Io3 => 0x40000000, + #[cfg(tsc_v3)] + TscIOPin::Group8Io4 => 0x80000000, + } + } +} + +/// Spread Spectrum Deviation +#[derive(Copy, Clone)] +pub struct SSDeviation(u8); +impl SSDeviation { + /// Create new deviation value, acceptable inputs are 1-128 + pub fn new(val: u8) -> Result<Self, ()> { + if val == 0 || val > 128 { + return Err(()); + } + Ok(Self(val - 1)) + } +} + +impl Into<u8> for SSDeviation { + fn into(self) -> u8 { + self.0 + } +} + +/// Charge transfer pulse cycles +#[allow(missing_docs)] +#[derive(Copy, Clone, PartialEq)] +pub enum ChargeTransferPulseCycle { + _1, + _2, + _3, + _4, + _5, + _6, + _7, + _8, + _9, + _10, + _11, + _12, + _13, + _14, + _15, + _16, +} + +impl Into<u8> for ChargeTransferPulseCycle { + fn into(self) -> u8 { + match self { + ChargeTransferPulseCycle::_1 => 0, + ChargeTransferPulseCycle::_2 => 1, + ChargeTransferPulseCycle::_3 => 2, + ChargeTransferPulseCycle::_4 => 3, + ChargeTransferPulseCycle::_5 => 4, + ChargeTransferPulseCycle::_6 => 5, + ChargeTransferPulseCycle::_7 => 6, + ChargeTransferPulseCycle::_8 => 7, + ChargeTransferPulseCycle::_9 => 8, + ChargeTransferPulseCycle::_10 => 9, + ChargeTransferPulseCycle::_11 => 10, + ChargeTransferPulseCycle::_12 => 11, + ChargeTransferPulseCycle::_13 => 12, + ChargeTransferPulseCycle::_14 => 13, + ChargeTransferPulseCycle::_15 => 14, + ChargeTransferPulseCycle::_16 => 15, + } + } +} + +/// Prescaler divider +#[allow(missing_docs)] +#[derive(Copy, Clone, PartialEq)] +pub enum PGPrescalerDivider { + _1, + _2, + _4, + _8, + _16, + _32, + _64, + _128, +} + +impl Into<u8> for PGPrescalerDivider { + fn into(self) -> u8 { + match self { + PGPrescalerDivider::_1 => 0, + PGPrescalerDivider::_2 => 1, + PGPrescalerDivider::_4 => 2, + PGPrescalerDivider::_8 => 3, + PGPrescalerDivider::_16 => 4, + PGPrescalerDivider::_32 => 5, + PGPrescalerDivider::_64 => 6, + PGPrescalerDivider::_128 => 7, + } + } +} + +/// Max count +#[allow(missing_docs)] +#[derive(Copy, Clone)] +pub enum MaxCount { + _255, + _511, + _1023, + _2047, + _4095, + _8191, + _16383, +} + +impl Into<u8> for MaxCount { + fn into(self) -> u8 { + match self { + MaxCount::_255 => 0, + MaxCount::_511 => 1, + MaxCount::_1023 => 2, + MaxCount::_2047 => 3, + MaxCount::_4095 => 4, + MaxCount::_8191 => 5, + MaxCount::_16383 => 6, + } + } +} diff --git a/embassy-stm32/src/tsc/mod.rs b/embassy-stm32/src/tsc/mod.rs new file mode 100644 index 000000000..bf583f04c --- /dev/null +++ b/embassy-stm32/src/tsc/mod.rs @@ -0,0 +1,936 @@ +//! TSC Peripheral Interface +//! +//! +//! # Example (stm32) +//! ``` rust, ignore +//! +//! let mut device_config = embassy_stm32::Config::default(); +//! { +//! device_config.rcc.mux = ClockSrc::MSI(Msirange::RANGE_4MHZ); +//! } +//! +//! let context = embassy_stm32::init(device_config); +//! +//! let config = tsc::Config { +//! ct_pulse_high_length: ChargeTransferPulseCycle::_2, +//! ct_pulse_low_length: ChargeTransferPulseCycle::_2, +//! spread_spectrum: false, +//! spread_spectrum_deviation: SSDeviation::new(2).unwrap(), +//! spread_spectrum_prescaler: false, +//! pulse_generator_prescaler: PGPrescalerDivider::_4, +//! max_count_value: MaxCount::_8191, +//! io_default_mode: false, +//! synchro_pin_polarity: false, +//! acquisition_mode: false, +//! max_count_interrupt: false, +//! channel_ios: TscIOPin::Group2Io2 | TscIOPin::Group7Io3, +//! shield_ios: TscIOPin::Group1Io3.into(), +//! sampling_ios: TscIOPin::Group1Io2 | TscIOPin::Group2Io1 | TscIOPin::Group7Io2, +//! }; +//! +//! let mut g1: PinGroup<embassy_stm32::peripherals::TSC, G1> = PinGroup::new(); +//! g1.set_io2(context.PB13, PinType::Sample); +//! g1.set_io3(context.PB14, PinType::Shield); +//! +//! let mut g2: PinGroup<embassy_stm32::peripherals::TSC, G2> = PinGroup::new(); +//! g2.set_io1(context.PB4, PinType::Sample); +//! g2.set_io2(context.PB5, PinType::Channel); +//! +//! let mut g7: PinGroup<embassy_stm32::peripherals::TSC, G7> = PinGroup::new(); +//! g7.set_io2(context.PE3, PinType::Sample); +//! g7.set_io3(context.PE4, PinType::Channel); +//! +//! let mut touch_controller = tsc::Tsc::new( +//! context.TSC, +//! Some(g1), +//! Some(g2), +//! None, +//! None, +//! None, +//! None, +//! Some(g7), +//! None, +//! config, +//! ); +//! +//! touch_controller.discharge_io(true); +//! Timer::after_millis(1).await; +//! +//! touch_controller.start(); +//! +//! ``` + +#![macro_use] + +/// Enums defined for peripheral parameters +pub mod enums; + +use core::marker::PhantomData; + +use embassy_hal_internal::{into_ref, PeripheralRef}; +pub use enums::*; + +use crate::gpio::{AFType, AnyPin}; +use crate::pac::tsc::Tsc as Regs; +use crate::rcc::RccPeripheral; +use crate::{peripherals, Peripheral}; + +#[cfg(tsc_v1)] +const TSC_NUM_GROUPS: u32 = 6; +#[cfg(tsc_v2)] +const TSC_NUM_GROUPS: u32 = 7; +#[cfg(tsc_v3)] +const TSC_NUM_GROUPS: u32 = 8; + +/// Error type defined for TSC +#[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum Error { + /// Test error for TSC + Test, +} + +/// Pin type definition to control IO parameters +pub enum PinType { + /// Sensing channel pin connected to an electrode + Channel, + /// Sampling capacitor pin, one required for every pin group + Sample, + /// Shield pin connected to capacitive sensing shield + Shield, +} + +/// Peripheral state +#[derive(PartialEq, Clone, Copy)] +pub enum State { + /// Peripheral is being setup or reconfigured + Reset, + /// Ready to start acquisition + Ready, + /// In process of sensor acquisition + Busy, + /// Error occured during acquisition + Error, +} + +/// Individual group status checked after acquisition reported as complete +/// For groups with multiple channel pins, may take longer because acquisitions +/// are done sequentially. Check this status before pulling count for each +/// sampled channel +#[derive(PartialEq)] +pub enum GroupStatus { + /// Acquisition for channel still in progress + Ongoing, + /// Acquisition either not started or complete + Complete, +} + +/// Group identifier used to interrogate status +#[allow(missing_docs)] +pub enum Group { + One, + Two, + Three, + Four, + Five, + Six, + #[cfg(any(tsc_v2, tsc_v3))] + Seven, + #[cfg(tsc_v3)] + Eight, +} + +impl Into<usize> for Group { + fn into(self) -> usize { + match self { + Group::One => 0, + Group::Two => 1, + Group::Three => 2, + Group::Four => 3, + Group::Five => 4, + Group::Six => 5, + #[cfg(any(tsc_v2, tsc_v3))] + Group::Seven => 6, + #[cfg(tsc_v3)] + Group::Eight => 7, + } + } +} + +/// Peripheral configuration +#[derive(Clone, Copy)] +pub struct Config { + /// Duration of high state of the charge transfer pulse + pub ct_pulse_high_length: ChargeTransferPulseCycle, + /// Duration of the low state of the charge transfer pulse + pub ct_pulse_low_length: ChargeTransferPulseCycle, + /// Enable/disable of spread spectrum feature + pub spread_spectrum: bool, + /// Adds variable number of periods of the SS clk to pulse high state + pub spread_spectrum_deviation: SSDeviation, + /// Selects AHB clock divider used to generate SS clk + pub spread_spectrum_prescaler: bool, + /// Selects AHB clock divider used to generate pulse generator clk + pub pulse_generator_prescaler: PGPrescalerDivider, + /// Maximum number of charge tranfer pulses that can be generated before error + pub max_count_value: MaxCount, + /// Defines config of all IOs when no ongoing acquisition + pub io_default_mode: bool, + /// Polarity of sync input pin + pub synchro_pin_polarity: bool, + /// Acquisition starts when start bit is set or with sync pin input + pub acquisition_mode: bool, + /// Enable max count interrupt + pub max_count_interrupt: bool, + /// Channel IO mask + pub channel_ios: u32, + /// Shield IO mask + pub shield_ios: u32, + /// Sampling IO mask + pub sampling_ios: u32, +} + +impl Default for Config { + fn default() -> Self { + Self { + ct_pulse_high_length: ChargeTransferPulseCycle::_1, + ct_pulse_low_length: ChargeTransferPulseCycle::_1, + spread_spectrum: false, + spread_spectrum_deviation: SSDeviation::new(1).unwrap(), + spread_spectrum_prescaler: false, + pulse_generator_prescaler: PGPrescalerDivider::_1, + max_count_value: MaxCount::_255, + io_default_mode: false, + synchro_pin_polarity: false, + acquisition_mode: false, + max_count_interrupt: false, + channel_ios: 0, + shield_ios: 0, + sampling_ios: 0, + } + } +} + +/// Pin struct that maintains usage +#[allow(missing_docs)] +pub struct TscPin<'d, T, C> { + _pin: PeripheralRef<'d, AnyPin>, + role: PinType, + phantom: PhantomData<(T, C)>, +} + +enum GroupError { + NoSample, + ChannelShield, +} + +/// Pin group definition +/// Pins are organized into groups of four IOs, all groups with a +/// sampling channel must also have a sampling capacitor channel. +#[allow(missing_docs)] +#[derive(Default)] +pub struct PinGroup<'d, T, C> { + d1: Option<TscPin<'d, T, C>>, + d2: Option<TscPin<'d, T, C>>, + d3: Option<TscPin<'d, T, C>>, + d4: Option<TscPin<'d, T, C>>, +} + +impl<'d, T: Instance, C> PinGroup<'d, T, C> { + /// Create new sensing group + pub fn new() -> Self { + Self { + d1: None, + d2: None, + d3: None, + d4: None, + } + } + + fn contains_shield(&self) -> bool { + let mut shield_count = 0; + + if let Some(pin) = &self.d1 { + if let PinType::Shield = pin.role { + shield_count += 1; + } + } + + if let Some(pin) = &self.d2 { + if let PinType::Shield = pin.role { + shield_count += 1; + } + } + + if let Some(pin) = &self.d3 { + if let PinType::Shield = pin.role { + shield_count += 1; + } + } + + if let Some(pin) = &self.d4 { + if let PinType::Shield = pin.role { + shield_count += 1; + } + } + + shield_count == 1 + } + + fn check_group(&self) -> Result<(), GroupError> { + let mut channel_count = 0; + let mut shield_count = 0; + let mut sample_count = 0; + if let Some(pin) = &self.d1 { + match pin.role { + PinType::Channel => { + channel_count += 1; + } + PinType::Shield => { + shield_count += 1; + } + PinType::Sample => { + sample_count += 1; + } + } + } + + if let Some(pin) = &self.d2 { + match pin.role { + PinType::Channel => { + channel_count += 1; + } + PinType::Shield => { + shield_count += 1; + } + PinType::Sample => { + sample_count += 1; + } + } + } + + if let Some(pin) = &self.d3 { + match pin.role { + PinType::Channel => { + channel_count += 1; + } + PinType::Shield => { + shield_count += 1; + } + PinType::Sample => { + sample_count += 1; + } + } + } + + if let Some(pin) = &self.d4 { + match pin.role { + PinType::Channel => { + channel_count += 1; + } + PinType::Shield => { + shield_count += 1; + } + PinType::Sample => { + sample_count += 1; + } + } + } + + // Every group requires one sampling capacitor + if sample_count != 1 { + return Err(GroupError::NoSample); + } + + // Each group must have at least one shield or channel IO + if shield_count == 0 && channel_count == 0 { + return Err(GroupError::ChannelShield); + } + + // Any group can either contain channel ios or a shield IO + if shield_count != 0 && channel_count != 0 { + return Err(GroupError::ChannelShield); + } + + // No more than one shield IO is allow per group and amongst all groups + if shield_count > 1 { + return Err(GroupError::ChannelShield); + } + + Ok(()) + } +} + +macro_rules! group_impl { + ($group:ident, $trait1:ident, $trait2:ident, $trait3:ident, $trait4:ident) => { + impl<'d, T: Instance> PinGroup<'d, T, $group> { + #[doc = concat!("Create a new pin1 for ", stringify!($group), " TSC group instance.")] + pub fn set_io1(&mut self, pin: impl Peripheral<P = impl $trait1<T>> + 'd, role: PinType) { + into_ref!(pin); + critical_section::with(|_| { + pin.set_low(); + pin.set_as_af( + pin.af_num(), + match role { + PinType::Channel => AFType::OutputPushPull, + PinType::Sample => AFType::OutputOpenDrain, + PinType::Shield => AFType::OutputPushPull, + }, + ); + self.d1 = Some(TscPin { + _pin: pin.map_into(), + role: role, + phantom: PhantomData, + }) + }) + } + + #[doc = concat!("Create a new pin2 for ", stringify!($group), " TSC group instance.")] + pub fn set_io2(&mut self, pin: impl Peripheral<P = impl $trait2<T>> + 'd, role: PinType) { + into_ref!(pin); + critical_section::with(|_| { + pin.set_low(); + pin.set_as_af( + pin.af_num(), + match role { + PinType::Channel => AFType::OutputPushPull, + PinType::Sample => AFType::OutputOpenDrain, + PinType::Shield => AFType::OutputPushPull, + }, + ); + self.d2 = Some(TscPin { + _pin: pin.map_into(), + role: role, + phantom: PhantomData, + }) + }) + } + + #[doc = concat!("Create a new pin3 for ", stringify!($group), " TSC group instance.")] + pub fn set_io3(&mut self, pin: impl Peripheral<P = impl $trait3<T>> + 'd, role: PinType) { + into_ref!(pin); + critical_section::with(|_| { + pin.set_low(); + pin.set_as_af( + pin.af_num(), + match role { + PinType::Channel => AFType::OutputPushPull, + PinType::Sample => AFType::OutputOpenDrain, + PinType::Shield => AFType::OutputPushPull, + }, + ); + self.d3 = Some(TscPin { + _pin: pin.map_into(), + role: role, + phantom: PhantomData, + }) + }) + } + + #[doc = concat!("Create a new pin4 for ", stringify!($group), " TSC group instance.")] + pub fn set_io4(&mut self, pin: impl Peripheral<P = impl $trait4<T>> + 'd, role: PinType) { + into_ref!(pin); + critical_section::with(|_| { + pin.set_low(); + pin.set_as_af( + pin.af_num(), + match role { + PinType::Channel => AFType::OutputPushPull, + PinType::Sample => AFType::OutputOpenDrain, + PinType::Shield => AFType::OutputPushPull, + }, + ); + self.d4 = Some(TscPin { + _pin: pin.map_into(), + role: role, + phantom: PhantomData, + }) + }) + } + } + }; +} + +group_impl!(G1, G1IO1Pin, G1IO2Pin, G1IO3Pin, G1IO4Pin); +group_impl!(G2, G2IO1Pin, G2IO2Pin, G2IO3Pin, G2IO4Pin); +group_impl!(G3, G3IO1Pin, G3IO2Pin, G3IO3Pin, G3IO4Pin); +group_impl!(G4, G4IO1Pin, G4IO2Pin, G4IO3Pin, G4IO4Pin); +group_impl!(G5, G5IO1Pin, G5IO2Pin, G5IO3Pin, G5IO4Pin); +group_impl!(G6, G6IO1Pin, G6IO2Pin, G6IO3Pin, G6IO4Pin); +group_impl!(G7, G7IO1Pin, G7IO2Pin, G7IO3Pin, G7IO4Pin); +group_impl!(G8, G8IO1Pin, G8IO2Pin, G8IO3Pin, G8IO4Pin); + +/// Group 1 marker type. +pub enum G1 {} +/// Group 2 marker type. +pub enum G2 {} +/// Group 3 marker type. +pub enum G3 {} +/// Group 4 marker type. +pub enum G4 {} +/// Group 5 marker type. +pub enum G5 {} +/// Group 6 marker type. +pub enum G6 {} +/// Group 7 marker type. +pub enum G7 {} +/// Group 8 marker type. +pub enum G8 {} + +/// TSC driver +pub struct Tsc<'d, T: Instance> { + _peri: PeripheralRef<'d, T>, + _g1: Option<PinGroup<'d, T, G1>>, + _g2: Option<PinGroup<'d, T, G2>>, + _g3: Option<PinGroup<'d, T, G3>>, + _g4: Option<PinGroup<'d, T, G4>>, + _g5: Option<PinGroup<'d, T, G5>>, + _g6: Option<PinGroup<'d, T, G6>>, + #[cfg(any(tsc_v2, tsc_v3))] + _g7: Option<PinGroup<'d, T, G7>>, + #[cfg(tsc_v3)] + _g8: Option<PinGroup<'d, T, G8>>, + state: State, + config: Config, +} + +impl<'d, T: Instance> Tsc<'d, T> { + /// Create new TSC driver + pub fn new( + peri: impl Peripheral<P = T> + 'd, + g1: Option<PinGroup<'d, T, G1>>, + g2: Option<PinGroup<'d, T, G2>>, + g3: Option<PinGroup<'d, T, G3>>, + g4: Option<PinGroup<'d, T, G4>>, + g5: Option<PinGroup<'d, T, G5>>, + g6: Option<PinGroup<'d, T, G6>>, + #[cfg(any(tsc_v2, tsc_v3))] g7: Option<PinGroup<'d, T, G7>>, + #[cfg(tsc_v3)] g8: Option<PinGroup<'d, T, G8>>, + config: Config, + ) -> Self { + // Need to check valid pin configuration input + let g1 = g1.filter(|b| b.check_group().is_ok()); + let g2 = g2.filter(|b| b.check_group().is_ok()); + let g3 = g3.filter(|b| b.check_group().is_ok()); + let g4 = g4.filter(|b| b.check_group().is_ok()); + let g5 = g5.filter(|b| b.check_group().is_ok()); + let g6 = g6.filter(|b| b.check_group().is_ok()); + #[cfg(any(tsc_v2, tsc_v3))] + let g7 = g7.filter(|b| b.check_group().is_ok()); + #[cfg(tsc_v3)] + let g8 = g8.filter(|b| b.check_group().is_ok()); + + match Self::check_shields( + &g1, + &g2, + &g3, + &g4, + &g5, + &g6, + #[cfg(any(tsc_v2, tsc_v3))] + &g7, + #[cfg(tsc_v3)] + &g8, + ) { + Ok(()) => Self::new_inner( + peri, + g1, + g2, + g3, + g4, + g5, + g6, + #[cfg(any(tsc_v2, tsc_v3))] + g7, + #[cfg(tsc_v3)] + g8, + config, + ), + Err(_) => Self::new_inner( + peri, + None, + None, + None, + None, + None, + None, + #[cfg(any(tsc_v2, tsc_v3))] + None, + #[cfg(tsc_v3)] + None, + config, + ), + } + } + + fn check_shields( + g1: &Option<PinGroup<'d, T, G1>>, + g2: &Option<PinGroup<'d, T, G2>>, + g3: &Option<PinGroup<'d, T, G3>>, + g4: &Option<PinGroup<'d, T, G4>>, + g5: &Option<PinGroup<'d, T, G5>>, + g6: &Option<PinGroup<'d, T, G6>>, + #[cfg(any(tsc_v2, tsc_v3))] g7: &Option<PinGroup<'d, T, G7>>, + #[cfg(tsc_v3)] g8: &Option<PinGroup<'d, T, G8>>, + ) -> Result<(), GroupError> { + let mut shield_count = 0; + + if let Some(pin_group) = g1 { + if pin_group.contains_shield() { + shield_count += 1; + } + }; + if let Some(pin_group) = g2 { + if pin_group.contains_shield() { + shield_count += 1; + } + }; + if let Some(pin_group) = g3 { + if pin_group.contains_shield() { + shield_count += 1; + } + }; + if let Some(pin_group) = g4 { + if pin_group.contains_shield() { + shield_count += 1; + } + }; + if let Some(pin_group) = g5 { + if pin_group.contains_shield() { + shield_count += 1; + } + }; + if let Some(pin_group) = g6 { + if pin_group.contains_shield() { + shield_count += 1; + } + }; + #[cfg(any(tsc_v2, tsc_v3))] + if let Some(pin_group) = g7 { + if pin_group.contains_shield() { + shield_count += 1; + } + }; + #[cfg(tsc_v3)] + if let Some(pin_group) = g8 { + if pin_group.contains_shield() { + shield_count += 1; + } + }; + + if shield_count > 1 { + return Err(GroupError::ChannelShield); + } + + Ok(()) + } + + fn extract_groups(io_mask: u32) -> u32 { + let mut groups: u32 = 0; + for idx in 0..TSC_NUM_GROUPS { + if io_mask & (0x0F << idx * 4) != 0 { + groups |= 1 << idx + } + } + groups + } + + fn new_inner( + peri: impl Peripheral<P = T> + 'd, + g1: Option<PinGroup<'d, T, G1>>, + g2: Option<PinGroup<'d, T, G2>>, + g3: Option<PinGroup<'d, T, G3>>, + g4: Option<PinGroup<'d, T, G4>>, + g5: Option<PinGroup<'d, T, G5>>, + g6: Option<PinGroup<'d, T, G6>>, + #[cfg(any(tsc_v2, tsc_v3))] g7: Option<PinGroup<'d, T, G7>>, + #[cfg(tsc_v3)] g8: Option<PinGroup<'d, T, G8>>, + config: Config, + ) -> Self { + into_ref!(peri); + + T::enable_and_reset(); + + T::REGS.cr().modify(|w| { + w.set_tsce(true); + w.set_ctph(config.ct_pulse_high_length.into()); + w.set_ctpl(config.ct_pulse_low_length.into()); + w.set_sse(config.spread_spectrum); + // Prevent invalid configuration for pulse generator prescaler + if config.ct_pulse_low_length == ChargeTransferPulseCycle::_1 + && (config.pulse_generator_prescaler == PGPrescalerDivider::_1 + || config.pulse_generator_prescaler == PGPrescalerDivider::_2) + { + w.set_pgpsc(PGPrescalerDivider::_4.into()); + } else if config.ct_pulse_low_length == ChargeTransferPulseCycle::_2 + && config.pulse_generator_prescaler == PGPrescalerDivider::_1 + { + w.set_pgpsc(PGPrescalerDivider::_2.into()); + } else { + w.set_pgpsc(config.pulse_generator_prescaler.into()); + } + w.set_ssd(config.spread_spectrum_deviation.into()); + w.set_sspsc(config.spread_spectrum_prescaler); + + w.set_mcv(config.max_count_value.into()); + w.set_syncpol(config.synchro_pin_polarity); + w.set_am(config.acquisition_mode); + }); + + // Set IO configuration + // Disable Schmitt trigger hysteresis on all used TSC IOs + T::REGS + .iohcr() + .write(|w| w.0 = !(config.channel_ios | config.shield_ios | config.sampling_ios)); + + // Set channel and shield IOs + T::REGS.ioccr().write(|w| w.0 = config.channel_ios | config.shield_ios); + + // Set sampling IOs + T::REGS.ioscr().write(|w| w.0 = config.sampling_ios); + + // Set the groups to be acquired + T::REGS + .iogcsr() + .write(|w| w.0 = Self::extract_groups(config.channel_ios)); + + // Disable interrupts + T::REGS.ier().modify(|w| { + w.set_eoaie(false); + w.set_mceie(false); + }); + + // Clear flags + T::REGS.icr().modify(|w| { + w.set_eoaic(true); + w.set_mceic(true); + }); + + Self { + _peri: peri, + _g1: g1, + _g2: g2, + _g3: g3, + _g4: g4, + _g5: g5, + _g6: g6, + #[cfg(any(tsc_v2, tsc_v3))] + _g7: g7, + #[cfg(tsc_v3)] + _g8: g8, + state: State::Ready, + config, + } + } + + /// Start charge transfer acquisition + pub fn start(&mut self) { + self.state = State::Busy; + + // Disable interrupts + T::REGS.ier().modify(|w| { + w.set_eoaie(false); + w.set_mceie(false); + }); + + // Clear flags + T::REGS.icr().modify(|w| { + w.set_eoaic(true); + w.set_mceic(true); + }); + + // Set the touch sensing IOs not acquired to the default mode + T::REGS.cr().modify(|w| { + w.set_iodef(self.config.io_default_mode); + }); + + // Start the acquisition + T::REGS.cr().modify(|w| { + w.set_start(true); + }); + } + + /// Start charge transfer acquisition with interrupts enabled + pub fn start_it(&mut self) { + self.state = State::Busy; + + // Enable interrupts + T::REGS.ier().modify(|w| { + w.set_eoaie(true); + w.set_mceie(self.config.max_count_interrupt); + }); + + // Clear flags + T::REGS.icr().modify(|w| { + w.set_eoaic(true); + w.set_mceic(true); + }); + + // Set the touch sensing IOs not acquired to the default mode + T::REGS.cr().modify(|w| { + w.set_iodef(self.config.io_default_mode); + }); + + // Start the acquisition + T::REGS.cr().modify(|w| { + w.set_start(true); + }); + } + + /// Stop charge transfer acquisition + pub fn stop(&mut self) { + T::REGS.cr().modify(|w| { + w.set_start(false); + }); + + // Set the touch sensing IOs in low power mode + T::REGS.cr().modify(|w| { + w.set_iodef(false); + }); + + // Clear flags + T::REGS.icr().modify(|w| { + w.set_eoaic(true); + w.set_mceic(true); + }); + + self.state = State::Ready; + } + + /// Stop charge transfer acquisition and clear interrupts + pub fn stop_it(&mut self) { + T::REGS.cr().modify(|w| { + w.set_start(false); + }); + + // Set the touch sensing IOs in low power mode + T::REGS.cr().modify(|w| { + w.set_iodef(false); + }); + + // Disable interrupts + T::REGS.ier().modify(|w| { + w.set_eoaie(false); + w.set_mceie(false); + }); + + // Clear flags + T::REGS.icr().modify(|w| { + w.set_eoaic(true); + w.set_mceic(true); + }); + + self.state = State::Ready; + } + + /// Wait for end of acquisition + pub fn poll_for_acquisition(&mut self) { + while self.get_state() == State::Busy {} + } + + /// Get current state of acquisition + pub fn get_state(&mut self) -> State { + if self.state == State::Busy { + if T::REGS.isr().read().eoaf() { + if T::REGS.isr().read().mcef() { + self.state = State::Error + } else { + self.state = State::Ready + } + } + } + self.state + } + + /// Get the individual group status to check acquisition complete + pub fn group_get_status(&mut self, index: Group) -> GroupStatus { + // Status bits are set by hardware when the acquisition on the corresponding + // enabled analog IO group is complete, cleared when new acquisition is started + let status = match index { + Group::One => T::REGS.iogcsr().read().g1s(), + Group::Two => T::REGS.iogcsr().read().g2s(), + Group::Three => T::REGS.iogcsr().read().g3s(), + Group::Four => T::REGS.iogcsr().read().g4s(), + Group::Five => T::REGS.iogcsr().read().g5s(), + Group::Six => T::REGS.iogcsr().read().g6s(), + #[cfg(any(tsc_v2, tsc_v3))] + Group::Seven => T::REGS.iogcsr().read().g7s(), + #[cfg(tsc_v3)] + Group::Eight => T::REGS.iogcsr().read().g8s(), + }; + match status { + true => GroupStatus::Complete, + false => GroupStatus::Ongoing, + } + } + + /// Get the count for the acquisiton, valid once group status is set + pub fn group_get_value(&mut self, index: Group) -> u16 { + T::REGS.iogcr(index.into()).read().cnt() + } + + /// Discharge the IOs for subsequent acquisition + pub fn discharge_io(&mut self, status: bool) { + // Set the touch sensing IOs in low power mode + T::REGS.cr().modify(|w| { + w.set_iodef(!status); + }); + } +} + +impl<'d, T: Instance> Drop for Tsc<'d, T> { + fn drop(&mut self) { + T::disable(); + } +} + +pub(crate) trait SealedInstance { + const REGS: Regs; +} + +/// TSC instance trait +#[allow(private_bounds)] +pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} + +foreach_peripheral!( + (tsc, $inst:ident) => { + impl SealedInstance for peripherals::$inst { + const REGS: Regs = crate::pac::$inst; + } + + impl Instance for peripherals::$inst {} + }; +); + +pin_trait!(G1IO1Pin, Instance); +pin_trait!(G1IO2Pin, Instance); +pin_trait!(G1IO3Pin, Instance); +pin_trait!(G1IO4Pin, Instance); +pin_trait!(G2IO1Pin, Instance); +pin_trait!(G2IO2Pin, Instance); +pin_trait!(G2IO3Pin, Instance); +pin_trait!(G2IO4Pin, Instance); +pin_trait!(G3IO1Pin, Instance); +pin_trait!(G3IO2Pin, Instance); +pin_trait!(G3IO3Pin, Instance); +pin_trait!(G3IO4Pin, Instance); +pin_trait!(G4IO1Pin, Instance); +pin_trait!(G4IO2Pin, Instance); +pin_trait!(G4IO3Pin, Instance); +pin_trait!(G4IO4Pin, Instance); +pin_trait!(G5IO1Pin, Instance); +pin_trait!(G5IO2Pin, Instance); +pin_trait!(G5IO3Pin, Instance); +pin_trait!(G5IO4Pin, Instance); +pin_trait!(G6IO1Pin, Instance); +pin_trait!(G6IO2Pin, Instance); +pin_trait!(G6IO3Pin, Instance); +pin_trait!(G6IO4Pin, Instance); +pin_trait!(G7IO1Pin, Instance); +pin_trait!(G7IO2Pin, Instance); +pin_trait!(G7IO3Pin, Instance); +pin_trait!(G7IO4Pin, Instance); +pin_trait!(G8IO1Pin, Instance); +pin_trait!(G8IO2Pin, Instance); +pin_trait!(G8IO3Pin, Instance); +pin_trait!(G8IO4Pin, Instance); diff --git a/embassy-stm32/src/ucpd.rs b/embassy-stm32/src/ucpd.rs index fe614b811..d6d0682b9 100644 --- a/embassy-stm32/src/ucpd.rs +++ b/embassy-stm32/src/ucpd.rs @@ -20,10 +20,10 @@ use core::sync::atomic::{AtomicBool, Ordering}; use core::task::Poll; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::{into_ref, Peripheral}; use embassy_sync::waitqueue::AtomicWaker; -use crate::dma::{AnyChannel, Request, Transfer, TransferOptions}; +use crate::dma::{ChannelAndRequest, TransferOptions}; use crate::interrupt; use crate::interrupt::typelevel::Interrupt; use crate::pac::ucpd::vals::{Anamode, Ccenable, PscUsbpdclk, Txmode}; @@ -58,7 +58,7 @@ pub(crate) fn init( }) } - #[cfg(any(stm32h5, stm32u5))] + #[cfg(any(stm32h5, stm32u5, stm32h7rs))] { crate::pac::PWR.ucpdr().modify(|w| { w.set_ucpd_dbdis(!ucpd1_db_enable); @@ -179,10 +179,14 @@ impl<'d, T: Instance> Ucpd<'d, T> { self.cc_phy, PdPhy { _lifetime: PhantomData, - rx_dma_ch: rx_dma.map_into(), - rx_dma_req, - tx_dma_ch: tx_dma.map_into(), - tx_dma_req, + rx_dma: ChannelAndRequest { + channel: rx_dma.map_into(), + request: rx_dma_req, + }, + tx_dma: ChannelAndRequest { + channel: tx_dma.map_into(), + request: tx_dma_req, + }, }, ) } @@ -309,10 +313,8 @@ pub enum TxError { /// Power Delivery (PD) PHY. pub struct PdPhy<'d, T: Instance> { _lifetime: PhantomData<&'d mut T>, - rx_dma_ch: PeripheralRef<'d, AnyChannel>, - rx_dma_req: Request, - tx_dma_ch: PeripheralRef<'d, AnyChannel>, - tx_dma_req: Request, + rx_dma: ChannelAndRequest<'d>, + tx_dma: ChannelAndRequest<'d>, } impl<'d, T: Instance> Drop for PdPhy<'d, T> { @@ -337,13 +339,8 @@ impl<'d, T: Instance> PdPhy<'d, T> { let r = T::REGS; let dma = unsafe { - Transfer::new_read( - &self.rx_dma_ch, - self.rx_dma_req, - r.rxdr().as_ptr() as *mut u8, - buf, - TransferOptions::default(), - ) + self.rx_dma + .read(r.rxdr().as_ptr() as *mut u8, buf, TransferOptions::default()) }; // Clear interrupt flags (possibly set from last receive). @@ -356,7 +353,7 @@ impl<'d, T: Instance> PdPhy<'d, T> { r.cr().modify(|w| w.set_phyrxen(true)); let _on_drop = OnDrop::new(|| { r.cr().modify(|w| w.set_phyrxen(false)); - self.enable_rx_interrupt(false); + Self::enable_rx_interrupt(false); }); poll_fn(|cx| { @@ -377,7 +374,7 @@ impl<'d, T: Instance> PdPhy<'d, T> { Poll::Ready(ret) } else { T::state().waker.register(cx.waker()); - self.enable_rx_interrupt(true); + Self::enable_rx_interrupt(true); Poll::Pending } }) @@ -393,7 +390,7 @@ impl<'d, T: Instance> PdPhy<'d, T> { Ok(r.rx_payszr().read().rxpaysz().into()) } - fn enable_rx_interrupt(&self, enable: bool) { + fn enable_rx_interrupt(enable: bool) { T::REGS.imr().modify(|w| w.set_rxmsgendie(enable)); } @@ -405,7 +402,7 @@ impl<'d, T: Instance> PdPhy<'d, T> { // might still be running because there is no way to abort an ongoing // message transmission. Wait for it to finish but ignore errors. if r.cr().read().txsend() { - if let Err(TxError::HardReset) = self.wait_tx_done().await { + if let Err(TxError::HardReset) = Self::wait_tx_done().await { return Err(TxError::HardReset); } } @@ -418,13 +415,8 @@ impl<'d, T: Instance> PdPhy<'d, T> { // Start the DMA and let it do its thing in the background. let _dma = unsafe { - Transfer::new_write( - &self.tx_dma_ch, - self.tx_dma_req, - buf, - r.txdr().as_ptr() as *mut u8, - TransferOptions::default(), - ) + self.tx_dma + .write(buf, r.txdr().as_ptr() as *mut u8, TransferOptions::default()) }; // Configure and start the transmission. @@ -434,11 +426,11 @@ impl<'d, T: Instance> PdPhy<'d, T> { w.set_txsend(true); }); - self.wait_tx_done().await + Self::wait_tx_done().await } - async fn wait_tx_done(&self) -> Result<(), TxError> { - let _on_drop = OnDrop::new(|| self.enable_tx_interrupts(false)); + async fn wait_tx_done() -> Result<(), TxError> { + let _on_drop = OnDrop::new(|| Self::enable_tx_interrupts(false)); poll_fn(|cx| { let r = T::REGS; let sr = r.sr().read(); @@ -453,14 +445,14 @@ impl<'d, T: Instance> PdPhy<'d, T> { Poll::Ready(Ok(())) } else { T::state().waker.register(cx.waker()); - self.enable_tx_interrupts(true); + Self::enable_tx_interrupts(true); Poll::Pending } }) .await } - fn enable_tx_interrupts(&self, enable: bool) { + fn enable_tx_interrupts(enable: bool) { T::REGS.imr().modify(|w| { w.set_txmsgdiscie(enable); w.set_txmsgsentie(enable); diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 949ac1b13..492ad334b 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -1,152 +1,174 @@ +use core::future::poll_fn; +use core::marker::PhantomData; use core::slice; -use core::sync::atomic::AtomicBool; +use core::sync::atomic::{AtomicBool, AtomicU8, Ordering}; +use core::task::Poll; +use embassy_embedded_hal::SetConfig; use embassy_hal_internal::atomic_ring_buffer::RingBuffer; +use embassy_hal_internal::{into_ref, Peripheral}; use embassy_sync::waitqueue::AtomicWaker; -use super::*; +#[cfg(not(any(usart_v1, usart_v2)))] +use super::DePin; +use super::{ + clear_interrupt_flags, configure, rdr, reconfigure, sr, tdr, Config, ConfigError, CtsPin, Error, Info, Instance, + Regs, RtsPin, RxPin, TxPin, +}; +use crate::gpio::AFType; +use crate::interrupt::typelevel::Interrupt as _; +use crate::interrupt::{self, InterruptExt}; +use crate::time::Hertz; /// Interrupt handler. -pub struct InterruptHandler<T: BasicInstance> { +pub struct InterruptHandler<T: Instance> { _phantom: PhantomData<T>, } -impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { +impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { unsafe fn on_interrupt() { - let r = T::regs(); - let state = T::buffered_state(); + on_interrupt(T::info().regs, T::buffered_state()) + } +} - // RX - let sr_val = sr(r).read(); - // On v1 & v2, reading DR clears the rxne, error and idle interrupt - // flags. Keep this close to the SR read to reduce the chance of a - // flag being set in-between. - let dr = if sr_val.rxne() || cfg!(any(usart_v1, usart_v2)) && (sr_val.ore() || sr_val.idle()) { - Some(rdr(r).read_volatile()) +unsafe fn on_interrupt(r: Regs, state: &'static State) { + // RX + let sr_val = sr(r).read(); + // On v1 & v2, reading DR clears the rxne, error and idle interrupt + // flags. Keep this close to the SR read to reduce the chance of a + // flag being set in-between. + let dr = if sr_val.rxne() || cfg!(any(usart_v1, usart_v2)) && (sr_val.ore() || sr_val.idle()) { + Some(rdr(r).read_volatile()) + } else { + None + }; + clear_interrupt_flags(r, sr_val); + + if sr_val.pe() { + warn!("Parity error"); + } + if sr_val.fe() { + warn!("Framing error"); + } + if sr_val.ne() { + warn!("Noise error"); + } + if sr_val.ore() { + warn!("Overrun error"); + } + if sr_val.rxne() { + let mut rx_writer = state.rx_buf.writer(); + let buf = rx_writer.push_slice(); + if !buf.is_empty() { + if let Some(byte) = dr { + buf[0] = byte; + rx_writer.push_done(1); + } } else { - None - }; - clear_interrupt_flags(r, sr_val); - - if sr_val.pe() { - warn!("Parity error"); - } - if sr_val.fe() { - warn!("Framing error"); - } - if sr_val.ne() { - warn!("Noise error"); - } - if sr_val.ore() { - warn!("Overrun error"); - } - if sr_val.rxne() { - let mut rx_writer = state.rx_buf.writer(); - let buf = rx_writer.push_slice(); - if !buf.is_empty() { - if let Some(byte) = dr { - buf[0] = byte; - rx_writer.push_done(1); - } - } else { - // FIXME: Should we disable any further RX interrupts when the buffer becomes full. - } - - if !state.rx_buf.is_empty() { - state.rx_waker.wake(); - } + // FIXME: Should we disable any further RX interrupts when the buffer becomes full. } - if sr_val.idle() { + if !state.rx_buf.is_empty() { state.rx_waker.wake(); } + } - // With `usart_v4` hardware FIFO is enabled and Transmission complete (TC) - // indicates that all bytes are pushed out from the FIFO. - // For other usart variants it shows that last byte from the buffer was just sent. - if sr_val.tc() { - // For others it is cleared above with `clear_interrupt_flags`. - #[cfg(any(usart_v1, usart_v2))] - sr(r).modify(|w| w.set_tc(false)); + if sr_val.idle() { + state.rx_waker.wake(); + } + // With `usart_v4` hardware FIFO is enabled and Transmission complete (TC) + // indicates that all bytes are pushed out from the FIFO. + // For other usart variants it shows that last byte from the buffer was just sent. + if sr_val.tc() { + // For others it is cleared above with `clear_interrupt_flags`. + #[cfg(any(usart_v1, usart_v2))] + sr(r).modify(|w| w.set_tc(false)); + + r.cr1().modify(|w| { + w.set_tcie(false); + }); + + state.tx_done.store(true, Ordering::Release); + state.tx_waker.wake(); + } + + // TX + if sr(r).read().txe() { + let mut tx_reader = state.tx_buf.reader(); + let buf = tx_reader.pop_slice(); + if !buf.is_empty() { r.cr1().modify(|w| { - w.set_tcie(false); + w.set_txeie(true); }); - state.tx_done.store(true, Ordering::Release); - state.tx_waker.wake(); - } - - // TX - if sr(r).read().txe() { - let mut tx_reader = state.tx_buf.reader(); - let buf = tx_reader.pop_slice(); - if !buf.is_empty() { + // Enable transmission complete interrupt when last byte is going to be sent out. + if buf.len() == 1 { r.cr1().modify(|w| { - w.set_txeie(true); - }); - - // Enable transmission complete interrupt when last byte is going to be sent out. - if buf.len() == 1 { - r.cr1().modify(|w| { - w.set_tcie(true); - }); - } - - tdr(r).write_volatile(buf[0].into()); - tx_reader.pop_done(1); - } else { - // Disable interrupt until we have something to transmit again. - r.cr1().modify(|w| { - w.set_txeie(false); + w.set_tcie(true); }); } + + tdr(r).write_volatile(buf[0].into()); + tx_reader.pop_done(1); + } else { + // Disable interrupt until we have something to transmit again. + r.cr1().modify(|w| { + w.set_txeie(false); + }); } } } -pub(crate) struct State { - pub(crate) rx_waker: AtomicWaker, - pub(crate) rx_buf: RingBuffer, - pub(crate) tx_waker: AtomicWaker, - pub(crate) tx_buf: RingBuffer, - pub(crate) tx_done: AtomicBool, +pub(super) struct State { + rx_waker: AtomicWaker, + rx_buf: RingBuffer, + tx_waker: AtomicWaker, + tx_buf: RingBuffer, + tx_done: AtomicBool, + tx_rx_refcount: AtomicU8, } impl State { - /// Create new state - pub(crate) const fn new() -> Self { + pub(super) const fn new() -> Self { Self { rx_buf: RingBuffer::new(), tx_buf: RingBuffer::new(), rx_waker: AtomicWaker::new(), tx_waker: AtomicWaker::new(), tx_done: AtomicBool::new(true), + tx_rx_refcount: AtomicU8::new(0), } } } /// Bidirectional buffered UART -pub struct BufferedUart<'d, T: BasicInstance> { - rx: BufferedUartRx<'d, T>, - tx: BufferedUartTx<'d, T>, +pub struct BufferedUart<'d> { + rx: BufferedUartRx<'d>, + tx: BufferedUartTx<'d>, } /// Tx-only buffered UART /// /// Created with [BufferedUart::split] -pub struct BufferedUartTx<'d, T: BasicInstance> { - phantom: PhantomData<&'d mut T>, +pub struct BufferedUartTx<'d> { + info: &'static Info, + state: &'static State, + kernel_clock: Hertz, + _phantom: PhantomData<&'d mut ()>, } /// Rx-only buffered UART /// /// Created with [BufferedUart::split] -pub struct BufferedUartRx<'d, T: BasicInstance> { - phantom: PhantomData<&'d mut T>, +pub struct BufferedUartRx<'d> { + info: &'static Info, + state: &'static State, + kernel_clock: Hertz, + _phantom: PhantomData<&'d mut ()>, } -impl<'d, T: BasicInstance> SetConfig for BufferedUart<'d, T> { +impl<'d> SetConfig for BufferedUart<'d> { type Config = Config; type ConfigError = ConfigError; @@ -155,7 +177,7 @@ impl<'d, T: BasicInstance> SetConfig for BufferedUart<'d, T> { } } -impl<'d, T: BasicInstance> SetConfig for BufferedUartRx<'d, T> { +impl<'d> SetConfig for BufferedUartRx<'d> { type Config = Config; type ConfigError = ConfigError; @@ -164,7 +186,7 @@ impl<'d, T: BasicInstance> SetConfig for BufferedUartRx<'d, T> { } } -impl<'d, T: BasicInstance> SetConfig for BufferedUartTx<'d, T> { +impl<'d> SetConfig for BufferedUartTx<'d> { type Config = Config; type ConfigError = ConfigError; @@ -173,9 +195,9 @@ impl<'d, T: BasicInstance> SetConfig for BufferedUartTx<'d, T> { } } -impl<'d, T: BasicInstance> BufferedUart<'d, T> { +impl<'d> BufferedUart<'d> { /// Create a new bidirectional buffered UART driver - pub fn new( + pub fn new<T: Instance>( peri: impl Peripheral<P = T> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd, @@ -184,15 +206,13 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { rx_buffer: &'d mut [u8], config: Config, ) -> Result<Self, ConfigError> { - // UartRx and UartTx have one refcount ea. - T::enable_and_reset(); T::enable_and_reset(); Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) } /// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins - pub fn new_with_rtscts( + pub fn new_with_rtscts<T: Instance>( peri: impl Peripheral<P = T> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd, @@ -205,13 +225,11 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { ) -> Result<Self, ConfigError> { into_ref!(cts, rts); - // UartRx and UartTx have one refcount ea. - T::enable_and_reset(); T::enable_and_reset(); rts.set_as_af(rts.af_num(), AFType::OutputPushPull); cts.set_as_af(cts.af_num(), AFType::Input); - T::regs().cr3().write(|w| { + T::info().regs.cr3().write(|w| { w.set_rtse(true); w.set_ctse(true); }); @@ -221,7 +239,7 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { /// Create a new bidirectional buffered UART driver with a driver-enable pin #[cfg(not(any(usart_v1, usart_v2)))] - pub fn new_with_de( + pub fn new_with_de<T: Instance>( peri: impl Peripheral<P = T> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd, @@ -233,19 +251,17 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { ) -> Result<Self, ConfigError> { into_ref!(de); - // UartRx and UartTx have one refcount ea. - T::enable_and_reset(); T::enable_and_reset(); de.set_as_af(de.af_num(), AFType::OutputPushPull); - T::regs().cr3().write(|w| { + T::info().regs.cr3().write(|w| { w.set_dem(true); }); Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) } - fn new_inner( + fn new_inner<T: Instance>( _peri: impl Peripheral<P = T> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd, @@ -255,17 +271,19 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { ) -> Result<Self, ConfigError> { into_ref!(_peri, rx, tx); + let info = T::info(); let state = T::buffered_state(); + let kernel_clock = T::frequency(); let len = tx_buffer.len(); unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; let len = rx_buffer.len(); unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; - let r = T::regs(); + let r = info.regs; rx.set_as_af(rx.af_num(), AFType::Input); tx.set_as_af(tx.af_num(), AFType::OutputPushPull); - configure(r, &config, T::frequency(), T::KIND, true, true)?; + configure(info, kernel_clock, &config, true, true)?; r.cr1().modify(|w| { w.set_rxneie(true); @@ -275,22 +293,34 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { T::Interrupt::unpend(); unsafe { T::Interrupt::enable() }; + state.tx_rx_refcount.store(2, Ordering::Relaxed); + Ok(Self { - rx: BufferedUartRx { phantom: PhantomData }, - tx: BufferedUartTx { phantom: PhantomData }, + rx: BufferedUartRx { + info, + state, + kernel_clock, + _phantom: PhantomData, + }, + tx: BufferedUartTx { + info, + state, + kernel_clock, + _phantom: PhantomData, + }, }) } /// Split the driver into a Tx and Rx part (useful for sending to separate tasks) - pub fn split(self) -> (BufferedUartTx<'d, T>, BufferedUartRx<'d, T>) { + pub fn split(self) -> (BufferedUartTx<'d>, BufferedUartRx<'d>) { (self.tx, self.rx) } /// Reconfigure the driver pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::<T>(config)?; + reconfigure(self.rx.info, self.rx.kernel_clock, config)?; - T::regs().cr1().modify(|w| { + self.rx.info.regs.cr1().modify(|w| { w.set_rxneie(true); w.set_idleie(true); }); @@ -299,10 +329,10 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { } } -impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { +impl<'d> BufferedUartRx<'d> { async fn read(&self, buf: &mut [u8]) -> Result<usize, Error> { poll_fn(move |cx| { - let state = T::buffered_state(); + let state = self.state; let mut rx_reader = unsafe { state.rx_buf.reader() }; let data = rx_reader.pop_slice(); @@ -314,7 +344,7 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { rx_reader.pop_done(len); if do_pend { - T::Interrupt::pend(); + self.info.interrupt.pend(); } return Poll::Ready(Ok(len)); @@ -328,7 +358,7 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { fn blocking_read(&self, buf: &mut [u8]) -> Result<usize, Error> { loop { - let state = T::buffered_state(); + let state = self.state; let mut rx_reader = unsafe { state.rx_buf.reader() }; let data = rx_reader.pop_slice(); @@ -340,7 +370,7 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { rx_reader.pop_done(len); if do_pend { - T::Interrupt::pend(); + self.info.interrupt.pend(); } return Ok(len); @@ -350,7 +380,7 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { async fn fill_buf(&self) -> Result<&[u8], Error> { poll_fn(move |cx| { - let state = T::buffered_state(); + let state = self.state; let mut rx_reader = unsafe { state.rx_buf.reader() }; let (p, n) = rx_reader.pop_buf(); if n == 0 { @@ -365,20 +395,20 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { } fn consume(&self, amt: usize) { - let state = T::buffered_state(); + let state = self.state; let mut rx_reader = unsafe { state.rx_buf.reader() }; let full = state.rx_buf.is_full(); rx_reader.pop_done(amt); if full { - T::Interrupt::pend(); + self.info.interrupt.pend(); } } /// Reconfigure the driver pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::<T>(config)?; + reconfigure(self.info, self.kernel_clock, config)?; - T::regs().cr1().modify(|w| { + self.info.regs.cr1().modify(|w| { w.set_rxneie(true); w.set_idleie(true); }); @@ -387,10 +417,10 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { } } -impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { +impl<'d> BufferedUartTx<'d> { async fn write(&self, buf: &[u8]) -> Result<usize, Error> { poll_fn(move |cx| { - let state = T::buffered_state(); + let state = self.state; state.tx_done.store(false, Ordering::Release); let empty = state.tx_buf.is_empty(); @@ -407,7 +437,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { tx_writer.push_done(n); if empty { - T::Interrupt::pend(); + self.info.interrupt.pend(); } Poll::Ready(Ok(n)) @@ -417,7 +447,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { async fn flush(&self) -> Result<(), Error> { poll_fn(move |cx| { - let state = T::buffered_state(); + let state = self.state; if !state.tx_done.load(Ordering::Acquire) { state.tx_waker.register(cx.waker()); @@ -431,7 +461,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { fn blocking_write(&self, buf: &[u8]) -> Result<usize, Error> { loop { - let state = T::buffered_state(); + let state = self.state; let empty = state.tx_buf.is_empty(); let mut tx_writer = unsafe { state.tx_buf.writer() }; @@ -442,7 +472,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { tx_writer.push_done(n); if empty { - T::Interrupt::pend(); + self.info.interrupt.pend(); } return Ok(n); @@ -452,7 +482,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { fn blocking_flush(&self) -> Result<(), Error> { loop { - let state = T::buffered_state(); + let state = self.state; if state.tx_buf.is_empty() { return Ok(()); } @@ -461,9 +491,9 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { /// Reconfigure the driver pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::<T>(config)?; + reconfigure(self.info, self.kernel_clock, config)?; - T::regs().cr1().modify(|w| { + self.info.regs.cr1().modify(|w| { w.set_rxneie(true); w.set_idleie(true); }); @@ -472,65 +502,78 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { } } -impl<'d, T: BasicInstance> Drop for BufferedUartRx<'d, T> { +impl<'d> Drop for BufferedUartRx<'d> { fn drop(&mut self) { - let state = T::buffered_state(); + let state = self.state; unsafe { state.rx_buf.deinit(); // TX is inactive if the the buffer is not available. // We can now unregister the interrupt handler if state.tx_buf.len() == 0 { - T::Interrupt::disable(); + self.info.interrupt.disable(); } } - T::disable(); + drop_tx_rx(self.info, state); } } -impl<'d, T: BasicInstance> Drop for BufferedUartTx<'d, T> { +impl<'d> Drop for BufferedUartTx<'d> { fn drop(&mut self) { - let state = T::buffered_state(); + let state = self.state; unsafe { state.tx_buf.deinit(); // RX is inactive if the the buffer is not available. // We can now unregister the interrupt handler if state.rx_buf.len() == 0 { - T::Interrupt::disable(); + self.info.interrupt.disable(); } } - T::disable(); + drop_tx_rx(self.info, state); } } -impl<'d, T: BasicInstance> embedded_io_async::ErrorType for BufferedUart<'d, T> { +fn drop_tx_rx(info: &Info, state: &State) { + // We cannot use atomic subtraction here, because it's not supported for all targets + let is_last_drop = critical_section::with(|_| { + let refcount = state.tx_rx_refcount.load(Ordering::Relaxed); + assert!(refcount >= 1); + state.tx_rx_refcount.store(refcount - 1, Ordering::Relaxed); + refcount == 1 + }); + if is_last_drop { + info.enable_bit.disable(); + } +} + +impl<'d> embedded_io_async::ErrorType for BufferedUart<'d> { type Error = Error; } -impl<'d, T: BasicInstance> embedded_io_async::ErrorType for BufferedUartRx<'d, T> { +impl<'d> embedded_io_async::ErrorType for BufferedUartRx<'d> { type Error = Error; } -impl<'d, T: BasicInstance> embedded_io_async::ErrorType for BufferedUartTx<'d, T> { +impl<'d> embedded_io_async::ErrorType for BufferedUartTx<'d> { type Error = Error; } -impl<'d, T: BasicInstance> embedded_io_async::Read for BufferedUart<'d, T> { +impl<'d> embedded_io_async::Read for BufferedUart<'d> { async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { self.rx.read(buf).await } } -impl<'d, T: BasicInstance> embedded_io_async::Read for BufferedUartRx<'d, T> { +impl<'d> embedded_io_async::Read for BufferedUartRx<'d> { async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { Self::read(self, buf).await } } -impl<'d, T: BasicInstance> embedded_io_async::BufRead for BufferedUart<'d, T> { +impl<'d> embedded_io_async::BufRead for BufferedUart<'d> { async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { self.rx.fill_buf().await } @@ -540,7 +583,7 @@ impl<'d, T: BasicInstance> embedded_io_async::BufRead for BufferedUart<'d, T> { } } -impl<'d, T: BasicInstance> embedded_io_async::BufRead for BufferedUartRx<'d, T> { +impl<'d> embedded_io_async::BufRead for BufferedUartRx<'d> { async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { Self::fill_buf(self).await } @@ -550,7 +593,7 @@ impl<'d, T: BasicInstance> embedded_io_async::BufRead for BufferedUartRx<'d, T> } } -impl<'d, T: BasicInstance> embedded_io_async::Write for BufferedUart<'d, T> { +impl<'d> embedded_io_async::Write for BufferedUart<'d> { async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { self.tx.write(buf).await } @@ -560,7 +603,7 @@ impl<'d, T: BasicInstance> embedded_io_async::Write for BufferedUart<'d, T> { } } -impl<'d, T: BasicInstance> embedded_io_async::Write for BufferedUartTx<'d, T> { +impl<'d> embedded_io_async::Write for BufferedUartTx<'d> { async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { Self::write(self, buf).await } @@ -570,19 +613,19 @@ impl<'d, T: BasicInstance> embedded_io_async::Write for BufferedUartTx<'d, T> { } } -impl<'d, T: BasicInstance> embedded_io::Read for BufferedUart<'d, T> { +impl<'d> embedded_io::Read for BufferedUart<'d> { fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { self.rx.blocking_read(buf) } } -impl<'d, T: BasicInstance> embedded_io::Read for BufferedUartRx<'d, T> { +impl<'d> embedded_io::Read for BufferedUartRx<'d> { fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { self.blocking_read(buf) } } -impl<'d, T: BasicInstance> embedded_io::Write for BufferedUart<'d, T> { +impl<'d> embedded_io::Write for BufferedUart<'d> { fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { self.tx.blocking_write(buf) } @@ -592,7 +635,7 @@ impl<'d, T: BasicInstance> embedded_io::Write for BufferedUart<'d, T> { } } -impl<'d, T: BasicInstance> embedded_io::Write for BufferedUartTx<'d, T> { +impl<'d> embedded_io::Write for BufferedUartTx<'d> { fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { Self::blocking_write(self, buf) } @@ -602,11 +645,11 @@ impl<'d, T: BasicInstance> embedded_io::Write for BufferedUartTx<'d, T> { } } -impl<'d, T: BasicInstance> embedded_hal_02::serial::Read<u8> for BufferedUartRx<'d, T> { +impl<'d> embedded_hal_02::serial::Read<u8> for BufferedUartRx<'d> { type Error = Error; fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { - let r = T::regs(); + let r = self.info.regs; unsafe { let sr = sr(r).read(); if sr.pe() { @@ -630,7 +673,7 @@ impl<'d, T: BasicInstance> embedded_hal_02::serial::Read<u8> for BufferedUartRx< } } -impl<'d, T: BasicInstance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx<'d, T> { +impl<'d> embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx<'d> { type Error = Error; fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> { @@ -649,7 +692,7 @@ impl<'d, T: BasicInstance> embedded_hal_02::blocking::serial::Write<u8> for Buff } } -impl<'d, T: BasicInstance> embedded_hal_02::serial::Read<u8> for BufferedUart<'d, T> { +impl<'d> embedded_hal_02::serial::Read<u8> for BufferedUart<'d> { type Error = Error; fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { @@ -657,7 +700,7 @@ impl<'d, T: BasicInstance> embedded_hal_02::serial::Read<u8> for BufferedUart<'d } } -impl<'d, T: BasicInstance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUart<'d, T> { +impl<'d> embedded_hal_02::blocking::serial::Write<u8> for BufferedUart<'d> { type Error = Error; fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> { @@ -676,25 +719,25 @@ impl<'d, T: BasicInstance> embedded_hal_02::blocking::serial::Write<u8> for Buff } } -impl<'d, T: BasicInstance> embedded_hal_nb::serial::ErrorType for BufferedUart<'d, T> { +impl<'d> embedded_hal_nb::serial::ErrorType for BufferedUart<'d> { type Error = Error; } -impl<'d, T: BasicInstance> embedded_hal_nb::serial::ErrorType for BufferedUartTx<'d, T> { +impl<'d> embedded_hal_nb::serial::ErrorType for BufferedUartTx<'d> { type Error = Error; } -impl<'d, T: BasicInstance> embedded_hal_nb::serial::ErrorType for BufferedUartRx<'d, T> { +impl<'d> embedded_hal_nb::serial::ErrorType for BufferedUartRx<'d> { type Error = Error; } -impl<'d, T: BasicInstance> embedded_hal_nb::serial::Read for BufferedUartRx<'d, T> { +impl<'d> embedded_hal_nb::serial::Read for BufferedUartRx<'d> { fn read(&mut self) -> nb::Result<u8, Self::Error> { embedded_hal_02::serial::Read::read(self) } } -impl<'d, T: BasicInstance> embedded_hal_nb::serial::Write for BufferedUartTx<'d, T> { +impl<'d> embedded_hal_nb::serial::Write for BufferedUartTx<'d> { fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other) } @@ -704,13 +747,13 @@ impl<'d, T: BasicInstance> embedded_hal_nb::serial::Write for BufferedUartTx<'d, } } -impl<'d, T: BasicInstance> embedded_hal_nb::serial::Read for BufferedUart<'d, T> { +impl<'d> embedded_hal_nb::serial::Read for BufferedUart<'d> { fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { embedded_hal_02::serial::Read::read(&mut self.rx) } } -impl<'d, T: BasicInstance> embedded_hal_nb::serial::Write for BufferedUart<'d, T> { +impl<'d> embedded_hal_nb::serial::Write for BufferedUart<'d> { fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { self.tx.blocking_write(&[char]).map(drop).map_err(nb::Error::Other) } diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 7c0523a25..b24335f3a 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -4,18 +4,20 @@ use core::future::poll_fn; use core::marker::PhantomData; -use core::sync::atomic::{compiler_fence, Ordering}; +use core::sync::atomic::{compiler_fence, AtomicU8, Ordering}; use core::task::Poll; use embassy_embedded_hal::SetConfig; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::PeripheralRef; use embassy_sync::waitqueue::AtomicWaker; -use futures::future::{select, Either}; +use futures_util::future::{select, Either}; -use crate::dma::{NoDma, Transfer}; -use crate::gpio::AFType; -use crate::interrupt::typelevel::Interrupt; +use crate::dma::ChannelAndRequest; +use crate::gpio::{AFType, AnyPin, SealedPin}; +use crate::interrupt::typelevel::Interrupt as _; +use crate::interrupt::{self, Interrupt, InterruptExt}; +use crate::mode::{Async, Blocking, Mode}; #[allow(unused_imports)] #[cfg(not(any(usart_v1, usart_v2)))] use crate::pac::usart::regs::Isr as Sr; @@ -26,57 +28,59 @@ use crate::pac::usart::Lpuart as Regs; #[cfg(any(usart_v1, usart_v2))] use crate::pac::usart::Usart as Regs; use crate::pac::usart::{regs, vals}; +use crate::rcc::{ClockEnableBit, SealedRccPeripheral}; use crate::time::Hertz; -use crate::{interrupt, peripherals, Peripheral}; +use crate::Peripheral; /// Interrupt handler. -pub struct InterruptHandler<T: BasicInstance> { +pub struct InterruptHandler<T: Instance> { _phantom: PhantomData<T>, } -impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { +impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { unsafe fn on_interrupt() { - let r = T::regs(); - let s = T::state(); - - let (sr, cr1, cr3) = (sr(r).read(), r.cr1().read(), r.cr3().read()); - - let has_errors = (sr.pe() && cr1.peie()) || ((sr.fe() || sr.ne() || sr.ore()) && cr3.eie()); - if has_errors { - // clear all interrupts and DMA Rx Request - r.cr1().modify(|w| { - // disable RXNE interrupt - w.set_rxneie(false); - // disable parity interrupt - w.set_peie(false); - // disable idle line interrupt - w.set_idleie(false); - }); - r.cr3().modify(|w| { - // disable Error Interrupt: (Frame error, Noise error, Overrun error) - w.set_eie(false); - // disable DMA Rx Request - w.set_dmar(false); - }); - } else if cr1.idleie() && sr.idle() { - // IDLE detected: no more data will come - r.cr1().modify(|w| { - // disable idle line detection - w.set_idleie(false); - }); - } else if cr1.rxneie() { - // We cannot check the RXNE flag as it is auto-cleared by the DMA controller - - // It is up to the listener to determine if this in fact was a RX event and disable the RXNE detection - } else { - return; - } - - compiler_fence(Ordering::SeqCst); - s.rx_waker.wake(); + on_interrupt(T::info().regs, T::state()) } } +unsafe fn on_interrupt(r: Regs, s: &'static State) { + let (sr, cr1, cr3) = (sr(r).read(), r.cr1().read(), r.cr3().read()); + + let has_errors = (sr.pe() && cr1.peie()) || ((sr.fe() || sr.ne() || sr.ore()) && cr3.eie()); + if has_errors { + // clear all interrupts and DMA Rx Request + r.cr1().modify(|w| { + // disable RXNE interrupt + w.set_rxneie(false); + // disable parity interrupt + w.set_peie(false); + // disable idle line interrupt + w.set_idleie(false); + }); + r.cr3().modify(|w| { + // disable Error Interrupt: (Frame error, Noise error, Overrun error) + w.set_eie(false); + // disable DMA Rx Request + w.set_dmar(false); + }); + } else if cr1.idleie() && sr.idle() { + // IDLE detected: no more data will come + r.cr1().modify(|w| { + // disable idle line detection + w.set_idleie(false); + }); + } else if cr1.rxneie() { + // We cannot check the RXNE flag as it is auto-cleared by the DMA controller + + // It is up to the listener to determine if this in fact was a RX event and disable the RXNE detection + } else { + return; + } + + compiler_fence(Ordering::SeqCst); + s.rx_waker.wake(); +} + #[derive(Clone, Copy, PartialEq, Eq, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] /// Number of data bits @@ -162,6 +166,26 @@ pub struct Config { /// Set this to true to invert RX pin signal values (V<sub>DD</sub> =0/mark, Gnd = 1/idle). #[cfg(any(usart_v3, usart_v4))] pub invert_rx: bool, + + // private: set by new_half_duplex, not by the user. + half_duplex: bool, +} + +impl Config { + fn tx_af(&self) -> AFType { + #[cfg(any(usart_v3, usart_v4))] + if self.swap_rx_tx { + return AFType::Input; + }; + AFType::OutputPushPull + } + fn rx_af(&self) -> AFType { + #[cfg(any(usart_v3, usart_v4))] + if self.swap_rx_tx { + return AFType::OutputPushPull; + }; + AFType::Input + } } impl Default for Config { @@ -181,6 +205,7 @@ impl Default for Config { invert_tx: false, #[cfg(any(usart_v3, usart_v4))] invert_rx: false, + half_duplex: false, } } } @@ -217,12 +242,12 @@ enum ReadCompletionEvent { /// /// See [`UartRx`] for more details, and see [`BufferedUart`] and [`RingBufferedUartRx`] /// as alternatives that do provide the necessary guarantees for `embedded_io::Read`. -pub struct Uart<'d, T: BasicInstance, TxDma = NoDma, RxDma = NoDma> { - tx: UartTx<'d, T, TxDma>, - rx: UartRx<'d, T, RxDma>, +pub struct Uart<'d, M: Mode> { + tx: UartTx<'d, M>, + rx: UartRx<'d, M>, } -impl<'d, T: BasicInstance, TxDma, RxDma> SetConfig for Uart<'d, T, TxDma, RxDma> { +impl<'d, M: Mode> SetConfig for Uart<'d, M> { type Config = Config; type ConfigError = ConfigError; @@ -236,12 +261,18 @@ impl<'d, T: BasicInstance, TxDma, RxDma> SetConfig for Uart<'d, T, TxDma, RxDma> /// /// Can be obtained from [`Uart::split`], or can be constructed independently, /// if you do not need the receiving half of the driver. -pub struct UartTx<'d, T: BasicInstance, TxDma = NoDma> { - phantom: PhantomData<&'d mut T>, - tx_dma: PeripheralRef<'d, TxDma>, +pub struct UartTx<'d, M: Mode> { + info: &'static Info, + state: &'static State, + kernel_clock: Hertz, + tx: Option<PeripheralRef<'d, AnyPin>>, + cts: Option<PeripheralRef<'d, AnyPin>>, + de: Option<PeripheralRef<'d, AnyPin>>, + tx_dma: Option<ChannelAndRequest<'d>>, + _phantom: PhantomData<M>, } -impl<'d, T: BasicInstance, TxDma> SetConfig for UartTx<'d, T, TxDma> { +impl<'d, M: Mode> SetConfig for UartTx<'d, M> { type Config = Config; type ConfigError = ConfigError; @@ -279,15 +310,20 @@ impl<'d, T: BasicInstance, TxDma> SetConfig for UartTx<'d, T, TxDma> { /// store data received between calls. /// /// Also see [this github comment](https://github.com/embassy-rs/embassy/pull/2185#issuecomment-1810047043). -pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> { - _peri: PeripheralRef<'d, T>, - rx_dma: PeripheralRef<'d, RxDma>, +pub struct UartRx<'d, M: Mode> { + info: &'static Info, + state: &'static State, + kernel_clock: Hertz, + rx: Option<PeripheralRef<'d, AnyPin>>, + rts: Option<PeripheralRef<'d, AnyPin>>, + rx_dma: Option<ChannelAndRequest<'d>>, detect_previous_overrun: bool, #[cfg(any(usart_v1, usart_v2))] buffered_sr: stm32_metapac::usart::regs::Sr, + _phantom: PhantomData<M>, } -impl<'d, T: BasicInstance, RxDma> SetConfig for UartRx<'d, T, RxDma> { +impl<'d, M: Mode> SetConfig for UartRx<'d, M> { type Config = Config; type ConfigError = ConfigError; @@ -296,86 +332,142 @@ impl<'d, T: BasicInstance, RxDma> SetConfig for UartRx<'d, T, RxDma> { } } -impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { +impl<'d> UartTx<'d, Async> { /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power. - pub fn new( + pub fn new<T: Instance>( peri: impl Peripheral<P = T> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd, - tx_dma: impl Peripheral<P = TxDma> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, config: Config, ) -> Result<Self, ConfigError> { - T::enable_and_reset(); - - Self::new_inner(peri, tx, tx_dma, config) + Self::new_inner( + peri, + new_pin!(tx, AFType::OutputPushPull), + None, + new_dma!(tx_dma), + config, + ) } /// Create a new tx-only UART with a clear-to-send pin - pub fn new_with_cts( + pub fn new_with_cts<T: Instance>( peri: impl Peripheral<P = T> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd, cts: impl Peripheral<P = impl CtsPin<T>> + 'd, - tx_dma: impl Peripheral<P = TxDma> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, config: Config, ) -> Result<Self, ConfigError> { - into_ref!(cts); - - T::enable_and_reset(); - - cts.set_as_af(cts.af_num(), AFType::Input); - T::regs().cr3().write(|w| { - w.set_ctse(true); - }); - Self::new_inner(peri, tx, tx_dma, config) + Self::new_inner( + peri, + new_pin!(tx, AFType::OutputPushPull), + new_pin!(cts, AFType::Input), + new_dma!(tx_dma), + config, + ) } - fn new_inner( - _peri: impl Peripheral<P = T> + 'd, + /// Initiate an asynchronous UART write + pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { + let r = self.info.regs; + + // Disable Receiver for Half-Duplex mode + if r.cr3().read().hdsel() { + r.cr1().modify(|reg| reg.set_re(false)); + } + + let ch = self.tx_dma.as_mut().unwrap(); + r.cr3().modify(|reg| { + reg.set_dmat(true); + }); + // If we don't assign future to a variable, the data register pointer + // is held across an await and makes the future non-Send. + let transfer = unsafe { ch.write(buffer, tdr(r), Default::default()) }; + transfer.await; + Ok(()) + } + + /// Wait until transmission complete + pub async fn flush(&mut self) -> Result<(), Error> { + self.blocking_flush() + } +} + +impl<'d> UartTx<'d, Blocking> { + /// Create a new blocking tx-only UART with no hardware flow control. + /// + /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power. + pub fn new_blocking<T: Instance>( + peri: impl Peripheral<P = T> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd, - tx_dma: impl Peripheral<P = TxDma> + 'd, config: Config, ) -> Result<Self, ConfigError> { - into_ref!(_peri, tx, tx_dma); + Self::new_inner(peri, new_pin!(tx, AFType::OutputPushPull), None, None, config) + } - let r = T::regs(); + /// Create a new blocking tx-only UART with a clear-to-send pin + pub fn new_blocking_with_cts<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + tx: impl Peripheral<P = impl TxPin<T>> + 'd, + cts: impl Peripheral<P = impl CtsPin<T>> + 'd, + config: Config, + ) -> Result<Self, ConfigError> { + Self::new_inner( + peri, + new_pin!(tx, AFType::OutputPushPull), + new_pin!(cts, AFType::Input), + None, + config, + ) + } +} - tx.set_as_af(tx.af_num(), AFType::OutputPushPull); +impl<'d, M: Mode> UartTx<'d, M> { + fn new_inner<T: Instance>( + _peri: impl Peripheral<P = T> + 'd, + tx: Option<PeripheralRef<'d, AnyPin>>, + cts: Option<PeripheralRef<'d, AnyPin>>, + tx_dma: Option<ChannelAndRequest<'d>>, + config: Config, + ) -> Result<Self, ConfigError> { + T::enable_and_reset(); - configure(r, &config, T::frequency(), T::KIND, false, true)?; + let info = T::info(); + let state = T::state(); + let kernel_clock = T::frequency(); + let r = info.regs; + r.cr3().modify(|w| { + w.set_ctse(cts.is_some()); + }); + configure(info, kernel_clock, &config, false, true)?; - // create state once! - let _s = T::state(); + state.tx_rx_refcount.store(1, Ordering::Relaxed); Ok(Self { + info, + state, + kernel_clock, + tx, + cts, + de: None, tx_dma, - phantom: PhantomData, + _phantom: PhantomData, }) } /// Reconfigure the driver pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::<T>(config) - } - - /// Initiate an asynchronous UART write - pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> - where - TxDma: crate::usart::TxDma<T>, - { - let ch = &mut self.tx_dma; - let request = ch.request(); - T::regs().cr3().modify(|reg| { - reg.set_dmat(true); - }); - // If we don't assign future to a variable, the data register pointer - // is held across an await and makes the future non-Send. - let transfer = unsafe { Transfer::new_write(ch, request, buffer, tdr(T::regs()), Default::default()) }; - transfer.await; - Ok(()) + reconfigure(self.info, self.kernel_clock, config) } /// Perform a blocking UART write pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { - let r = T::regs(); + let r = self.info.regs; + + // Disable Receiver for Half-Duplex mode + if r.cr3().read().hdsel() { + r.cr1().modify(|reg| reg.set_re(false)); + } + for &b in buffer { while !sr(r).read().txe() {} unsafe { tdr(r).write_volatile(b) }; @@ -385,169 +477,63 @@ impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { /// Block until transmission complete pub fn blocking_flush(&mut self) -> Result<(), Error> { - let r = T::regs(); - while !sr(r).read().tc() {} - Ok(()) + blocking_flush(self.info) } } -impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { +fn blocking_flush(info: &Info) -> Result<(), Error> { + let r = info.regs; + while !sr(r).read().tc() {} + + // Enable Receiver after transmission complete for Half-Duplex mode + if r.cr3().read().hdsel() { + r.cr1().modify(|reg| reg.set_re(true)); + } + + Ok(()) +} + +impl<'d> UartRx<'d, Async> { + /// Create a new rx-only UART with no hardware flow control. + /// /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power. - pub fn new( + pub fn new<T: Instance>( peri: impl Peripheral<P = T> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd, - rx_dma: impl Peripheral<P = RxDma> + 'd, + rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, config: Config, ) -> Result<Self, ConfigError> { - T::enable_and_reset(); - - Self::new_inner(peri, rx, rx_dma, config) + Self::new_inner(peri, new_pin!(rx, AFType::Input), None, new_dma!(rx_dma), config) } /// Create a new rx-only UART with a request-to-send pin - pub fn new_with_rts( + pub fn new_with_rts<T: Instance>( peri: impl Peripheral<P = T> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd, rts: impl Peripheral<P = impl RtsPin<T>> + 'd, - rx_dma: impl Peripheral<P = RxDma> + 'd, + rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, config: Config, ) -> Result<Self, ConfigError> { - into_ref!(rts); - - T::enable_and_reset(); - - rts.set_as_af(rts.af_num(), AFType::OutputPushPull); - T::regs().cr3().write(|w| { - w.set_rtse(true); - }); - - Self::new_inner(peri, rx, rx_dma, config) - } - - fn new_inner( - peri: impl Peripheral<P = T> + 'd, - rx: impl Peripheral<P = impl RxPin<T>> + 'd, - rx_dma: impl Peripheral<P = RxDma> + 'd, - config: Config, - ) -> Result<Self, ConfigError> { - into_ref!(peri, rx, rx_dma); - - let r = T::regs(); - - rx.set_as_af(rx.af_num(), AFType::Input); - - configure(r, &config, T::frequency(), T::KIND, true, false)?; - - T::Interrupt::unpend(); - unsafe { T::Interrupt::enable() }; - - // create state once! - let _s = T::state(); - - Ok(Self { - _peri: peri, - rx_dma, - detect_previous_overrun: config.detect_previous_overrun, - #[cfg(any(usart_v1, usart_v2))] - buffered_sr: stm32_metapac::usart::regs::Sr(0), - }) - } - - /// Reconfigure the driver - pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::<T>(config) - } - - #[cfg(any(usart_v1, usart_v2))] - fn check_rx_flags(&mut self) -> Result<bool, Error> { - let r = T::regs(); - loop { - // Handle all buffered error flags. - if self.buffered_sr.pe() { - self.buffered_sr.set_pe(false); - return Err(Error::Parity); - } else if self.buffered_sr.fe() { - self.buffered_sr.set_fe(false); - return Err(Error::Framing); - } else if self.buffered_sr.ne() { - self.buffered_sr.set_ne(false); - return Err(Error::Noise); - } else if self.buffered_sr.ore() { - self.buffered_sr.set_ore(false); - return Err(Error::Overrun); - } else if self.buffered_sr.rxne() { - self.buffered_sr.set_rxne(false); - return Ok(true); - } else { - // No error flags from previous iterations were set: Check the actual status register - let sr = r.sr().read(); - if !sr.rxne() { - return Ok(false); - } - - // Buffer the status register and let the loop handle the error flags. - self.buffered_sr = sr; - } - } - } - - #[cfg(any(usart_v3, usart_v4))] - fn check_rx_flags(&mut self) -> Result<bool, Error> { - let r = T::regs(); - let sr = r.isr().read(); - if sr.pe() { - r.icr().write(|w| w.set_pe(true)); - return Err(Error::Parity); - } else if sr.fe() { - r.icr().write(|w| w.set_fe(true)); - return Err(Error::Framing); - } else if sr.ne() { - r.icr().write(|w| w.set_ne(true)); - return Err(Error::Noise); - } else if sr.ore() { - r.icr().write(|w| w.set_ore(true)); - return Err(Error::Overrun); - } - Ok(sr.rxne()) + Self::new_inner( + peri, + new_pin!(rx, AFType::Input), + new_pin!(rts, AFType::OutputPushPull), + new_dma!(rx_dma), + config, + ) } /// Initiate an asynchronous UART read - pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> - where - RxDma: crate::usart::RxDma<T>, - { + pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { self.inner_read(buffer, false).await?; Ok(()) } - /// Read a single u8 if there is one available, otherwise return WouldBlock - pub fn nb_read(&mut self) -> Result<u8, nb::Error<Error>> { - let r = T::regs(); - if self.check_rx_flags()? { - Ok(unsafe { rdr(r).read_volatile() }) - } else { - Err(nb::Error::WouldBlock) - } - } - - /// Perform a blocking read into `buffer` - pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { - let r = T::regs(); - for b in buffer { - while !self.check_rx_flags()? {} - unsafe { *b = rdr(r).read_volatile() } - } - Ok(()) - } - /// Initiate an asynchronous read with idle line detection enabled - pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error> - where - RxDma: crate::usart::RxDma<T>, - { + pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { self.inner_read(buffer, true).await } @@ -555,11 +541,13 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { &mut self, buffer: &mut [u8], enable_idle_line_detection: bool, - ) -> Result<ReadCompletionEvent, Error> - where - RxDma: crate::usart::RxDma<T>, - { - let r = T::regs(); + ) -> Result<ReadCompletionEvent, Error> { + let r = self.info.regs; + + // Call flush for Half-Duplex mode. It prevents reading of bytes which have just been written. + if r.cr3().read().hdsel() { + blocking_flush(self.info)?; + } // make sure USART state is restored to neutral state when this future is dropped let on_drop = OnDrop::new(move || { @@ -581,15 +569,14 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { }); }); - let ch = &mut self.rx_dma; - let request = ch.request(); + let ch = self.rx_dma.as_mut().unwrap(); let buffer_len = buffer.len(); // Start USART DMA // will not do anything yet because DMAR is not yet set // future which will complete when DMA Read request completes - let transfer = unsafe { Transfer::new_read(ch, request, rdr(T::regs()), buffer, Default::default()) }; + let transfer = unsafe { ch.read(rdr(r), buffer, Default::default()) }; // clear ORE flag just before enabling DMA Rx Request: can be mandatory for the second transfer if !self.detect_previous_overrun { @@ -664,9 +651,8 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { compiler_fence(Ordering::SeqCst); // future which completes when idle line or error is detected + let s = self.state; let abort = poll_fn(move |cx| { - let s = T::state(); - s.rx_waker.register(cx.waker()); let sr = sr(r).read(); @@ -732,10 +718,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { r } - async fn inner_read(&mut self, buffer: &mut [u8], enable_idle_line_detection: bool) -> Result<usize, Error> - where - RxDma: crate::usart::RxDma<T>, - { + async fn inner_read(&mut self, buffer: &mut [u8], enable_idle_line_detection: bool) -> Result<usize, Error> { if buffer.is_empty() { return Ok(0); } else if buffer.len() > 0xFFFF { @@ -755,119 +738,298 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { } } -impl<'d, T: BasicInstance, TxDma> Drop for UartTx<'d, T, TxDma> { - fn drop(&mut self) { - T::disable(); +impl<'d> UartRx<'d, Blocking> { + /// Create a new rx-only UART with no hardware flow control. + /// + /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power. + pub fn new_blocking<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + rx: impl Peripheral<P = impl RxPin<T>> + 'd, + config: Config, + ) -> Result<Self, ConfigError> { + Self::new_inner(peri, new_pin!(rx, AFType::Input), None, None, config) + } + + /// Create a new rx-only UART with a request-to-send pin + pub fn new_blocking_with_rts<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + rx: impl Peripheral<P = impl RxPin<T>> + 'd, + rts: impl Peripheral<P = impl RtsPin<T>> + 'd, + config: Config, + ) -> Result<Self, ConfigError> { + Self::new_inner( + peri, + new_pin!(rx, AFType::Input), + new_pin!(rts, AFType::OutputPushPull), + None, + config, + ) } } -impl<'d, T: BasicInstance, TxDma> Drop for UartRx<'d, T, TxDma> { - fn drop(&mut self) { - T::disable(); +impl<'d, M: Mode> UartRx<'d, M> { + fn new_inner<T: Instance>( + _peri: impl Peripheral<P = T> + 'd, + rx: Option<PeripheralRef<'d, AnyPin>>, + rts: Option<PeripheralRef<'d, AnyPin>>, + rx_dma: Option<ChannelAndRequest<'d>>, + config: Config, + ) -> Result<Self, ConfigError> { + T::enable_and_reset(); + + let info = T::info(); + let state = T::state(); + let kernel_clock = T::frequency(); + let r = info.regs; + r.cr3().write(|w| { + w.set_rtse(rts.is_some()); + }); + configure(info, kernel_clock, &config, true, false)?; + + T::Interrupt::unpend(); + unsafe { T::Interrupt::enable() }; + + state.tx_rx_refcount.store(1, Ordering::Relaxed); + + Ok(Self { + _phantom: PhantomData, + info, + state, + kernel_clock, + rx, + rts, + rx_dma, + detect_previous_overrun: config.detect_previous_overrun, + #[cfg(any(usart_v1, usart_v2))] + buffered_sr: stm32_metapac::usart::regs::Sr(0), + }) + } + + /// Reconfigure the driver + pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + reconfigure(self.info, self.kernel_clock, config) + } + + #[cfg(any(usart_v1, usart_v2))] + fn check_rx_flags(&mut self) -> Result<bool, Error> { + let r = self.info.regs; + loop { + // Handle all buffered error flags. + if self.buffered_sr.pe() { + self.buffered_sr.set_pe(false); + return Err(Error::Parity); + } else if self.buffered_sr.fe() { + self.buffered_sr.set_fe(false); + return Err(Error::Framing); + } else if self.buffered_sr.ne() { + self.buffered_sr.set_ne(false); + return Err(Error::Noise); + } else if self.buffered_sr.ore() { + self.buffered_sr.set_ore(false); + return Err(Error::Overrun); + } else if self.buffered_sr.rxne() { + self.buffered_sr.set_rxne(false); + return Ok(true); + } else { + // No error flags from previous iterations were set: Check the actual status register + let sr = r.sr().read(); + if !sr.rxne() { + return Ok(false); + } + + // Buffer the status register and let the loop handle the error flags. + self.buffered_sr = sr; + } + } + } + + #[cfg(any(usart_v3, usart_v4))] + fn check_rx_flags(&mut self) -> Result<bool, Error> { + let r = self.info.regs; + let sr = r.isr().read(); + if sr.pe() { + r.icr().write(|w| w.set_pe(true)); + return Err(Error::Parity); + } else if sr.fe() { + r.icr().write(|w| w.set_fe(true)); + return Err(Error::Framing); + } else if sr.ne() { + r.icr().write(|w| w.set_ne(true)); + return Err(Error::Noise); + } else if sr.ore() { + r.icr().write(|w| w.set_ore(true)); + return Err(Error::Overrun); + } + Ok(sr.rxne()) + } + + /// Read a single u8 if there is one available, otherwise return WouldBlock + pub(crate) fn nb_read(&mut self) -> Result<u8, nb::Error<Error>> { + let r = self.info.regs; + if self.check_rx_flags()? { + Ok(unsafe { rdr(r).read_volatile() }) + } else { + Err(nb::Error::WouldBlock) + } + } + + /// Perform a blocking read into `buffer` + pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { + let r = self.info.regs; + + // Call flush for Half-Duplex mode. It prevents reading of bytes which have just been written. + if r.cr3().read().hdsel() { + blocking_flush(self.info)?; + } + + for b in buffer { + while !self.check_rx_flags()? {} + unsafe { *b = rdr(r).read_volatile() } + } + Ok(()) } } -impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { +impl<'d, M: Mode> Drop for UartTx<'d, M> { + fn drop(&mut self) { + self.tx.as_ref().map(|x| x.set_as_disconnected()); + self.cts.as_ref().map(|x| x.set_as_disconnected()); + self.de.as_ref().map(|x| x.set_as_disconnected()); + drop_tx_rx(self.info, self.state); + } +} + +impl<'d, M: Mode> Drop for UartRx<'d, M> { + fn drop(&mut self) { + self.rx.as_ref().map(|x| x.set_as_disconnected()); + self.rts.as_ref().map(|x| x.set_as_disconnected()); + drop_tx_rx(self.info, self.state); + } +} + +fn drop_tx_rx(info: &Info, state: &State) { + // We cannot use atomic subtraction here, because it's not supported for all targets + let is_last_drop = critical_section::with(|_| { + let refcount = state.tx_rx_refcount.load(Ordering::Relaxed); + assert!(refcount >= 1); + state.tx_rx_refcount.store(refcount - 1, Ordering::Relaxed); + refcount == 1 + }); + if is_last_drop { + info.enable_bit.disable(); + } +} + +impl<'d> Uart<'d, Async> { /// Create a new bidirectional UART - pub fn new( + pub fn new<T: Instance>( peri: impl Peripheral<P = T> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, - tx_dma: impl Peripheral<P = TxDma> + 'd, - rx_dma: impl Peripheral<P = RxDma> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, + rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, config: Config, ) -> Result<Self, ConfigError> { - // UartRx and UartTx have one refcount ea. - T::enable_and_reset(); - T::enable_and_reset(); - - Self::new_inner_configure(peri, rx, tx, tx_dma, rx_dma, config) + Self::new_inner( + peri, + new_pin!(rx, config.rx_af()), + new_pin!(tx, config.tx_af()), + None, + None, + None, + new_dma!(tx_dma), + new_dma!(rx_dma), + config, + ) } /// Create a new bidirectional UART with request-to-send and clear-to-send pins - pub fn new_with_rtscts( + pub fn new_with_rtscts<T: Instance>( peri: impl Peripheral<P = T> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, rts: impl Peripheral<P = impl RtsPin<T>> + 'd, cts: impl Peripheral<P = impl CtsPin<T>> + 'd, - tx_dma: impl Peripheral<P = TxDma> + 'd, - rx_dma: impl Peripheral<P = RxDma> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, + rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, config: Config, ) -> Result<Self, ConfigError> { - into_ref!(cts, rts); - - // UartRx and UartTx have one refcount ea. - T::enable_and_reset(); - T::enable_and_reset(); - - rts.set_as_af(rts.af_num(), AFType::OutputPushPull); - cts.set_as_af(cts.af_num(), AFType::Input); - T::regs().cr3().write(|w| { - w.set_rtse(true); - w.set_ctse(true); - }); - Self::new_inner_configure(peri, rx, tx, tx_dma, rx_dma, config) + Self::new_inner( + peri, + new_pin!(rx, config.rx_af()), + new_pin!(tx, config.tx_af()), + new_pin!(rts, AFType::OutputPushPull), + new_pin!(cts, AFType::Input), + None, + new_dma!(tx_dma), + new_dma!(rx_dma), + config, + ) } #[cfg(not(any(usart_v1, usart_v2)))] /// Create a new bidirectional UART with a driver-enable pin - pub fn new_with_de( + pub fn new_with_de<T: Instance>( peri: impl Peripheral<P = T> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, de: impl Peripheral<P = impl DePin<T>> + 'd, - tx_dma: impl Peripheral<P = TxDma> + 'd, - rx_dma: impl Peripheral<P = RxDma> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, + rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, config: Config, ) -> Result<Self, ConfigError> { - into_ref!(de); - - // UartRx and UartTx have one refcount ea. - T::enable_and_reset(); - T::enable_and_reset(); - - de.set_as_af(de.af_num(), AFType::OutputPushPull); - T::regs().cr3().write(|w| { - w.set_dem(true); - }); - Self::new_inner_configure(peri, rx, tx, tx_dma, rx_dma, config) + Self::new_inner( + peri, + new_pin!(rx, config.rx_af()), + new_pin!(tx, config.tx_af()), + None, + None, + new_pin!(de, AFType::OutputPushPull), + new_dma!(tx_dma), + new_dma!(rx_dma), + config, + ) } /// Create a single-wire half-duplex Uart transceiver on a single Tx pin. /// - /// See [`new_half_duplex_on_rx`][`Self::new_half_duplex_on_rx`] if you would prefer to use an Rx pin. - /// There is no functional difference between these methods, as both allow bidirectional communication. + /// See [`new_half_duplex_on_rx`][`Self::new_half_duplex_on_rx`] if you would prefer to use an Rx pin + /// (when it is available for your chip). There is no functional difference between these methods, as both + /// allow bidirectional communication. /// /// The pin is always released when no data is transmitted. Thus, it acts as a standard /// I/O in idle or in reception. /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict /// on the line must be managed by software (for instance by using a centralized arbiter). - #[cfg(not(any(usart_v1, usart_v2)))] #[doc(alias("HDSEL"))] - pub fn new_half_duplex( + pub fn new_half_duplex<T: Instance>( peri: impl Peripheral<P = T> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, - tx_dma: impl Peripheral<P = TxDma> + 'd, - rx_dma: impl Peripheral<P = RxDma> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, + rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, mut config: Config, ) -> Result<Self, ConfigError> { - // UartRx and UartTx have one refcount ea. - T::enable_and_reset(); - T::enable_and_reset(); + #[cfg(not(any(usart_v1, usart_v2)))] + { + config.swap_rx_tx = false; + } + config.half_duplex = true; - config.swap_rx_tx = false; - - into_ref!(peri, tx, tx_dma, rx_dma); - - T::regs().cr3().write(|w| w.set_hdsel(true)); - tx.set_as_af(tx.af_num(), AFType::OutputPushPull); - - Self::new_inner(peri, tx_dma, rx_dma, config) + Self::new_inner( + peri, + None, + new_pin!(tx, AFType::OutputPushPull), + None, + None, + None, + new_dma!(tx_dma), + new_dma!(rx_dma), + config, + ) } /// Create a single-wire half-duplex Uart transceiver on a single Rx pin. @@ -881,81 +1043,229 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { /// on the line must be managed by software (for instance by using a centralized arbiter). #[cfg(not(any(usart_v1, usart_v2)))] #[doc(alias("HDSEL"))] - pub fn new_half_duplex_on_rx( + pub fn new_half_duplex_on_rx<T: Instance>( peri: impl Peripheral<P = T> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, - tx_dma: impl Peripheral<P = TxDma> + 'd, - rx_dma: impl Peripheral<P = RxDma> + 'd, + tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, + rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, mut config: Config, ) -> Result<Self, ConfigError> { - // UartRx and UartTx have one refcount ea. - T::enable_and_reset(); - T::enable_and_reset(); - config.swap_rx_tx = true; + config.half_duplex = true; - into_ref!(peri, rx, tx_dma, rx_dma); - - T::regs().cr3().write(|w| w.set_hdsel(true)); - rx.set_as_af(rx.af_num(), AFType::OutputPushPull); - - Self::new_inner(peri, tx_dma, rx_dma, config) + Self::new_inner( + peri, + None, + None, + new_pin!(rx, AFType::OutputPushPull), + None, + None, + new_dma!(tx_dma), + new_dma!(rx_dma), + config, + ) } - fn new_inner_configure( + /// Perform an asynchronous write + pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { + self.tx.write(buffer).await + } + + /// Perform an asynchronous read into `buffer` + pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { + self.rx.read(buffer).await + } + + /// Perform an an asynchronous read with idle line detection enabled + pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { + self.rx.read_until_idle(buffer).await + } +} + +impl<'d> Uart<'d, Blocking> { + /// Create a new blocking bidirectional UART. + pub fn new_blocking<T: Instance>( peri: impl Peripheral<P = T> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd, - tx_dma: impl Peripheral<P = TxDma> + 'd, - rx_dma: impl Peripheral<P = RxDma> + 'd, config: Config, ) -> Result<Self, ConfigError> { - into_ref!(peri, rx, tx, tx_dma, rx_dma); - - // Some chips do not have swap_rx_tx bit - cfg_if::cfg_if! { - if #[cfg(any(usart_v3, usart_v4))] { - if config.swap_rx_tx { - let (rx, tx) = (tx, rx); - rx.set_as_af(rx.af_num(), AFType::Input); - tx.set_as_af(tx.af_num(), AFType::OutputPushPull); - } else { - rx.set_as_af(rx.af_num(), AFType::Input); - tx.set_as_af(tx.af_num(), AFType::OutputPushPull); - } - } else { - rx.set_as_af(rx.af_num(), AFType::Input); - tx.set_as_af(tx.af_num(), AFType::OutputPushPull); - } - } - - Self::new_inner(peri, tx_dma, rx_dma, config) + Self::new_inner( + peri, + new_pin!(rx, config.rx_af()), + new_pin!(tx, config.tx_af()), + None, + None, + None, + None, + None, + config, + ) } - fn new_inner( - peri: PeripheralRef<'d, T>, - tx_dma: PeripheralRef<'d, TxDma>, - rx_dma: PeripheralRef<'d, RxDma>, + /// Create a new bidirectional UART with request-to-send and clear-to-send pins + pub fn new_blocking_with_rtscts<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + rx: impl Peripheral<P = impl RxPin<T>> + 'd, + tx: impl Peripheral<P = impl TxPin<T>> + 'd, + rts: impl Peripheral<P = impl RtsPin<T>> + 'd, + cts: impl Peripheral<P = impl CtsPin<T>> + 'd, config: Config, ) -> Result<Self, ConfigError> { - let r = T::regs(); + Self::new_inner( + peri, + new_pin!(rx, config.rx_af()), + new_pin!(tx, config.tx_af()), + new_pin!(rts, AFType::OutputPushPull), + new_pin!(cts, AFType::Input), + None, + None, + None, + config, + ) + } - configure(r, &config, T::frequency(), T::KIND, true, true)?; + #[cfg(not(any(usart_v1, usart_v2)))] + /// Create a new bidirectional UART with a driver-enable pin + pub fn new_blocking_with_de<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + rx: impl Peripheral<P = impl RxPin<T>> + 'd, + tx: impl Peripheral<P = impl TxPin<T>> + 'd, + de: impl Peripheral<P = impl DePin<T>> + 'd, + config: Config, + ) -> Result<Self, ConfigError> { + Self::new_inner( + peri, + new_pin!(rx, config.rx_af()), + new_pin!(tx, config.tx_af()), + None, + None, + new_pin!(de, AFType::OutputPushPull), + None, + None, + config, + ) + } + + /// Create a single-wire half-duplex Uart transceiver on a single Tx pin. + /// + /// See [`new_half_duplex_on_rx`][`Self::new_half_duplex_on_rx`] if you would prefer to use an Rx pin + /// (when it is available for your chip). There is no functional difference between these methods, as both + /// allow bidirectional communication. + /// + /// The pin is always released when no data is transmitted. Thus, it acts as a standard + /// I/O in idle or in reception. + /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict + /// on the line must be managed by software (for instance by using a centralized arbiter). + #[doc(alias("HDSEL"))] + pub fn new_blocking_half_duplex<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + tx: impl Peripheral<P = impl TxPin<T>> + 'd, + mut config: Config, + ) -> Result<Self, ConfigError> { + #[cfg(not(any(usart_v1, usart_v2)))] + { + config.swap_rx_tx = false; + } + config.half_duplex = true; + + Self::new_inner( + peri, + None, + new_pin!(tx, AFType::OutputPushPull), + None, + None, + None, + None, + None, + config, + ) + } + + /// Create a single-wire half-duplex Uart transceiver on a single Rx pin. + /// + /// See [`new_half_duplex`][`Self::new_half_duplex`] if you would prefer to use an Tx pin. + /// There is no functional difference between these methods, as both allow bidirectional communication. + /// + /// The pin is always released when no data is transmitted. Thus, it acts as a standard + /// I/O in idle or in reception. + /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict + /// on the line must be managed by software (for instance by using a centralized arbiter). + #[cfg(not(any(usart_v1, usart_v2)))] + #[doc(alias("HDSEL"))] + pub fn new_blocking_half_duplex_on_rx<T: Instance>( + peri: impl Peripheral<P = T> + 'd, + rx: impl Peripheral<P = impl RxPin<T>> + 'd, + mut config: Config, + ) -> Result<Self, ConfigError> { + config.swap_rx_tx = true; + config.half_duplex = true; + + Self::new_inner( + peri, + None, + None, + new_pin!(rx, AFType::OutputPushPull), + None, + None, + None, + None, + config, + ) + } +} + +impl<'d, M: Mode> Uart<'d, M> { + fn new_inner<T: Instance>( + _peri: impl Peripheral<P = T> + 'd, + rx: Option<PeripheralRef<'d, AnyPin>>, + tx: Option<PeripheralRef<'d, AnyPin>>, + rts: Option<PeripheralRef<'d, AnyPin>>, + cts: Option<PeripheralRef<'d, AnyPin>>, + de: Option<PeripheralRef<'d, AnyPin>>, + tx_dma: Option<ChannelAndRequest<'d>>, + rx_dma: Option<ChannelAndRequest<'d>>, + config: Config, + ) -> Result<Self, ConfigError> { + T::enable_and_reset(); + + let info = T::info(); + let state = T::state(); + let kernel_clock = T::frequency(); + let r = info.regs; + + r.cr3().write(|w| { + w.set_rtse(rts.is_some()); + w.set_ctse(cts.is_some()); + #[cfg(not(any(usart_v1, usart_v2)))] + w.set_dem(de.is_some()); + }); + configure(info, kernel_clock, &config, true, true)?; T::Interrupt::unpend(); unsafe { T::Interrupt::enable() }; - // create state once! - let _s = T::state(); + state.tx_rx_refcount.store(2, Ordering::Relaxed); Ok(Self { tx: UartTx { + _phantom: PhantomData, + info, + state, + kernel_clock, + tx, + cts, + de, tx_dma, - phantom: PhantomData, }, rx: UartRx { - _peri: peri, + _phantom: PhantomData, + info, + state, + kernel_clock, + rx, + rts, rx_dma, detect_previous_overrun: config.detect_previous_overrun, #[cfg(any(usart_v1, usart_v2))] @@ -964,14 +1274,6 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { }) } - /// Initiate an asynchronous write - pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> - where - TxDma: crate::usart::TxDma<T>, - { - self.tx.write(buffer).await - } - /// Perform a blocking write pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { self.tx.blocking_write(buffer) @@ -982,16 +1284,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { self.tx.blocking_flush() } - /// Initiate an asynchronous read into `buffer` - pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> - where - RxDma: crate::usart::RxDma<T>, - { - self.rx.read(buffer).await - } - /// Read a single `u8` or return `WouldBlock` - pub fn nb_read(&mut self) -> Result<u8, nb::Error<Error>> { + pub(crate) fn nb_read(&mut self) -> Result<u8, nb::Error<Error>> { self.rx.nb_read() } @@ -1000,43 +1294,37 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { self.rx.blocking_read(buffer) } - /// Initiate an an asynchronous read with idle line detection enabled - pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error> - where - RxDma: crate::usart::RxDma<T>, - { - self.rx.read_until_idle(buffer).await - } - /// Split the Uart into a transmitter and receiver, which is /// particularly useful when having two tasks correlating to /// transmitting and receiving. - pub fn split(self) -> (UartTx<'d, T, TxDma>, UartRx<'d, T, RxDma>) { + pub fn split(self) -> (UartTx<'d, M>, UartRx<'d, M>) { (self.tx, self.rx) } } -fn reconfigure<T: BasicInstance>(config: &Config) -> Result<(), ConfigError> { - T::Interrupt::disable(); - let r = T::regs(); +fn reconfigure(info: &Info, kernel_clock: Hertz, config: &Config) -> Result<(), ConfigError> { + info.interrupt.disable(); + let r = info.regs; let cr = r.cr1().read(); - configure(r, config, T::frequency(), T::KIND, cr.re(), cr.te())?; + configure(info, kernel_clock, config, cr.re(), cr.te())?; - T::Interrupt::unpend(); - unsafe { T::Interrupt::enable() }; + info.interrupt.unpend(); + unsafe { info.interrupt.enable() }; Ok(()) } fn configure( - r: Regs, + info: &Info, + kernel_clock: Hertz, config: &Config, - pclk_freq: Hertz, - kind: Kind, enable_rx: bool, enable_tx: bool, ) -> Result<(), ConfigError> { + let r = info.regs; + let kind = info.kind; + if !enable_rx && !enable_tx { return Err(ConfigError::RxOrTxNotEnabled); } @@ -1062,8 +1350,14 @@ fn configure( let (mul, brr_min, brr_max) = match kind { #[cfg(any(usart_v3, usart_v4))] - Kind::Lpuart => (256, 0x300, 0x10_0000), - Kind::Uart => (1, 0x10, 0x1_0000), + Kind::Lpuart => { + trace!("USART: Kind::Lpuart"); + (256, 0x300, 0x10_0000) + } + Kind::Uart => { + trace!("USART: Kind::Uart"); + (1, 0x10, 0x1_0000) + } }; fn calculate_brr(baud: u32, pclk: u32, presc: u32, mul: u32) -> u32 { @@ -1090,7 +1384,7 @@ fn configure( let mut over8 = false; let mut found_brr = None; for &(presc, _presc_val) in &DIVS { - let brr = calculate_brr(config.baudrate, pclk_freq.0, presc as u32, mul); + let brr = calculate_brr(config.baudrate, kernel_clock.0, presc as u32, mul); trace!( "USART: presc={}, div=0x{:08x} (mantissa = {}, fraction = {})", presc, @@ -1131,7 +1425,7 @@ fn configure( "Using {} oversampling, desired baudrate: {}, actual baudrate: {}", oversampling, config.baudrate, - pclk_freq.0 / brr * mul + kernel_clock.0 / brr * mul ); r.cr2().write(|w| { @@ -1150,9 +1444,10 @@ fn configure( } }); - #[cfg(not(usart_v1))] r.cr3().modify(|w| { + #[cfg(not(usart_v1))] w.set_onebit(config.assume_noise_free); + w.set_hdsel(config.half_duplex); }); r.cr1().write(|w| { @@ -1165,34 +1460,48 @@ fn configure( // configure word size // if using odd or even parity it must be configured to 9bits w.set_m0(if config.parity != Parity::ParityNone { + trace!("USART: m0: vals::M0::BIT9"); vals::M0::BIT9 } else { + trace!("USART: m0: vals::M0::BIT8"); vals::M0::BIT8 }); // configure parity w.set_pce(config.parity != Parity::ParityNone); w.set_ps(match config.parity { - Parity::ParityOdd => vals::Ps::ODD, - Parity::ParityEven => vals::Ps::EVEN, - _ => vals::Ps::EVEN, + Parity::ParityOdd => { + trace!("USART: set_ps: vals::Ps::ODD"); + vals::Ps::ODD + } + Parity::ParityEven => { + trace!("USART: set_ps: vals::Ps::EVEN"); + vals::Ps::EVEN + } + _ => { + trace!("USART: set_ps: vals::Ps::EVEN"); + vals::Ps::EVEN + } }); #[cfg(not(usart_v1))] w.set_over8(vals::Over8::from_bits(over8 as _)); #[cfg(usart_v4)] - w.set_fifoen(true); + { + trace!("USART: set_fifoen: true (usart_v4)"); + w.set_fifoen(true); + } }); Ok(()) } -impl<'d, T: BasicInstance, RxDma> embedded_hal_02::serial::Read<u8> for UartRx<'d, T, RxDma> { +impl<'d, M: Mode> embedded_hal_02::serial::Read<u8> for UartRx<'d, M> { type Error = Error; fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { self.nb_read() } } -impl<'d, T: BasicInstance, TxDma> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, T, TxDma> { +impl<'d, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, M> { type Error = Error; fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { self.blocking_write(buffer) @@ -1202,14 +1511,14 @@ impl<'d, T: BasicInstance, TxDma> embedded_hal_02::blocking::serial::Write<u8> f } } -impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_02::serial::Read<u8> for Uart<'d, T, TxDma, RxDma> { +impl<'d, M: Mode> embedded_hal_02::serial::Read<u8> for Uart<'d, M> { type Error = Error; fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { self.nb_read() } } -impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, T, TxDma, RxDma> { +impl<'d, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, M> { type Error = Error; fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { self.blocking_write(buffer) @@ -1231,25 +1540,25 @@ impl embedded_hal_nb::serial::Error for Error { } } -impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_nb::serial::ErrorType for Uart<'d, T, TxDma, RxDma> { +impl<'d, M: Mode> embedded_hal_nb::serial::ErrorType for Uart<'d, M> { type Error = Error; } -impl<'d, T: BasicInstance, TxDma> embedded_hal_nb::serial::ErrorType for UartTx<'d, T, TxDma> { +impl<'d, M: Mode> embedded_hal_nb::serial::ErrorType for UartTx<'d, M> { type Error = Error; } -impl<'d, T: BasicInstance, RxDma> embedded_hal_nb::serial::ErrorType for UartRx<'d, T, RxDma> { +impl<'d, M: Mode> embedded_hal_nb::serial::ErrorType for UartRx<'d, M> { type Error = Error; } -impl<'d, T: BasicInstance, RxDma> embedded_hal_nb::serial::Read for UartRx<'d, T, RxDma> { +impl<'d, M: Mode> embedded_hal_nb::serial::Read for UartRx<'d, M> { fn read(&mut self) -> nb::Result<u8, Self::Error> { self.nb_read() } } -impl<'d, T: BasicInstance, TxDma> embedded_hal_nb::serial::Write for UartTx<'d, T, TxDma> { +impl<'d, M: Mode> embedded_hal_nb::serial::Write for UartTx<'d, M> { fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { self.blocking_write(&[char]).map_err(nb::Error::Other) } @@ -1259,13 +1568,13 @@ impl<'d, T: BasicInstance, TxDma> embedded_hal_nb::serial::Write for UartTx<'d, } } -impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_nb::serial::Read for Uart<'d, T, TxDma, RxDma> { +impl<'d, M: Mode> embedded_hal_nb::serial::Read for Uart<'d, M> { fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { self.nb_read() } } -impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_nb::serial::Write for Uart<'d, T, TxDma, RxDma> { +impl<'d, M: Mode> embedded_hal_nb::serial::Write for Uart<'d, M> { fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { self.blocking_write(&[char]).map_err(nb::Error::Other) } @@ -1281,24 +1590,15 @@ impl embedded_io::Error for Error { } } -impl<T, TxDma, RxDma> embedded_io::ErrorType for Uart<'_, T, TxDma, RxDma> -where - T: BasicInstance, -{ +impl<M: Mode> embedded_io::ErrorType for Uart<'_, M> { type Error = Error; } -impl<T, TxDma> embedded_io::ErrorType for UartTx<'_, T, TxDma> -where - T: BasicInstance, -{ +impl<M: Mode> embedded_io::ErrorType for UartTx<'_, M> { type Error = Error; } -impl<T, TxDma, RxDma> embedded_io::Write for Uart<'_, T, TxDma, RxDma> -where - T: BasicInstance, -{ +impl<M: Mode> embedded_io::Write for Uart<'_, M> { fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { self.blocking_write(buf)?; Ok(buf.len()) @@ -1309,10 +1609,7 @@ where } } -impl<T, TxDma> embedded_io::Write for UartTx<'_, T, TxDma> -where - T: BasicInstance, -{ +impl<M: Mode> embedded_io::Write for UartTx<'_, M> { fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { self.blocking_write(buf)?; Ok(buf.len()) @@ -1323,11 +1620,7 @@ where } } -impl<T, TxDma, RxDma> embedded_io_async::Write for Uart<'_, T, TxDma, RxDma> -where - T: BasicInstance, - TxDma: self::TxDma<T>, -{ +impl embedded_io_async::Write for Uart<'_, Async> { async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { self.write(buf).await?; Ok(buf.len()) @@ -1338,11 +1631,7 @@ where } } -impl<T, TxDma> embedded_io_async::Write for UartTx<'_, T, TxDma> -where - T: BasicInstance, - TxDma: self::TxDma<T>, -{ +impl embedded_io_async::Write for UartTx<'_, Async> { async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { self.write(buf).await?; Ok(buf.len()) @@ -1415,72 +1704,75 @@ enum Kind { struct State { rx_waker: AtomicWaker, + tx_rx_refcount: AtomicU8, } impl State { const fn new() -> Self { Self { rx_waker: AtomicWaker::new(), + tx_rx_refcount: AtomicU8::new(0), } } } -trait SealedBasicInstance: crate::rcc::RccPeripheral { - const KIND: Kind; +struct Info { + regs: Regs, + enable_bit: ClockEnableBit, + interrupt: Interrupt, + kind: Kind, +} - fn regs() -> Regs; +#[allow(private_interfaces)] +pub(crate) trait SealedInstance: crate::rcc::RccPeripheral { + fn info() -> &'static Info; fn state() -> &'static State; - fn buffered_state() -> &'static buffered::State; } -trait SealedFullInstance: SealedBasicInstance { - #[allow(unused)] - fn regs_uart() -> crate::pac::usart::Usart; -} - -/// Basic UART driver instance +/// USART peripheral instance trait. #[allow(private_bounds)] -pub trait BasicInstance: Peripheral<P = Self> + SealedBasicInstance + 'static + Send { - /// Interrupt for this instance. +pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { + /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } -/// Full UART driver instance -#[allow(private_bounds)] -pub trait FullInstance: SealedFullInstance {} +pin_trait!(RxPin, Instance); +pin_trait!(TxPin, Instance); +pin_trait!(CtsPin, Instance); +pin_trait!(RtsPin, Instance); +pin_trait!(CkPin, Instance); +pin_trait!(DePin, Instance); -pin_trait!(RxPin, BasicInstance); -pin_trait!(TxPin, BasicInstance); -pin_trait!(CtsPin, BasicInstance); -pin_trait!(RtsPin, BasicInstance); -pin_trait!(CkPin, BasicInstance); -pin_trait!(DePin, BasicInstance); - -dma_trait!(TxDma, BasicInstance); -dma_trait!(RxDma, BasicInstance); +dma_trait!(TxDma, Instance); +dma_trait!(RxDma, Instance); macro_rules! impl_usart { ($inst:ident, $irq:ident, $kind:expr) => { - impl SealedBasicInstance for crate::peripherals::$inst { - const KIND: Kind = $kind; - - fn regs() -> Regs { - unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) } + #[allow(private_interfaces)] + impl SealedInstance for crate::peripherals::$inst { + fn info() -> &'static Info { + static INFO: Info = Info { + regs: unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) }, + enable_bit: crate::peripherals::$inst::ENABLE_BIT, + interrupt: crate::interrupt::typelevel::$irq::IRQ, + kind: $kind, + }; + &INFO } - fn state() -> &'static crate::usart::State { - static STATE: crate::usart::State = crate::usart::State::new(); + fn state() -> &'static State { + static STATE: State = State::new(); &STATE } fn buffered_state() -> &'static buffered::State { - static STATE: buffered::State = buffered::State::new(); - &STATE + static BUFFERED_STATE: buffered::State = buffered::State::new(); + &BUFFERED_STATE } } - impl BasicInstance for peripherals::$inst { + impl Instance for crate::peripherals::$inst { type Interrupt = crate::interrupt::typelevel::$irq; } }; @@ -1490,16 +1782,7 @@ foreach_interrupt!( ($inst:ident, usart, LPUART, $signal_name:ident, $irq:ident) => { impl_usart!($inst, $irq, Kind::Lpuart); }; - ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => { impl_usart!($inst, $irq, Kind::Uart); - - impl SealedFullInstance for peripherals::$inst { - fn regs_uart() -> crate::pac::usart::Usart { - crate::pac::$inst - } - } - - impl FullInstance for peripherals::$inst {} }; ); diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index b852f0176..f3a88b93f 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs @@ -4,22 +4,25 @@ use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy_embedded_hal::SetConfig; -use embassy_hal_internal::PeripheralRef; -use futures::future::{select, Either}; +use futures_util::future::{select, Either}; -use super::{clear_interrupt_flags, rdr, reconfigure, sr, BasicInstance, Config, ConfigError, Error, UartRx}; +use super::{clear_interrupt_flags, rdr, reconfigure, sr, Config, ConfigError, Error, Info, State, UartRx}; use crate::dma::ReadableRingBuffer; +use crate::mode::Async; +use crate::time::Hertz; use crate::usart::{Regs, Sr}; /// Rx-only Ring-buffered UART Driver /// /// Created with [UartRx::into_ring_buffered] -pub struct RingBufferedUartRx<'d, T: BasicInstance> { - _peri: PeripheralRef<'d, T>, +pub struct RingBufferedUartRx<'d> { + info: &'static Info, + state: &'static State, + kernel_clock: Hertz, ring_buf: ReadableRingBuffer<'d, u8>, } -impl<'d, T: BasicInstance> SetConfig for RingBufferedUartRx<'d, T> { +impl<'d> SetConfig for RingBufferedUartRx<'d> { type Config = Config; type ConfigError = ConfigError; @@ -28,30 +31,38 @@ impl<'d, T: BasicInstance> SetConfig for RingBufferedUartRx<'d, T> { } } -impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> UartRx<'d, T, RxDma> { +impl<'d> UartRx<'d, Async> { /// Turn the `UartRx` into a buffered uart which can continously receive in the background /// without the possibility of losing bytes. The `dma_buf` is a buffer registered to the /// DMA controller, and must be large enough to prevent overflows. - pub fn into_ring_buffered(self, dma_buf: &'d mut [u8]) -> RingBufferedUartRx<'d, T> { + pub fn into_ring_buffered(mut self, dma_buf: &'d mut [u8]) -> RingBufferedUartRx<'d> { assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); - let request = self.rx_dma.request(); let opts = Default::default(); // Safety: we forget the struct before this function returns. - let rx_dma = unsafe { self.rx_dma.clone_unchecked() }; - let _peri = unsafe { self._peri.clone_unchecked() }; + let rx_dma = self.rx_dma.as_mut().unwrap(); + let request = rx_dma.request; + let rx_dma = unsafe { rx_dma.channel.clone_unchecked() }; - let ring_buf = unsafe { ReadableRingBuffer::new(rx_dma, request, rdr(T::regs()), dma_buf, opts) }; + let info = self.info; + let state = self.state; + let kernel_clock = self.kernel_clock; + let ring_buf = unsafe { ReadableRingBuffer::new(rx_dma, request, rdr(info.regs), dma_buf, opts) }; // Don't disable the clock mem::forget(self); - RingBufferedUartRx { _peri, ring_buf } + RingBufferedUartRx { + info, + state, + kernel_clock, + ring_buf, + } } } -impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> { +impl<'d> RingBufferedUartRx<'d> { /// Clear the ring buffer and start receiving in the background pub fn start(&mut self) -> Result<(), Error> { // Clear the ring buffer so that it is ready to receive data @@ -68,10 +79,9 @@ impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> { Err(err) } - /// Cleanly stop and reconfigure the driver + /// Reconfigure the driver pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - self.teardown_uart(); - reconfigure::<T>(config) + reconfigure(self.info, self.kernel_clock, config) } /// Start uart background receive @@ -82,7 +92,7 @@ impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> { // start the dma controller self.ring_buf.start(); - let r = T::regs(); + let r = self.info.regs; // clear all interrupts and DMA Rx Request r.cr1().modify(|w| { // disable RXNE interrupt @@ -104,7 +114,7 @@ impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> { fn teardown_uart(&mut self) { self.ring_buf.request_stop(); - let r = T::regs(); + let r = self.info.regs; // clear all interrupts and DMA Rx Request r.cr1().modify(|w| { // disable RXNE interrupt @@ -133,14 +143,14 @@ impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> { /// Receive in the background is terminated if an error is returned. /// It must then manually be started again by calling `start()` or by re-calling `read()`. pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { - let r = T::regs(); + let r = self.info.regs; // Start background receive if it was not already started if !r.cr3().read().dmar() { self.start()?; } - check_for_errors(clear_idle_flag(T::regs()))?; + check_for_errors(clear_idle_flag(r))?; loop { match self.ring_buf.read(buf) { @@ -181,15 +191,15 @@ impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> { }); // Future which completes when idle line is detected + let s = self.state; let uart = poll_fn(|cx| { - let s = T::state(); s.rx_waker.register(cx.waker()); compiler_fence(Ordering::SeqCst); // Critical section is needed so that IDLE isn't set after // our read but before we clear it. - let sr = critical_section::with(|_| clear_idle_flag(T::regs())); + let sr = critical_section::with(|_| clear_idle_flag(self.info.regs)); check_for_errors(sr)?; @@ -208,13 +218,13 @@ impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> { } } -impl<T: BasicInstance> Drop for RingBufferedUartRx<'_, T> { +impl Drop for RingBufferedUartRx<'_> { fn drop(&mut self) { self.teardown_uart(); - - T::disable(); + super::drop_tx_rx(self.info, self.state); } } + /// Return an error result if the Sr register has errors fn check_for_errors(s: Sr) -> Result<(), Error> { if s.pe() { @@ -245,17 +255,11 @@ fn clear_idle_flag(r: Regs) -> Sr { sr } -impl<T> embedded_io_async::ErrorType for RingBufferedUartRx<'_, T> -where - T: BasicInstance, -{ +impl embedded_io_async::ErrorType for RingBufferedUartRx<'_> { type Error = Error; } -impl<T> embedded_io_async::Read for RingBufferedUartRx<'_, T> -where - T: BasicInstance, -{ +impl embedded_io_async::Read for RingBufferedUartRx<'_> { async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { self.read(buf).await } diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs index 1e3c44167..349438ec5 100644 --- a/embassy-stm32/src/usb/mod.rs +++ b/embassy-stm32/src/usb/mod.rs @@ -23,7 +23,7 @@ fn common_init<T: Instance>() { ) } - #[cfg(any(stm32l4, stm32l5, stm32wb))] + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32u0))] critical_section::with(|_| crate::pac::PWR.cr2().modify(|w| w.set_usv(true))); #[cfg(pwr_h5)] diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs index b0e7067bd..3debd5079 100644 --- a/embassy-stm32/src/usb/otg.rs +++ b/embassy-stm32/src/usb/otg.rs @@ -1,22 +1,21 @@ -use core::cell::UnsafeCell; use core::marker::PhantomData; -use core::sync::atomic::{AtomicBool, AtomicU16, Ordering}; -use core::task::Poll; use embassy_hal_internal::{into_ref, Peripheral}; -use embassy_sync::waitqueue::AtomicWaker; -use embassy_usb_driver::{ - Bus as _, Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointIn, EndpointInfo, EndpointOut, - EndpointType, Event, Unsupported, +use embassy_usb_driver::{EndpointAddress, EndpointAllocError, EndpointType, Event, Unsupported}; +use embassy_usb_synopsys_otg::otg_v1::vals::Dspd; +use embassy_usb_synopsys_otg::otg_v1::Otg; +pub use embassy_usb_synopsys_otg::Config; +use embassy_usb_synopsys_otg::{ + on_interrupt as on_interrupt_impl, Bus as OtgBus, ControlPipe, Driver as OtgDriver, Endpoint, In, OtgInstance, Out, + PhyType, State, }; -use futures::future::poll_fn; use crate::gpio::AFType; use crate::interrupt; use crate::interrupt::typelevel::Interrupt; -use crate::pac::otg::{regs, vals}; use crate::rcc::{RccPeripheral, SealedRccPeripheral}; -use crate::time::Hertz; + +const MAX_EP_COUNT: usize = 9; /// Interrupt handler. pub struct InterruptHandler<T: Instance> { @@ -29,142 +28,9 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl let r = T::regs(); let state = T::state(); - let ints = r.gintsts().read(); - if ints.wkupint() || ints.usbsusp() || ints.usbrst() || ints.enumdne() || ints.otgint() || ints.srqint() { - // Mask interrupts and notify `Bus` to process them - r.gintmsk().write(|_| {}); - T::state().bus_waker.wake(); - } + let setup_late_cnak = quirk_setup_late_cnak(r); - // Handle RX - while r.gintsts().read().rxflvl() { - let status = r.grxstsp().read(); - trace!("=== status {:08x}", status.0); - let ep_num = status.epnum() as usize; - let len = status.bcnt() as usize; - - assert!(ep_num < T::ENDPOINT_COUNT); - - match status.pktstsd() { - vals::Pktstsd::SETUP_DATA_RX => { - trace!("SETUP_DATA_RX"); - assert!(len == 8, "invalid SETUP packet length={}", len); - assert!(ep_num == 0, "invalid SETUP packet endpoint={}", ep_num); - - // flushing TX if something stuck in control endpoint - if r.dieptsiz(ep_num).read().pktcnt() != 0 { - r.grstctl().modify(|w| { - w.set_txfnum(ep_num as _); - w.set_txfflsh(true); - }); - while r.grstctl().read().txfflsh() {} - } - - if state.ep0_setup_ready.load(Ordering::Relaxed) == false { - // SAFETY: exclusive access ensured by atomic bool - let data = unsafe { &mut *state.ep0_setup_data.get() }; - data[0..4].copy_from_slice(&r.fifo(0).read().0.to_ne_bytes()); - data[4..8].copy_from_slice(&r.fifo(0).read().0.to_ne_bytes()); - state.ep0_setup_ready.store(true, Ordering::Release); - state.ep_out_wakers[0].wake(); - } else { - error!("received SETUP before previous finished processing"); - // discard FIFO - r.fifo(0).read(); - r.fifo(0).read(); - } - } - vals::Pktstsd::OUT_DATA_RX => { - trace!("OUT_DATA_RX ep={} len={}", ep_num, len); - - if state.ep_out_size[ep_num].load(Ordering::Acquire) == EP_OUT_BUFFER_EMPTY { - // SAFETY: Buffer size is allocated to be equal to endpoint's maximum packet size - // We trust the peripheral to not exceed its configured MPSIZ - let buf = unsafe { core::slice::from_raw_parts_mut(*state.ep_out_buffers[ep_num].get(), len) }; - - for chunk in buf.chunks_mut(4) { - // RX FIFO is shared so always read from fifo(0) - let data = r.fifo(0).read().0; - chunk.copy_from_slice(&data.to_ne_bytes()[0..chunk.len()]); - } - - state.ep_out_size[ep_num].store(len as u16, Ordering::Release); - state.ep_out_wakers[ep_num].wake(); - } else { - error!("ep_out buffer overflow index={}", ep_num); - - // discard FIFO data - let len_words = (len + 3) / 4; - for _ in 0..len_words { - r.fifo(0).read().data(); - } - } - } - vals::Pktstsd::OUT_DATA_DONE => { - trace!("OUT_DATA_DONE ep={}", ep_num); - } - vals::Pktstsd::SETUP_DATA_DONE => { - trace!("SETUP_DATA_DONE ep={}", ep_num); - - if quirk_setup_late_cnak(r) { - // Clear NAK to indicate we are ready to receive more data - r.doepctl(ep_num).modify(|w| w.set_cnak(true)); - } - } - x => trace!("unknown PKTSTS: {}", x.to_bits()), - } - } - - // IN endpoint interrupt - if ints.iepint() { - let mut ep_mask = r.daint().read().iepint(); - let mut ep_num = 0; - - // Iterate over endpoints while there are non-zero bits in the mask - while ep_mask != 0 { - if ep_mask & 1 != 0 { - let ep_ints = r.diepint(ep_num).read(); - - // clear all - r.diepint(ep_num).write_value(ep_ints); - - // TXFE is cleared in DIEPEMPMSK - if ep_ints.txfe() { - critical_section::with(|_| { - r.diepempmsk().modify(|w| { - w.set_ineptxfem(w.ineptxfem() & !(1 << ep_num)); - }); - }); - } - - state.ep_in_wakers[ep_num].wake(); - trace!("in ep={} irq val={:08x}", ep_num, ep_ints.0); - } - - ep_mask >>= 1; - ep_num += 1; - } - } - - // not needed? reception handled in rxflvl - // OUT endpoint interrupt - // if ints.oepint() { - // let mut ep_mask = r.daint().read().oepint(); - // let mut ep_num = 0; - - // while ep_mask != 0 { - // if ep_mask & 1 != 0 { - // let ep_ints = r.doepint(ep_num).read(); - // // clear all - // r.doepint(ep_num).write_value(ep_ints); - // state.ep_out_wakers[ep_num].wake(); - // trace!("out ep={} irq val={:08x}", ep_num, ep_ints.0); - // } - - // ep_mask >>= 1; - // ep_num += 1; - // } - // } + on_interrupt_impl(r, state, T::ENDPOINT_COUNT, setup_late_cnak); } } @@ -187,129 +53,10 @@ macro_rules! config_ulpi_pins { // The following numbers are pessimistic and were figured out empirically. const RX_FIFO_EXTRA_SIZE_WORDS: u16 = 30; -/// USB PHY type -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum PhyType { - /// Internal Full-Speed PHY - /// - /// Available on most High-Speed peripherals. - InternalFullSpeed, - /// Internal High-Speed PHY - /// - /// Available on a few STM32 chips. - InternalHighSpeed, - /// External ULPI High-Speed PHY - ExternalHighSpeed, -} - -impl PhyType { - /// Get whether this PHY is any of the internal types. - pub fn internal(&self) -> bool { - match self { - PhyType::InternalFullSpeed | PhyType::InternalHighSpeed => true, - PhyType::ExternalHighSpeed => false, - } - } - - /// Get whether this PHY is any of the high-speed types. - pub fn high_speed(&self) -> bool { - match self { - PhyType::InternalFullSpeed => false, - PhyType::ExternalHighSpeed | PhyType::InternalHighSpeed => true, - } - } - - fn to_dspd(&self) -> vals::Dspd { - match self { - PhyType::InternalFullSpeed => vals::Dspd::FULL_SPEED_INTERNAL, - PhyType::InternalHighSpeed => vals::Dspd::HIGH_SPEED, - PhyType::ExternalHighSpeed => vals::Dspd::HIGH_SPEED, - } - } -} - -/// Indicates that [State::ep_out_buffers] is empty. -const EP_OUT_BUFFER_EMPTY: u16 = u16::MAX; - -/// USB OTG driver state. -pub struct State<const EP_COUNT: usize> { - /// Holds received SETUP packets. Available if [State::ep0_setup_ready] is true. - ep0_setup_data: UnsafeCell<[u8; 8]>, - ep0_setup_ready: AtomicBool, - ep_in_wakers: [AtomicWaker; EP_COUNT], - ep_out_wakers: [AtomicWaker; EP_COUNT], - /// RX FIFO is shared so extra buffers are needed to dequeue all data without waiting on each endpoint. - /// Buffers are ready when associated [State::ep_out_size] != [EP_OUT_BUFFER_EMPTY]. - ep_out_buffers: [UnsafeCell<*mut u8>; EP_COUNT], - ep_out_size: [AtomicU16; EP_COUNT], - bus_waker: AtomicWaker, -} - -unsafe impl<const EP_COUNT: usize> Send for State<EP_COUNT> {} -unsafe impl<const EP_COUNT: usize> Sync for State<EP_COUNT> {} - -impl<const EP_COUNT: usize> State<EP_COUNT> { - /// Create a new State. - pub const fn new() -> Self { - const NEW_AW: AtomicWaker = AtomicWaker::new(); - const NEW_BUF: UnsafeCell<*mut u8> = UnsafeCell::new(0 as _); - const NEW_SIZE: AtomicU16 = AtomicU16::new(EP_OUT_BUFFER_EMPTY); - - Self { - ep0_setup_data: UnsafeCell::new([0u8; 8]), - ep0_setup_ready: AtomicBool::new(false), - ep_in_wakers: [NEW_AW; EP_COUNT], - ep_out_wakers: [NEW_AW; EP_COUNT], - ep_out_buffers: [NEW_BUF; EP_COUNT], - ep_out_size: [NEW_SIZE; EP_COUNT], - bus_waker: NEW_AW, - } - } -} - -#[derive(Debug, Clone, Copy)] -struct EndpointData { - ep_type: EndpointType, - max_packet_size: u16, - fifo_size_words: u16, -} - -/// USB driver config. -#[non_exhaustive] -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct Config { - /// Enable VBUS detection. - /// - /// The USB spec requires USB devices monitor for USB cable plug/unplug and react accordingly. - /// This is done by checkihg whether there is 5V on the VBUS pin or not. - /// - /// If your device is bus-powered (powers itself from the USB host via VBUS), then this is optional. - /// (if there's no power in VBUS your device would be off anyway, so it's fine to always assume - /// there's power in VBUS, i.e. the USB cable is always plugged in.) - /// - /// If your device is self-powered (i.e. it gets power from a source other than the USB cable, and - /// therefore can stay powered through USB cable plug/unplug) then you MUST set this to true. - /// - /// If you set this to true, you must connect VBUS to PA9 for FS, PB13 for HS, possibly with a - /// voltage divider. See ST application note AN4879 and the reference manual for more details. - pub vbus_detection: bool, -} - -impl Default for Config { - fn default() -> Self { - Self { vbus_detection: true } - } -} - /// USB driver. pub struct Driver<'d, T: Instance> { - config: Config, phantom: PhantomData<&'d mut T>, - ep_in: [Option<EndpointData>; MAX_EP_COUNT], - ep_out: [Option<EndpointData>; MAX_EP_COUNT], - ep_out_buffer: &'d mut [u8], - ep_out_buffer_offset: usize, - phy_type: PhyType, + inner: OtgDriver<'d, MAX_EP_COUNT>, } impl<'d, T: Instance> Driver<'d, T> { @@ -317,7 +64,7 @@ impl<'d, T: Instance> Driver<'d, T> { /// /// # Arguments /// - /// * `ep_out_buffer` - An internal buffer used to temporarily store recevied packets. + /// * `ep_out_buffer` - An internal buffer used to temporarily store received packets. /// Must be large enough to fit all OUT endpoint max packet sizes. /// Endpoint allocation will fail if it is too small. pub fn new_fs( @@ -333,14 +80,22 @@ impl<'d, T: Instance> Driver<'d, T> { dp.set_as_af(dp.af_num(), AFType::OutputPushPull); dm.set_as_af(dm.af_num(), AFType::OutputPushPull); - Self { - config, - phantom: PhantomData, - ep_in: [None; MAX_EP_COUNT], - ep_out: [None; MAX_EP_COUNT], - ep_out_buffer, - ep_out_buffer_offset: 0, + let regs = T::regs(); + + let instance = OtgInstance { + regs, + state: T::state(), + fifo_depth_words: T::FIFO_DEPTH_WORDS, + extra_rx_fifo_words: RX_FIFO_EXTRA_SIZE_WORDS, + endpoint_count: T::ENDPOINT_COUNT, phy_type: PhyType::InternalFullSpeed, + quirk_setup_late_cnak: quirk_setup_late_cnak(regs), + calculate_trdt_fn: calculate_trdt::<T>, + }; + + Self { + inner: OtgDriver::new(ep_out_buffer, instance, config), + phantom: PhantomData, } } @@ -348,7 +103,7 @@ impl<'d, T: Instance> Driver<'d, T> { /// /// # Arguments /// - /// * `ep_out_buffer` - An internal buffer used to temporarily store recevied packets. + /// * `ep_out_buffer` - An internal buffer used to temporarily store received packets. /// Must be large enough to fit all OUT endpoint max packet sizes. /// Endpoint allocation will fail if it is too small. pub fn new_hs_ulpi( @@ -376,111 +131,30 @@ impl<'d, T: Instance> Driver<'d, T> { ulpi_d7 ); - Self { - config, - phantom: PhantomData, - ep_in: [None; MAX_EP_COUNT], - ep_out: [None; MAX_EP_COUNT], - ep_out_buffer, - ep_out_buffer_offset: 0, + let regs = T::regs(); + + let instance = OtgInstance { + regs: T::regs(), + state: T::state(), + fifo_depth_words: T::FIFO_DEPTH_WORDS, + extra_rx_fifo_words: RX_FIFO_EXTRA_SIZE_WORDS, + endpoint_count: T::ENDPOINT_COUNT, phy_type: PhyType::ExternalHighSpeed, + quirk_setup_late_cnak: quirk_setup_late_cnak(regs), + calculate_trdt_fn: calculate_trdt::<T>, + }; + + Self { + inner: OtgDriver::new(ep_out_buffer, instance, config), + phantom: PhantomData, } } - - // Returns total amount of words (u32) allocated in dedicated FIFO - fn allocated_fifo_words(&self) -> u16 { - RX_FIFO_EXTRA_SIZE_WORDS + ep_fifo_size(&self.ep_out) + ep_fifo_size(&self.ep_in) - } - - fn alloc_endpoint<D: Dir>( - &mut self, - ep_type: EndpointType, - max_packet_size: u16, - interval_ms: u8, - ) -> Result<Endpoint<'d, T, D>, EndpointAllocError> { - trace!( - "allocating type={:?} mps={:?} interval_ms={}, dir={:?}", - ep_type, - max_packet_size, - interval_ms, - D::dir() - ); - - if D::dir() == Direction::Out { - if self.ep_out_buffer_offset + max_packet_size as usize >= self.ep_out_buffer.len() { - error!("Not enough endpoint out buffer capacity"); - return Err(EndpointAllocError); - } - }; - - let fifo_size_words = match D::dir() { - Direction::Out => (max_packet_size + 3) / 4, - // INEPTXFD requires minimum size of 16 words - Direction::In => u16::max((max_packet_size + 3) / 4, 16), - }; - - if fifo_size_words + self.allocated_fifo_words() > T::FIFO_DEPTH_WORDS { - error!("Not enough FIFO capacity"); - return Err(EndpointAllocError); - } - - let eps = match D::dir() { - Direction::Out => &mut self.ep_out, - Direction::In => &mut self.ep_in, - }; - - // Find free endpoint slot - let slot = eps.iter_mut().enumerate().find(|(i, ep)| { - if *i == 0 && ep_type != EndpointType::Control { - // reserved for control pipe - false - } else { - ep.is_none() - } - }); - - let index = match slot { - Some((index, ep)) => { - *ep = Some(EndpointData { - ep_type, - max_packet_size, - fifo_size_words, - }); - index - } - None => { - error!("No free endpoints available"); - return Err(EndpointAllocError); - } - }; - - trace!(" index={}", index); - - if D::dir() == Direction::Out { - // Buffer capacity check was done above, now allocation cannot fail - unsafe { - *T::state().ep_out_buffers[index].get() = - self.ep_out_buffer.as_mut_ptr().offset(self.ep_out_buffer_offset as _); - } - self.ep_out_buffer_offset += max_packet_size as usize; - } - - Ok(Endpoint { - _phantom: PhantomData, - info: EndpointInfo { - addr: EndpointAddress::from_parts(index, D::dir()), - ep_type, - max_packet_size, - interval_ms, - }, - }) - } } impl<'d, T: Instance> embassy_usb_driver::Driver<'d> for Driver<'d, T> { - type EndpointOut = Endpoint<'d, T, Out>; - type EndpointIn = Endpoint<'d, T, In>; - type ControlPipe = ControlPipe<'d, T>; + type EndpointOut = Endpoint<'d, Out>; + type EndpointIn = Endpoint<'d, In>; + type ControlPipe = ControlPipe<'d>; type Bus = Bus<'d, T>; fn alloc_endpoint_in( @@ -489,7 +163,7 @@ impl<'d, T: Instance> embassy_usb_driver::Driver<'d> for Driver<'d, T> { max_packet_size: u16, interval_ms: u8, ) -> Result<Self::EndpointIn, EndpointAllocError> { - self.alloc_endpoint(ep_type, max_packet_size, interval_ms) + self.inner.alloc_endpoint_in(ep_type, max_packet_size, interval_ms) } fn alloc_endpoint_out( @@ -498,115 +172,58 @@ impl<'d, T: Instance> embassy_usb_driver::Driver<'d> for Driver<'d, T> { max_packet_size: u16, interval_ms: u8, ) -> Result<Self::EndpointOut, EndpointAllocError> { - self.alloc_endpoint(ep_type, max_packet_size, interval_ms) + self.inner.alloc_endpoint_out(ep_type, max_packet_size, interval_ms) } - fn start(mut self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { - let ep_out = self - .alloc_endpoint(EndpointType::Control, control_max_packet_size, 0) - .unwrap(); - let ep_in = self - .alloc_endpoint(EndpointType::Control, control_max_packet_size, 0) - .unwrap(); - assert_eq!(ep_out.info.addr.index(), 0); - assert_eq!(ep_in.info.addr.index(), 0); - - trace!("start"); + fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { + let (bus, cp) = self.inner.start(control_max_packet_size); ( Bus { - config: self.config, phantom: PhantomData, - ep_in: self.ep_in, - ep_out: self.ep_out, - phy_type: self.phy_type, + inner: bus, inited: false, }, - ControlPipe { - _phantom: PhantomData, - max_packet_size: control_max_packet_size, - ep_out, - ep_in, - }, + cp, ) } } /// USB bus. pub struct Bus<'d, T: Instance> { - config: Config, phantom: PhantomData<&'d mut T>, - ep_in: [Option<EndpointData>; MAX_EP_COUNT], - ep_out: [Option<EndpointData>; MAX_EP_COUNT], - phy_type: PhyType, + inner: OtgBus<'d, MAX_EP_COUNT>, inited: bool, } -impl<'d, T: Instance> Bus<'d, T> { - fn restore_irqs() { - T::regs().gintmsk().write(|w| { - w.set_usbrst(true); - w.set_enumdnem(true); - w.set_usbsuspm(true); - w.set_wuim(true); - w.set_iepint(true); - w.set_oepint(true); - w.set_rxflvlm(true); - w.set_srqim(true); - w.set_otgint(true); - }); - } -} - impl<'d, T: Instance> Bus<'d, T> { fn init(&mut self) { super::common_init::<T>(); - #[cfg(stm32f7)] - { - // Enable ULPI clock if external PHY is used - let ulpien = !self.phy_type.internal(); - critical_section::with(|_| { - crate::pac::RCC.ahb1enr().modify(|w| { - if T::HIGH_SPEED { - w.set_usb_otg_hsulpien(ulpien); - } else { - w.set_usb_otg_hsen(ulpien); - } - }); + // Enable ULPI clock if external PHY is used + let phy_type = self.inner.phy_type(); + let _ulpien = !phy_type.internal(); - // Low power mode - crate::pac::RCC.ahb1lpenr().modify(|w| { - if T::HIGH_SPEED { - w.set_usb_otg_hsulpilpen(ulpien); - } else { - w.set_usb_otg_hslpen(ulpien); - } - }); + #[cfg(any(stm32f2, stm32f4, stm32f7))] + if T::HIGH_SPEED { + critical_section::with(|_| { + let rcc = crate::pac::RCC; + rcc.ahb1enr().modify(|w| w.set_usb_otg_hsulpien(_ulpien)); + rcc.ahb1lpenr().modify(|w| w.set_usb_otg_hsulpilpen(_ulpien)); }); } #[cfg(stm32h7)] - { - // Enable ULPI clock if external PHY is used - let ulpien = !self.phy_type.internal(); - critical_section::with(|_| { - crate::pac::RCC.ahb1enr().modify(|w| { - if T::HIGH_SPEED { - w.set_usb_otg_hs_ulpien(ulpien); - } else { - w.set_usb_otg_fs_ulpien(ulpien); - } - }); - crate::pac::RCC.ahb1lpenr().modify(|w| { - if T::HIGH_SPEED { - w.set_usb_otg_hs_ulpilpen(ulpien); - } else { - w.set_usb_otg_fs_ulpilpen(ulpien); - } - }); - }); - } + critical_section::with(|_| { + let rcc = crate::pac::RCC; + if T::HIGH_SPEED { + rcc.ahb1enr().modify(|w| w.set_usb_otg_hs_ulpien(_ulpien)); + rcc.ahb1lpenr().modify(|w| w.set_usb_otg_hs_ulpilpen(_ulpien)); + } else { + rcc.ahb1enr().modify(|w| w.set_usb_otg_fs_ulpien(_ulpien)); + rcc.ahb1lpenr().modify(|w| w.set_usb_otg_fs_ulpilpen(_ulpien)); + } + }); let r = T::regs(); let core_id = r.cid().read().0; @@ -616,200 +233,21 @@ impl<'d, T: Instance> Bus<'d, T> { while !r.grstctl().read().ahbidl() {} // Configure as device. - r.gusbcfg().write(|w| { - // Force device mode - w.set_fdmod(true); - // Enable internal full-speed PHY - w.set_physel(self.phy_type.internal() && !self.phy_type.high_speed()); - }); + self.inner.configure_as_device(); // Configuring Vbus sense and SOF output match core_id { - 0x0000_1200 | 0x0000_1100 => { - assert!(self.phy_type != PhyType::InternalHighSpeed); - - r.gccfg_v1().modify(|w| { - // Enable internal full-speed PHY, logic is inverted - w.set_pwrdwn(self.phy_type.internal()); - }); - - // F429-like chips have the GCCFG.NOVBUSSENS bit - r.gccfg_v1().modify(|w| { - w.set_novbussens(!self.config.vbus_detection); - w.set_vbusasen(false); - w.set_vbusbsen(self.config.vbus_detection); - w.set_sofouten(false); - }); - } - 0x0000_2000 | 0x0000_2100 | 0x0000_2300 | 0x0000_3000 | 0x0000_3100 => { - // F446-like chips have the GCCFG.VBDEN bit with the opposite meaning - r.gccfg_v2().modify(|w| { - // Enable internal full-speed PHY, logic is inverted - w.set_pwrdwn(self.phy_type.internal() && !self.phy_type.high_speed()); - w.set_phyhsen(self.phy_type.internal() && self.phy_type.high_speed()); - }); - - r.gccfg_v2().modify(|w| { - w.set_vbden(self.config.vbus_detection); - }); - - // Force B-peripheral session - r.gotgctl().modify(|w| { - w.set_bvaloen(!self.config.vbus_detection); - w.set_bvaloval(true); - }); - } + 0x0000_1200 | 0x0000_1100 => self.inner.config_v1(), + 0x0000_2000 | 0x0000_2100 | 0x0000_2300 | 0x0000_3000 | 0x0000_3100 => self.inner.config_v2v3(), _ => unimplemented!("Unknown USB core id {:X}", core_id), } - - // Soft disconnect. - r.dctl().write(|w| w.set_sdis(true)); - - // Set speed. - r.dcfg().write(|w| { - w.set_pfivl(vals::Pfivl::FRAME_INTERVAL_80); - w.set_dspd(self.phy_type.to_dspd()); - }); - - // Unmask transfer complete EP interrupt - r.diepmsk().write(|w| { - w.set_xfrcm(true); - }); - - // Unmask and clear core interrupts - Bus::<T>::restore_irqs(); - r.gintsts().write_value(regs::Gintsts(0xFFFF_FFFF)); - - // Unmask global interrupt - r.gahbcfg().write(|w| { - w.set_gint(true); // unmask global interrupt - }); - - // Connect - r.dctl().write(|w| w.set_sdis(false)); - } - - fn init_fifo(&mut self) { - trace!("init_fifo"); - - let r = T::regs(); - - // Configure RX fifo size. All endpoints share the same FIFO area. - let rx_fifo_size_words = RX_FIFO_EXTRA_SIZE_WORDS + ep_fifo_size(&self.ep_out); - trace!("configuring rx fifo size={}", rx_fifo_size_words); - - r.grxfsiz().modify(|w| w.set_rxfd(rx_fifo_size_words)); - - // Configure TX (USB in direction) fifo size for each endpoint - let mut fifo_top = rx_fifo_size_words; - for i in 0..T::ENDPOINT_COUNT { - if let Some(ep) = self.ep_in[i] { - trace!( - "configuring tx fifo ep={}, offset={}, size={}", - i, - fifo_top, - ep.fifo_size_words - ); - - let dieptxf = if i == 0 { r.dieptxf0() } else { r.dieptxf(i - 1) }; - - dieptxf.write(|w| { - w.set_fd(ep.fifo_size_words); - w.set_sa(fifo_top); - }); - - fifo_top += ep.fifo_size_words; - } - } - - assert!( - fifo_top <= T::FIFO_DEPTH_WORDS, - "FIFO allocations exceeded maximum capacity" - ); - - // Flush fifos - r.grstctl().write(|w| { - w.set_rxfflsh(true); - w.set_txfflsh(true); - w.set_txfnum(0x10); - }); - loop { - let x = r.grstctl().read(); - if !x.rxfflsh() && !x.txfflsh() { - break; - } - } - } - - fn configure_endpoints(&mut self) { - trace!("configure_endpoints"); - - let r = T::regs(); - - // Configure IN endpoints - for (index, ep) in self.ep_in.iter().enumerate() { - if let Some(ep) = ep { - critical_section::with(|_| { - r.diepctl(index).write(|w| { - if index == 0 { - w.set_mpsiz(ep0_mpsiz(ep.max_packet_size)); - } else { - w.set_mpsiz(ep.max_packet_size); - w.set_eptyp(to_eptyp(ep.ep_type)); - w.set_sd0pid_sevnfrm(true); - w.set_txfnum(index as _); - w.set_snak(true); - } - }); - }); - } - } - - // Configure OUT endpoints - for (index, ep) in self.ep_out.iter().enumerate() { - if let Some(ep) = ep { - critical_section::with(|_| { - r.doepctl(index).write(|w| { - if index == 0 { - w.set_mpsiz(ep0_mpsiz(ep.max_packet_size)); - } else { - w.set_mpsiz(ep.max_packet_size); - w.set_eptyp(to_eptyp(ep.ep_type)); - w.set_sd0pid_sevnfrm(true); - } - }); - - r.doeptsiz(index).modify(|w| { - w.set_xfrsiz(ep.max_packet_size as _); - if index == 0 { - w.set_rxdpid_stupcnt(1); - } else { - w.set_pktcnt(1); - } - }); - }); - } - } - - // Enable IRQs for allocated endpoints - r.daintmsk().modify(|w| { - w.set_iepm(ep_irq_mask(&self.ep_in)); - // OUT interrupts not used, handled in RXFLVL - // w.set_oepm(ep_irq_mask(&self.ep_out)); - }); - } - - fn disable_all_endpoints(&mut self) { - for i in 0..T::ENDPOINT_COUNT { - self.endpoint_set_enabled(EndpointAddress::from_parts(i, Direction::In), false); - self.endpoint_set_enabled(EndpointAddress::from_parts(i, Direction::Out), false); - } } fn disable(&mut self) { T::Interrupt::disable(); <T as SealedRccPeripheral>::disable(); + self.inited = false; #[cfg(stm32l4)] crate::pac::PWR.cr2().modify(|w| w.set_usv(false)); @@ -819,222 +257,37 @@ impl<'d, T: Instance> Bus<'d, T> { impl<'d, T: Instance> embassy_usb_driver::Bus for Bus<'d, T> { async fn poll(&mut self) -> Event { - poll_fn(move |cx| { - if !self.inited { - self.init(); - self.inited = true; + if !self.inited { + self.init(); + self.inited = true; + } - // If no vbus detection, just return a single PowerDetected event at startup. - if !self.config.vbus_detection { - return Poll::Ready(Event::PowerDetected); - } - } - - let r = T::regs(); - - T::state().bus_waker.register(cx.waker()); - - let ints = r.gintsts().read(); - - if ints.srqint() { - trace!("vbus detected"); - - r.gintsts().write(|w| w.set_srqint(true)); // clear - Self::restore_irqs(); - - if self.config.vbus_detection { - return Poll::Ready(Event::PowerDetected); - } - } - - if ints.otgint() { - let otgints = r.gotgint().read(); - r.gotgint().write_value(otgints); // clear all - Self::restore_irqs(); - - if otgints.sedet() { - trace!("vbus removed"); - if self.config.vbus_detection { - self.disable_all_endpoints(); - return Poll::Ready(Event::PowerRemoved); - } - } - } - - if ints.usbrst() { - trace!("reset"); - - self.init_fifo(); - self.configure_endpoints(); - - // Reset address - critical_section::with(|_| { - r.dcfg().modify(|w| { - w.set_dad(0); - }); - }); - - r.gintsts().write(|w| w.set_usbrst(true)); // clear - Self::restore_irqs(); - } - - if ints.enumdne() { - trace!("enumdne"); - - let speed = r.dsts().read().enumspd(); - let trdt = calculate_trdt(speed, T::frequency()); - trace!(" speed={} trdt={}", speed.to_bits(), trdt); - r.gusbcfg().modify(|w| w.set_trdt(trdt)); - - r.gintsts().write(|w| w.set_enumdne(true)); // clear - Self::restore_irqs(); - - return Poll::Ready(Event::Reset); - } - - if ints.usbsusp() { - trace!("suspend"); - r.gintsts().write(|w| w.set_usbsusp(true)); // clear - Self::restore_irqs(); - return Poll::Ready(Event::Suspend); - } - - if ints.wkupint() { - trace!("resume"); - r.gintsts().write(|w| w.set_wkupint(true)); // clear - Self::restore_irqs(); - return Poll::Ready(Event::Resume); - } - - Poll::Pending - }) - .await + self.inner.poll().await } fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) { - trace!("endpoint_set_stalled ep={:?} en={}", ep_addr, stalled); - - assert!( - ep_addr.index() < T::ENDPOINT_COUNT, - "endpoint_set_stalled index {} out of range", - ep_addr.index() - ); - - let regs = T::regs(); - match ep_addr.direction() { - Direction::Out => { - critical_section::with(|_| { - regs.doepctl(ep_addr.index()).modify(|w| { - w.set_stall(stalled); - }); - }); - - T::state().ep_out_wakers[ep_addr.index()].wake(); - } - Direction::In => { - critical_section::with(|_| { - regs.diepctl(ep_addr.index()).modify(|w| { - w.set_stall(stalled); - }); - }); - - T::state().ep_in_wakers[ep_addr.index()].wake(); - } - } + self.inner.endpoint_set_stalled(ep_addr, stalled) } fn endpoint_is_stalled(&mut self, ep_addr: EndpointAddress) -> bool { - assert!( - ep_addr.index() < T::ENDPOINT_COUNT, - "endpoint_is_stalled index {} out of range", - ep_addr.index() - ); - - let regs = T::regs(); - - match ep_addr.direction() { - Direction::Out => regs.doepctl(ep_addr.index()).read().stall(), - Direction::In => regs.diepctl(ep_addr.index()).read().stall(), - } + self.inner.endpoint_is_stalled(ep_addr) } fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool) { - trace!("endpoint_set_enabled ep={:?} en={}", ep_addr, enabled); - - assert!( - ep_addr.index() < T::ENDPOINT_COUNT, - "endpoint_set_enabled index {} out of range", - ep_addr.index() - ); - - let r = T::regs(); - match ep_addr.direction() { - Direction::Out => { - critical_section::with(|_| { - // cancel transfer if active - if !enabled && r.doepctl(ep_addr.index()).read().epena() { - r.doepctl(ep_addr.index()).modify(|w| { - w.set_snak(true); - w.set_epdis(true); - }) - } - - r.doepctl(ep_addr.index()).modify(|w| { - w.set_usbaep(enabled); - }); - - // Flush tx fifo - r.grstctl().write(|w| { - w.set_txfflsh(true); - w.set_txfnum(ep_addr.index() as _); - }); - loop { - let x = r.grstctl().read(); - if !x.txfflsh() { - break; - } - } - }); - - // Wake `Endpoint::wait_enabled()` - T::state().ep_out_wakers[ep_addr.index()].wake(); - } - Direction::In => { - critical_section::with(|_| { - // cancel transfer if active - if !enabled && r.diepctl(ep_addr.index()).read().epena() { - r.diepctl(ep_addr.index()).modify(|w| { - w.set_snak(true); // set NAK - w.set_epdis(true); - }) - } - - r.diepctl(ep_addr.index()).modify(|w| { - w.set_usbaep(enabled); - w.set_cnak(enabled); // clear NAK that might've been set by SNAK above. - }) - }); - - // Wake `Endpoint::wait_enabled()` - T::state().ep_in_wakers[ep_addr.index()].wake(); - } - } + self.inner.endpoint_set_enabled(ep_addr, enabled) } async fn enable(&mut self) { - trace!("enable"); - // TODO: enable the peripheral once enable/disable semantics are cleared up in embassy-usb + self.inner.enable().await } async fn disable(&mut self) { - trace!("disable"); - - // TODO: disable the peripheral once enable/disable semantics are cleared up in embassy-usb - //Bus::disable(self); + // NOTE: inner call is a no-op + self.inner.disable().await } async fn remote_wakeup(&mut self) -> Result<(), Unsupported> { - Err(Unsupported) + self.inner.remote_wakeup().await } } @@ -1044,405 +297,13 @@ impl<'d, T: Instance> Drop for Bus<'d, T> { } } -trait Dir { - fn dir() -> Direction; -} - -/// Marker type for the "IN" direction. -pub enum In {} -impl Dir for In { - fn dir() -> Direction { - Direction::In - } -} - -/// Marker type for the "OUT" direction. -pub enum Out {} -impl Dir for Out { - fn dir() -> Direction { - Direction::Out - } -} - -/// USB endpoint. -pub struct Endpoint<'d, T: Instance, D> { - _phantom: PhantomData<(&'d mut T, D)>, - info: EndpointInfo, -} - -impl<'d, T: Instance> embassy_usb_driver::Endpoint for Endpoint<'d, T, In> { - fn info(&self) -> &EndpointInfo { - &self.info - } - - async fn wait_enabled(&mut self) { - poll_fn(|cx| { - let ep_index = self.info.addr.index(); - - T::state().ep_in_wakers[ep_index].register(cx.waker()); - - if T::regs().diepctl(ep_index).read().usbaep() { - Poll::Ready(()) - } else { - Poll::Pending - } - }) - .await - } -} - -impl<'d, T: Instance> embassy_usb_driver::Endpoint for Endpoint<'d, T, Out> { - fn info(&self) -> &EndpointInfo { - &self.info - } - - async fn wait_enabled(&mut self) { - poll_fn(|cx| { - let ep_index = self.info.addr.index(); - - T::state().ep_out_wakers[ep_index].register(cx.waker()); - - if T::regs().doepctl(ep_index).read().usbaep() { - Poll::Ready(()) - } else { - Poll::Pending - } - }) - .await - } -} - -impl<'d, T: Instance> embassy_usb_driver::EndpointOut for Endpoint<'d, T, Out> { - async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> { - trace!("read start len={}", buf.len()); - - poll_fn(|cx| { - let r = T::regs(); - let index = self.info.addr.index(); - let state = T::state(); - - state.ep_out_wakers[index].register(cx.waker()); - - let doepctl = r.doepctl(index).read(); - trace!("read ep={:?}: doepctl {:08x}", self.info.addr, doepctl.0,); - if !doepctl.usbaep() { - trace!("read ep={:?} error disabled", self.info.addr); - return Poll::Ready(Err(EndpointError::Disabled)); - } - - let len = state.ep_out_size[index].load(Ordering::Relaxed); - if len != EP_OUT_BUFFER_EMPTY { - trace!("read ep={:?} done len={}", self.info.addr, len); - - if len as usize > buf.len() { - return Poll::Ready(Err(EndpointError::BufferOverflow)); - } - - // SAFETY: exclusive access ensured by `ep_out_size` atomic variable - let data = unsafe { core::slice::from_raw_parts(*state.ep_out_buffers[index].get(), len as usize) }; - buf[..len as usize].copy_from_slice(data); - - // Release buffer - state.ep_out_size[index].store(EP_OUT_BUFFER_EMPTY, Ordering::Release); - - critical_section::with(|_| { - // Receive 1 packet - T::regs().doeptsiz(index).modify(|w| { - w.set_xfrsiz(self.info.max_packet_size as _); - w.set_pktcnt(1); - }); - - // Clear NAK to indicate we are ready to receive more data - T::regs().doepctl(index).modify(|w| { - w.set_cnak(true); - }); - }); - - Poll::Ready(Ok(len as usize)) - } else { - Poll::Pending - } - }) - .await - } -} - -impl<'d, T: Instance> embassy_usb_driver::EndpointIn for Endpoint<'d, T, In> { - async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> { - trace!("write ep={:?} data={:?}", self.info.addr, buf); - - if buf.len() > self.info.max_packet_size as usize { - return Err(EndpointError::BufferOverflow); - } - - let r = T::regs(); - let index = self.info.addr.index(); - let state = T::state(); - - // Wait for previous transfer to complete and check if endpoint is disabled - poll_fn(|cx| { - state.ep_in_wakers[index].register(cx.waker()); - - let diepctl = r.diepctl(index).read(); - let dtxfsts = r.dtxfsts(index).read(); - trace!( - "write ep={:?}: diepctl {:08x} ftxfsts {:08x}", - self.info.addr, - diepctl.0, - dtxfsts.0 - ); - if !diepctl.usbaep() { - trace!("write ep={:?} wait for prev: error disabled", self.info.addr); - Poll::Ready(Err(EndpointError::Disabled)) - } else if !diepctl.epena() { - trace!("write ep={:?} wait for prev: ready", self.info.addr); - Poll::Ready(Ok(())) - } else { - trace!("write ep={:?} wait for prev: pending", self.info.addr); - Poll::Pending - } - }) - .await?; - - if buf.len() > 0 { - poll_fn(|cx| { - state.ep_in_wakers[index].register(cx.waker()); - - let size_words = (buf.len() + 3) / 4; - - let fifo_space = r.dtxfsts(index).read().ineptfsav() as usize; - if size_words > fifo_space { - // Not enough space in fifo, enable tx fifo empty interrupt - critical_section::with(|_| { - r.diepempmsk().modify(|w| { - w.set_ineptxfem(w.ineptxfem() | (1 << index)); - }); - }); - - trace!("tx fifo for ep={} full, waiting for txfe", index); - - Poll::Pending - } else { - trace!("write ep={:?} wait for fifo: ready", self.info.addr); - Poll::Ready(()) - } - }) - .await - } - - // Setup transfer size - r.dieptsiz(index).write(|w| { - w.set_mcnt(1); - w.set_pktcnt(1); - w.set_xfrsiz(buf.len() as _); - }); - - critical_section::with(|_| { - // Enable endpoint - r.diepctl(index).modify(|w| { - w.set_cnak(true); - w.set_epena(true); - }); - }); - - // Write data to FIFO - for chunk in buf.chunks(4) { - let mut tmp = [0u8; 4]; - tmp[0..chunk.len()].copy_from_slice(chunk); - r.fifo(index).write_value(regs::Fifo(u32::from_ne_bytes(tmp))); - } - - trace!("write done ep={:?}", self.info.addr); - - Ok(()) - } -} - -/// USB control pipe. -pub struct ControlPipe<'d, T: Instance> { - _phantom: PhantomData<&'d mut T>, - max_packet_size: u16, - ep_in: Endpoint<'d, T, In>, - ep_out: Endpoint<'d, T, Out>, -} - -impl<'d, T: Instance> embassy_usb_driver::ControlPipe for ControlPipe<'d, T> { - fn max_packet_size(&self) -> usize { - usize::from(self.max_packet_size) - } - - async fn setup(&mut self) -> [u8; 8] { - poll_fn(|cx| { - let state = T::state(); - - state.ep_out_wakers[0].register(cx.waker()); - - let r = T::regs(); - - if state.ep0_setup_ready.load(Ordering::Relaxed) { - let data = unsafe { *state.ep0_setup_data.get() }; - state.ep0_setup_ready.store(false, Ordering::Release); - - // EP0 should not be controlled by `Bus` so this RMW does not need a critical section - // Receive 1 SETUP packet - r.doeptsiz(self.ep_out.info.addr.index()).modify(|w| { - w.set_rxdpid_stupcnt(1); - }); - - // Clear NAK to indicate we are ready to receive more data - if !quirk_setup_late_cnak(r) { - r.doepctl(self.ep_out.info.addr.index()).modify(|w| w.set_cnak(true)); - } - - trace!("SETUP received: {:?}", data); - Poll::Ready(data) - } else { - trace!("SETUP waiting"); - Poll::Pending - } - }) - .await - } - - async fn data_out(&mut self, buf: &mut [u8], _first: bool, _last: bool) -> Result<usize, EndpointError> { - trace!("control: data_out"); - let len = self.ep_out.read(buf).await?; - trace!("control: data_out read: {:?}", &buf[..len]); - Ok(len) - } - - async fn data_in(&mut self, data: &[u8], _first: bool, last: bool) -> Result<(), EndpointError> { - trace!("control: data_in write: {:?}", data); - self.ep_in.write(data).await?; - - // wait for status response from host after sending the last packet - if last { - trace!("control: data_in waiting for status"); - self.ep_out.read(&mut []).await?; - trace!("control: complete"); - } - - Ok(()) - } - - async fn accept(&mut self) { - trace!("control: accept"); - - self.ep_in.write(&[]).await.ok(); - - trace!("control: accept OK"); - } - - async fn reject(&mut self) { - trace!("control: reject"); - - // EP0 should not be controlled by `Bus` so this RMW does not need a critical section - let regs = T::regs(); - regs.diepctl(self.ep_in.info.addr.index()).modify(|w| { - w.set_stall(true); - }); - regs.doepctl(self.ep_out.info.addr.index()).modify(|w| { - w.set_stall(true); - }); - } - - async fn accept_set_address(&mut self, addr: u8) { - trace!("setting addr: {}", addr); - critical_section::with(|_| { - T::regs().dcfg().modify(|w| { - w.set_dad(addr); - }); - }); - - // synopsys driver requires accept to be sent after changing address - self.accept().await - } -} - -/// Translates HAL [EndpointType] into PAC [vals::Eptyp] -fn to_eptyp(ep_type: EndpointType) -> vals::Eptyp { - match ep_type { - EndpointType::Control => vals::Eptyp::CONTROL, - EndpointType::Isochronous => vals::Eptyp::ISOCHRONOUS, - EndpointType::Bulk => vals::Eptyp::BULK, - EndpointType::Interrupt => vals::Eptyp::INTERRUPT, - } -} - -/// Calculates total allocated FIFO size in words -fn ep_fifo_size(eps: &[Option<EndpointData>]) -> u16 { - eps.iter().map(|ep| ep.map(|ep| ep.fifo_size_words).unwrap_or(0)).sum() -} - -/// Generates IRQ mask for enabled endpoints -fn ep_irq_mask(eps: &[Option<EndpointData>]) -> u16 { - eps.iter().enumerate().fold( - 0, - |mask, (index, ep)| { - if ep.is_some() { - mask | (1 << index) - } else { - mask - } - }, - ) -} - -/// Calculates MPSIZ value for EP0, which uses special values. -fn ep0_mpsiz(max_packet_size: u16) -> u16 { - match max_packet_size { - 8 => 0b11, - 16 => 0b10, - 32 => 0b01, - 64 => 0b00, - other => panic!("Unsupported EP0 size: {}", other), - } -} - -fn calculate_trdt(speed: vals::Dspd, ahb_freq: Hertz) -> u8 { - match speed { - vals::Dspd::HIGH_SPEED => { - // From RM0431 (F72xx), RM0090 (F429), RM0390 (F446) - if ahb_freq.0 >= 30_000_000 { - 0x9 - } else { - panic!("AHB frequency is too low") - } - } - vals::Dspd::FULL_SPEED_EXTERNAL | vals::Dspd::FULL_SPEED_INTERNAL => { - // From RM0431 (F72xx), RM0090 (F429) - match ahb_freq.0 { - 0..=14_199_999 => panic!("AHB frequency is too low"), - 14_200_000..=14_999_999 => 0xF, - 15_000_000..=15_999_999 => 0xE, - 16_000_000..=17_199_999 => 0xD, - 17_200_000..=18_499_999 => 0xC, - 18_500_000..=19_999_999 => 0xB, - 20_000_000..=21_799_999 => 0xA, - 21_800_000..=23_999_999 => 0x9, - 24_000_000..=27_499_999 => 0x8, - 27_500_000..=31_999_999 => 0x7, // 27.7..32 in code from CubeIDE - 32_000_000..=u32::MAX => 0x6, - } - } - _ => unimplemented!(), - } -} - -fn quirk_setup_late_cnak(r: crate::pac::otg::Otg) -> bool { - r.cid().read().0 & 0xf000 == 0x1000 -} - -// Using Instance::ENDPOINT_COUNT requires feature(const_generic_expr) so just define maximum eps -const MAX_EP_COUNT: usize = 9; - trait SealedInstance { const HIGH_SPEED: bool; const FIFO_DEPTH_WORDS: u16; const ENDPOINT_COUNT: usize; - fn regs() -> crate::pac::otg::Otg; - fn state() -> &'static super::State<{ MAX_EP_COUNT }>; + fn regs() -> Otg; + fn state() -> &'static State<{ MAX_EP_COUNT }>; } /// USB instance trait. @@ -1510,7 +371,7 @@ foreach_interrupt!( } else if #[cfg(stm32g0x1)] { const FIFO_DEPTH_WORDS: u16 = 512; const ENDPOINT_COUNT: usize = 8; - } else if #[cfg(stm32h7)] { + } else if #[cfg(any(stm32h7, stm32h7rs))] { const FIFO_DEPTH_WORDS: u16 = 1024; const ENDPOINT_COUNT: usize = 9; } else if #[cfg(stm32u5)] { @@ -1521,8 +382,8 @@ foreach_interrupt!( } } - fn regs() -> crate::pac::otg::Otg { - crate::pac::USB_OTG_FS + fn regs() -> Otg { + unsafe { Otg::from_ptr(crate::pac::USB_OTG_FS.as_ptr()) } } fn state() -> &'static State<MAX_EP_COUNT> { @@ -1559,7 +420,7 @@ foreach_interrupt!( stm32f469, stm32f479, stm32f7, - stm32h7, + stm32h7, stm32h7rs, ))] { const FIFO_DEPTH_WORDS: u16 = 1024; const ENDPOINT_COUNT: usize = 9; @@ -1571,9 +432,9 @@ foreach_interrupt!( } } - fn regs() -> crate::pac::otg::Otg { + fn regs() -> Otg { // OTG HS registers are a superset of FS registers - unsafe { crate::pac::otg::Otg::from_ptr(crate::pac::USB_OTG_HS.as_ptr()) } + unsafe { Otg::from_ptr(crate::pac::USB_OTG_HS.as_ptr()) } } fn state() -> &'static State<MAX_EP_COUNT> { @@ -1587,3 +448,38 @@ foreach_interrupt!( } }; ); + +fn calculate_trdt<T: Instance>(speed: Dspd) -> u8 { + let ahb_freq = T::frequency().0; + match speed { + Dspd::HIGH_SPEED => { + // From RM0431 (F72xx), RM0090 (F429), RM0390 (F446) + if ahb_freq >= 30_000_000 { + 0x9 + } else { + panic!("AHB frequency is too low") + } + } + Dspd::FULL_SPEED_EXTERNAL | Dspd::FULL_SPEED_INTERNAL => { + // From RM0431 (F72xx), RM0090 (F429) + match ahb_freq { + 0..=14_199_999 => panic!("AHB frequency is too low"), + 14_200_000..=14_999_999 => 0xF, + 15_000_000..=15_999_999 => 0xE, + 16_000_000..=17_199_999 => 0xD, + 17_200_000..=18_499_999 => 0xC, + 18_500_000..=19_999_999 => 0xB, + 20_000_000..=21_799_999 => 0xA, + 21_800_000..=23_999_999 => 0x9, + 24_000_000..=27_499_999 => 0x8, + 27_500_000..=31_999_999 => 0x7, // 27.7..32 in code from CubeIDE + 32_000_000..=u32::MAX => 0x6, + } + } + _ => unimplemented!(), + } +} + +fn quirk_setup_late_cnak(r: Otg) -> bool { + r.cid().read().0 & 0xf000 == 0x1000 +} diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index f48808cb3..81a2d2623 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs @@ -107,14 +107,14 @@ const EP_COUNT: usize = 8; #[cfg(any(usbram_16x1_512, usbram_16x2_512))] const USBRAM_SIZE: usize = 512; -#[cfg(usbram_16x2_1024)] +#[cfg(any(usbram_16x2_1024, usbram_32_1024))] const USBRAM_SIZE: usize = 1024; #[cfg(usbram_32_2048)] const USBRAM_SIZE: usize = 2048; -#[cfg(not(usbram_32_2048))] +#[cfg(not(any(usbram_32_2048, usbram_32_1024)))] const USBRAM_ALIGN: usize = 2; -#[cfg(usbram_32_2048)] +#[cfg(any(usbram_32_2048, usbram_32_1024))] const USBRAM_ALIGN: usize = 4; const NEW_AW: AtomicWaker = AtomicWaker::new(); @@ -159,7 +159,7 @@ fn calc_out_len(len: u16) -> (u16, u16) { } } -#[cfg(not(usbram_32_2048))] +#[cfg(not(any(usbram_32_2048, usbram_32_1024)))] mod btable { use super::*; @@ -180,7 +180,7 @@ mod btable { USBRAM.mem(index * 4 + 3).read() } } -#[cfg(usbram_32_2048)] +#[cfg(any(usbram_32_2048, usbram_32_1024))] mod btable { use super::*; @@ -224,9 +224,9 @@ impl<T: Instance> EndpointBuffer<T> { let n = USBRAM_ALIGN.min(buf.len() - i * USBRAM_ALIGN); val[..n].copy_from_slice(&buf[i * USBRAM_ALIGN..][..n]); - #[cfg(not(usbram_32_2048))] + #[cfg(not(any(usbram_32_2048, usbram_32_1024)))] let val = u16::from_le_bytes(val); - #[cfg(usbram_32_2048)] + #[cfg(any(usbram_32_2048, usbram_32_1024))] let val = u32::from_le_bytes(val); USBRAM.mem(self.addr as usize / USBRAM_ALIGN + i).write_value(val); } diff --git a/embassy-sync/CHANGELOG.md b/embassy-sync/CHANGELOG.md index 3f6b39d8b..a283adc0c 100644 --- a/embassy-sync/CHANGELOG.md +++ b/embassy-sync/CHANGELOG.md @@ -7,7 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -- Add `len`, `is_empty` and `is_full` functions to `Channel`. +## 0.6.0 - 2024-05-29 + +- Add `capacity`, `free_capacity`, `clear`, `len`, `is_empty` and `is_full` functions to `Channel`. +- Add `capacity`, `free_capacity`, `clear`, `len`, `is_empty` and `is_full` functions to `PriorityChannel`. +- Add `capacity`, `free_capacity`, `clear`, `len`, `is_empty` and `is_full` functions to `PubSubChannel`. +- Made `PubSubBehavior` sealed + - If you called `.publish_immediate(...)` on the queue directly before, then now call `.immediate_publisher().publish_immediate(...)` +- Add OnceLock sync primitive. +- Add constructor for DynamicChannel +- Add ready_to_receive functions to Channel and Receiver. ## 0.5.0 - 2023-12-04 diff --git a/embassy-sync/Cargo.toml b/embassy-sync/Cargo.toml index aaf6fab1d..7b7d2bf8e 100644 --- a/embassy-sync/Cargo.toml +++ b/embassy-sync/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-sync" -version = "0.5.0" +version = "0.6.0" edition = "2021" description = "no-std, no-alloc synchronization primitives with async support" repository = "https://github.com/embassy-rs/embassy" diff --git a/embassy-sync/src/channel.rs b/embassy-sync/src/channel.rs index 18be462cb..55ac5fb66 100644 --- a/embassy-sync/src/channel.rs +++ b/embassy-sync/src/channel.rs @@ -42,7 +42,7 @@ where M: RawMutex, { fn clone(&self) -> Self { - Sender { channel: self.channel } + *self } } @@ -81,7 +81,7 @@ pub struct DynamicSender<'ch, T> { impl<'ch, T> Clone for DynamicSender<'ch, T> { fn clone(&self) -> Self { - DynamicSender { channel: self.channel } + *self } } @@ -135,7 +135,7 @@ where M: RawMutex, { fn clone(&self) -> Self { - Receiver { channel: self.channel } + *self } } @@ -152,6 +152,13 @@ where self.channel.receive() } + /// Is a value ready to be received in the channel + /// + /// See [`Channel::ready_to_receive()`]. + pub fn ready_to_receive(&self) -> ReceiveReadyFuture<'_, M, T, N> { + self.channel.ready_to_receive() + } + /// Attempt to immediately receive the next value. /// /// See [`Channel::try_receive()`] @@ -181,7 +188,7 @@ pub struct DynamicReceiver<'ch, T> { impl<'ch, T> Clone for DynamicReceiver<'ch, T> { fn clone(&self) -> Self { - DynamicReceiver { channel: self.channel } + *self } } @@ -246,6 +253,26 @@ where } } +/// Future returned by [`Channel::ready_to_receive`] and [`Receiver::ready_to_receive`]. +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct ReceiveReadyFuture<'ch, M, T, const N: usize> +where + M: RawMutex, +{ + channel: &'ch Channel<M, T, N>, +} + +impl<'ch, M, T, const N: usize> Future for ReceiveReadyFuture<'ch, M, T, N> +where + M: RawMutex, +{ + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { + self.channel.poll_ready_to_receive(cx) + } +} + /// Future returned by [`DynamicReceiver::receive`]. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct DynamicReceiveFuture<'ch, T> { @@ -450,6 +477,10 @@ impl<T, const N: usize> ChannelState<T, N> { } } + fn clear(&mut self) { + self.queue.clear(); + } + fn len(&self) -> usize { self.queue.len() } @@ -577,6 +608,14 @@ where ReceiveFuture { channel: self } } + /// Is a value ready to be received in the channel + /// + /// If there are no messages in the channel's buffer, this method will + /// wait until there is at least one + pub fn ready_to_receive(&self) -> ReceiveReadyFuture<'_, M, T, N> { + ReceiveReadyFuture { channel: self } + } + /// Attempt to immediately receive a message. /// /// This method will either receive a message from the channel immediately or return an error @@ -585,6 +624,23 @@ where self.lock(|c| c.try_receive()) } + /// Returns the maximum number of elements the channel can hold. + pub const fn capacity(&self) -> usize { + N + } + + /// Returns the free capacity of the channel. + /// + /// This is equivalent to `capacity() - len()` + pub fn free_capacity(&self) -> usize { + N - self.len() + } + + /// Clears all elements in the channel. + pub fn clear(&self) { + self.lock(|c| c.clear()); + } + /// Returns the number of elements currently in the channel. pub fn len(&self) -> usize { self.lock(|c| c.len()) diff --git a/embassy-sync/src/mutex.rs b/embassy-sync/src/mutex.rs index 72459d660..8c3a3af9f 100644 --- a/embassy-sync/src/mutex.rs +++ b/embassy-sync/src/mutex.rs @@ -5,6 +5,7 @@ use core::cell::{RefCell, UnsafeCell}; use core::future::poll_fn; use core::ops::{Deref, DerefMut}; use core::task::Poll; +use core::{fmt, mem}; use crate::blocking_mutex::raw::RawMutex; use crate::blocking_mutex::Mutex as BlockingMutex; @@ -128,12 +129,49 @@ where } } +impl<M: RawMutex, T> From<T> for Mutex<M, T> { + fn from(from: T) -> Self { + Self::new(from) + } +} + +impl<M, T> Default for Mutex<M, T> +where + M: RawMutex, + T: ?Sized + Default, +{ + fn default() -> Self { + Self::new(Default::default()) + } +} + +impl<M, T> fmt::Debug for Mutex<M, T> +where + M: RawMutex, + T: ?Sized + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut d = f.debug_struct("Mutex"); + match self.try_lock() { + Ok(value) => { + d.field("inner", &&*value); + } + Err(TryLockError) => { + d.field("inner", &format_args!("<locked>")); + } + } + + d.finish_non_exhaustive() + } +} + /// Async mutex guard. /// /// Owning an instance of this type indicates having /// successfully locked the mutex, and grants access to the contents. /// /// Dropping it unlocks the mutex. +#[clippy::has_significant_drop] pub struct MutexGuard<'a, M, T> where M: RawMutex, @@ -142,6 +180,25 @@ where mutex: &'a Mutex<M, T>, } +impl<'a, M, T> MutexGuard<'a, M, T> +where + M: RawMutex, + T: ?Sized, +{ + /// Returns a locked view over a portion of the locked data. + pub fn map<U>(this: Self, fun: impl FnOnce(&mut T) -> &mut U) -> MappedMutexGuard<'a, M, U> { + let mutex = this.mutex; + let value = fun(unsafe { &mut *this.mutex.inner.get() }); + // Don't run the `drop` method for MutexGuard. The ownership of the underlying + // locked state is being moved to the returned MappedMutexGuard. + mem::forget(this); + MappedMutexGuard { + state: &mutex.state, + value, + } + } +} + impl<'a, M, T> Drop for MutexGuard<'a, M, T> where M: RawMutex, @@ -180,3 +237,155 @@ where unsafe { &mut *(self.mutex.inner.get()) } } } + +impl<'a, M, T> fmt::Debug for MutexGuard<'a, M, T> +where + M: RawMutex, + T: ?Sized + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +impl<'a, M, T> fmt::Display for MutexGuard<'a, M, T> +where + M: RawMutex, + T: ?Sized + fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&**self, f) + } +} + +/// A handle to a held `Mutex` that has had a function applied to it via [`MutexGuard::map`] or +/// [`MappedMutexGuard::map`]. +/// +/// This can be used to hold a subfield of the protected data. +#[clippy::has_significant_drop] +pub struct MappedMutexGuard<'a, M, T> +where + M: RawMutex, + T: ?Sized, +{ + state: &'a BlockingMutex<M, RefCell<State>>, + value: *mut T, +} + +impl<'a, M, T> MappedMutexGuard<'a, M, T> +where + M: RawMutex, + T: ?Sized, +{ + /// Returns a locked view over a portion of the locked data. + pub fn map<U>(this: Self, fun: impl FnOnce(&mut T) -> &mut U) -> MappedMutexGuard<'a, M, U> { + let state = this.state; + let value = fun(unsafe { &mut *this.value }); + // Don't run the `drop` method for MutexGuard. The ownership of the underlying + // locked state is being moved to the returned MappedMutexGuard. + mem::forget(this); + MappedMutexGuard { state, value } + } +} + +impl<'a, M, T> Deref for MappedMutexGuard<'a, M, T> +where + M: RawMutex, + T: ?Sized, +{ + type Target = T; + fn deref(&self) -> &Self::Target { + // Safety: the MutexGuard represents exclusive access to the contents + // of the mutex, so it's OK to get it. + unsafe { &*self.value } + } +} + +impl<'a, M, T> DerefMut for MappedMutexGuard<'a, M, T> +where + M: RawMutex, + T: ?Sized, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + // Safety: the MutexGuard represents exclusive access to the contents + // of the mutex, so it's OK to get it. + unsafe { &mut *self.value } + } +} + +impl<'a, M, T> Drop for MappedMutexGuard<'a, M, T> +where + M: RawMutex, + T: ?Sized, +{ + fn drop(&mut self) { + self.state.lock(|s| { + let mut s = unwrap!(s.try_borrow_mut()); + s.locked = false; + s.waker.wake(); + }) + } +} + +unsafe impl<M, T> Send for MappedMutexGuard<'_, M, T> +where + M: RawMutex + Sync, + T: Send + ?Sized, +{ +} + +unsafe impl<M, T> Sync for MappedMutexGuard<'_, M, T> +where + M: RawMutex + Sync, + T: Sync + ?Sized, +{ +} + +impl<'a, M, T> fmt::Debug for MappedMutexGuard<'a, M, T> +where + M: RawMutex, + T: ?Sized + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +impl<'a, M, T> fmt::Display for MappedMutexGuard<'a, M, T> +where + M: RawMutex, + T: ?Sized + fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&**self, f) + } +} + +#[cfg(test)] +mod tests { + use crate::blocking_mutex::raw::NoopRawMutex; + use crate::mutex::{Mutex, MutexGuard}; + + #[futures_test::test] + async fn mapped_guard_releases_lock_when_dropped() { + let mutex: Mutex<NoopRawMutex, [i32; 2]> = Mutex::new([0, 1]); + + { + let guard = mutex.lock().await; + assert_eq!(*guard, [0, 1]); + let mut mapped = MutexGuard::map(guard, |this| &mut this[1]); + assert_eq!(*mapped, 1); + *mapped = 2; + } + + { + let guard = mutex.lock().await; + assert_eq!(*guard, [0, 2]); + let mut mapped = MutexGuard::map(guard, |this| &mut this[1]); + assert_eq!(*mapped, 2); + *mapped = 3; + } + + assert_eq!(*mutex.lock().await, [0, 3]); + } +} diff --git a/embassy-sync/src/once_lock.rs b/embassy-sync/src/once_lock.rs index 31cc99711..55608ba32 100644 --- a/embassy-sync/src/once_lock.rs +++ b/embassy-sync/src/once_lock.rs @@ -1,4 +1,4 @@ -//! Syncronization primitive for initializing a value once, allowing others to await a reference to the value. +//! Synchronization primitive for initializing a value once, allowing others to await a reference to the value. use core::cell::Cell; use core::future::poll_fn; @@ -13,7 +13,7 @@ use core::task::Poll; /// /// **Note**: this implementation uses a busy loop to poll the value, /// which is not as efficient as registering a dedicated `Waker`. -/// However, the if the usecase for is to initialize a static variable +/// However, if the usecase for it is to initialize a static variable /// relatively early in the program life cycle, it should be fine. /// /// # Example @@ -78,7 +78,7 @@ impl<T> OnceLock<T> { /// Set the underlying value. If the value is already set, this will return an error with the given value. pub fn init(&self, value: T) -> Result<(), T> { // Critical section is required to ensure that the value is - // not simultaniously initialized elsewhere at the same time. + // not simultaneously initialized elsewhere at the same time. critical_section::with(|_| { // If the value is not set, set it and return Ok. if !self.init.load(Ordering::Relaxed) { @@ -99,7 +99,7 @@ impl<T> OnceLock<T> { F: FnOnce() -> T, { // Critical section is required to ensure that the value is - // not simultaniously initialized elsewhere at the same time. + // not simultaneously initialized elsewhere at the same time. critical_section::with(|_| { // If the value is not set, set it. if !self.init.load(Ordering::Relaxed) { diff --git a/embassy-sync/src/pipe.rs b/embassy-sync/src/pipe.rs index 42fe8ebd0..cd5b8ed75 100644 --- a/embassy-sync/src/pipe.rs +++ b/embassy-sync/src/pipe.rs @@ -25,7 +25,7 @@ where M: RawMutex, { fn clone(&self) -> Self { - Writer { pipe: self.pipe } + *self } } diff --git a/embassy-sync/src/priority_channel.rs b/embassy-sync/src/priority_channel.rs index e77678c24..24c6c5a7f 100644 --- a/embassy-sync/src/priority_channel.rs +++ b/embassy-sync/src/priority_channel.rs @@ -33,7 +33,7 @@ where M: RawMutex, { fn clone(&self) -> Self { - Sender { channel: self.channel } + *self } } @@ -101,7 +101,7 @@ where M: RawMutex, { fn clone(&self) -> Self { - Receiver { channel: self.channel } + *self } } @@ -314,6 +314,22 @@ where Poll::Pending } } + + fn clear(&mut self) { + self.queue.clear(); + } + + fn len(&self) -> usize { + self.queue.len() + } + + fn is_empty(&self) -> bool { + self.queue.is_empty() + } + + fn is_full(&self) -> bool { + self.queue.len() == self.queue.capacity() + } } /// A bounded channel for communicating between asynchronous tasks @@ -323,7 +339,7 @@ where /// buffer is full, attempts to `send` new messages will wait until a message is /// received from the channel. /// -/// Sent data may be reordered based on their priorty within the channel. +/// Sent data may be reordered based on their priority within the channel. /// For example, in a [`Max`](heapless::binary_heap::Max) [`PriorityChannel`] /// containing `u32`'s, data sent in the following order `[1, 2, 3]` will be received as `[3, 2, 1]`. pub struct PriorityChannel<M, T, K, const N: usize> @@ -433,6 +449,38 @@ where pub fn try_receive(&self) -> Result<T, TryReceiveError> { self.lock(|c| c.try_receive()) } + + /// Returns the maximum number of elements the channel can hold. + pub const fn capacity(&self) -> usize { + N + } + + /// Returns the free capacity of the channel. + /// + /// This is equivalent to `capacity() - len()` + pub fn free_capacity(&self) -> usize { + N - self.len() + } + + /// Clears all elements in the channel. + pub fn clear(&self) { + self.lock(|c| c.clear()); + } + + /// Returns the number of elements currently in the channel. + pub fn len(&self) -> usize { + self.lock(|c| c.len()) + } + + /// Returns whether the channel is empty. + pub fn is_empty(&self) -> bool { + self.lock(|c| c.is_empty()) + } + + /// Returns whether the channel is full. + pub fn is_full(&self) -> bool { + self.lock(|c| c.is_full()) + } } /// Implements the DynamicChannel to allow creating types that are unaware of the queue size with the diff --git a/embassy-sync/src/pubsub/mod.rs b/embassy-sync/src/pubsub/mod.rs index 6afd54af5..66c9b0017 100644 --- a/embassy-sync/src/pubsub/mod.rs +++ b/embassy-sync/src/pubsub/mod.rs @@ -160,9 +160,41 @@ impl<M: RawMutex, T: Clone, const CAP: usize, const SUBS: usize, const PUBS: usi pub fn dyn_immediate_publisher(&self) -> DynImmediatePublisher<T> { DynImmediatePublisher(ImmediatePub::new(self)) } + + /// Returns the maximum number of elements the channel can hold. + pub const fn capacity(&self) -> usize { + CAP + } + + /// Returns the free capacity of the channel. + /// + /// This is equivalent to `capacity() - len()` + pub fn free_capacity(&self) -> usize { + CAP - self.len() + } + + /// Clears all elements in the channel. + pub fn clear(&self) { + self.inner.lock(|inner| inner.borrow_mut().clear()); + } + + /// Returns the number of elements currently in the channel. + pub fn len(&self) -> usize { + self.inner.lock(|inner| inner.borrow().len()) + } + + /// Returns whether the channel is empty. + pub fn is_empty(&self) -> bool { + self.inner.lock(|inner| inner.borrow().is_empty()) + } + + /// Returns whether the channel is full. + pub fn is_full(&self) -> bool { + self.inner.lock(|inner| inner.borrow().is_full()) + } } -impl<M: RawMutex, T: Clone, const CAP: usize, const SUBS: usize, const PUBS: usize> PubSubBehavior<T> +impl<M: RawMutex, T: Clone, const CAP: usize, const SUBS: usize, const PUBS: usize> SealedPubSubBehavior<T> for PubSubChannel<M, T, CAP, SUBS, PUBS> { fn get_message_with_context(&self, next_message_id: &mut u64, cx: Option<&mut Context<'_>>) -> Poll<WaitResult<T>> { @@ -221,13 +253,6 @@ impl<M: RawMutex, T: Clone, const CAP: usize, const SUBS: usize, const PUBS: usi }) } - fn space(&self) -> usize { - self.inner.lock(|s| { - let s = s.borrow(); - s.queue.capacity() - s.queue.len() - }) - } - fn unregister_subscriber(&self, subscriber_next_message_id: u64) { self.inner.lock(|s| { let mut s = s.borrow_mut(); @@ -241,6 +266,30 @@ impl<M: RawMutex, T: Clone, const CAP: usize, const SUBS: usize, const PUBS: usi s.unregister_publisher() }) } + + fn capacity(&self) -> usize { + self.capacity() + } + + fn free_capacity(&self) -> usize { + self.free_capacity() + } + + fn clear(&self) { + self.clear(); + } + + fn len(&self) -> usize { + self.len() + } + + fn is_empty(&self) -> bool { + self.is_empty() + } + + fn is_full(&self) -> bool { + self.is_full() + } } /// Internal state for the PubSub channel @@ -366,6 +415,22 @@ impl<T: Clone, const CAP: usize, const SUBS: usize, const PUBS: usize> PubSubSta fn unregister_publisher(&mut self) { self.publisher_count -= 1; } + + fn clear(&mut self) { + self.queue.clear(); + } + + fn len(&self) -> usize { + self.queue.len() + } + + fn is_empty(&self) -> bool { + self.queue.is_empty() + } + + fn is_full(&self) -> bool { + self.queue.is_full() + } } /// Error type for the [PubSubChannel] @@ -382,10 +447,10 @@ pub enum Error { /// 'Middle level' behaviour of the pubsub channel. /// This trait is used so that Sub and Pub can be generic over the channel. -pub trait PubSubBehavior<T> { +trait SealedPubSubBehavior<T> { /// Try to get a message from the queue with the given message id. /// - /// If the message is not yet present and a context is given, then its waker is registered in the subsriber wakers. + /// If the message is not yet present and a context is given, then its waker is registered in the subscriber wakers. fn get_message_with_context(&self, next_message_id: &mut u64, cx: Option<&mut Context<'_>>) -> Poll<WaitResult<T>>; /// Get the amount of messages that are between the given the next_message_id and the most recent message. @@ -400,8 +465,25 @@ pub trait PubSubBehavior<T> { /// Publish a message immediately fn publish_immediate(&self, message: T); - /// The amount of messages that can still be published without having to wait or without having to lag the subscribers - fn space(&self) -> usize; + /// Returns the maximum number of elements the channel can hold. + fn capacity(&self) -> usize; + + /// Returns the free capacity of the channel. + /// + /// This is equivalent to `capacity() - len()` + fn free_capacity(&self) -> usize; + + /// Clears all elements in the channel. + fn clear(&self); + + /// Returns the number of elements currently in the channel. + fn len(&self) -> usize; + + /// Returns whether the channel is empty. + fn is_empty(&self) -> bool; + + /// Returns whether the channel is full. + fn is_full(&self) -> bool; /// Let the channel know that a subscriber has dropped fn unregister_subscriber(&self, subscriber_next_message_id: u64); @@ -410,6 +492,13 @@ pub trait PubSubBehavior<T> { fn unregister_publisher(&self); } +/// 'Middle level' behaviour of the pubsub channel. +/// This trait is used so that Sub and Pub can be generic over the channel. +#[allow(private_bounds)] +pub trait PubSubBehavior<T>: SealedPubSubBehavior<T> {} + +impl<T, C: SealedPubSubBehavior<T>> PubSubBehavior<T> for C {} + /// The result of the subscriber wait procedure #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -542,6 +631,7 @@ mod tests { assert_eq!(pub0.try_publish(0), Ok(())); assert_eq!(pub0.try_publish(0), Ok(())); assert_eq!(pub0.try_publish(0), Ok(())); + assert!(pub0.is_full()); assert_eq!(pub0.try_publish(0), Err(0)); drop(sub0); @@ -574,32 +664,42 @@ mod tests { } #[futures_test::test] - async fn correct_space() { + async fn correct_len() { let channel = PubSubChannel::<NoopRawMutex, u32, 4, 4, 4>::new(); let mut sub0 = channel.subscriber().unwrap(); let mut sub1 = channel.subscriber().unwrap(); let pub0 = channel.publisher().unwrap(); - assert_eq!(pub0.space(), 4); + assert!(sub0.is_empty()); + assert!(sub1.is_empty()); + assert!(pub0.is_empty()); + assert_eq!(pub0.free_capacity(), 4); + assert_eq!(pub0.len(), 0); pub0.publish(42).await; - assert_eq!(pub0.space(), 3); + assert_eq!(pub0.free_capacity(), 3); + assert_eq!(pub0.len(), 1); pub0.publish(42).await; - assert_eq!(pub0.space(), 2); + assert_eq!(pub0.free_capacity(), 2); + assert_eq!(pub0.len(), 2); sub0.next_message().await; sub0.next_message().await; - assert_eq!(pub0.space(), 2); + assert_eq!(pub0.free_capacity(), 2); + assert_eq!(pub0.len(), 2); sub1.next_message().await; - assert_eq!(pub0.space(), 3); + assert_eq!(pub0.free_capacity(), 3); + assert_eq!(pub0.len(), 1); + sub1.next_message().await; - assert_eq!(pub0.space(), 4); + assert_eq!(pub0.free_capacity(), 4); + assert_eq!(pub0.len(), 0); } #[futures_test::test] @@ -610,29 +710,29 @@ mod tests { let mut sub0 = channel.subscriber().unwrap(); let mut sub1 = channel.subscriber().unwrap(); - assert_eq!(4, pub0.space()); + assert_eq!(4, pub0.free_capacity()); pub0.publish(1).await; pub0.publish(2).await; - assert_eq!(2, channel.space()); + assert_eq!(2, channel.free_capacity()); assert_eq!(1, sub0.try_next_message_pure().unwrap()); assert_eq!(2, sub0.try_next_message_pure().unwrap()); - assert_eq!(2, channel.space()); + assert_eq!(2, channel.free_capacity()); drop(sub0); - assert_eq!(2, channel.space()); + assert_eq!(2, channel.free_capacity()); assert_eq!(1, sub1.try_next_message_pure().unwrap()); - assert_eq!(3, channel.space()); + assert_eq!(3, channel.free_capacity()); drop(sub1); - assert_eq!(4, channel.space()); + assert_eq!(4, channel.free_capacity()); } struct CloneCallCounter(usize); diff --git a/embassy-sync/src/pubsub/publisher.rs b/embassy-sync/src/pubsub/publisher.rs index e1edc9eb9..e66b3b1db 100644 --- a/embassy-sync/src/pubsub/publisher.rs +++ b/embassy-sync/src/pubsub/publisher.rs @@ -43,12 +43,36 @@ impl<'a, PSB: PubSubBehavior<T> + ?Sized, T: Clone> Pub<'a, PSB, T> { self.channel.publish_with_context(message, None) } - /// The amount of messages that can still be published without having to wait or without having to lag the subscribers + /// Returns the maximum number of elements the ***channel*** can hold. + pub fn capacity(&self) -> usize { + self.channel.capacity() + } + + /// Returns the free capacity of the ***channel***. /// - /// *Note: In the time between checking this and a publish action, other publishers may have had time to publish something. - /// So checking doesn't give any guarantees.* - pub fn space(&self) -> usize { - self.channel.space() + /// This is equivalent to `capacity() - len()` + pub fn free_capacity(&self) -> usize { + self.channel.free_capacity() + } + + /// Clears all elements in the ***channel***. + pub fn clear(&self) { + self.channel.clear(); + } + + /// Returns the number of elements currently in the ***channel***. + pub fn len(&self) -> usize { + self.channel.len() + } + + /// Returns whether the ***channel*** is empty. + pub fn is_empty(&self) -> bool { + self.channel.is_empty() + } + + /// Returns whether the ***channel*** is full. + pub fn is_full(&self) -> bool { + self.channel.is_full() } } @@ -124,12 +148,36 @@ impl<'a, PSB: PubSubBehavior<T> + ?Sized, T: Clone> ImmediatePub<'a, PSB, T> { self.channel.publish_with_context(message, None) } - /// The amount of messages that can still be published without having to wait or without having to lag the subscribers + /// Returns the maximum number of elements the ***channel*** can hold. + pub fn capacity(&self) -> usize { + self.channel.capacity() + } + + /// Returns the free capacity of the ***channel***. /// - /// *Note: In the time between checking this and a publish action, other publishers may have had time to publish something. - /// So checking doesn't give any guarantees.* - pub fn space(&self) -> usize { - self.channel.space() + /// This is equivalent to `capacity() - len()` + pub fn free_capacity(&self) -> usize { + self.channel.free_capacity() + } + + /// Clears all elements in the ***channel***. + pub fn clear(&self) { + self.channel.clear(); + } + + /// Returns the number of elements currently in the ***channel***. + pub fn len(&self) -> usize { + self.channel.len() + } + + /// Returns whether the ***channel*** is empty. + pub fn is_empty(&self) -> bool { + self.channel.is_empty() + } + + /// Returns whether the ***channel*** is full. + pub fn is_full(&self) -> bool { + self.channel.is_full() } } diff --git a/embassy-sync/src/pubsub/subscriber.rs b/embassy-sync/src/pubsub/subscriber.rs index f420a75f0..6ad660cb3 100644 --- a/embassy-sync/src/pubsub/subscriber.rs +++ b/embassy-sync/src/pubsub/subscriber.rs @@ -65,10 +65,44 @@ impl<'a, PSB: PubSubBehavior<T> + ?Sized, T: Clone> Sub<'a, PSB, T> { } } - /// The amount of messages this subscriber hasn't received yet + /// The amount of messages this subscriber hasn't received yet. This is like [Self::len] but specifically + /// for this subscriber. pub fn available(&self) -> u64 { self.channel.available(self.next_message_id) } + + /// Returns the maximum number of elements the ***channel*** can hold. + pub fn capacity(&self) -> usize { + self.channel.capacity() + } + + /// Returns the free capacity of the ***channel***. + /// + /// This is equivalent to `capacity() - len()` + pub fn free_capacity(&self) -> usize { + self.channel.free_capacity() + } + + /// Clears all elements in the ***channel***. + pub fn clear(&self) { + self.channel.clear(); + } + + /// Returns the number of elements currently in the ***channel***. + /// See [Self::available] for how many messages are available for this subscriber. + pub fn len(&self) -> usize { + self.channel.len() + } + + /// Returns whether the ***channel*** is empty. + pub fn is_empty(&self) -> bool { + self.channel.is_empty() + } + + /// Returns whether the ***channel*** is full. + pub fn is_full(&self) -> bool { + self.channel.is_full() + } } impl<'a, PSB: PubSubBehavior<T> + ?Sized, T: Clone> Drop for Sub<'a, PSB, T> { diff --git a/embassy-sync/src/waitqueue/multi_waker.rs b/embassy-sync/src/waitqueue/multi_waker.rs index 824d192da..0e520bf40 100644 --- a/embassy-sync/src/waitqueue/multi_waker.rs +++ b/embassy-sync/src/waitqueue/multi_waker.rs @@ -14,7 +14,7 @@ impl<const N: usize> MultiWakerRegistration<N> { } /// Register a waker. If the buffer is full the function returns it in the error - pub fn register<'a>(&mut self, w: &'a Waker) { + pub fn register(&mut self, w: &Waker) { // If we already have some waker that wakes the same task as `w`, do nothing. // This avoids cloning wakers, and avoids unnecessary mass-wakes. for w2 in &self.wakers { diff --git a/embassy-time-queue-driver/README.md b/embassy-time-queue-driver/README.md index 8852b0358..b9fb12d94 100644 --- a/embassy-time-queue-driver/README.md +++ b/embassy-time-queue-driver/README.md @@ -4,5 +4,5 @@ This crate contains the driver trait used by the [`embassy-time`](https://crates You should rarely need to use this crate directly. Only use it when implementing your own timer queue. -There is two timer queue implementations, one in `embassy-time` enabled by the `generic-queue` feature, and +There is two timer queue implementations, one in `embassy-time` enabled by the `generic-queue` feature, and another in `embassy-executor` enabled by the `integrated-timers` feature. diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml index 6b0a0f22d..ca7ad2d09 100644 --- a/embassy-time/Cargo.toml +++ b/embassy-time/Cargo.toml @@ -42,7 +42,7 @@ generic-queue = [] #! The following features set how many timers are used for the generic queue. At most one #! `generic-queue-*` feature can be enabled. If none is enabled, a default of 64 timers is used. -#! +#! #! When using embassy-time from libraries, you should *not* enable any `generic-queue-*` feature, to allow the #! end user to pick. @@ -60,7 +60,7 @@ generic-queue-128 = ["generic-queue"] #! ### Tick Rate #! #! At most 1 `tick-*` feature can be enabled. If none is enabled, a default of 1MHz is used. -#! +#! #! If the time driver in use supports using arbitrary tick rates, you can enable one `tick-*` #! feature from your binary crate to set the tick rate. The driver will use configured tick rate. #! If the time driver supports a fixed tick rate, it will enable one feature itself, so you should @@ -71,7 +71,7 @@ generic-queue-128 = ["generic-queue"] #! <details> #! <summary>Available tick rates:</summary> #! <!-- Next line must be left empty for the features to render correctly! --> -#! +#! # BEGIN TICKS # Generated by gen_tick.py. DO NOT EDIT. diff --git a/embassy-time/README.md b/embassy-time/README.md index f5d46df7b..6a4b049b4 100644 --- a/embassy-time/README.md +++ b/embassy-time/README.md @@ -5,7 +5,7 @@ Timekeeping, delays and timeouts. Timekeeping is done with elapsed time since system boot. Time is represented in ticks, where the tick rate is defined either by the driver (in the case of a fixed-rate tick) or chosen by the user with a [tick rate](#tick-rate) feature. The chosen -tick rate applies to everything in `embassy-time` and thus determines the maximum +tick rate applies to everything in `embassy-time` and thus determines the maximum timing resolution of <code>(1 / tick_rate) seconds</code>. Tick counts are 64 bits. The default tick rate of 1Mhz supports diff --git a/embassy-time/src/queue_generic.rs b/embassy-time/src/queue_generic.rs index cf7a986d5..4882afd3e 100644 --- a/embassy-time/src/queue_generic.rs +++ b/embassy-time/src/queue_generic.rs @@ -177,9 +177,10 @@ embassy_time_queue_driver::timer_queue_impl!(static QUEUE: Queue = Queue::new()) #[cfg(test)] #[cfg(feature = "mock-driver")] mod tests { - use core::cell::Cell; - use core::task::{RawWaker, RawWakerVTable, Waker}; - use std::rc::Rc; + use core::sync::atomic::{AtomicBool, Ordering}; + use core::task::Waker; + use std::sync::Arc; + use std::task::Wake; use serial_test::serial; @@ -188,42 +189,26 @@ mod tests { use crate::{Duration, Instant}; struct TestWaker { - pub awoken: Rc<Cell<bool>>, - pub waker: Waker, + pub awoken: AtomicBool, } - impl TestWaker { - fn new() -> Self { - let flag = Rc::new(Cell::new(false)); - - const VTABLE: RawWakerVTable = RawWakerVTable::new( - |data: *const ()| { - unsafe { - Rc::increment_strong_count(data as *const Cell<bool>); - } - - RawWaker::new(data as _, &VTABLE) - }, - |data: *const ()| unsafe { - let data = data as *const Cell<bool>; - data.as_ref().unwrap().set(true); - Rc::decrement_strong_count(data); - }, - |data: *const ()| unsafe { - (data as *const Cell<bool>).as_ref().unwrap().set(true); - }, - |data: *const ()| unsafe { - Rc::decrement_strong_count(data); - }, - ); - - let raw = RawWaker::new(Rc::into_raw(flag.clone()) as _, &VTABLE); - - Self { - awoken: flag.clone(), - waker: unsafe { Waker::from_raw(raw) }, - } + impl Wake for TestWaker { + fn wake(self: Arc<Self>) { + self.awoken.store(true, Ordering::Relaxed); } + + fn wake_by_ref(self: &Arc<Self>) { + self.awoken.store(true, Ordering::Relaxed); + } + } + + fn test_waker() -> (Arc<TestWaker>, Waker) { + let arc = Arc::new(TestWaker { + awoken: AtomicBool::new(false), + }); + let waker = Waker::from(arc.clone()); + + (arc, waker) } fn setup() { @@ -249,11 +234,11 @@ mod tests { assert_eq!(queue_len(), 0); - let waker = TestWaker::new(); + let (flag, waker) = test_waker(); - QUEUE.schedule_wake(Instant::from_secs(1), &waker.waker); + QUEUE.schedule_wake(Instant::from_secs(1), &waker); - assert!(!waker.awoken.get()); + assert!(!flag.awoken.load(Ordering::Relaxed)); assert_eq!(queue_len(), 1); } @@ -262,23 +247,23 @@ mod tests { fn test_schedule_same() { setup(); - let waker = TestWaker::new(); + let (_flag, waker) = test_waker(); - QUEUE.schedule_wake(Instant::from_secs(1), &waker.waker); + QUEUE.schedule_wake(Instant::from_secs(1), &waker); assert_eq!(queue_len(), 1); - QUEUE.schedule_wake(Instant::from_secs(1), &waker.waker); + QUEUE.schedule_wake(Instant::from_secs(1), &waker); assert_eq!(queue_len(), 1); - QUEUE.schedule_wake(Instant::from_secs(100), &waker.waker); + QUEUE.schedule_wake(Instant::from_secs(100), &waker); assert_eq!(queue_len(), 1); - let waker2 = TestWaker::new(); + let (_flag2, waker2) = test_waker(); - QUEUE.schedule_wake(Instant::from_secs(100), &waker2.waker); + QUEUE.schedule_wake(Instant::from_secs(100), &waker2); assert_eq!(queue_len(), 2); } @@ -288,21 +273,21 @@ mod tests { fn test_trigger() { setup(); - let waker = TestWaker::new(); + let (flag, waker) = test_waker(); - QUEUE.schedule_wake(Instant::from_secs(100), &waker.waker); + QUEUE.schedule_wake(Instant::from_secs(100), &waker); - assert!(!waker.awoken.get()); + assert!(!flag.awoken.load(Ordering::Relaxed)); MockDriver::get().advance(Duration::from_secs(99)); - assert!(!waker.awoken.get()); + assert!(!flag.awoken.load(Ordering::Relaxed)); assert_eq!(queue_len(), 1); MockDriver::get().advance(Duration::from_secs(1)); - assert!(waker.awoken.get()); + assert!(flag.awoken.load(Ordering::Relaxed)); assert_eq!(queue_len(), 0); } @@ -312,18 +297,18 @@ mod tests { fn test_immediate_trigger() { setup(); - let waker = TestWaker::new(); + let (flag, waker) = test_waker(); - QUEUE.schedule_wake(Instant::from_secs(100), &waker.waker); + QUEUE.schedule_wake(Instant::from_secs(100), &waker); MockDriver::get().advance(Duration::from_secs(50)); - let waker2 = TestWaker::new(); + let (flag2, waker2) = test_waker(); - QUEUE.schedule_wake(Instant::from_secs(40), &waker2.waker); + QUEUE.schedule_wake(Instant::from_secs(40), &waker2); - assert!(!waker.awoken.get()); - assert!(waker2.awoken.get()); + assert!(!flag.awoken.load(Ordering::Relaxed)); + assert!(flag2.awoken.load(Ordering::Relaxed)); assert_eq!(queue_len(), 1); } @@ -333,30 +318,31 @@ mod tests { setup(); for i in 1..super::QUEUE_SIZE { - let waker = TestWaker::new(); + let (flag, waker) = test_waker(); - QUEUE.schedule_wake(Instant::from_secs(310), &waker.waker); + QUEUE.schedule_wake(Instant::from_secs(310), &waker); assert_eq!(queue_len(), i); - assert!(!waker.awoken.get()); + assert!(!flag.awoken.load(Ordering::Relaxed)); } - let first_waker = TestWaker::new(); + let (flag, waker) = test_waker(); - QUEUE.schedule_wake(Instant::from_secs(300), &first_waker.waker); + QUEUE.schedule_wake(Instant::from_secs(300), &waker); assert_eq!(queue_len(), super::QUEUE_SIZE); - assert!(!first_waker.awoken.get()); + assert!(!flag.awoken.load(Ordering::Relaxed)); - let second_waker = TestWaker::new(); + let (flag2, waker2) = test_waker(); - QUEUE.schedule_wake(Instant::from_secs(305), &second_waker.waker); + QUEUE.schedule_wake(Instant::from_secs(305), &waker2); assert_eq!(queue_len(), super::QUEUE_SIZE); - assert!(first_waker.awoken.get()); + assert!(flag.awoken.load(Ordering::Relaxed)); - QUEUE.schedule_wake(Instant::from_secs(320), &TestWaker::new().waker); + let (_flag3, waker3) = test_waker(); + QUEUE.schedule_wake(Instant::from_secs(320), &waker3); assert_eq!(queue_len(), super::QUEUE_SIZE); - assert!(second_waker.awoken.get()); + assert!(flag2.awoken.load(Ordering::Relaxed)); } } diff --git a/embassy-time/src/timer.rs b/embassy-time/src/timer.rs index 757c3ff00..bc39d8bc7 100644 --- a/embassy-time/src/timer.rs +++ b/embassy-time/src/timer.rs @@ -1,10 +1,10 @@ use core::future::{poll_fn, Future}; -use core::pin::Pin; +use core::pin::{pin, Pin}; use core::task::{Context, Poll}; use futures_util::future::{select, Either}; use futures_util::stream::FusedStream; -use futures_util::{pin_mut, Stream}; +use futures_util::Stream; use crate::{Duration, Instant}; @@ -19,8 +19,7 @@ pub struct TimeoutError; /// work on the future is stopped (`poll` is no longer called), the future is dropped and `Err(TimeoutError)` is returned. pub async fn with_timeout<F: Future>(timeout: Duration, fut: F) -> Result<F::Output, TimeoutError> { let timeout_fut = Timer::after(timeout); - pin_mut!(fut); - match select(fut, timeout_fut).await { + match select(pin!(fut), timeout_fut).await { Either::Left((r, _)) => Ok(r), Either::Right(_) => Err(TimeoutError), } @@ -32,8 +31,7 @@ pub async fn with_timeout<F: Future>(timeout: Duration, fut: F) -> Result<F::Out /// work on the future is stopped (`poll` is no longer called), the future is dropped and `Err(TimeoutError)` is returned. pub async fn with_deadline<F: Future>(at: Instant, fut: F) -> Result<F::Output, TimeoutError> { let timeout_fut = Timer::at(at); - pin_mut!(fut); - match select(fut, timeout_fut).await { + match select(pin!(fut), timeout_fut).await { Either::Left((r, _)) => Ok(r), Either::Right(_) => Err(TimeoutError), } diff --git a/embassy-usb-dfu/Cargo.toml b/embassy-usb-dfu/Cargo.toml index 4d6ffeb5f..267e412c0 100644 --- a/embassy-usb-dfu/Cargo.toml +++ b/embassy-usb-dfu/Cargo.toml @@ -31,9 +31,9 @@ cortex-m = { version = "0.7.7", features = ["inline-asm"], optional = true } defmt = { version = "0.3.5", optional = true } embassy-boot = { version = "0.2.0", path = "../embassy-boot" } embassy-futures = { version = "0.1.1", path = "../embassy-futures" } -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embassy-time = { version = "0.3.0", path = "../embassy-time" } -embassy-usb = { version = "0.1.0", path = "../embassy-usb", default-features = false } +embassy-usb = { version = "0.2.0", path = "../embassy-usb", default-features = false } embedded-storage = { version = "0.3.1" } esp32c3-hal = { version = "0.13.0", optional = true, default-features = false } diff --git a/embassy-usb-driver/Cargo.toml b/embassy-usb-driver/Cargo.toml index 837878621..41493f00d 100644 --- a/embassy-usb-driver/Cargo.toml +++ b/embassy-usb-driver/Cargo.toml @@ -9,10 +9,8 @@ categories = ["embedded", "hardware-support", "no-std", "asynchronous"] repository = "https://github.com/embassy-rs/embassy" documentation = "https://docs.embassy.dev/embassy-usb-driver" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [package.metadata.embassy_docs] -src_base = "https://github.com/embassy-rs/embassy/blob/embassy-usb-driver-v$VERSION/embassy-usb/src/" +src_base = "https://github.com/embassy-rs/embassy/blob/embassy-usb-driver-v$VERSION/embassy-usb-driver/src/" src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-usb-driver/src/" features = ["defmt"] target = "thumbv7em-none-eabi" diff --git a/embassy-usb-logger/CHANGELOG.md b/embassy-usb-logger/CHANGELOG.md new file mode 100644 index 000000000..4cd84b8be --- /dev/null +++ b/embassy-usb-logger/CHANGELOG.md @@ -0,0 +1,28 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +## 0.2.0 - 2024-05-20 + +### Added + +- [#2414](https://github.com/embassy-rs/embassy/pull/2414) USB logger can now use an existing USB device (@JomerDev) + +### Changed + +- Update `embassy-usb` to 0.2.0 + +### Fixed + +- No more data loss at `Pipe` wraparound +- [#2414](https://github.com/embassy-rs/embassy/pull/2414) Messages that are exactly `MAX_PACKET_SIZE` long are no +longer delayed (@JomerDev) + +## 0.1.0 - 2024-01-14 + +- Initial Release diff --git a/embassy-usb-logger/Cargo.toml b/embassy-usb-logger/Cargo.toml index cb23fed1b..62b4ee723 100644 --- a/embassy-usb-logger/Cargo.toml +++ b/embassy-usb-logger/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-usb-logger" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "MIT OR Apache-2.0" description = "`log` implementation for USB serial using `embassy-usb`." @@ -15,7 +15,7 @@ src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-usb-l target = "thumbv7em-none-eabi" [dependencies] -embassy-usb = { version = "0.1.0", path = "../embassy-usb" } -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-usb = { version = "0.2.0", path = "../embassy-usb" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } log = "0.4" diff --git a/embassy-usb-synopsys-otg/Cargo.toml b/embassy-usb-synopsys-otg/Cargo.toml new file mode 100644 index 000000000..68ab0415f --- /dev/null +++ b/embassy-usb-synopsys-otg/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "embassy-usb-synopsys-otg" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" +description = "`embassy-usb-driver` implementation for Synopsys OTG USB controllers" +keywords = ["embedded", "async", "usb", "hal", "embedded-hal"] +categories = ["embedded", "hardware-support", "no-std", "asynchronous"] +repository = "https://github.com/embassy-rs/embassy" +documentation = "https://docs.embassy.dev/embassy-usb-synopsys-otg" + +[package.metadata.embassy_docs] +src_base = "https://github.com/embassy-rs/embassy/blob/embassy-usb-synopsys-otg-v$VERSION/embassy-usb-synopsys-otg/src/" +src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-usb-synopsys-otg/src/" +features = ["defmt"] +target = "thumbv7em-none-eabi" + +[dependencies] +critical-section = "1.1" + +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } +embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver" } + +defmt = { version = "0.3", optional = true } +log = { version = "0.4.14", optional = true } diff --git a/embassy-usb-synopsys-otg/README.md b/embassy-usb-synopsys-otg/README.md new file mode 100644 index 000000000..5354f07bf --- /dev/null +++ b/embassy-usb-synopsys-otg/README.md @@ -0,0 +1,16 @@ +# Embassy USB driver for the Synopsys USB OTG core + +This crate implements [`embassy-usb-driver`](https://crates.io/crates/embassy-usb-driver) for Synopsys USB OTG devices. + +It contains the "core" of the driver that is common across all chips using +the Synopsys OTG IP, but it doesn't contain chip-specific initialization such +as clock setup and GPIO muxing. You most likely don't want to use this crate +directly, but use it through a HAL that does the initialization for you. + +List of HALs integrating this driver: + +- [`embassy-stm32`](https://crates.io/crates/embassy-stm32), for STMicroelectronics STM32 chips. +- [`esp-hal`](https://crates.io/crates/esp-hal), for Espressif ESP32 chips. + +If you wish to integrate this crate into your device's HAL, you will need to add the +device-specific initialization. See the above crates for examples on how to do it. \ No newline at end of file diff --git a/embassy-usb-synopsys-otg/src/fmt.rs b/embassy-usb-synopsys-otg/src/fmt.rs new file mode 100644 index 000000000..2ac42c557 --- /dev/null +++ b/embassy-usb-synopsys-otg/src/fmt.rs @@ -0,0 +1,257 @@ +#![macro_use] +#![allow(unused)] + +use core::fmt::{Debug, Display, LowerHex}; + +#[cfg(all(feature = "defmt", feature = "log"))] +compile_error!("You may not enable both `defmt` and `log` features."); + +macro_rules! assert { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::assert!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::assert!($($x)*); + } + }; +} + +macro_rules! assert_eq { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::assert_eq!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::assert_eq!($($x)*); + } + }; +} + +macro_rules! assert_ne { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::assert_ne!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::assert_ne!($($x)*); + } + }; +} + +macro_rules! debug_assert { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::debug_assert!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::debug_assert!($($x)*); + } + }; +} + +macro_rules! debug_assert_eq { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::debug_assert_eq!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::debug_assert_eq!($($x)*); + } + }; +} + +macro_rules! debug_assert_ne { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::debug_assert_ne!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::debug_assert_ne!($($x)*); + } + }; +} + +macro_rules! todo { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::todo!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::todo!($($x)*); + } + }; +} + +#[cfg(not(feature = "defmt"))] +macro_rules! unreachable { + ($($x:tt)*) => { + ::core::unreachable!($($x)*) + }; +} + +#[cfg(feature = "defmt")] +macro_rules! unreachable { + ($($x:tt)*) => { + ::defmt::unreachable!($($x)*) + }; +} + +macro_rules! panic { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::panic!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::panic!($($x)*); + } + }; +} + +macro_rules! trace { + ($s:literal $(, $x:expr)* $(,)?) => { + { + #[cfg(feature = "log")] + ::log::trace!($s $(, $x)*); + #[cfg(feature = "defmt")] + ::defmt::trace!($s $(, $x)*); + #[cfg(not(any(feature = "log", feature="defmt")))] + let _ = ($( & $x ),*); + } + }; +} + +macro_rules! debug { + ($s:literal $(, $x:expr)* $(,)?) => { + { + #[cfg(feature = "log")] + ::log::debug!($s $(, $x)*); + #[cfg(feature = "defmt")] + ::defmt::debug!($s $(, $x)*); + #[cfg(not(any(feature = "log", feature="defmt")))] + let _ = ($( & $x ),*); + } + }; +} + +macro_rules! info { + ($s:literal $(, $x:expr)* $(,)?) => { + { + #[cfg(feature = "log")] + ::log::info!($s $(, $x)*); + #[cfg(feature = "defmt")] + ::defmt::info!($s $(, $x)*); + #[cfg(not(any(feature = "log", feature="defmt")))] + let _ = ($( & $x ),*); + } + }; +} + +macro_rules! warn { + ($s:literal $(, $x:expr)* $(,)?) => { + { + #[cfg(feature = "log")] + ::log::warn!($s $(, $x)*); + #[cfg(feature = "defmt")] + ::defmt::warn!($s $(, $x)*); + #[cfg(not(any(feature = "log", feature="defmt")))] + let _ = ($( & $x ),*); + } + }; +} + +macro_rules! error { + ($s:literal $(, $x:expr)* $(,)?) => { + { + #[cfg(feature = "log")] + ::log::error!($s $(, $x)*); + #[cfg(feature = "defmt")] + ::defmt::error!($s $(, $x)*); + #[cfg(not(any(feature = "log", feature="defmt")))] + let _ = ($( & $x ),*); + } + }; +} + +#[cfg(feature = "defmt")] +macro_rules! unwrap { + ($($x:tt)*) => { + ::defmt::unwrap!($($x)*) + }; +} + +#[cfg(not(feature = "defmt"))] +macro_rules! unwrap { + ($arg:expr) => { + match $crate::fmt::Try::into_result($arg) { + ::core::result::Result::Ok(t) => t, + ::core::result::Result::Err(e) => { + ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e); + } + } + }; + ($arg:expr, $($msg:expr),+ $(,)? ) => { + match $crate::fmt::Try::into_result($arg) { + ::core::result::Result::Ok(t) => t, + ::core::result::Result::Err(e) => { + ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e); + } + } + } +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub struct NoneError; + +pub trait Try { + type Ok; + type Error; + fn into_result(self) -> Result<Self::Ok, Self::Error>; +} + +impl<T> Try for Option<T> { + type Ok = T; + type Error = NoneError; + + #[inline] + fn into_result(self) -> Result<T, NoneError> { + self.ok_or(NoneError) + } +} + +impl<T, E> Try for Result<T, E> { + type Ok = T; + type Error = E; + + #[inline] + fn into_result(self) -> Self { + self + } +} + +pub(crate) struct Bytes<'a>(pub &'a [u8]); + +impl<'a> Debug for Bytes<'a> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{:#02x?}", self.0) + } +} + +impl<'a> Display for Bytes<'a> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{:#02x?}", self.0) + } +} + +impl<'a> LowerHex for Bytes<'a> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{:#02x?}", self.0) + } +} + +#[cfg(feature = "defmt")] +impl<'a> defmt::Format for Bytes<'a> { + fn format(&self, fmt: defmt::Formatter) { + defmt::write!(fmt, "{:02x}", self.0) + } +} diff --git a/embassy-usb-synopsys-otg/src/lib.rs b/embassy-usb-synopsys-otg/src/lib.rs new file mode 100644 index 000000000..b90e059f6 --- /dev/null +++ b/embassy-usb-synopsys-otg/src/lib.rs @@ -0,0 +1,1336 @@ +#![cfg_attr(not(test), no_std)] +#![allow(async_fn_in_trait)] +#![doc = include_str!("../README.md")] +#![warn(missing_docs)] + +// This must go FIRST so that all the other modules see its macros. +mod fmt; + +use core::cell::UnsafeCell; +use core::future::poll_fn; +use core::marker::PhantomData; +use core::sync::atomic::{AtomicBool, AtomicU16, Ordering}; +use core::task::Poll; + +use embassy_sync::waitqueue::AtomicWaker; +use embassy_usb_driver::{ + Bus as _, Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointIn, EndpointInfo, EndpointOut, + EndpointType, Event, Unsupported, +}; + +pub mod otg_v1; + +use otg_v1::{regs, vals, Otg}; + +/// Handle interrupts. +pub unsafe fn on_interrupt<const MAX_EP_COUNT: usize>( + r: Otg, + state: &State<MAX_EP_COUNT>, + ep_count: usize, + quirk_setup_late_cnak: bool, +) { + let ints = r.gintsts().read(); + if ints.wkupint() || ints.usbsusp() || ints.usbrst() || ints.enumdne() || ints.otgint() || ints.srqint() { + // Mask interrupts and notify `Bus` to process them + r.gintmsk().write(|_| {}); + state.bus_waker.wake(); + } + + // Handle RX + while r.gintsts().read().rxflvl() { + let status = r.grxstsp().read(); + trace!("=== status {:08x}", status.0); + let ep_num = status.epnum() as usize; + let len = status.bcnt() as usize; + + assert!(ep_num < ep_count); + + match status.pktstsd() { + vals::Pktstsd::SETUP_DATA_RX => { + trace!("SETUP_DATA_RX"); + assert!(len == 8, "invalid SETUP packet length={}", len); + assert!(ep_num == 0, "invalid SETUP packet endpoint={}", ep_num); + + // flushing TX if something stuck in control endpoint + if r.dieptsiz(ep_num).read().pktcnt() != 0 { + r.grstctl().modify(|w| { + w.set_txfnum(ep_num as _); + w.set_txfflsh(true); + }); + while r.grstctl().read().txfflsh() {} + } + + if state.cp_state.setup_ready.load(Ordering::Relaxed) == false { + // SAFETY: exclusive access ensured by atomic bool + let data = unsafe { &mut *state.cp_state.setup_data.get() }; + data[0..4].copy_from_slice(&r.fifo(0).read().0.to_ne_bytes()); + data[4..8].copy_from_slice(&r.fifo(0).read().0.to_ne_bytes()); + state.cp_state.setup_ready.store(true, Ordering::Release); + state.ep_states[0].out_waker.wake(); + } else { + error!("received SETUP before previous finished processing"); + // discard FIFO + r.fifo(0).read(); + r.fifo(0).read(); + } + } + vals::Pktstsd::OUT_DATA_RX => { + trace!("OUT_DATA_RX ep={} len={}", ep_num, len); + + if state.ep_states[ep_num].out_size.load(Ordering::Acquire) == EP_OUT_BUFFER_EMPTY { + // SAFETY: Buffer size is allocated to be equal to endpoint's maximum packet size + // We trust the peripheral to not exceed its configured MPSIZ + let buf = + unsafe { core::slice::from_raw_parts_mut(*state.ep_states[ep_num].out_buffer.get(), len) }; + + for chunk in buf.chunks_mut(4) { + // RX FIFO is shared so always read from fifo(0) + let data = r.fifo(0).read().0; + chunk.copy_from_slice(&data.to_ne_bytes()[0..chunk.len()]); + } + + state.ep_states[ep_num].out_size.store(len as u16, Ordering::Release); + state.ep_states[ep_num].out_waker.wake(); + } else { + error!("ep_out buffer overflow index={}", ep_num); + + // discard FIFO data + let len_words = (len + 3) / 4; + for _ in 0..len_words { + r.fifo(0).read().data(); + } + } + } + vals::Pktstsd::OUT_DATA_DONE => { + trace!("OUT_DATA_DONE ep={}", ep_num); + } + vals::Pktstsd::SETUP_DATA_DONE => { + trace!("SETUP_DATA_DONE ep={}", ep_num); + + if quirk_setup_late_cnak { + // Clear NAK to indicate we are ready to receive more data + r.doepctl(ep_num).modify(|w| w.set_cnak(true)); + } + } + x => trace!("unknown PKTSTS: {}", x.to_bits()), + } + } + + // IN endpoint interrupt + if ints.iepint() { + let mut ep_mask = r.daint().read().iepint(); + let mut ep_num = 0; + + // Iterate over endpoints while there are non-zero bits in the mask + while ep_mask != 0 { + if ep_mask & 1 != 0 { + let ep_ints = r.diepint(ep_num).read(); + + // clear all + r.diepint(ep_num).write_value(ep_ints); + + // TXFE is cleared in DIEPEMPMSK + if ep_ints.txfe() { + critical_section::with(|_| { + r.diepempmsk().modify(|w| { + w.set_ineptxfem(w.ineptxfem() & !(1 << ep_num)); + }); + }); + } + + state.ep_states[ep_num].in_waker.wake(); + trace!("in ep={} irq val={:08x}", ep_num, ep_ints.0); + } + + ep_mask >>= 1; + ep_num += 1; + } + } + + // not needed? reception handled in rxflvl + // OUT endpoint interrupt + // if ints.oepint() { + // let mut ep_mask = r.daint().read().oepint(); + // let mut ep_num = 0; + + // while ep_mask != 0 { + // if ep_mask & 1 != 0 { + // let ep_ints = r.doepint(ep_num).read(); + // // clear all + // r.doepint(ep_num).write_value(ep_ints); + // state.ep_out_wakers[ep_num].wake(); + // trace!("out ep={} irq val={:08x}", ep_num, ep_ints.0); + // } + + // ep_mask >>= 1; + // ep_num += 1; + // } + // } +} + +/// USB PHY type +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum PhyType { + /// Internal Full-Speed PHY + /// + /// Available on most High-Speed peripherals. + InternalFullSpeed, + /// Internal High-Speed PHY + /// + /// Available on a few STM32 chips. + InternalHighSpeed, + /// External ULPI High-Speed PHY + ExternalHighSpeed, +} + +impl PhyType { + /// Get whether this PHY is any of the internal types. + pub fn internal(&self) -> bool { + match self { + PhyType::InternalFullSpeed | PhyType::InternalHighSpeed => true, + PhyType::ExternalHighSpeed => false, + } + } + + /// Get whether this PHY is any of the high-speed types. + pub fn high_speed(&self) -> bool { + match self { + PhyType::InternalFullSpeed => false, + PhyType::ExternalHighSpeed | PhyType::InternalHighSpeed => true, + } + } + + fn to_dspd(&self) -> vals::Dspd { + match self { + PhyType::InternalFullSpeed => vals::Dspd::FULL_SPEED_INTERNAL, + PhyType::InternalHighSpeed => vals::Dspd::HIGH_SPEED, + PhyType::ExternalHighSpeed => vals::Dspd::HIGH_SPEED, + } + } +} + +/// Indicates that [State::ep_out_buffers] is empty. +const EP_OUT_BUFFER_EMPTY: u16 = u16::MAX; + +struct EpState { + in_waker: AtomicWaker, + out_waker: AtomicWaker, + /// RX FIFO is shared so extra buffers are needed to dequeue all data without waiting on each endpoint. + /// Buffers are ready when associated [State::ep_out_size] != [EP_OUT_BUFFER_EMPTY]. + out_buffer: UnsafeCell<*mut u8>, + out_size: AtomicU16, +} + +// SAFETY: The EndpointAllocator ensures that the buffer points to valid memory exclusive for each endpoint and is +// large enough to hold the maximum packet size. Access to the buffer is synchronized between the USB interrupt and the +// EndpointOut impl using the out_size atomic variable. +unsafe impl Send for EpState {} +unsafe impl Sync for EpState {} + +struct ControlPipeSetupState { + /// Holds received SETUP packets. Available if [Ep0State::setup_ready] is true. + setup_data: UnsafeCell<[u8; 8]>, + setup_ready: AtomicBool, +} + +/// USB OTG driver state. +pub struct State<const EP_COUNT: usize> { + cp_state: ControlPipeSetupState, + ep_states: [EpState; EP_COUNT], + bus_waker: AtomicWaker, +} + +unsafe impl<const EP_COUNT: usize> Send for State<EP_COUNT> {} +unsafe impl<const EP_COUNT: usize> Sync for State<EP_COUNT> {} + +impl<const EP_COUNT: usize> State<EP_COUNT> { + /// Create a new State. + pub const fn new() -> Self { + const NEW_AW: AtomicWaker = AtomicWaker::new(); + const NEW_BUF: UnsafeCell<*mut u8> = UnsafeCell::new(0 as _); + const NEW_SIZE: AtomicU16 = AtomicU16::new(EP_OUT_BUFFER_EMPTY); + const NEW_EP_STATE: EpState = EpState { + in_waker: NEW_AW, + out_waker: NEW_AW, + out_buffer: NEW_BUF, + out_size: NEW_SIZE, + }; + + Self { + cp_state: ControlPipeSetupState { + setup_data: UnsafeCell::new([0u8; 8]), + setup_ready: AtomicBool::new(false), + }, + ep_states: [NEW_EP_STATE; EP_COUNT], + bus_waker: NEW_AW, + } + } +} + +#[derive(Debug, Clone, Copy)] +struct EndpointData { + ep_type: EndpointType, + max_packet_size: u16, + fifo_size_words: u16, +} + +/// USB driver config. +#[non_exhaustive] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub struct Config { + /// Enable VBUS detection. + /// + /// The USB spec requires USB devices monitor for USB cable plug/unplug and react accordingly. + /// This is done by checking whether there is 5V on the VBUS pin or not. + /// + /// If your device is bus-powered (powers itself from the USB host via VBUS), then this is optional. + /// (If there's no power in VBUS your device would be off anyway, so it's fine to always assume + /// there's power in VBUS, i.e. the USB cable is always plugged in.) + /// + /// If your device is self-powered (i.e. it gets power from a source other than the USB cable, and + /// therefore can stay powered through USB cable plug/unplug) then you MUST set this to true. + /// + /// If you set this to true, you must connect VBUS to PA9 for FS, PB13 for HS, possibly with a + /// voltage divider. See ST application note AN4879 and the reference manual for more details. + pub vbus_detection: bool, + + /// Enable transceiver delay. + /// + /// Some ULPI PHYs like the Microchip USB334x series require a delay between the ULPI register write that initiates + /// the HS Chirp and the subsequent transmit command, otherwise the HS Chirp does not get executed and the deivce + /// enumerates in FS mode. Some USB Link IP like those in the STM32H7 series support adding this delay to work with + /// the affected PHYs. + pub xcvrdly: bool, +} + +impl Default for Config { + fn default() -> Self { + Self { + vbus_detection: false, + xcvrdly: false, + } + } +} + +/// USB OTG driver. +pub struct Driver<'d, const MAX_EP_COUNT: usize> { + config: Config, + ep_in: [Option<EndpointData>; MAX_EP_COUNT], + ep_out: [Option<EndpointData>; MAX_EP_COUNT], + ep_out_buffer: &'d mut [u8], + ep_out_buffer_offset: usize, + instance: OtgInstance<'d, MAX_EP_COUNT>, +} + +impl<'d, const MAX_EP_COUNT: usize> Driver<'d, MAX_EP_COUNT> { + /// Initializes the USB OTG peripheral. + /// + /// # Arguments + /// + /// * `ep_out_buffer` - An internal buffer used to temporarily store received packets. + /// Must be large enough to fit all OUT endpoint max packet sizes. + /// Endpoint allocation will fail if it is too small. + /// * `instance` - The USB OTG peripheral instance and its configuration. + /// * `config` - The USB driver configuration. + pub fn new(ep_out_buffer: &'d mut [u8], instance: OtgInstance<'d, MAX_EP_COUNT>, config: Config) -> Self { + Self { + config, + ep_in: [None; MAX_EP_COUNT], + ep_out: [None; MAX_EP_COUNT], + ep_out_buffer, + ep_out_buffer_offset: 0, + instance, + } + } + + /// Returns the total amount of words (u32) allocated in dedicated FIFO. + fn allocated_fifo_words(&self) -> u16 { + self.instance.extra_rx_fifo_words + ep_fifo_size(&self.ep_out) + ep_fifo_size(&self.ep_in) + } + + /// Creates an [`Endpoint`] with the given parameters. + fn alloc_endpoint<D: Dir>( + &mut self, + ep_type: EndpointType, + max_packet_size: u16, + interval_ms: u8, + ) -> Result<Endpoint<'d, D>, EndpointAllocError> { + trace!( + "allocating type={:?} mps={:?} interval_ms={}, dir={:?}", + ep_type, + max_packet_size, + interval_ms, + D::dir() + ); + + if D::dir() == Direction::Out { + if self.ep_out_buffer_offset + max_packet_size as usize >= self.ep_out_buffer.len() { + error!("Not enough endpoint out buffer capacity"); + return Err(EndpointAllocError); + } + }; + + let fifo_size_words = match D::dir() { + Direction::Out => (max_packet_size + 3) / 4, + // INEPTXFD requires minimum size of 16 words + Direction::In => u16::max((max_packet_size + 3) / 4, 16), + }; + + if fifo_size_words + self.allocated_fifo_words() > self.instance.fifo_depth_words { + error!("Not enough FIFO capacity"); + return Err(EndpointAllocError); + } + + let eps = match D::dir() { + Direction::Out => &mut self.ep_out, + Direction::In => &mut self.ep_in, + }; + + // Find free endpoint slot + let slot = eps.iter_mut().enumerate().find(|(i, ep)| { + if *i == 0 && ep_type != EndpointType::Control { + // reserved for control pipe + false + } else { + ep.is_none() + } + }); + + let index = match slot { + Some((index, ep)) => { + *ep = Some(EndpointData { + ep_type, + max_packet_size, + fifo_size_words, + }); + index + } + None => { + error!("No free endpoints available"); + return Err(EndpointAllocError); + } + }; + + trace!(" index={}", index); + + let state = &self.instance.state.ep_states[index]; + if D::dir() == Direction::Out { + // Buffer capacity check was done above, now allocation cannot fail + unsafe { + *state.out_buffer.get() = self.ep_out_buffer.as_mut_ptr().offset(self.ep_out_buffer_offset as _); + } + self.ep_out_buffer_offset += max_packet_size as usize; + } + + Ok(Endpoint { + _phantom: PhantomData, + regs: self.instance.regs, + state, + info: EndpointInfo { + addr: EndpointAddress::from_parts(index, D::dir()), + ep_type, + max_packet_size, + interval_ms, + }, + }) + } +} + +impl<'d, const MAX_EP_COUNT: usize> embassy_usb_driver::Driver<'d> for Driver<'d, MAX_EP_COUNT> { + type EndpointOut = Endpoint<'d, Out>; + type EndpointIn = Endpoint<'d, In>; + type ControlPipe = ControlPipe<'d>; + type Bus = Bus<'d, MAX_EP_COUNT>; + + fn alloc_endpoint_in( + &mut self, + ep_type: EndpointType, + max_packet_size: u16, + interval_ms: u8, + ) -> Result<Self::EndpointIn, EndpointAllocError> { + self.alloc_endpoint(ep_type, max_packet_size, interval_ms) + } + + fn alloc_endpoint_out( + &mut self, + ep_type: EndpointType, + max_packet_size: u16, + interval_ms: u8, + ) -> Result<Self::EndpointOut, EndpointAllocError> { + self.alloc_endpoint(ep_type, max_packet_size, interval_ms) + } + + fn start(mut self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { + let ep_out = self + .alloc_endpoint(EndpointType::Control, control_max_packet_size, 0) + .unwrap(); + let ep_in = self + .alloc_endpoint(EndpointType::Control, control_max_packet_size, 0) + .unwrap(); + assert_eq!(ep_out.info.addr.index(), 0); + assert_eq!(ep_in.info.addr.index(), 0); + + trace!("start"); + + let regs = self.instance.regs; + let quirk_setup_late_cnak = self.instance.quirk_setup_late_cnak; + let cp_setup_state = &self.instance.state.cp_state; + ( + Bus { + config: self.config, + ep_in: self.ep_in, + ep_out: self.ep_out, + inited: false, + instance: self.instance, + }, + ControlPipe { + max_packet_size: control_max_packet_size, + setup_state: cp_setup_state, + ep_out, + ep_in, + regs, + quirk_setup_late_cnak, + }, + ) + } +} + +/// USB bus. +pub struct Bus<'d, const MAX_EP_COUNT: usize> { + config: Config, + ep_in: [Option<EndpointData>; MAX_EP_COUNT], + ep_out: [Option<EndpointData>; MAX_EP_COUNT], + instance: OtgInstance<'d, MAX_EP_COUNT>, + inited: bool, +} + +impl<'d, const MAX_EP_COUNT: usize> Bus<'d, MAX_EP_COUNT> { + fn restore_irqs(&mut self) { + self.instance.regs.gintmsk().write(|w| { + w.set_usbrst(true); + w.set_enumdnem(true); + w.set_usbsuspm(true); + w.set_wuim(true); + w.set_iepint(true); + w.set_oepint(true); + w.set_rxflvlm(true); + w.set_srqim(true); + w.set_otgint(true); + }); + } + + /// Returns the PHY type. + pub fn phy_type(&self) -> PhyType { + self.instance.phy_type + } + + /// Configures the PHY as a device. + pub fn configure_as_device(&mut self) { + let r = self.instance.regs; + let phy_type = self.instance.phy_type; + r.gusbcfg().write(|w| { + // Force device mode + w.set_fdmod(true); + // Enable internal full-speed PHY + w.set_physel(phy_type.internal() && !phy_type.high_speed()); + }); + } + + /// Applies configuration specific to + /// Core ID 0x0000_1100 and 0x0000_1200 + pub fn config_v1(&mut self) { + let r = self.instance.regs; + let phy_type = self.instance.phy_type; + assert!(phy_type != PhyType::InternalHighSpeed); + + r.gccfg_v1().modify(|w| { + // Enable internal full-speed PHY, logic is inverted + w.set_pwrdwn(phy_type.internal()); + }); + + // F429-like chips have the GCCFG.NOVBUSSENS bit + r.gccfg_v1().modify(|w| { + w.set_novbussens(!self.config.vbus_detection); + w.set_vbusasen(false); + w.set_vbusbsen(self.config.vbus_detection); + w.set_sofouten(false); + }); + } + + /// Applies configuration specific to + /// Core ID 0x0000_2000, 0x0000_2100, 0x0000_2300, 0x0000_3000 and 0x0000_3100 + pub fn config_v2v3(&mut self) { + let r = self.instance.regs; + let phy_type = self.instance.phy_type; + + // F446-like chips have the GCCFG.VBDEN bit with the opposite meaning + r.gccfg_v2().modify(|w| { + // Enable internal full-speed PHY, logic is inverted + w.set_pwrdwn(phy_type.internal() && !phy_type.high_speed()); + w.set_phyhsen(phy_type.internal() && phy_type.high_speed()); + }); + + r.gccfg_v2().modify(|w| { + w.set_vbden(self.config.vbus_detection); + }); + + // Force B-peripheral session + r.gotgctl().modify(|w| { + w.set_bvaloen(!self.config.vbus_detection); + w.set_bvaloval(true); + }); + } + + fn init(&mut self) { + let r = self.instance.regs; + let phy_type = self.instance.phy_type; + + // Soft disconnect. + r.dctl().write(|w| w.set_sdis(true)); + + // Set speed. + r.dcfg().write(|w| { + w.set_pfivl(vals::Pfivl::FRAME_INTERVAL_80); + w.set_dspd(phy_type.to_dspd()); + if self.config.xcvrdly { + w.set_xcvrdly(true); + } + }); + + // Unmask transfer complete EP interrupt + r.diepmsk().write(|w| { + w.set_xfrcm(true); + }); + + // Unmask and clear core interrupts + self.restore_irqs(); + r.gintsts().write_value(regs::Gintsts(0xFFFF_FFFF)); + + // Unmask global interrupt + r.gahbcfg().write(|w| { + w.set_gint(true); // unmask global interrupt + }); + + // Connect + r.dctl().write(|w| w.set_sdis(false)); + } + + fn init_fifo(&mut self) { + trace!("init_fifo"); + + let regs = self.instance.regs; + // ERRATA NOTE: Don't interrupt FIFOs being written to. The interrupt + // handler COULD interrupt us here and do FIFO operations, so ensure + // the interrupt does not occur. + critical_section::with(|_| { + // Configure RX fifo size. All endpoints share the same FIFO area. + let rx_fifo_size_words = self.instance.extra_rx_fifo_words + ep_fifo_size(&self.ep_out); + trace!("configuring rx fifo size={}", rx_fifo_size_words); + + regs.grxfsiz().modify(|w| w.set_rxfd(rx_fifo_size_words)); + + // Configure TX (USB in direction) fifo size for each endpoint + let mut fifo_top = rx_fifo_size_words; + for i in 0..self.instance.endpoint_count { + if let Some(ep) = self.ep_in[i] { + trace!( + "configuring tx fifo ep={}, offset={}, size={}", + i, + fifo_top, + ep.fifo_size_words + ); + + let dieptxf = if i == 0 { regs.dieptxf0() } else { regs.dieptxf(i - 1) }; + + dieptxf.write(|w| { + w.set_fd(ep.fifo_size_words); + w.set_sa(fifo_top); + }); + + fifo_top += ep.fifo_size_words; + } + } + + assert!( + fifo_top <= self.instance.fifo_depth_words, + "FIFO allocations exceeded maximum capacity" + ); + + // Flush fifos + regs.grstctl().write(|w| { + w.set_rxfflsh(true); + w.set_txfflsh(true); + w.set_txfnum(0x10); + }); + }); + + loop { + let x = regs.grstctl().read(); + if !x.rxfflsh() && !x.txfflsh() { + break; + } + } + } + + fn configure_endpoints(&mut self) { + trace!("configure_endpoints"); + + let regs = self.instance.regs; + + // Configure IN endpoints + for (index, ep) in self.ep_in.iter().enumerate() { + if let Some(ep) = ep { + critical_section::with(|_| { + regs.diepctl(index).write(|w| { + if index == 0 { + w.set_mpsiz(ep0_mpsiz(ep.max_packet_size)); + } else { + w.set_mpsiz(ep.max_packet_size); + w.set_eptyp(to_eptyp(ep.ep_type)); + w.set_sd0pid_sevnfrm(true); + w.set_txfnum(index as _); + w.set_snak(true); + } + }); + }); + } + } + + // Configure OUT endpoints + for (index, ep) in self.ep_out.iter().enumerate() { + if let Some(ep) = ep { + critical_section::with(|_| { + regs.doepctl(index).write(|w| { + if index == 0 { + w.set_mpsiz(ep0_mpsiz(ep.max_packet_size)); + } else { + w.set_mpsiz(ep.max_packet_size); + w.set_eptyp(to_eptyp(ep.ep_type)); + w.set_sd0pid_sevnfrm(true); + } + }); + + regs.doeptsiz(index).modify(|w| { + w.set_xfrsiz(ep.max_packet_size as _); + if index == 0 { + w.set_rxdpid_stupcnt(1); + } else { + w.set_pktcnt(1); + } + }); + }); + } + } + + // Enable IRQs for allocated endpoints + regs.daintmsk().modify(|w| { + w.set_iepm(ep_irq_mask(&self.ep_in)); + // OUT interrupts not used, handled in RXFLVL + // w.set_oepm(ep_irq_mask(&self.ep_out)); + }); + } + + fn disable_all_endpoints(&mut self) { + for i in 0..self.instance.endpoint_count { + self.endpoint_set_enabled(EndpointAddress::from_parts(i, Direction::In), false); + self.endpoint_set_enabled(EndpointAddress::from_parts(i, Direction::Out), false); + } + } +} + +impl<'d, const MAX_EP_COUNT: usize> embassy_usb_driver::Bus for Bus<'d, MAX_EP_COUNT> { + async fn poll(&mut self) -> Event { + poll_fn(move |cx| { + if !self.inited { + self.init(); + self.inited = true; + + // If no vbus detection, just return a single PowerDetected event at startup. + if !self.config.vbus_detection { + return Poll::Ready(Event::PowerDetected); + } + } + + let regs = self.instance.regs; + self.instance.state.bus_waker.register(cx.waker()); + + let ints = regs.gintsts().read(); + + if ints.srqint() { + trace!("vbus detected"); + + regs.gintsts().write(|w| w.set_srqint(true)); // clear + self.restore_irqs(); + + if self.config.vbus_detection { + return Poll::Ready(Event::PowerDetected); + } + } + + if ints.otgint() { + let otgints = regs.gotgint().read(); + regs.gotgint().write_value(otgints); // clear all + self.restore_irqs(); + + if otgints.sedet() { + trace!("vbus removed"); + if self.config.vbus_detection { + self.disable_all_endpoints(); + return Poll::Ready(Event::PowerRemoved); + } + } + } + + if ints.usbrst() { + trace!("reset"); + + self.init_fifo(); + self.configure_endpoints(); + + // Reset address + critical_section::with(|_| { + regs.dcfg().modify(|w| { + w.set_dad(0); + }); + }); + + regs.gintsts().write(|w| w.set_usbrst(true)); // clear + self.restore_irqs(); + } + + if ints.enumdne() { + trace!("enumdne"); + + let speed = regs.dsts().read().enumspd(); + let trdt = (self.instance.calculate_trdt_fn)(speed); + trace!(" speed={} trdt={}", speed.to_bits(), trdt); + regs.gusbcfg().modify(|w| w.set_trdt(trdt)); + + regs.gintsts().write(|w| w.set_enumdne(true)); // clear + self.restore_irqs(); + + return Poll::Ready(Event::Reset); + } + + if ints.usbsusp() { + trace!("suspend"); + regs.gintsts().write(|w| w.set_usbsusp(true)); // clear + self.restore_irqs(); + return Poll::Ready(Event::Suspend); + } + + if ints.wkupint() { + trace!("resume"); + regs.gintsts().write(|w| w.set_wkupint(true)); // clear + self.restore_irqs(); + return Poll::Ready(Event::Resume); + } + + Poll::Pending + }) + .await + } + + fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) { + trace!("endpoint_set_stalled ep={:?} en={}", ep_addr, stalled); + + assert!( + ep_addr.index() < self.instance.endpoint_count, + "endpoint_set_stalled index {} out of range", + ep_addr.index() + ); + + let regs = self.instance.regs; + let state = self.instance.state; + match ep_addr.direction() { + Direction::Out => { + critical_section::with(|_| { + regs.doepctl(ep_addr.index()).modify(|w| { + w.set_stall(stalled); + }); + }); + + state.ep_states[ep_addr.index()].out_waker.wake(); + } + Direction::In => { + critical_section::with(|_| { + regs.diepctl(ep_addr.index()).modify(|w| { + w.set_stall(stalled); + }); + }); + + state.ep_states[ep_addr.index()].in_waker.wake(); + } + } + } + + fn endpoint_is_stalled(&mut self, ep_addr: EndpointAddress) -> bool { + assert!( + ep_addr.index() < self.instance.endpoint_count, + "endpoint_is_stalled index {} out of range", + ep_addr.index() + ); + + let regs = self.instance.regs; + match ep_addr.direction() { + Direction::Out => regs.doepctl(ep_addr.index()).read().stall(), + Direction::In => regs.diepctl(ep_addr.index()).read().stall(), + } + } + + fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool) { + trace!("endpoint_set_enabled ep={:?} en={}", ep_addr, enabled); + + assert!( + ep_addr.index() < self.instance.endpoint_count, + "endpoint_set_enabled index {} out of range", + ep_addr.index() + ); + + let regs = self.instance.regs; + let state = self.instance.state; + match ep_addr.direction() { + Direction::Out => { + critical_section::with(|_| { + // cancel transfer if active + if !enabled && regs.doepctl(ep_addr.index()).read().epena() { + regs.doepctl(ep_addr.index()).modify(|w| { + w.set_snak(true); + w.set_epdis(true); + }) + } + + regs.doepctl(ep_addr.index()).modify(|w| { + w.set_usbaep(enabled); + }); + + // Flush tx fifo + regs.grstctl().write(|w| { + w.set_txfflsh(true); + w.set_txfnum(ep_addr.index() as _); + }); + loop { + let x = regs.grstctl().read(); + if !x.txfflsh() { + break; + } + } + }); + + // Wake `Endpoint::wait_enabled()` + state.ep_states[ep_addr.index()].out_waker.wake(); + } + Direction::In => { + critical_section::with(|_| { + // cancel transfer if active + if !enabled && regs.diepctl(ep_addr.index()).read().epena() { + regs.diepctl(ep_addr.index()).modify(|w| { + w.set_snak(true); // set NAK + w.set_epdis(true); + }) + } + + regs.diepctl(ep_addr.index()).modify(|w| { + w.set_usbaep(enabled); + w.set_cnak(enabled); // clear NAK that might've been set by SNAK above. + }) + }); + + // Wake `Endpoint::wait_enabled()` + state.ep_states[ep_addr.index()].in_waker.wake(); + } + } + } + + async fn enable(&mut self) { + trace!("enable"); + // TODO: enable the peripheral once enable/disable semantics are cleared up in embassy-usb + } + + async fn disable(&mut self) { + trace!("disable"); + + // TODO: disable the peripheral once enable/disable semantics are cleared up in embassy-usb + //Bus::disable(self); + } + + async fn remote_wakeup(&mut self) -> Result<(), Unsupported> { + Err(Unsupported) + } +} + +/// USB endpoint direction. +trait Dir { + /// Returns the direction value. + fn dir() -> Direction; +} + +/// Marker type for the "IN" direction. +pub enum In {} +impl Dir for In { + fn dir() -> Direction { + Direction::In + } +} + +/// Marker type for the "OUT" direction. +pub enum Out {} +impl Dir for Out { + fn dir() -> Direction { + Direction::Out + } +} + +/// USB endpoint. +pub struct Endpoint<'d, D> { + _phantom: PhantomData<D>, + regs: Otg, + info: EndpointInfo, + state: &'d EpState, +} + +impl<'d> embassy_usb_driver::Endpoint for Endpoint<'d, In> { + fn info(&self) -> &EndpointInfo { + &self.info + } + + async fn wait_enabled(&mut self) { + poll_fn(|cx| { + let ep_index = self.info.addr.index(); + + self.state.in_waker.register(cx.waker()); + + if self.regs.diepctl(ep_index).read().usbaep() { + Poll::Ready(()) + } else { + Poll::Pending + } + }) + .await + } +} + +impl<'d> embassy_usb_driver::Endpoint for Endpoint<'d, Out> { + fn info(&self) -> &EndpointInfo { + &self.info + } + + async fn wait_enabled(&mut self) { + poll_fn(|cx| { + let ep_index = self.info.addr.index(); + + self.state.out_waker.register(cx.waker()); + + if self.regs.doepctl(ep_index).read().usbaep() { + Poll::Ready(()) + } else { + Poll::Pending + } + }) + .await + } +} + +impl<'d> embassy_usb_driver::EndpointOut for Endpoint<'d, Out> { + async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> { + trace!("read start len={}", buf.len()); + + poll_fn(|cx| { + let index = self.info.addr.index(); + self.state.out_waker.register(cx.waker()); + + let doepctl = self.regs.doepctl(index).read(); + trace!("read ep={:?}: doepctl {:08x}", self.info.addr, doepctl.0,); + if !doepctl.usbaep() { + trace!("read ep={:?} error disabled", self.info.addr); + return Poll::Ready(Err(EndpointError::Disabled)); + } + + let len = self.state.out_size.load(Ordering::Relaxed); + if len != EP_OUT_BUFFER_EMPTY { + trace!("read ep={:?} done len={}", self.info.addr, len); + + if len as usize > buf.len() { + return Poll::Ready(Err(EndpointError::BufferOverflow)); + } + + // SAFETY: exclusive access ensured by `out_size` atomic variable + let data = unsafe { core::slice::from_raw_parts(*self.state.out_buffer.get(), len as usize) }; + buf[..len as usize].copy_from_slice(data); + + // Release buffer + self.state.out_size.store(EP_OUT_BUFFER_EMPTY, Ordering::Release); + + critical_section::with(|_| { + // Receive 1 packet + self.regs.doeptsiz(index).modify(|w| { + w.set_xfrsiz(self.info.max_packet_size as _); + w.set_pktcnt(1); + }); + + // Clear NAK to indicate we are ready to receive more data + self.regs.doepctl(index).modify(|w| { + w.set_cnak(true); + }); + }); + + Poll::Ready(Ok(len as usize)) + } else { + Poll::Pending + } + }) + .await + } +} + +impl<'d> embassy_usb_driver::EndpointIn for Endpoint<'d, In> { + async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> { + trace!("write ep={:?} data={:?}", self.info.addr, buf); + + if buf.len() > self.info.max_packet_size as usize { + return Err(EndpointError::BufferOverflow); + } + + let index = self.info.addr.index(); + // Wait for previous transfer to complete and check if endpoint is disabled + poll_fn(|cx| { + self.state.in_waker.register(cx.waker()); + + let diepctl = self.regs.diepctl(index).read(); + let dtxfsts = self.regs.dtxfsts(index).read(); + trace!( + "write ep={:?}: diepctl {:08x} ftxfsts {:08x}", + self.info.addr, + diepctl.0, + dtxfsts.0 + ); + if !diepctl.usbaep() { + trace!("write ep={:?} wait for prev: error disabled", self.info.addr); + Poll::Ready(Err(EndpointError::Disabled)) + } else if !diepctl.epena() { + trace!("write ep={:?} wait for prev: ready", self.info.addr); + Poll::Ready(Ok(())) + } else { + trace!("write ep={:?} wait for prev: pending", self.info.addr); + Poll::Pending + } + }) + .await?; + + if buf.len() > 0 { + poll_fn(|cx| { + self.state.in_waker.register(cx.waker()); + + let size_words = (buf.len() + 3) / 4; + + let fifo_space = self.regs.dtxfsts(index).read().ineptfsav() as usize; + if size_words > fifo_space { + // Not enough space in fifo, enable tx fifo empty interrupt + critical_section::with(|_| { + self.regs.diepempmsk().modify(|w| { + w.set_ineptxfem(w.ineptxfem() | (1 << index)); + }); + }); + + trace!("tx fifo for ep={} full, waiting for txfe", index); + + Poll::Pending + } else { + trace!("write ep={:?} wait for fifo: ready", self.info.addr); + Poll::Ready(()) + } + }) + .await + } + + // ERRATA: Transmit data FIFO is corrupted when a write sequence to the FIFO is interrupted with + // accesses to certain OTG_FS registers. + // + // Prevent the interrupt (which might poke FIFOs) from executing while copying data to FIFOs. + critical_section::with(|_| { + // Setup transfer size + self.regs.dieptsiz(index).write(|w| { + w.set_mcnt(1); + w.set_pktcnt(1); + w.set_xfrsiz(buf.len() as _); + }); + + // Enable endpoint + self.regs.diepctl(index).modify(|w| { + w.set_cnak(true); + w.set_epena(true); + }); + + // Write data to FIFO + for chunk in buf.chunks(4) { + let mut tmp = [0u8; 4]; + tmp[0..chunk.len()].copy_from_slice(chunk); + self.regs.fifo(index).write_value(regs::Fifo(u32::from_ne_bytes(tmp))); + } + }); + + trace!("write done ep={:?}", self.info.addr); + + Ok(()) + } +} + +/// USB control pipe. +pub struct ControlPipe<'d> { + max_packet_size: u16, + regs: Otg, + setup_state: &'d ControlPipeSetupState, + ep_in: Endpoint<'d, In>, + ep_out: Endpoint<'d, Out>, + quirk_setup_late_cnak: bool, +} + +impl<'d> embassy_usb_driver::ControlPipe for ControlPipe<'d> { + fn max_packet_size(&self) -> usize { + usize::from(self.max_packet_size) + } + + async fn setup(&mut self) -> [u8; 8] { + poll_fn(|cx| { + self.ep_out.state.out_waker.register(cx.waker()); + + if self.setup_state.setup_ready.load(Ordering::Relaxed) { + let data = unsafe { *self.setup_state.setup_data.get() }; + self.setup_state.setup_ready.store(false, Ordering::Release); + + // EP0 should not be controlled by `Bus` so this RMW does not need a critical section + // Receive 1 SETUP packet + self.regs.doeptsiz(self.ep_out.info.addr.index()).modify(|w| { + w.set_rxdpid_stupcnt(1); + }); + + // Clear NAK to indicate we are ready to receive more data + if !self.quirk_setup_late_cnak { + self.regs + .doepctl(self.ep_out.info.addr.index()) + .modify(|w| w.set_cnak(true)); + } + + trace!("SETUP received: {:?}", data); + Poll::Ready(data) + } else { + trace!("SETUP waiting"); + Poll::Pending + } + }) + .await + } + + async fn data_out(&mut self, buf: &mut [u8], _first: bool, _last: bool) -> Result<usize, EndpointError> { + trace!("control: data_out"); + let len = self.ep_out.read(buf).await?; + trace!("control: data_out read: {:?}", &buf[..len]); + Ok(len) + } + + async fn data_in(&mut self, data: &[u8], _first: bool, last: bool) -> Result<(), EndpointError> { + trace!("control: data_in write: {:?}", data); + self.ep_in.write(data).await?; + + // wait for status response from host after sending the last packet + if last { + trace!("control: data_in waiting for status"); + self.ep_out.read(&mut []).await?; + trace!("control: complete"); + } + + Ok(()) + } + + async fn accept(&mut self) { + trace!("control: accept"); + + self.ep_in.write(&[]).await.ok(); + + trace!("control: accept OK"); + } + + async fn reject(&mut self) { + trace!("control: reject"); + + // EP0 should not be controlled by `Bus` so this RMW does not need a critical section + self.regs.diepctl(self.ep_in.info.addr.index()).modify(|w| { + w.set_stall(true); + }); + self.regs.doepctl(self.ep_out.info.addr.index()).modify(|w| { + w.set_stall(true); + }); + } + + async fn accept_set_address(&mut self, addr: u8) { + trace!("setting addr: {}", addr); + critical_section::with(|_| { + self.regs.dcfg().modify(|w| { + w.set_dad(addr); + }); + }); + + // synopsys driver requires accept to be sent after changing address + self.accept().await + } +} + +/// Translates HAL [EndpointType] into PAC [vals::Eptyp] +fn to_eptyp(ep_type: EndpointType) -> vals::Eptyp { + match ep_type { + EndpointType::Control => vals::Eptyp::CONTROL, + EndpointType::Isochronous => vals::Eptyp::ISOCHRONOUS, + EndpointType::Bulk => vals::Eptyp::BULK, + EndpointType::Interrupt => vals::Eptyp::INTERRUPT, + } +} + +/// Calculates total allocated FIFO size in words +fn ep_fifo_size(eps: &[Option<EndpointData>]) -> u16 { + eps.iter().map(|ep| ep.map(|ep| ep.fifo_size_words).unwrap_or(0)).sum() +} + +/// Generates IRQ mask for enabled endpoints +fn ep_irq_mask(eps: &[Option<EndpointData>]) -> u16 { + eps.iter().enumerate().fold( + 0, + |mask, (index, ep)| { + if ep.is_some() { + mask | (1 << index) + } else { + mask + } + }, + ) +} + +/// Calculates MPSIZ value for EP0, which uses special values. +fn ep0_mpsiz(max_packet_size: u16) -> u16 { + match max_packet_size { + 8 => 0b11, + 16 => 0b10, + 32 => 0b01, + 64 => 0b00, + other => panic!("Unsupported EP0 size: {}", other), + } +} + +/// Hardware-dependent USB IP configuration. +pub struct OtgInstance<'d, const MAX_EP_COUNT: usize> { + /// The USB peripheral. + pub regs: Otg, + /// The USB state. + pub state: &'d State<MAX_EP_COUNT>, + /// FIFO depth in words. + pub fifo_depth_words: u16, + /// Number of used endpoints. + pub endpoint_count: usize, + /// The PHY type. + pub phy_type: PhyType, + /// Extra RX FIFO words needed by some implementations. + pub extra_rx_fifo_words: u16, + /// Whether to set up late cnak + pub quirk_setup_late_cnak: bool, + /// Function to calculate TRDT value based on some internal clock speed. + pub calculate_trdt_fn: fn(speed: vals::Dspd) -> u8, +} diff --git a/embassy-usb-synopsys-otg/src/otg_v1.rs b/embassy-usb-synopsys-otg/src/otg_v1.rs new file mode 100644 index 000000000..111bc4a63 --- /dev/null +++ b/embassy-usb-synopsys-otg/src/otg_v1.rs @@ -0,0 +1,4482 @@ +//! Register definitions for Synopsys DesignWare USB OTG core + +#![allow(missing_docs)] + +use core::marker::PhantomData; + +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct RW; +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct R; +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct W; + +mod sealed { + use super::*; + pub trait Access {} + impl Access for R {} + impl Access for W {} + impl Access for RW {} +} + +pub trait Access: sealed::Access + Copy {} +impl Access for R {} +impl Access for W {} +impl Access for RW {} + +pub trait Read: Access {} +impl Read for RW {} +impl Read for R {} + +pub trait Write: Access {} +impl Write for RW {} +impl Write for W {} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct Reg<T: Copy, A: Access> { + ptr: *mut u8, + phantom: PhantomData<*mut (T, A)>, +} +unsafe impl<T: Copy, A: Access> Send for Reg<T, A> {} +unsafe impl<T: Copy, A: Access> Sync for Reg<T, A> {} + +impl<T: Copy, A: Access> Reg<T, A> { + #[allow(clippy::missing_safety_doc)] + #[inline(always)] + pub const unsafe fn from_ptr(ptr: *mut T) -> Self { + Self { + ptr: ptr as _, + phantom: PhantomData, + } + } + + #[inline(always)] + pub const fn as_ptr(&self) -> *mut T { + self.ptr as _ + } +} + +impl<T: Copy, A: Read> Reg<T, A> { + #[inline(always)] + pub fn read(&self) -> T { + unsafe { (self.ptr as *mut T).read_volatile() } + } +} + +impl<T: Copy, A: Write> Reg<T, A> { + #[inline(always)] + pub fn write_value(&self, val: T) { + unsafe { (self.ptr as *mut T).write_volatile(val) } + } +} + +impl<T: Default + Copy, A: Write> Reg<T, A> { + #[inline(always)] + pub fn write<R>(&self, f: impl FnOnce(&mut T) -> R) -> R { + let mut val = Default::default(); + let res = f(&mut val); + self.write_value(val); + res + } +} + +impl<T: Copy, A: Read + Write> Reg<T, A> { + #[inline(always)] + pub fn modify<R>(&self, f: impl FnOnce(&mut T) -> R) -> R { + let mut val = self.read(); + let res = f(&mut val); + self.write_value(val); + res + } +} + +#[doc = "USB on the go"] +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct Otg { + ptr: *mut u8, +} +unsafe impl Send for Otg {} +unsafe impl Sync for Otg {} +impl Otg { + #[inline(always)] + pub const unsafe fn from_ptr(ptr: *mut ()) -> Self { + Self { ptr: ptr as _ } + } + #[inline(always)] + pub const fn as_ptr(&self) -> *mut () { + self.ptr as _ + } + #[doc = "Control and status register"] + #[inline(always)] + pub const fn gotgctl(self) -> Reg<regs::Gotgctl, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0usize) as _) } + } + #[doc = "Interrupt register"] + #[inline(always)] + pub const fn gotgint(self) -> Reg<regs::Gotgint, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x04usize) as _) } + } + #[doc = "AHB configuration register"] + #[inline(always)] + pub const fn gahbcfg(self) -> Reg<regs::Gahbcfg, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x08usize) as _) } + } + #[doc = "USB configuration register"] + #[inline(always)] + pub const fn gusbcfg(self) -> Reg<regs::Gusbcfg, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0cusize) as _) } + } + #[doc = "Reset register"] + #[inline(always)] + pub const fn grstctl(self) -> Reg<regs::Grstctl, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x10usize) as _) } + } + #[doc = "Core interrupt register"] + #[inline(always)] + pub const fn gintsts(self) -> Reg<regs::Gintsts, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x14usize) as _) } + } + #[doc = "Interrupt mask register"] + #[inline(always)] + pub const fn gintmsk(self) -> Reg<regs::Gintmsk, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x18usize) as _) } + } + #[doc = "Receive status debug read register"] + #[inline(always)] + pub const fn grxstsr(self) -> Reg<regs::Grxsts, R> { + unsafe { Reg::from_ptr(self.ptr.add(0x1cusize) as _) } + } + #[doc = "Status read and pop register"] + #[inline(always)] + pub const fn grxstsp(self) -> Reg<regs::Grxsts, R> { + unsafe { Reg::from_ptr(self.ptr.add(0x20usize) as _) } + } + #[doc = "Receive FIFO size register"] + #[inline(always)] + pub const fn grxfsiz(self) -> Reg<regs::Grxfsiz, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x24usize) as _) } + } + #[doc = "Endpoint 0 transmit FIFO size register (device mode)"] + #[inline(always)] + pub const fn dieptxf0(self) -> Reg<regs::Fsiz, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x28usize) as _) } + } + #[doc = "Non-periodic transmit FIFO size register (host mode)"] + #[inline(always)] + pub const fn hnptxfsiz(self) -> Reg<regs::Fsiz, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x28usize) as _) } + } + #[doc = "Non-periodic transmit FIFO/queue status register (host mode)"] + #[inline(always)] + pub const fn hnptxsts(self) -> Reg<regs::Hnptxsts, R> { + unsafe { Reg::from_ptr(self.ptr.add(0x2cusize) as _) } + } + #[doc = "OTG I2C access register"] + #[inline(always)] + pub const fn gi2cctl(self) -> Reg<regs::Gi2cctl, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x30usize) as _) } + } + #[doc = "General core configuration register, for core_id 0x0000_1xxx"] + #[inline(always)] + pub const fn gccfg_v1(self) -> Reg<regs::GccfgV1, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x38usize) as _) } + } + #[doc = "General core configuration register, for core_id 0x0000_\\[23\\]xxx"] + #[inline(always)] + pub const fn gccfg_v2(self) -> Reg<regs::GccfgV2, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x38usize) as _) } + } + #[doc = "Core ID register"] + #[inline(always)] + pub const fn cid(self) -> Reg<regs::Cid, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x3cusize) as _) } + } + #[doc = "OTG core LPM configuration register"] + #[inline(always)] + pub const fn glpmcfg(self) -> Reg<regs::Glpmcfg, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x54usize) as _) } + } + #[doc = "Host periodic transmit FIFO size register"] + #[inline(always)] + pub const fn hptxfsiz(self) -> Reg<regs::Fsiz, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0100usize) as _) } + } + #[doc = "Device IN endpoint transmit FIFO size register"] + #[inline(always)] + pub const fn dieptxf(self, n: usize) -> Reg<regs::Fsiz, RW> { + assert!(n < 7usize); + unsafe { Reg::from_ptr(self.ptr.add(0x0104usize + n * 4usize) as _) } + } + #[doc = "Host configuration register"] + #[inline(always)] + pub const fn hcfg(self) -> Reg<regs::Hcfg, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0400usize) as _) } + } + #[doc = "Host frame interval register"] + #[inline(always)] + pub const fn hfir(self) -> Reg<regs::Hfir, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0404usize) as _) } + } + #[doc = "Host frame number/frame time remaining register"] + #[inline(always)] + pub const fn hfnum(self) -> Reg<regs::Hfnum, R> { + unsafe { Reg::from_ptr(self.ptr.add(0x0408usize) as _) } + } + #[doc = "Periodic transmit FIFO/queue status register"] + #[inline(always)] + pub const fn hptxsts(self) -> Reg<regs::Hptxsts, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0410usize) as _) } + } + #[doc = "Host all channels interrupt register"] + #[inline(always)] + pub const fn haint(self) -> Reg<regs::Haint, R> { + unsafe { Reg::from_ptr(self.ptr.add(0x0414usize) as _) } + } + #[doc = "Host all channels interrupt mask register"] + #[inline(always)] + pub const fn haintmsk(self) -> Reg<regs::Haintmsk, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0418usize) as _) } + } + #[doc = "Host port control and status register"] + #[inline(always)] + pub const fn hprt(self) -> Reg<regs::Hprt, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0440usize) as _) } + } + #[doc = "Host channel characteristics register"] + #[inline(always)] + pub const fn hcchar(self, n: usize) -> Reg<regs::Hcchar, RW> { + assert!(n < 12usize); + unsafe { Reg::from_ptr(self.ptr.add(0x0500usize + n * 32usize) as _) } + } + #[doc = "Host channel split control register"] + #[inline(always)] + pub const fn hcsplt(self, n: usize) -> Reg<u32, RW> { + assert!(n < 12usize); + unsafe { Reg::from_ptr(self.ptr.add(0x0504usize + n * 32usize) as _) } + } + #[doc = "Host channel interrupt register"] + #[inline(always)] + pub const fn hcint(self, n: usize) -> Reg<regs::Hcint, RW> { + assert!(n < 12usize); + unsafe { Reg::from_ptr(self.ptr.add(0x0508usize + n * 32usize) as _) } + } + #[doc = "Host channel mask register"] + #[inline(always)] + pub const fn hcintmsk(self, n: usize) -> Reg<regs::Hcintmsk, RW> { + assert!(n < 12usize); + unsafe { Reg::from_ptr(self.ptr.add(0x050cusize + n * 32usize) as _) } + } + #[doc = "Host channel transfer size register"] + #[inline(always)] + pub const fn hctsiz(self, n: usize) -> Reg<regs::Hctsiz, RW> { + assert!(n < 12usize); + unsafe { Reg::from_ptr(self.ptr.add(0x0510usize + n * 32usize) as _) } + } + #[doc = "Device configuration register"] + #[inline(always)] + pub const fn dcfg(self) -> Reg<regs::Dcfg, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0800usize) as _) } + } + #[doc = "Device control register"] + #[inline(always)] + pub const fn dctl(self) -> Reg<regs::Dctl, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0804usize) as _) } + } + #[doc = "Device status register"] + #[inline(always)] + pub const fn dsts(self) -> Reg<regs::Dsts, R> { + unsafe { Reg::from_ptr(self.ptr.add(0x0808usize) as _) } + } + #[doc = "Device IN endpoint common interrupt mask register"] + #[inline(always)] + pub const fn diepmsk(self) -> Reg<regs::Diepmsk, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0810usize) as _) } + } + #[doc = "Device OUT endpoint common interrupt mask register"] + #[inline(always)] + pub const fn doepmsk(self) -> Reg<regs::Doepmsk, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0814usize) as _) } + } + #[doc = "Device all endpoints interrupt register"] + #[inline(always)] + pub const fn daint(self) -> Reg<regs::Daint, R> { + unsafe { Reg::from_ptr(self.ptr.add(0x0818usize) as _) } + } + #[doc = "All endpoints interrupt mask register"] + #[inline(always)] + pub const fn daintmsk(self) -> Reg<regs::Daintmsk, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x081cusize) as _) } + } + #[doc = "Device VBUS discharge time register"] + #[inline(always)] + pub const fn dvbusdis(self) -> Reg<regs::Dvbusdis, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0828usize) as _) } + } + #[doc = "Device VBUS pulsing time register"] + #[inline(always)] + pub const fn dvbuspulse(self) -> Reg<regs::Dvbuspulse, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x082cusize) as _) } + } + #[doc = "Device IN endpoint FIFO empty interrupt mask register"] + #[inline(always)] + pub const fn diepempmsk(self) -> Reg<regs::Diepempmsk, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0834usize) as _) } + } + #[doc = "Device IN endpoint control register"] + #[inline(always)] + pub const fn diepctl(self, n: usize) -> Reg<regs::Diepctl, RW> { + assert!(n < 16usize); + unsafe { Reg::from_ptr(self.ptr.add(0x0900usize + n * 32usize) as _) } + } + #[doc = "Device IN endpoint interrupt register"] + #[inline(always)] + pub const fn diepint(self, n: usize) -> Reg<regs::Diepint, RW> { + assert!(n < 16usize); + unsafe { Reg::from_ptr(self.ptr.add(0x0908usize + n * 32usize) as _) } + } + #[doc = "Device IN endpoint transfer size register"] + #[inline(always)] + pub const fn dieptsiz(self, n: usize) -> Reg<regs::Dieptsiz, RW> { + assert!(n < 16usize); + unsafe { Reg::from_ptr(self.ptr.add(0x0910usize + n * 32usize) as _) } + } + #[doc = "Device IN endpoint transmit FIFO status register"] + #[inline(always)] + pub const fn dtxfsts(self, n: usize) -> Reg<regs::Dtxfsts, R> { + assert!(n < 16usize); + unsafe { Reg::from_ptr(self.ptr.add(0x0918usize + n * 32usize) as _) } + } + #[doc = "Device OUT endpoint control register"] + #[inline(always)] + pub const fn doepctl(self, n: usize) -> Reg<regs::Doepctl, RW> { + assert!(n < 16usize); + unsafe { Reg::from_ptr(self.ptr.add(0x0b00usize + n * 32usize) as _) } + } + #[doc = "Device OUT endpoint interrupt register"] + #[inline(always)] + pub const fn doepint(self, n: usize) -> Reg<regs::Doepint, RW> { + assert!(n < 16usize); + unsafe { Reg::from_ptr(self.ptr.add(0x0b08usize + n * 32usize) as _) } + } + #[doc = "Device OUT endpoint transfer size register"] + #[inline(always)] + pub const fn doeptsiz(self, n: usize) -> Reg<regs::Doeptsiz, RW> { + assert!(n < 16usize); + unsafe { Reg::from_ptr(self.ptr.add(0x0b10usize + n * 32usize) as _) } + } + #[doc = "Power and clock gating control register"] + #[inline(always)] + pub const fn pcgcctl(self) -> Reg<regs::Pcgcctl, RW> { + unsafe { Reg::from_ptr(self.ptr.add(0x0e00usize) as _) } + } + #[doc = "Device endpoint / host channel FIFO register"] + #[inline(always)] + pub const fn fifo(self, n: usize) -> Reg<regs::Fifo, RW> { + assert!(n < 16usize); + unsafe { Reg::from_ptr(self.ptr.add(0x1000usize + n * 4096usize) as _) } + } +} +pub mod regs { + #[doc = "Core ID register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Cid(pub u32); + impl Cid { + #[doc = "Product ID field"] + #[inline(always)] + pub const fn product_id(&self) -> u32 { + let val = (self.0 >> 0usize) & 0xffff_ffff; + val as u32 + } + #[doc = "Product ID field"] + #[inline(always)] + pub fn set_product_id(&mut self, val: u32) { + self.0 = (self.0 & !(0xffff_ffff << 0usize)) | (((val as u32) & 0xffff_ffff) << 0usize); + } + } + impl Default for Cid { + #[inline(always)] + fn default() -> Cid { + Cid(0) + } + } + #[doc = "Device all endpoints interrupt register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Daint(pub u32); + impl Daint { + #[doc = "IN endpoint interrupt bits"] + #[inline(always)] + pub const fn iepint(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "IN endpoint interrupt bits"] + #[inline(always)] + pub fn set_iepint(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + #[doc = "OUT endpoint interrupt bits"] + #[inline(always)] + pub const fn oepint(&self) -> u16 { + let val = (self.0 >> 16usize) & 0xffff; + val as u16 + } + #[doc = "OUT endpoint interrupt bits"] + #[inline(always)] + pub fn set_oepint(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 16usize)) | (((val as u32) & 0xffff) << 16usize); + } + } + impl Default for Daint { + #[inline(always)] + fn default() -> Daint { + Daint(0) + } + } + #[doc = "All endpoints interrupt mask register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Daintmsk(pub u32); + impl Daintmsk { + #[doc = "IN EP interrupt mask bits"] + #[inline(always)] + pub const fn iepm(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "IN EP interrupt mask bits"] + #[inline(always)] + pub fn set_iepm(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + #[doc = "OUT EP interrupt mask bits"] + #[inline(always)] + pub const fn oepm(&self) -> u16 { + let val = (self.0 >> 16usize) & 0xffff; + val as u16 + } + #[doc = "OUT EP interrupt mask bits"] + #[inline(always)] + pub fn set_oepm(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 16usize)) | (((val as u32) & 0xffff) << 16usize); + } + } + impl Default for Daintmsk { + #[inline(always)] + fn default() -> Daintmsk { + Daintmsk(0) + } + } + #[doc = "Device configuration register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Dcfg(pub u32); + impl Dcfg { + #[doc = "Device speed"] + #[inline(always)] + pub const fn dspd(&self) -> super::vals::Dspd { + let val = (self.0 >> 0usize) & 0x03; + super::vals::Dspd::from_bits(val as u8) + } + #[doc = "Device speed"] + #[inline(always)] + pub fn set_dspd(&mut self, val: super::vals::Dspd) { + self.0 = (self.0 & !(0x03 << 0usize)) | (((val.to_bits() as u32) & 0x03) << 0usize); + } + #[doc = "Non-zero-length status OUT handshake"] + #[inline(always)] + pub const fn nzlsohsk(&self) -> bool { + let val = (self.0 >> 2usize) & 0x01; + val != 0 + } + #[doc = "Non-zero-length status OUT handshake"] + #[inline(always)] + pub fn set_nzlsohsk(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 2usize)) | (((val as u32) & 0x01) << 2usize); + } + #[doc = "Device address"] + #[inline(always)] + pub const fn dad(&self) -> u8 { + let val = (self.0 >> 4usize) & 0x7f; + val as u8 + } + #[doc = "Device address"] + #[inline(always)] + pub fn set_dad(&mut self, val: u8) { + self.0 = (self.0 & !(0x7f << 4usize)) | (((val as u32) & 0x7f) << 4usize); + } + #[doc = "Periodic frame interval"] + #[inline(always)] + pub const fn pfivl(&self) -> super::vals::Pfivl { + let val = (self.0 >> 11usize) & 0x03; + super::vals::Pfivl::from_bits(val as u8) + } + #[doc = "Periodic frame interval"] + #[inline(always)] + pub fn set_pfivl(&mut self, val: super::vals::Pfivl) { + self.0 = (self.0 & !(0x03 << 11usize)) | (((val.to_bits() as u32) & 0x03) << 11usize); + } + #[doc = "Transceiver delay"] + #[inline(always)] + pub const fn xcvrdly(&self) -> bool { + let val = (self.0 >> 14usize) & 0x01; + val != 0 + } + #[doc = "Transceiver delay"] + #[inline(always)] + pub fn set_xcvrdly(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 14usize)) | (((val as u32) & 0x01) << 14usize); + } + } + impl Default for Dcfg { + #[inline(always)] + fn default() -> Dcfg { + Dcfg(0) + } + } + #[doc = "Device control register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Dctl(pub u32); + impl Dctl { + #[doc = "Remote wakeup signaling"] + #[inline(always)] + pub const fn rwusig(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Remote wakeup signaling"] + #[inline(always)] + pub fn set_rwusig(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "Soft disconnect"] + #[inline(always)] + pub const fn sdis(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "Soft disconnect"] + #[inline(always)] + pub fn set_sdis(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "Global IN NAK status"] + #[inline(always)] + pub const fn ginsts(&self) -> bool { + let val = (self.0 >> 2usize) & 0x01; + val != 0 + } + #[doc = "Global IN NAK status"] + #[inline(always)] + pub fn set_ginsts(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 2usize)) | (((val as u32) & 0x01) << 2usize); + } + #[doc = "Global OUT NAK status"] + #[inline(always)] + pub const fn gonsts(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "Global OUT NAK status"] + #[inline(always)] + pub fn set_gonsts(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "Test control"] + #[inline(always)] + pub const fn tctl(&self) -> u8 { + let val = (self.0 >> 4usize) & 0x07; + val as u8 + } + #[doc = "Test control"] + #[inline(always)] + pub fn set_tctl(&mut self, val: u8) { + self.0 = (self.0 & !(0x07 << 4usize)) | (((val as u32) & 0x07) << 4usize); + } + #[doc = "Set global IN NAK"] + #[inline(always)] + pub const fn sginak(&self) -> bool { + let val = (self.0 >> 7usize) & 0x01; + val != 0 + } + #[doc = "Set global IN NAK"] + #[inline(always)] + pub fn set_sginak(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 7usize)) | (((val as u32) & 0x01) << 7usize); + } + #[doc = "Clear global IN NAK"] + #[inline(always)] + pub const fn cginak(&self) -> bool { + let val = (self.0 >> 8usize) & 0x01; + val != 0 + } + #[doc = "Clear global IN NAK"] + #[inline(always)] + pub fn set_cginak(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 8usize)) | (((val as u32) & 0x01) << 8usize); + } + #[doc = "Set global OUT NAK"] + #[inline(always)] + pub const fn sgonak(&self) -> bool { + let val = (self.0 >> 9usize) & 0x01; + val != 0 + } + #[doc = "Set global OUT NAK"] + #[inline(always)] + pub fn set_sgonak(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 9usize)) | (((val as u32) & 0x01) << 9usize); + } + #[doc = "Clear global OUT NAK"] + #[inline(always)] + pub const fn cgonak(&self) -> bool { + let val = (self.0 >> 10usize) & 0x01; + val != 0 + } + #[doc = "Clear global OUT NAK"] + #[inline(always)] + pub fn set_cgonak(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 10usize)) | (((val as u32) & 0x01) << 10usize); + } + #[doc = "Power-on programming done"] + #[inline(always)] + pub const fn poprgdne(&self) -> bool { + let val = (self.0 >> 11usize) & 0x01; + val != 0 + } + #[doc = "Power-on programming done"] + #[inline(always)] + pub fn set_poprgdne(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 11usize)) | (((val as u32) & 0x01) << 11usize); + } + } + impl Default for Dctl { + #[inline(always)] + fn default() -> Dctl { + Dctl(0) + } + } + #[doc = "Device endpoint control register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Diepctl(pub u32); + impl Diepctl { + #[doc = "MPSIZ"] + #[inline(always)] + pub const fn mpsiz(&self) -> u16 { + let val = (self.0 >> 0usize) & 0x07ff; + val as u16 + } + #[doc = "MPSIZ"] + #[inline(always)] + pub fn set_mpsiz(&mut self, val: u16) { + self.0 = (self.0 & !(0x07ff << 0usize)) | (((val as u32) & 0x07ff) << 0usize); + } + #[doc = "USBAEP"] + #[inline(always)] + pub const fn usbaep(&self) -> bool { + let val = (self.0 >> 15usize) & 0x01; + val != 0 + } + #[doc = "USBAEP"] + #[inline(always)] + pub fn set_usbaep(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 15usize)) | (((val as u32) & 0x01) << 15usize); + } + #[doc = "EONUM/DPID"] + #[inline(always)] + pub const fn eonum_dpid(&self) -> bool { + let val = (self.0 >> 16usize) & 0x01; + val != 0 + } + #[doc = "EONUM/DPID"] + #[inline(always)] + pub fn set_eonum_dpid(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 16usize)) | (((val as u32) & 0x01) << 16usize); + } + #[doc = "NAKSTS"] + #[inline(always)] + pub const fn naksts(&self) -> bool { + let val = (self.0 >> 17usize) & 0x01; + val != 0 + } + #[doc = "NAKSTS"] + #[inline(always)] + pub fn set_naksts(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 17usize)) | (((val as u32) & 0x01) << 17usize); + } + #[doc = "EPTYP"] + #[inline(always)] + pub const fn eptyp(&self) -> super::vals::Eptyp { + let val = (self.0 >> 18usize) & 0x03; + super::vals::Eptyp::from_bits(val as u8) + } + #[doc = "EPTYP"] + #[inline(always)] + pub fn set_eptyp(&mut self, val: super::vals::Eptyp) { + self.0 = (self.0 & !(0x03 << 18usize)) | (((val.to_bits() as u32) & 0x03) << 18usize); + } + #[doc = "SNPM"] + #[inline(always)] + pub const fn snpm(&self) -> bool { + let val = (self.0 >> 20usize) & 0x01; + val != 0 + } + #[doc = "SNPM"] + #[inline(always)] + pub fn set_snpm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 20usize)) | (((val as u32) & 0x01) << 20usize); + } + #[doc = "STALL"] + #[inline(always)] + pub const fn stall(&self) -> bool { + let val = (self.0 >> 21usize) & 0x01; + val != 0 + } + #[doc = "STALL"] + #[inline(always)] + pub fn set_stall(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 21usize)) | (((val as u32) & 0x01) << 21usize); + } + #[doc = "TXFNUM"] + #[inline(always)] + pub const fn txfnum(&self) -> u8 { + let val = (self.0 >> 22usize) & 0x0f; + val as u8 + } + #[doc = "TXFNUM"] + #[inline(always)] + pub fn set_txfnum(&mut self, val: u8) { + self.0 = (self.0 & !(0x0f << 22usize)) | (((val as u32) & 0x0f) << 22usize); + } + #[doc = "CNAK"] + #[inline(always)] + pub const fn cnak(&self) -> bool { + let val = (self.0 >> 26usize) & 0x01; + val != 0 + } + #[doc = "CNAK"] + #[inline(always)] + pub fn set_cnak(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 26usize)) | (((val as u32) & 0x01) << 26usize); + } + #[doc = "SNAK"] + #[inline(always)] + pub const fn snak(&self) -> bool { + let val = (self.0 >> 27usize) & 0x01; + val != 0 + } + #[doc = "SNAK"] + #[inline(always)] + pub fn set_snak(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 27usize)) | (((val as u32) & 0x01) << 27usize); + } + #[doc = "SD0PID/SEVNFRM"] + #[inline(always)] + pub const fn sd0pid_sevnfrm(&self) -> bool { + let val = (self.0 >> 28usize) & 0x01; + val != 0 + } + #[doc = "SD0PID/SEVNFRM"] + #[inline(always)] + pub fn set_sd0pid_sevnfrm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 28usize)) | (((val as u32) & 0x01) << 28usize); + } + #[doc = "SODDFRM/SD1PID"] + #[inline(always)] + pub const fn soddfrm_sd1pid(&self) -> bool { + let val = (self.0 >> 29usize) & 0x01; + val != 0 + } + #[doc = "SODDFRM/SD1PID"] + #[inline(always)] + pub fn set_soddfrm_sd1pid(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 29usize)) | (((val as u32) & 0x01) << 29usize); + } + #[doc = "EPDIS"] + #[inline(always)] + pub const fn epdis(&self) -> bool { + let val = (self.0 >> 30usize) & 0x01; + val != 0 + } + #[doc = "EPDIS"] + #[inline(always)] + pub fn set_epdis(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 30usize)) | (((val as u32) & 0x01) << 30usize); + } + #[doc = "EPENA"] + #[inline(always)] + pub const fn epena(&self) -> bool { + let val = (self.0 >> 31usize) & 0x01; + val != 0 + } + #[doc = "EPENA"] + #[inline(always)] + pub fn set_epena(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 31usize)) | (((val as u32) & 0x01) << 31usize); + } + } + impl Default for Diepctl { + #[inline(always)] + fn default() -> Diepctl { + Diepctl(0) + } + } + #[doc = "Device IN endpoint FIFO empty interrupt mask register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Diepempmsk(pub u32); + impl Diepempmsk { + #[doc = "IN EP Tx FIFO empty interrupt mask bits"] + #[inline(always)] + pub const fn ineptxfem(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "IN EP Tx FIFO empty interrupt mask bits"] + #[inline(always)] + pub fn set_ineptxfem(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + } + impl Default for Diepempmsk { + #[inline(always)] + fn default() -> Diepempmsk { + Diepempmsk(0) + } + } + #[doc = "Device endpoint interrupt register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Diepint(pub u32); + impl Diepint { + #[doc = "XFRC"] + #[inline(always)] + pub const fn xfrc(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "XFRC"] + #[inline(always)] + pub fn set_xfrc(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "EPDISD"] + #[inline(always)] + pub const fn epdisd(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "EPDISD"] + #[inline(always)] + pub fn set_epdisd(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "TOC"] + #[inline(always)] + pub const fn toc(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "TOC"] + #[inline(always)] + pub fn set_toc(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "ITTXFE"] + #[inline(always)] + pub const fn ittxfe(&self) -> bool { + let val = (self.0 >> 4usize) & 0x01; + val != 0 + } + #[doc = "ITTXFE"] + #[inline(always)] + pub fn set_ittxfe(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 4usize)) | (((val as u32) & 0x01) << 4usize); + } + #[doc = "INEPNE"] + #[inline(always)] + pub const fn inepne(&self) -> bool { + let val = (self.0 >> 6usize) & 0x01; + val != 0 + } + #[doc = "INEPNE"] + #[inline(always)] + pub fn set_inepne(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 6usize)) | (((val as u32) & 0x01) << 6usize); + } + #[doc = "TXFE"] + #[inline(always)] + pub const fn txfe(&self) -> bool { + let val = (self.0 >> 7usize) & 0x01; + val != 0 + } + #[doc = "TXFE"] + #[inline(always)] + pub fn set_txfe(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 7usize)) | (((val as u32) & 0x01) << 7usize); + } + } + impl Default for Diepint { + #[inline(always)] + fn default() -> Diepint { + Diepint(0) + } + } + #[doc = "Device IN endpoint common interrupt mask register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Diepmsk(pub u32); + impl Diepmsk { + #[doc = "Transfer completed interrupt mask"] + #[inline(always)] + pub const fn xfrcm(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Transfer completed interrupt mask"] + #[inline(always)] + pub fn set_xfrcm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "Endpoint disabled interrupt mask"] + #[inline(always)] + pub const fn epdm(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "Endpoint disabled interrupt mask"] + #[inline(always)] + pub fn set_epdm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "Timeout condition mask (Non-isochronous endpoints)"] + #[inline(always)] + pub const fn tom(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "Timeout condition mask (Non-isochronous endpoints)"] + #[inline(always)] + pub fn set_tom(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "IN token received when TxFIFO empty mask"] + #[inline(always)] + pub const fn ittxfemsk(&self) -> bool { + let val = (self.0 >> 4usize) & 0x01; + val != 0 + } + #[doc = "IN token received when TxFIFO empty mask"] + #[inline(always)] + pub fn set_ittxfemsk(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 4usize)) | (((val as u32) & 0x01) << 4usize); + } + #[doc = "IN token received with EP mismatch mask"] + #[inline(always)] + pub const fn inepnmm(&self) -> bool { + let val = (self.0 >> 5usize) & 0x01; + val != 0 + } + #[doc = "IN token received with EP mismatch mask"] + #[inline(always)] + pub fn set_inepnmm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 5usize)) | (((val as u32) & 0x01) << 5usize); + } + #[doc = "IN endpoint NAK effective mask"] + #[inline(always)] + pub const fn inepnem(&self) -> bool { + let val = (self.0 >> 6usize) & 0x01; + val != 0 + } + #[doc = "IN endpoint NAK effective mask"] + #[inline(always)] + pub fn set_inepnem(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 6usize)) | (((val as u32) & 0x01) << 6usize); + } + } + impl Default for Diepmsk { + #[inline(always)] + fn default() -> Diepmsk { + Diepmsk(0) + } + } + #[doc = "Device endpoint transfer size register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Dieptsiz(pub u32); + impl Dieptsiz { + #[doc = "Transfer size"] + #[inline(always)] + pub const fn xfrsiz(&self) -> u32 { + let val = (self.0 >> 0usize) & 0x0007_ffff; + val as u32 + } + #[doc = "Transfer size"] + #[inline(always)] + pub fn set_xfrsiz(&mut self, val: u32) { + self.0 = (self.0 & !(0x0007_ffff << 0usize)) | (((val as u32) & 0x0007_ffff) << 0usize); + } + #[doc = "Packet count"] + #[inline(always)] + pub const fn pktcnt(&self) -> u16 { + let val = (self.0 >> 19usize) & 0x03ff; + val as u16 + } + #[doc = "Packet count"] + #[inline(always)] + pub fn set_pktcnt(&mut self, val: u16) { + self.0 = (self.0 & !(0x03ff << 19usize)) | (((val as u32) & 0x03ff) << 19usize); + } + #[doc = "Multi count"] + #[inline(always)] + pub const fn mcnt(&self) -> u8 { + let val = (self.0 >> 29usize) & 0x03; + val as u8 + } + #[doc = "Multi count"] + #[inline(always)] + pub fn set_mcnt(&mut self, val: u8) { + self.0 = (self.0 & !(0x03 << 29usize)) | (((val as u32) & 0x03) << 29usize); + } + } + impl Default for Dieptsiz { + #[inline(always)] + fn default() -> Dieptsiz { + Dieptsiz(0) + } + } + #[doc = "Device endpoint control register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Doepctl(pub u32); + impl Doepctl { + #[doc = "MPSIZ"] + #[inline(always)] + pub const fn mpsiz(&self) -> u16 { + let val = (self.0 >> 0usize) & 0x07ff; + val as u16 + } + #[doc = "MPSIZ"] + #[inline(always)] + pub fn set_mpsiz(&mut self, val: u16) { + self.0 = (self.0 & !(0x07ff << 0usize)) | (((val as u32) & 0x07ff) << 0usize); + } + #[doc = "USBAEP"] + #[inline(always)] + pub const fn usbaep(&self) -> bool { + let val = (self.0 >> 15usize) & 0x01; + val != 0 + } + #[doc = "USBAEP"] + #[inline(always)] + pub fn set_usbaep(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 15usize)) | (((val as u32) & 0x01) << 15usize); + } + #[doc = "EONUM/DPID"] + #[inline(always)] + pub const fn eonum_dpid(&self) -> bool { + let val = (self.0 >> 16usize) & 0x01; + val != 0 + } + #[doc = "EONUM/DPID"] + #[inline(always)] + pub fn set_eonum_dpid(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 16usize)) | (((val as u32) & 0x01) << 16usize); + } + #[doc = "NAKSTS"] + #[inline(always)] + pub const fn naksts(&self) -> bool { + let val = (self.0 >> 17usize) & 0x01; + val != 0 + } + #[doc = "NAKSTS"] + #[inline(always)] + pub fn set_naksts(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 17usize)) | (((val as u32) & 0x01) << 17usize); + } + #[doc = "EPTYP"] + #[inline(always)] + pub const fn eptyp(&self) -> super::vals::Eptyp { + let val = (self.0 >> 18usize) & 0x03; + super::vals::Eptyp::from_bits(val as u8) + } + #[doc = "EPTYP"] + #[inline(always)] + pub fn set_eptyp(&mut self, val: super::vals::Eptyp) { + self.0 = (self.0 & !(0x03 << 18usize)) | (((val.to_bits() as u32) & 0x03) << 18usize); + } + #[doc = "SNPM"] + #[inline(always)] + pub const fn snpm(&self) -> bool { + let val = (self.0 >> 20usize) & 0x01; + val != 0 + } + #[doc = "SNPM"] + #[inline(always)] + pub fn set_snpm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 20usize)) | (((val as u32) & 0x01) << 20usize); + } + #[doc = "STALL"] + #[inline(always)] + pub const fn stall(&self) -> bool { + let val = (self.0 >> 21usize) & 0x01; + val != 0 + } + #[doc = "STALL"] + #[inline(always)] + pub fn set_stall(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 21usize)) | (((val as u32) & 0x01) << 21usize); + } + #[doc = "CNAK"] + #[inline(always)] + pub const fn cnak(&self) -> bool { + let val = (self.0 >> 26usize) & 0x01; + val != 0 + } + #[doc = "CNAK"] + #[inline(always)] + pub fn set_cnak(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 26usize)) | (((val as u32) & 0x01) << 26usize); + } + #[doc = "SNAK"] + #[inline(always)] + pub const fn snak(&self) -> bool { + let val = (self.0 >> 27usize) & 0x01; + val != 0 + } + #[doc = "SNAK"] + #[inline(always)] + pub fn set_snak(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 27usize)) | (((val as u32) & 0x01) << 27usize); + } + #[doc = "SD0PID/SEVNFRM"] + #[inline(always)] + pub const fn sd0pid_sevnfrm(&self) -> bool { + let val = (self.0 >> 28usize) & 0x01; + val != 0 + } + #[doc = "SD0PID/SEVNFRM"] + #[inline(always)] + pub fn set_sd0pid_sevnfrm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 28usize)) | (((val as u32) & 0x01) << 28usize); + } + #[doc = "SODDFRM"] + #[inline(always)] + pub const fn soddfrm(&self) -> bool { + let val = (self.0 >> 29usize) & 0x01; + val != 0 + } + #[doc = "SODDFRM"] + #[inline(always)] + pub fn set_soddfrm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 29usize)) | (((val as u32) & 0x01) << 29usize); + } + #[doc = "EPDIS"] + #[inline(always)] + pub const fn epdis(&self) -> bool { + let val = (self.0 >> 30usize) & 0x01; + val != 0 + } + #[doc = "EPDIS"] + #[inline(always)] + pub fn set_epdis(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 30usize)) | (((val as u32) & 0x01) << 30usize); + } + #[doc = "EPENA"] + #[inline(always)] + pub const fn epena(&self) -> bool { + let val = (self.0 >> 31usize) & 0x01; + val != 0 + } + #[doc = "EPENA"] + #[inline(always)] + pub fn set_epena(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 31usize)) | (((val as u32) & 0x01) << 31usize); + } + } + impl Default for Doepctl { + #[inline(always)] + fn default() -> Doepctl { + Doepctl(0) + } + } + #[doc = "Device endpoint interrupt register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Doepint(pub u32); + impl Doepint { + #[doc = "XFRC"] + #[inline(always)] + pub const fn xfrc(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "XFRC"] + #[inline(always)] + pub fn set_xfrc(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "EPDISD"] + #[inline(always)] + pub const fn epdisd(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "EPDISD"] + #[inline(always)] + pub fn set_epdisd(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "STUP"] + #[inline(always)] + pub const fn stup(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "STUP"] + #[inline(always)] + pub fn set_stup(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "OTEPDIS"] + #[inline(always)] + pub const fn otepdis(&self) -> bool { + let val = (self.0 >> 4usize) & 0x01; + val != 0 + } + #[doc = "OTEPDIS"] + #[inline(always)] + pub fn set_otepdis(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 4usize)) | (((val as u32) & 0x01) << 4usize); + } + #[doc = "B2BSTUP"] + #[inline(always)] + pub const fn b2bstup(&self) -> bool { + let val = (self.0 >> 6usize) & 0x01; + val != 0 + } + #[doc = "B2BSTUP"] + #[inline(always)] + pub fn set_b2bstup(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 6usize)) | (((val as u32) & 0x01) << 6usize); + } + } + impl Default for Doepint { + #[inline(always)] + fn default() -> Doepint { + Doepint(0) + } + } + #[doc = "Device OUT endpoint common interrupt mask register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Doepmsk(pub u32); + impl Doepmsk { + #[doc = "Transfer completed interrupt mask"] + #[inline(always)] + pub const fn xfrcm(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Transfer completed interrupt mask"] + #[inline(always)] + pub fn set_xfrcm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "Endpoint disabled interrupt mask"] + #[inline(always)] + pub const fn epdm(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "Endpoint disabled interrupt mask"] + #[inline(always)] + pub fn set_epdm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "SETUP phase done mask"] + #[inline(always)] + pub const fn stupm(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "SETUP phase done mask"] + #[inline(always)] + pub fn set_stupm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "OUT token received when endpoint disabled mask"] + #[inline(always)] + pub const fn otepdm(&self) -> bool { + let val = (self.0 >> 4usize) & 0x01; + val != 0 + } + #[doc = "OUT token received when endpoint disabled mask"] + #[inline(always)] + pub fn set_otepdm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 4usize)) | (((val as u32) & 0x01) << 4usize); + } + } + impl Default for Doepmsk { + #[inline(always)] + fn default() -> Doepmsk { + Doepmsk(0) + } + } + #[doc = "Device OUT endpoint transfer size register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Doeptsiz(pub u32); + impl Doeptsiz { + #[doc = "Transfer size"] + #[inline(always)] + pub const fn xfrsiz(&self) -> u32 { + let val = (self.0 >> 0usize) & 0x0007_ffff; + val as u32 + } + #[doc = "Transfer size"] + #[inline(always)] + pub fn set_xfrsiz(&mut self, val: u32) { + self.0 = (self.0 & !(0x0007_ffff << 0usize)) | (((val as u32) & 0x0007_ffff) << 0usize); + } + #[doc = "Packet count"] + #[inline(always)] + pub const fn pktcnt(&self) -> u16 { + let val = (self.0 >> 19usize) & 0x03ff; + val as u16 + } + #[doc = "Packet count"] + #[inline(always)] + pub fn set_pktcnt(&mut self, val: u16) { + self.0 = (self.0 & !(0x03ff << 19usize)) | (((val as u32) & 0x03ff) << 19usize); + } + #[doc = "Received data PID/SETUP packet count"] + #[inline(always)] + pub const fn rxdpid_stupcnt(&self) -> u8 { + let val = (self.0 >> 29usize) & 0x03; + val as u8 + } + #[doc = "Received data PID/SETUP packet count"] + #[inline(always)] + pub fn set_rxdpid_stupcnt(&mut self, val: u8) { + self.0 = (self.0 & !(0x03 << 29usize)) | (((val as u32) & 0x03) << 29usize); + } + } + impl Default for Doeptsiz { + #[inline(always)] + fn default() -> Doeptsiz { + Doeptsiz(0) + } + } + #[doc = "Device status register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Dsts(pub u32); + impl Dsts { + #[doc = "Suspend status"] + #[inline(always)] + pub const fn suspsts(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Suspend status"] + #[inline(always)] + pub fn set_suspsts(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "Enumerated speed"] + #[inline(always)] + pub const fn enumspd(&self) -> super::vals::Dspd { + let val = (self.0 >> 1usize) & 0x03; + super::vals::Dspd::from_bits(val as u8) + } + #[doc = "Enumerated speed"] + #[inline(always)] + pub fn set_enumspd(&mut self, val: super::vals::Dspd) { + self.0 = (self.0 & !(0x03 << 1usize)) | (((val.to_bits() as u32) & 0x03) << 1usize); + } + #[doc = "Erratic error"] + #[inline(always)] + pub const fn eerr(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "Erratic error"] + #[inline(always)] + pub fn set_eerr(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "Frame number of the received SOF"] + #[inline(always)] + pub const fn fnsof(&self) -> u16 { + let val = (self.0 >> 8usize) & 0x3fff; + val as u16 + } + #[doc = "Frame number of the received SOF"] + #[inline(always)] + pub fn set_fnsof(&mut self, val: u16) { + self.0 = (self.0 & !(0x3fff << 8usize)) | (((val as u32) & 0x3fff) << 8usize); + } + } + impl Default for Dsts { + #[inline(always)] + fn default() -> Dsts { + Dsts(0) + } + } + #[doc = "Device IN endpoint transmit FIFO status register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Dtxfsts(pub u32); + impl Dtxfsts { + #[doc = "IN endpoint TxFIFO space available"] + #[inline(always)] + pub const fn ineptfsav(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "IN endpoint TxFIFO space available"] + #[inline(always)] + pub fn set_ineptfsav(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + } + impl Default for Dtxfsts { + #[inline(always)] + fn default() -> Dtxfsts { + Dtxfsts(0) + } + } + #[doc = "Device VBUS discharge time register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Dvbusdis(pub u32); + impl Dvbusdis { + #[doc = "Device VBUS discharge time"] + #[inline(always)] + pub const fn vbusdt(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "Device VBUS discharge time"] + #[inline(always)] + pub fn set_vbusdt(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + } + impl Default for Dvbusdis { + #[inline(always)] + fn default() -> Dvbusdis { + Dvbusdis(0) + } + } + #[doc = "Device VBUS pulsing time register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Dvbuspulse(pub u32); + impl Dvbuspulse { + #[doc = "Device VBUS pulsing time"] + #[inline(always)] + pub const fn dvbusp(&self) -> u16 { + let val = (self.0 >> 0usize) & 0x0fff; + val as u16 + } + #[doc = "Device VBUS pulsing time"] + #[inline(always)] + pub fn set_dvbusp(&mut self, val: u16) { + self.0 = (self.0 & !(0x0fff << 0usize)) | (((val as u32) & 0x0fff) << 0usize); + } + } + impl Default for Dvbuspulse { + #[inline(always)] + fn default() -> Dvbuspulse { + Dvbuspulse(0) + } + } + #[doc = "FIFO register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Fifo(pub u32); + impl Fifo { + #[doc = "Data"] + #[inline(always)] + pub const fn data(&self) -> u32 { + let val = (self.0 >> 0usize) & 0xffff_ffff; + val as u32 + } + #[doc = "Data"] + #[inline(always)] + pub fn set_data(&mut self, val: u32) { + self.0 = (self.0 & !(0xffff_ffff << 0usize)) | (((val as u32) & 0xffff_ffff) << 0usize); + } + } + impl Default for Fifo { + #[inline(always)] + fn default() -> Fifo { + Fifo(0) + } + } + #[doc = "FIFO size register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Fsiz(pub u32); + impl Fsiz { + #[doc = "RAM start address"] + #[inline(always)] + pub const fn sa(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "RAM start address"] + #[inline(always)] + pub fn set_sa(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + #[doc = "FIFO depth"] + #[inline(always)] + pub const fn fd(&self) -> u16 { + let val = (self.0 >> 16usize) & 0xffff; + val as u16 + } + #[doc = "FIFO depth"] + #[inline(always)] + pub fn set_fd(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 16usize)) | (((val as u32) & 0xffff) << 16usize); + } + } + impl Default for Fsiz { + #[inline(always)] + fn default() -> Fsiz { + Fsiz(0) + } + } + #[doc = "AHB configuration register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Gahbcfg(pub u32); + impl Gahbcfg { + #[doc = "Global interrupt mask"] + #[inline(always)] + pub const fn gint(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Global interrupt mask"] + #[inline(always)] + pub fn set_gint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "Burst length/type"] + #[inline(always)] + pub const fn hbstlen(&self) -> u8 { + let val = (self.0 >> 1usize) & 0x0f; + val as u8 + } + #[doc = "Burst length/type"] + #[inline(always)] + pub fn set_hbstlen(&mut self, val: u8) { + self.0 = (self.0 & !(0x0f << 1usize)) | (((val as u32) & 0x0f) << 1usize); + } + #[doc = "DMA enable"] + #[inline(always)] + pub const fn dmaen(&self) -> bool { + let val = (self.0 >> 5usize) & 0x01; + val != 0 + } + #[doc = "DMA enable"] + #[inline(always)] + pub fn set_dmaen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 5usize)) | (((val as u32) & 0x01) << 5usize); + } + #[doc = "TxFIFO empty level"] + #[inline(always)] + pub const fn txfelvl(&self) -> bool { + let val = (self.0 >> 7usize) & 0x01; + val != 0 + } + #[doc = "TxFIFO empty level"] + #[inline(always)] + pub fn set_txfelvl(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 7usize)) | (((val as u32) & 0x01) << 7usize); + } + #[doc = "Periodic TxFIFO empty level"] + #[inline(always)] + pub const fn ptxfelvl(&self) -> bool { + let val = (self.0 >> 8usize) & 0x01; + val != 0 + } + #[doc = "Periodic TxFIFO empty level"] + #[inline(always)] + pub fn set_ptxfelvl(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 8usize)) | (((val as u32) & 0x01) << 8usize); + } + } + impl Default for Gahbcfg { + #[inline(always)] + fn default() -> Gahbcfg { + Gahbcfg(0) + } + } + #[doc = "General core configuration register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct GccfgV1(pub u32); + impl GccfgV1 { + #[doc = "Power down"] + #[inline(always)] + pub const fn pwrdwn(&self) -> bool { + let val = (self.0 >> 16usize) & 0x01; + val != 0 + } + #[doc = "Power down"] + #[inline(always)] + pub fn set_pwrdwn(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 16usize)) | (((val as u32) & 0x01) << 16usize); + } + #[doc = "Enable the VBUS \"A\" sensing device"] + #[inline(always)] + pub const fn vbusasen(&self) -> bool { + let val = (self.0 >> 18usize) & 0x01; + val != 0 + } + #[doc = "Enable the VBUS \"A\" sensing device"] + #[inline(always)] + pub fn set_vbusasen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 18usize)) | (((val as u32) & 0x01) << 18usize); + } + #[doc = "Enable the VBUS \"B\" sensing device"] + #[inline(always)] + pub const fn vbusbsen(&self) -> bool { + let val = (self.0 >> 19usize) & 0x01; + val != 0 + } + #[doc = "Enable the VBUS \"B\" sensing device"] + #[inline(always)] + pub fn set_vbusbsen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 19usize)) | (((val as u32) & 0x01) << 19usize); + } + #[doc = "SOF output enable"] + #[inline(always)] + pub const fn sofouten(&self) -> bool { + let val = (self.0 >> 20usize) & 0x01; + val != 0 + } + #[doc = "SOF output enable"] + #[inline(always)] + pub fn set_sofouten(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 20usize)) | (((val as u32) & 0x01) << 20usize); + } + #[doc = "VBUS sensing disable"] + #[inline(always)] + pub const fn novbussens(&self) -> bool { + let val = (self.0 >> 21usize) & 0x01; + val != 0 + } + #[doc = "VBUS sensing disable"] + #[inline(always)] + pub fn set_novbussens(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 21usize)) | (((val as u32) & 0x01) << 21usize); + } + } + impl Default for GccfgV1 { + #[inline(always)] + fn default() -> GccfgV1 { + GccfgV1(0) + } + } + #[doc = "General core configuration register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct GccfgV2(pub u32); + impl GccfgV2 { + #[doc = "Data contact detection (DCD) status"] + #[inline(always)] + pub const fn dcdet(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Data contact detection (DCD) status"] + #[inline(always)] + pub fn set_dcdet(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "Primary detection (PD) status"] + #[inline(always)] + pub const fn pdet(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "Primary detection (PD) status"] + #[inline(always)] + pub fn set_pdet(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "Secondary detection (SD) status"] + #[inline(always)] + pub const fn sdet(&self) -> bool { + let val = (self.0 >> 2usize) & 0x01; + val != 0 + } + #[doc = "Secondary detection (SD) status"] + #[inline(always)] + pub fn set_sdet(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 2usize)) | (((val as u32) & 0x01) << 2usize); + } + #[doc = "DM pull-up detection status"] + #[inline(always)] + pub const fn ps2det(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "DM pull-up detection status"] + #[inline(always)] + pub fn set_ps2det(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "Power down"] + #[inline(always)] + pub const fn pwrdwn(&self) -> bool { + let val = (self.0 >> 16usize) & 0x01; + val != 0 + } + #[doc = "Power down"] + #[inline(always)] + pub fn set_pwrdwn(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 16usize)) | (((val as u32) & 0x01) << 16usize); + } + #[doc = "Battery charging detector (BCD) enable"] + #[inline(always)] + pub const fn bcden(&self) -> bool { + let val = (self.0 >> 17usize) & 0x01; + val != 0 + } + #[doc = "Battery charging detector (BCD) enable"] + #[inline(always)] + pub fn set_bcden(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 17usize)) | (((val as u32) & 0x01) << 17usize); + } + #[doc = "Data contact detection (DCD) mode enable"] + #[inline(always)] + pub const fn dcden(&self) -> bool { + let val = (self.0 >> 18usize) & 0x01; + val != 0 + } + #[doc = "Data contact detection (DCD) mode enable"] + #[inline(always)] + pub fn set_dcden(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 18usize)) | (((val as u32) & 0x01) << 18usize); + } + #[doc = "Primary detection (PD) mode enable"] + #[inline(always)] + pub const fn pden(&self) -> bool { + let val = (self.0 >> 19usize) & 0x01; + val != 0 + } + #[doc = "Primary detection (PD) mode enable"] + #[inline(always)] + pub fn set_pden(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 19usize)) | (((val as u32) & 0x01) << 19usize); + } + #[doc = "Secondary detection (SD) mode enable"] + #[inline(always)] + pub const fn sden(&self) -> bool { + let val = (self.0 >> 20usize) & 0x01; + val != 0 + } + #[doc = "Secondary detection (SD) mode enable"] + #[inline(always)] + pub fn set_sden(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 20usize)) | (((val as u32) & 0x01) << 20usize); + } + #[doc = "USB VBUS detection enable"] + #[inline(always)] + pub const fn vbden(&self) -> bool { + let val = (self.0 >> 21usize) & 0x01; + val != 0 + } + #[doc = "USB VBUS detection enable"] + #[inline(always)] + pub fn set_vbden(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 21usize)) | (((val as u32) & 0x01) << 21usize); + } + #[doc = "Internal high-speed PHY enable."] + #[inline(always)] + pub const fn phyhsen(&self) -> bool { + let val = (self.0 >> 23usize) & 0x01; + val != 0 + } + #[doc = "Internal high-speed PHY enable."] + #[inline(always)] + pub fn set_phyhsen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 23usize)) | (((val as u32) & 0x01) << 23usize); + } + } + impl Default for GccfgV2 { + #[inline(always)] + fn default() -> GccfgV2 { + GccfgV2(0) + } + } + #[doc = "I2C access register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Gi2cctl(pub u32); + impl Gi2cctl { + #[doc = "I2C Read/Write Data"] + #[inline(always)] + pub const fn rwdata(&self) -> u8 { + let val = (self.0 >> 0usize) & 0xff; + val as u8 + } + #[doc = "I2C Read/Write Data"] + #[inline(always)] + pub fn set_rwdata(&mut self, val: u8) { + self.0 = (self.0 & !(0xff << 0usize)) | (((val as u32) & 0xff) << 0usize); + } + #[doc = "I2C Register Address"] + #[inline(always)] + pub const fn regaddr(&self) -> u8 { + let val = (self.0 >> 8usize) & 0xff; + val as u8 + } + #[doc = "I2C Register Address"] + #[inline(always)] + pub fn set_regaddr(&mut self, val: u8) { + self.0 = (self.0 & !(0xff << 8usize)) | (((val as u32) & 0xff) << 8usize); + } + #[doc = "I2C Address"] + #[inline(always)] + pub const fn addr(&self) -> u8 { + let val = (self.0 >> 16usize) & 0x7f; + val as u8 + } + #[doc = "I2C Address"] + #[inline(always)] + pub fn set_addr(&mut self, val: u8) { + self.0 = (self.0 & !(0x7f << 16usize)) | (((val as u32) & 0x7f) << 16usize); + } + #[doc = "I2C Enable"] + #[inline(always)] + pub const fn i2cen(&self) -> bool { + let val = (self.0 >> 23usize) & 0x01; + val != 0 + } + #[doc = "I2C Enable"] + #[inline(always)] + pub fn set_i2cen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 23usize)) | (((val as u32) & 0x01) << 23usize); + } + #[doc = "I2C ACK"] + #[inline(always)] + pub const fn ack(&self) -> bool { + let val = (self.0 >> 24usize) & 0x01; + val != 0 + } + #[doc = "I2C ACK"] + #[inline(always)] + pub fn set_ack(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 24usize)) | (((val as u32) & 0x01) << 24usize); + } + #[doc = "I2C Device Address"] + #[inline(always)] + pub const fn i2cdevadr(&self) -> u8 { + let val = (self.0 >> 26usize) & 0x03; + val as u8 + } + #[doc = "I2C Device Address"] + #[inline(always)] + pub fn set_i2cdevadr(&mut self, val: u8) { + self.0 = (self.0 & !(0x03 << 26usize)) | (((val as u32) & 0x03) << 26usize); + } + #[doc = "I2C DatSe0 USB mode"] + #[inline(always)] + pub const fn i2cdatse0(&self) -> bool { + let val = (self.0 >> 28usize) & 0x01; + val != 0 + } + #[doc = "I2C DatSe0 USB mode"] + #[inline(always)] + pub fn set_i2cdatse0(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 28usize)) | (((val as u32) & 0x01) << 28usize); + } + #[doc = "Read/Write Indicator"] + #[inline(always)] + pub const fn rw(&self) -> bool { + let val = (self.0 >> 30usize) & 0x01; + val != 0 + } + #[doc = "Read/Write Indicator"] + #[inline(always)] + pub fn set_rw(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 30usize)) | (((val as u32) & 0x01) << 30usize); + } + #[doc = "I2C Busy/Done"] + #[inline(always)] + pub const fn bsydne(&self) -> bool { + let val = (self.0 >> 31usize) & 0x01; + val != 0 + } + #[doc = "I2C Busy/Done"] + #[inline(always)] + pub fn set_bsydne(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 31usize)) | (((val as u32) & 0x01) << 31usize); + } + } + impl Default for Gi2cctl { + #[inline(always)] + fn default() -> Gi2cctl { + Gi2cctl(0) + } + } + #[doc = "Interrupt mask register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Gintmsk(pub u32); + impl Gintmsk { + #[doc = "Mode mismatch interrupt mask"] + #[inline(always)] + pub const fn mmism(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "Mode mismatch interrupt mask"] + #[inline(always)] + pub fn set_mmism(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "OTG interrupt mask"] + #[inline(always)] + pub const fn otgint(&self) -> bool { + let val = (self.0 >> 2usize) & 0x01; + val != 0 + } + #[doc = "OTG interrupt mask"] + #[inline(always)] + pub fn set_otgint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 2usize)) | (((val as u32) & 0x01) << 2usize); + } + #[doc = "Start of frame mask"] + #[inline(always)] + pub const fn sofm(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "Start of frame mask"] + #[inline(always)] + pub fn set_sofm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "Receive FIFO non-empty mask"] + #[inline(always)] + pub const fn rxflvlm(&self) -> bool { + let val = (self.0 >> 4usize) & 0x01; + val != 0 + } + #[doc = "Receive FIFO non-empty mask"] + #[inline(always)] + pub fn set_rxflvlm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 4usize)) | (((val as u32) & 0x01) << 4usize); + } + #[doc = "Non-periodic TxFIFO empty mask"] + #[inline(always)] + pub const fn nptxfem(&self) -> bool { + let val = (self.0 >> 5usize) & 0x01; + val != 0 + } + #[doc = "Non-periodic TxFIFO empty mask"] + #[inline(always)] + pub fn set_nptxfem(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 5usize)) | (((val as u32) & 0x01) << 5usize); + } + #[doc = "Global non-periodic IN NAK effective mask"] + #[inline(always)] + pub const fn ginakeffm(&self) -> bool { + let val = (self.0 >> 6usize) & 0x01; + val != 0 + } + #[doc = "Global non-periodic IN NAK effective mask"] + #[inline(always)] + pub fn set_ginakeffm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 6usize)) | (((val as u32) & 0x01) << 6usize); + } + #[doc = "Global OUT NAK effective mask"] + #[inline(always)] + pub const fn gonakeffm(&self) -> bool { + let val = (self.0 >> 7usize) & 0x01; + val != 0 + } + #[doc = "Global OUT NAK effective mask"] + #[inline(always)] + pub fn set_gonakeffm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 7usize)) | (((val as u32) & 0x01) << 7usize); + } + #[doc = "Early suspend mask"] + #[inline(always)] + pub const fn esuspm(&self) -> bool { + let val = (self.0 >> 10usize) & 0x01; + val != 0 + } + #[doc = "Early suspend mask"] + #[inline(always)] + pub fn set_esuspm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 10usize)) | (((val as u32) & 0x01) << 10usize); + } + #[doc = "USB suspend mask"] + #[inline(always)] + pub const fn usbsuspm(&self) -> bool { + let val = (self.0 >> 11usize) & 0x01; + val != 0 + } + #[doc = "USB suspend mask"] + #[inline(always)] + pub fn set_usbsuspm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 11usize)) | (((val as u32) & 0x01) << 11usize); + } + #[doc = "USB reset mask"] + #[inline(always)] + pub const fn usbrst(&self) -> bool { + let val = (self.0 >> 12usize) & 0x01; + val != 0 + } + #[doc = "USB reset mask"] + #[inline(always)] + pub fn set_usbrst(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 12usize)) | (((val as u32) & 0x01) << 12usize); + } + #[doc = "Enumeration done mask"] + #[inline(always)] + pub const fn enumdnem(&self) -> bool { + let val = (self.0 >> 13usize) & 0x01; + val != 0 + } + #[doc = "Enumeration done mask"] + #[inline(always)] + pub fn set_enumdnem(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 13usize)) | (((val as u32) & 0x01) << 13usize); + } + #[doc = "Isochronous OUT packet dropped interrupt mask"] + #[inline(always)] + pub const fn isoodrpm(&self) -> bool { + let val = (self.0 >> 14usize) & 0x01; + val != 0 + } + #[doc = "Isochronous OUT packet dropped interrupt mask"] + #[inline(always)] + pub fn set_isoodrpm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 14usize)) | (((val as u32) & 0x01) << 14usize); + } + #[doc = "End of periodic frame interrupt mask"] + #[inline(always)] + pub const fn eopfm(&self) -> bool { + let val = (self.0 >> 15usize) & 0x01; + val != 0 + } + #[doc = "End of periodic frame interrupt mask"] + #[inline(always)] + pub fn set_eopfm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 15usize)) | (((val as u32) & 0x01) << 15usize); + } + #[doc = "Endpoint mismatch interrupt mask"] + #[inline(always)] + pub const fn epmism(&self) -> bool { + let val = (self.0 >> 17usize) & 0x01; + val != 0 + } + #[doc = "Endpoint mismatch interrupt mask"] + #[inline(always)] + pub fn set_epmism(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 17usize)) | (((val as u32) & 0x01) << 17usize); + } + #[doc = "IN endpoints interrupt mask"] + #[inline(always)] + pub const fn iepint(&self) -> bool { + let val = (self.0 >> 18usize) & 0x01; + val != 0 + } + #[doc = "IN endpoints interrupt mask"] + #[inline(always)] + pub fn set_iepint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 18usize)) | (((val as u32) & 0x01) << 18usize); + } + #[doc = "OUT endpoints interrupt mask"] + #[inline(always)] + pub const fn oepint(&self) -> bool { + let val = (self.0 >> 19usize) & 0x01; + val != 0 + } + #[doc = "OUT endpoints interrupt mask"] + #[inline(always)] + pub fn set_oepint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 19usize)) | (((val as u32) & 0x01) << 19usize); + } + #[doc = "Incomplete isochronous IN transfer mask"] + #[inline(always)] + pub const fn iisoixfrm(&self) -> bool { + let val = (self.0 >> 20usize) & 0x01; + val != 0 + } + #[doc = "Incomplete isochronous IN transfer mask"] + #[inline(always)] + pub fn set_iisoixfrm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 20usize)) | (((val as u32) & 0x01) << 20usize); + } + #[doc = "Incomplete periodic transfer mask (host mode) / Incomplete isochronous OUT transfer mask (device mode)"] + #[inline(always)] + pub const fn ipxfrm_iisooxfrm(&self) -> bool { + let val = (self.0 >> 21usize) & 0x01; + val != 0 + } + #[doc = "Incomplete periodic transfer mask (host mode) / Incomplete isochronous OUT transfer mask (device mode)"] + #[inline(always)] + pub fn set_ipxfrm_iisooxfrm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 21usize)) | (((val as u32) & 0x01) << 21usize); + } + #[doc = "Data fetch suspended mask"] + #[inline(always)] + pub const fn fsuspm(&self) -> bool { + let val = (self.0 >> 22usize) & 0x01; + val != 0 + } + #[doc = "Data fetch suspended mask"] + #[inline(always)] + pub fn set_fsuspm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 22usize)) | (((val as u32) & 0x01) << 22usize); + } + #[doc = "Reset detected interrupt mask"] + #[inline(always)] + pub const fn rstde(&self) -> bool { + let val = (self.0 >> 23usize) & 0x01; + val != 0 + } + #[doc = "Reset detected interrupt mask"] + #[inline(always)] + pub fn set_rstde(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 23usize)) | (((val as u32) & 0x01) << 23usize); + } + #[doc = "Host port interrupt mask"] + #[inline(always)] + pub const fn prtim(&self) -> bool { + let val = (self.0 >> 24usize) & 0x01; + val != 0 + } + #[doc = "Host port interrupt mask"] + #[inline(always)] + pub fn set_prtim(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 24usize)) | (((val as u32) & 0x01) << 24usize); + } + #[doc = "Host channels interrupt mask"] + #[inline(always)] + pub const fn hcim(&self) -> bool { + let val = (self.0 >> 25usize) & 0x01; + val != 0 + } + #[doc = "Host channels interrupt mask"] + #[inline(always)] + pub fn set_hcim(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 25usize)) | (((val as u32) & 0x01) << 25usize); + } + #[doc = "Periodic TxFIFO empty mask"] + #[inline(always)] + pub const fn ptxfem(&self) -> bool { + let val = (self.0 >> 26usize) & 0x01; + val != 0 + } + #[doc = "Periodic TxFIFO empty mask"] + #[inline(always)] + pub fn set_ptxfem(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 26usize)) | (((val as u32) & 0x01) << 26usize); + } + #[doc = "LPM interrupt mask"] + #[inline(always)] + pub const fn lpmintm(&self) -> bool { + let val = (self.0 >> 27usize) & 0x01; + val != 0 + } + #[doc = "LPM interrupt mask"] + #[inline(always)] + pub fn set_lpmintm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 27usize)) | (((val as u32) & 0x01) << 27usize); + } + #[doc = "Connector ID status change mask"] + #[inline(always)] + pub const fn cidschgm(&self) -> bool { + let val = (self.0 >> 28usize) & 0x01; + val != 0 + } + #[doc = "Connector ID status change mask"] + #[inline(always)] + pub fn set_cidschgm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 28usize)) | (((val as u32) & 0x01) << 28usize); + } + #[doc = "Disconnect detected interrupt mask"] + #[inline(always)] + pub const fn discint(&self) -> bool { + let val = (self.0 >> 29usize) & 0x01; + val != 0 + } + #[doc = "Disconnect detected interrupt mask"] + #[inline(always)] + pub fn set_discint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 29usize)) | (((val as u32) & 0x01) << 29usize); + } + #[doc = "Session request/new session detected interrupt mask"] + #[inline(always)] + pub const fn srqim(&self) -> bool { + let val = (self.0 >> 30usize) & 0x01; + val != 0 + } + #[doc = "Session request/new session detected interrupt mask"] + #[inline(always)] + pub fn set_srqim(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 30usize)) | (((val as u32) & 0x01) << 30usize); + } + #[doc = "Resume/remote wakeup detected interrupt mask"] + #[inline(always)] + pub const fn wuim(&self) -> bool { + let val = (self.0 >> 31usize) & 0x01; + val != 0 + } + #[doc = "Resume/remote wakeup detected interrupt mask"] + #[inline(always)] + pub fn set_wuim(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 31usize)) | (((val as u32) & 0x01) << 31usize); + } + } + impl Default for Gintmsk { + #[inline(always)] + fn default() -> Gintmsk { + Gintmsk(0) + } + } + #[doc = "Core interrupt register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Gintsts(pub u32); + impl Gintsts { + #[doc = "Current mode of operation"] + #[inline(always)] + pub const fn cmod(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Current mode of operation"] + #[inline(always)] + pub fn set_cmod(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "Mode mismatch interrupt"] + #[inline(always)] + pub const fn mmis(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "Mode mismatch interrupt"] + #[inline(always)] + pub fn set_mmis(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "OTG interrupt"] + #[inline(always)] + pub const fn otgint(&self) -> bool { + let val = (self.0 >> 2usize) & 0x01; + val != 0 + } + #[doc = "OTG interrupt"] + #[inline(always)] + pub fn set_otgint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 2usize)) | (((val as u32) & 0x01) << 2usize); + } + #[doc = "Start of frame"] + #[inline(always)] + pub const fn sof(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "Start of frame"] + #[inline(always)] + pub fn set_sof(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "RxFIFO non-empty"] + #[inline(always)] + pub const fn rxflvl(&self) -> bool { + let val = (self.0 >> 4usize) & 0x01; + val != 0 + } + #[doc = "RxFIFO non-empty"] + #[inline(always)] + pub fn set_rxflvl(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 4usize)) | (((val as u32) & 0x01) << 4usize); + } + #[doc = "Non-periodic TxFIFO empty"] + #[inline(always)] + pub const fn nptxfe(&self) -> bool { + let val = (self.0 >> 5usize) & 0x01; + val != 0 + } + #[doc = "Non-periodic TxFIFO empty"] + #[inline(always)] + pub fn set_nptxfe(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 5usize)) | (((val as u32) & 0x01) << 5usize); + } + #[doc = "Global IN non-periodic NAK effective"] + #[inline(always)] + pub const fn ginakeff(&self) -> bool { + let val = (self.0 >> 6usize) & 0x01; + val != 0 + } + #[doc = "Global IN non-periodic NAK effective"] + #[inline(always)] + pub fn set_ginakeff(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 6usize)) | (((val as u32) & 0x01) << 6usize); + } + #[doc = "Global OUT NAK effective"] + #[inline(always)] + pub const fn goutnakeff(&self) -> bool { + let val = (self.0 >> 7usize) & 0x01; + val != 0 + } + #[doc = "Global OUT NAK effective"] + #[inline(always)] + pub fn set_goutnakeff(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 7usize)) | (((val as u32) & 0x01) << 7usize); + } + #[doc = "Early suspend"] + #[inline(always)] + pub const fn esusp(&self) -> bool { + let val = (self.0 >> 10usize) & 0x01; + val != 0 + } + #[doc = "Early suspend"] + #[inline(always)] + pub fn set_esusp(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 10usize)) | (((val as u32) & 0x01) << 10usize); + } + #[doc = "USB suspend"] + #[inline(always)] + pub const fn usbsusp(&self) -> bool { + let val = (self.0 >> 11usize) & 0x01; + val != 0 + } + #[doc = "USB suspend"] + #[inline(always)] + pub fn set_usbsusp(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 11usize)) | (((val as u32) & 0x01) << 11usize); + } + #[doc = "USB reset"] + #[inline(always)] + pub const fn usbrst(&self) -> bool { + let val = (self.0 >> 12usize) & 0x01; + val != 0 + } + #[doc = "USB reset"] + #[inline(always)] + pub fn set_usbrst(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 12usize)) | (((val as u32) & 0x01) << 12usize); + } + #[doc = "Enumeration done"] + #[inline(always)] + pub const fn enumdne(&self) -> bool { + let val = (self.0 >> 13usize) & 0x01; + val != 0 + } + #[doc = "Enumeration done"] + #[inline(always)] + pub fn set_enumdne(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 13usize)) | (((val as u32) & 0x01) << 13usize); + } + #[doc = "Isochronous OUT packet dropped interrupt"] + #[inline(always)] + pub const fn isoodrp(&self) -> bool { + let val = (self.0 >> 14usize) & 0x01; + val != 0 + } + #[doc = "Isochronous OUT packet dropped interrupt"] + #[inline(always)] + pub fn set_isoodrp(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 14usize)) | (((val as u32) & 0x01) << 14usize); + } + #[doc = "End of periodic frame interrupt"] + #[inline(always)] + pub const fn eopf(&self) -> bool { + let val = (self.0 >> 15usize) & 0x01; + val != 0 + } + #[doc = "End of periodic frame interrupt"] + #[inline(always)] + pub fn set_eopf(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 15usize)) | (((val as u32) & 0x01) << 15usize); + } + #[doc = "IN endpoint interrupt"] + #[inline(always)] + pub const fn iepint(&self) -> bool { + let val = (self.0 >> 18usize) & 0x01; + val != 0 + } + #[doc = "IN endpoint interrupt"] + #[inline(always)] + pub fn set_iepint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 18usize)) | (((val as u32) & 0x01) << 18usize); + } + #[doc = "OUT endpoint interrupt"] + #[inline(always)] + pub const fn oepint(&self) -> bool { + let val = (self.0 >> 19usize) & 0x01; + val != 0 + } + #[doc = "OUT endpoint interrupt"] + #[inline(always)] + pub fn set_oepint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 19usize)) | (((val as u32) & 0x01) << 19usize); + } + #[doc = "Incomplete isochronous IN transfer"] + #[inline(always)] + pub const fn iisoixfr(&self) -> bool { + let val = (self.0 >> 20usize) & 0x01; + val != 0 + } + #[doc = "Incomplete isochronous IN transfer"] + #[inline(always)] + pub fn set_iisoixfr(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 20usize)) | (((val as u32) & 0x01) << 20usize); + } + #[doc = "Incomplete periodic transfer (host mode) / Incomplete isochronous OUT transfer (device mode)"] + #[inline(always)] + pub const fn ipxfr_incompisoout(&self) -> bool { + let val = (self.0 >> 21usize) & 0x01; + val != 0 + } + #[doc = "Incomplete periodic transfer (host mode) / Incomplete isochronous OUT transfer (device mode)"] + #[inline(always)] + pub fn set_ipxfr_incompisoout(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 21usize)) | (((val as u32) & 0x01) << 21usize); + } + #[doc = "Data fetch suspended"] + #[inline(always)] + pub const fn datafsusp(&self) -> bool { + let val = (self.0 >> 22usize) & 0x01; + val != 0 + } + #[doc = "Data fetch suspended"] + #[inline(always)] + pub fn set_datafsusp(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 22usize)) | (((val as u32) & 0x01) << 22usize); + } + #[doc = "Host port interrupt"] + #[inline(always)] + pub const fn hprtint(&self) -> bool { + let val = (self.0 >> 24usize) & 0x01; + val != 0 + } + #[doc = "Host port interrupt"] + #[inline(always)] + pub fn set_hprtint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 24usize)) | (((val as u32) & 0x01) << 24usize); + } + #[doc = "Host channels interrupt"] + #[inline(always)] + pub const fn hcint(&self) -> bool { + let val = (self.0 >> 25usize) & 0x01; + val != 0 + } + #[doc = "Host channels interrupt"] + #[inline(always)] + pub fn set_hcint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 25usize)) | (((val as u32) & 0x01) << 25usize); + } + #[doc = "Periodic TxFIFO empty"] + #[inline(always)] + pub const fn ptxfe(&self) -> bool { + let val = (self.0 >> 26usize) & 0x01; + val != 0 + } + #[doc = "Periodic TxFIFO empty"] + #[inline(always)] + pub fn set_ptxfe(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 26usize)) | (((val as u32) & 0x01) << 26usize); + } + #[doc = "Connector ID status change"] + #[inline(always)] + pub const fn cidschg(&self) -> bool { + let val = (self.0 >> 28usize) & 0x01; + val != 0 + } + #[doc = "Connector ID status change"] + #[inline(always)] + pub fn set_cidschg(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 28usize)) | (((val as u32) & 0x01) << 28usize); + } + #[doc = "Disconnect detected interrupt"] + #[inline(always)] + pub const fn discint(&self) -> bool { + let val = (self.0 >> 29usize) & 0x01; + val != 0 + } + #[doc = "Disconnect detected interrupt"] + #[inline(always)] + pub fn set_discint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 29usize)) | (((val as u32) & 0x01) << 29usize); + } + #[doc = "Session request/new session detected interrupt"] + #[inline(always)] + pub const fn srqint(&self) -> bool { + let val = (self.0 >> 30usize) & 0x01; + val != 0 + } + #[doc = "Session request/new session detected interrupt"] + #[inline(always)] + pub fn set_srqint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 30usize)) | (((val as u32) & 0x01) << 30usize); + } + #[doc = "Resume/remote wakeup detected interrupt"] + #[inline(always)] + pub const fn wkupint(&self) -> bool { + let val = (self.0 >> 31usize) & 0x01; + val != 0 + } + #[doc = "Resume/remote wakeup detected interrupt"] + #[inline(always)] + pub fn set_wkupint(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 31usize)) | (((val as u32) & 0x01) << 31usize); + } + } + impl Default for Gintsts { + #[inline(always)] + fn default() -> Gintsts { + Gintsts(0) + } + } + #[doc = "Core LPM configuration register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Glpmcfg(pub u32); + impl Glpmcfg { + #[doc = "LPM support enable"] + #[inline(always)] + pub const fn lpmen(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "LPM support enable"] + #[inline(always)] + pub fn set_lpmen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "LPM token acknowledge enable"] + #[inline(always)] + pub const fn lpmack(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "LPM token acknowledge enable"] + #[inline(always)] + pub fn set_lpmack(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "Best effort service latency"] + #[inline(always)] + pub const fn besl(&self) -> u8 { + let val = (self.0 >> 2usize) & 0x0f; + val as u8 + } + #[doc = "Best effort service latency"] + #[inline(always)] + pub fn set_besl(&mut self, val: u8) { + self.0 = (self.0 & !(0x0f << 2usize)) | (((val as u32) & 0x0f) << 2usize); + } + #[doc = "bRemoteWake value"] + #[inline(always)] + pub const fn remwake(&self) -> bool { + let val = (self.0 >> 6usize) & 0x01; + val != 0 + } + #[doc = "bRemoteWake value"] + #[inline(always)] + pub fn set_remwake(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 6usize)) | (((val as u32) & 0x01) << 6usize); + } + #[doc = "L1 Shallow Sleep enable"] + #[inline(always)] + pub const fn l1ssen(&self) -> bool { + let val = (self.0 >> 7usize) & 0x01; + val != 0 + } + #[doc = "L1 Shallow Sleep enable"] + #[inline(always)] + pub fn set_l1ssen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 7usize)) | (((val as u32) & 0x01) << 7usize); + } + #[doc = "BESL threshold"] + #[inline(always)] + pub const fn beslthrs(&self) -> u8 { + let val = (self.0 >> 8usize) & 0x0f; + val as u8 + } + #[doc = "BESL threshold"] + #[inline(always)] + pub fn set_beslthrs(&mut self, val: u8) { + self.0 = (self.0 & !(0x0f << 8usize)) | (((val as u32) & 0x0f) << 8usize); + } + #[doc = "L1 deep sleep enable"] + #[inline(always)] + pub const fn l1dsen(&self) -> bool { + let val = (self.0 >> 12usize) & 0x01; + val != 0 + } + #[doc = "L1 deep sleep enable"] + #[inline(always)] + pub fn set_l1dsen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 12usize)) | (((val as u32) & 0x01) << 12usize); + } + #[doc = "LPM response"] + #[inline(always)] + pub const fn lpmrst(&self) -> u8 { + let val = (self.0 >> 13usize) & 0x03; + val as u8 + } + #[doc = "LPM response"] + #[inline(always)] + pub fn set_lpmrst(&mut self, val: u8) { + self.0 = (self.0 & !(0x03 << 13usize)) | (((val as u32) & 0x03) << 13usize); + } + #[doc = "Port sleep status"] + #[inline(always)] + pub const fn slpsts(&self) -> bool { + let val = (self.0 >> 15usize) & 0x01; + val != 0 + } + #[doc = "Port sleep status"] + #[inline(always)] + pub fn set_slpsts(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 15usize)) | (((val as u32) & 0x01) << 15usize); + } + #[doc = "Sleep State Resume OK"] + #[inline(always)] + pub const fn l1rsmok(&self) -> bool { + let val = (self.0 >> 16usize) & 0x01; + val != 0 + } + #[doc = "Sleep State Resume OK"] + #[inline(always)] + pub fn set_l1rsmok(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 16usize)) | (((val as u32) & 0x01) << 16usize); + } + #[doc = "LPM Channel Index"] + #[inline(always)] + pub const fn lpmchidx(&self) -> u8 { + let val = (self.0 >> 17usize) & 0x0f; + val as u8 + } + #[doc = "LPM Channel Index"] + #[inline(always)] + pub fn set_lpmchidx(&mut self, val: u8) { + self.0 = (self.0 & !(0x0f << 17usize)) | (((val as u32) & 0x0f) << 17usize); + } + #[doc = "LPM retry count"] + #[inline(always)] + pub const fn lpmrcnt(&self) -> u8 { + let val = (self.0 >> 21usize) & 0x07; + val as u8 + } + #[doc = "LPM retry count"] + #[inline(always)] + pub fn set_lpmrcnt(&mut self, val: u8) { + self.0 = (self.0 & !(0x07 << 21usize)) | (((val as u32) & 0x07) << 21usize); + } + #[doc = "Send LPM transaction"] + #[inline(always)] + pub const fn sndlpm(&self) -> bool { + let val = (self.0 >> 24usize) & 0x01; + val != 0 + } + #[doc = "Send LPM transaction"] + #[inline(always)] + pub fn set_sndlpm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 24usize)) | (((val as u32) & 0x01) << 24usize); + } + #[doc = "LPM retry count status"] + #[inline(always)] + pub const fn lpmrcntsts(&self) -> u8 { + let val = (self.0 >> 25usize) & 0x07; + val as u8 + } + #[doc = "LPM retry count status"] + #[inline(always)] + pub fn set_lpmrcntsts(&mut self, val: u8) { + self.0 = (self.0 & !(0x07 << 25usize)) | (((val as u32) & 0x07) << 25usize); + } + #[doc = "Enable best effort service latency"] + #[inline(always)] + pub const fn enbesl(&self) -> bool { + let val = (self.0 >> 28usize) & 0x01; + val != 0 + } + #[doc = "Enable best effort service latency"] + #[inline(always)] + pub fn set_enbesl(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 28usize)) | (((val as u32) & 0x01) << 28usize); + } + } + impl Default for Glpmcfg { + #[inline(always)] + fn default() -> Glpmcfg { + Glpmcfg(0) + } + } + #[doc = "Control and status register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Gotgctl(pub u32); + impl Gotgctl { + #[doc = "Session request success"] + #[inline(always)] + pub const fn srqscs(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Session request success"] + #[inline(always)] + pub fn set_srqscs(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "Session request"] + #[inline(always)] + pub const fn srq(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "Session request"] + #[inline(always)] + pub fn set_srq(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "VBUS valid override enable"] + #[inline(always)] + pub const fn vbvaloen(&self) -> bool { + let val = (self.0 >> 2usize) & 0x01; + val != 0 + } + #[doc = "VBUS valid override enable"] + #[inline(always)] + pub fn set_vbvaloen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 2usize)) | (((val as u32) & 0x01) << 2usize); + } + #[doc = "VBUS valid override value"] + #[inline(always)] + pub const fn vbvaloval(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "VBUS valid override value"] + #[inline(always)] + pub fn set_vbvaloval(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "A-peripheral session valid override enable"] + #[inline(always)] + pub const fn avaloen(&self) -> bool { + let val = (self.0 >> 4usize) & 0x01; + val != 0 + } + #[doc = "A-peripheral session valid override enable"] + #[inline(always)] + pub fn set_avaloen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 4usize)) | (((val as u32) & 0x01) << 4usize); + } + #[doc = "A-peripheral session valid override value"] + #[inline(always)] + pub const fn avaloval(&self) -> bool { + let val = (self.0 >> 5usize) & 0x01; + val != 0 + } + #[doc = "A-peripheral session valid override value"] + #[inline(always)] + pub fn set_avaloval(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 5usize)) | (((val as u32) & 0x01) << 5usize); + } + #[doc = "B-peripheral session valid override enable"] + #[inline(always)] + pub const fn bvaloen(&self) -> bool { + let val = (self.0 >> 6usize) & 0x01; + val != 0 + } + #[doc = "B-peripheral session valid override enable"] + #[inline(always)] + pub fn set_bvaloen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 6usize)) | (((val as u32) & 0x01) << 6usize); + } + #[doc = "B-peripheral session valid override value"] + #[inline(always)] + pub const fn bvaloval(&self) -> bool { + let val = (self.0 >> 7usize) & 0x01; + val != 0 + } + #[doc = "B-peripheral session valid override value"] + #[inline(always)] + pub fn set_bvaloval(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 7usize)) | (((val as u32) & 0x01) << 7usize); + } + #[doc = "Host negotiation success"] + #[inline(always)] + pub const fn hngscs(&self) -> bool { + let val = (self.0 >> 8usize) & 0x01; + val != 0 + } + #[doc = "Host negotiation success"] + #[inline(always)] + pub fn set_hngscs(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 8usize)) | (((val as u32) & 0x01) << 8usize); + } + #[doc = "HNP request"] + #[inline(always)] + pub const fn hnprq(&self) -> bool { + let val = (self.0 >> 9usize) & 0x01; + val != 0 + } + #[doc = "HNP request"] + #[inline(always)] + pub fn set_hnprq(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 9usize)) | (((val as u32) & 0x01) << 9usize); + } + #[doc = "Host set HNP enable"] + #[inline(always)] + pub const fn hshnpen(&self) -> bool { + let val = (self.0 >> 10usize) & 0x01; + val != 0 + } + #[doc = "Host set HNP enable"] + #[inline(always)] + pub fn set_hshnpen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 10usize)) | (((val as u32) & 0x01) << 10usize); + } + #[doc = "Device HNP enabled"] + #[inline(always)] + pub const fn dhnpen(&self) -> bool { + let val = (self.0 >> 11usize) & 0x01; + val != 0 + } + #[doc = "Device HNP enabled"] + #[inline(always)] + pub fn set_dhnpen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 11usize)) | (((val as u32) & 0x01) << 11usize); + } + #[doc = "Embedded host enable"] + #[inline(always)] + pub const fn ehen(&self) -> bool { + let val = (self.0 >> 12usize) & 0x01; + val != 0 + } + #[doc = "Embedded host enable"] + #[inline(always)] + pub fn set_ehen(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 12usize)) | (((val as u32) & 0x01) << 12usize); + } + #[doc = "Connector ID status"] + #[inline(always)] + pub const fn cidsts(&self) -> bool { + let val = (self.0 >> 16usize) & 0x01; + val != 0 + } + #[doc = "Connector ID status"] + #[inline(always)] + pub fn set_cidsts(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 16usize)) | (((val as u32) & 0x01) << 16usize); + } + #[doc = "Long/short debounce time"] + #[inline(always)] + pub const fn dbct(&self) -> bool { + let val = (self.0 >> 17usize) & 0x01; + val != 0 + } + #[doc = "Long/short debounce time"] + #[inline(always)] + pub fn set_dbct(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 17usize)) | (((val as u32) & 0x01) << 17usize); + } + #[doc = "A-session valid"] + #[inline(always)] + pub const fn asvld(&self) -> bool { + let val = (self.0 >> 18usize) & 0x01; + val != 0 + } + #[doc = "A-session valid"] + #[inline(always)] + pub fn set_asvld(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 18usize)) | (((val as u32) & 0x01) << 18usize); + } + #[doc = "B-session valid"] + #[inline(always)] + pub const fn bsvld(&self) -> bool { + let val = (self.0 >> 19usize) & 0x01; + val != 0 + } + #[doc = "B-session valid"] + #[inline(always)] + pub fn set_bsvld(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 19usize)) | (((val as u32) & 0x01) << 19usize); + } + } + impl Default for Gotgctl { + #[inline(always)] + fn default() -> Gotgctl { + Gotgctl(0) + } + } + #[doc = "Interrupt register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Gotgint(pub u32); + impl Gotgint { + #[doc = "Session end detected"] + #[inline(always)] + pub const fn sedet(&self) -> bool { + let val = (self.0 >> 2usize) & 0x01; + val != 0 + } + #[doc = "Session end detected"] + #[inline(always)] + pub fn set_sedet(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 2usize)) | (((val as u32) & 0x01) << 2usize); + } + #[doc = "Session request success status change"] + #[inline(always)] + pub const fn srsschg(&self) -> bool { + let val = (self.0 >> 8usize) & 0x01; + val != 0 + } + #[doc = "Session request success status change"] + #[inline(always)] + pub fn set_srsschg(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 8usize)) | (((val as u32) & 0x01) << 8usize); + } + #[doc = "Host negotiation success status change"] + #[inline(always)] + pub const fn hnsschg(&self) -> bool { + let val = (self.0 >> 9usize) & 0x01; + val != 0 + } + #[doc = "Host negotiation success status change"] + #[inline(always)] + pub fn set_hnsschg(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 9usize)) | (((val as u32) & 0x01) << 9usize); + } + #[doc = "Host negotiation detected"] + #[inline(always)] + pub const fn hngdet(&self) -> bool { + let val = (self.0 >> 17usize) & 0x01; + val != 0 + } + #[doc = "Host negotiation detected"] + #[inline(always)] + pub fn set_hngdet(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 17usize)) | (((val as u32) & 0x01) << 17usize); + } + #[doc = "A-device timeout change"] + #[inline(always)] + pub const fn adtochg(&self) -> bool { + let val = (self.0 >> 18usize) & 0x01; + val != 0 + } + #[doc = "A-device timeout change"] + #[inline(always)] + pub fn set_adtochg(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 18usize)) | (((val as u32) & 0x01) << 18usize); + } + #[doc = "Debounce done"] + #[inline(always)] + pub const fn dbcdne(&self) -> bool { + let val = (self.0 >> 19usize) & 0x01; + val != 0 + } + #[doc = "Debounce done"] + #[inline(always)] + pub fn set_dbcdne(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 19usize)) | (((val as u32) & 0x01) << 19usize); + } + #[doc = "ID input pin changed"] + #[inline(always)] + pub const fn idchng(&self) -> bool { + let val = (self.0 >> 20usize) & 0x01; + val != 0 + } + #[doc = "ID input pin changed"] + #[inline(always)] + pub fn set_idchng(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 20usize)) | (((val as u32) & 0x01) << 20usize); + } + } + impl Default for Gotgint { + #[inline(always)] + fn default() -> Gotgint { + Gotgint(0) + } + } + #[doc = "Reset register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Grstctl(pub u32); + impl Grstctl { + #[doc = "Core soft reset"] + #[inline(always)] + pub const fn csrst(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Core soft reset"] + #[inline(always)] + pub fn set_csrst(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "HCLK soft reset"] + #[inline(always)] + pub const fn hsrst(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "HCLK soft reset"] + #[inline(always)] + pub fn set_hsrst(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "Host frame counter reset"] + #[inline(always)] + pub const fn fcrst(&self) -> bool { + let val = (self.0 >> 2usize) & 0x01; + val != 0 + } + #[doc = "Host frame counter reset"] + #[inline(always)] + pub fn set_fcrst(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 2usize)) | (((val as u32) & 0x01) << 2usize); + } + #[doc = "RxFIFO flush"] + #[inline(always)] + pub const fn rxfflsh(&self) -> bool { + let val = (self.0 >> 4usize) & 0x01; + val != 0 + } + #[doc = "RxFIFO flush"] + #[inline(always)] + pub fn set_rxfflsh(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 4usize)) | (((val as u32) & 0x01) << 4usize); + } + #[doc = "TxFIFO flush"] + #[inline(always)] + pub const fn txfflsh(&self) -> bool { + let val = (self.0 >> 5usize) & 0x01; + val != 0 + } + #[doc = "TxFIFO flush"] + #[inline(always)] + pub fn set_txfflsh(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 5usize)) | (((val as u32) & 0x01) << 5usize); + } + #[doc = "TxFIFO number"] + #[inline(always)] + pub const fn txfnum(&self) -> u8 { + let val = (self.0 >> 6usize) & 0x1f; + val as u8 + } + #[doc = "TxFIFO number"] + #[inline(always)] + pub fn set_txfnum(&mut self, val: u8) { + self.0 = (self.0 & !(0x1f << 6usize)) | (((val as u32) & 0x1f) << 6usize); + } + #[doc = "DMA request signal enabled for USB OTG HS"] + #[inline(always)] + pub const fn dmareq(&self) -> bool { + let val = (self.0 >> 30usize) & 0x01; + val != 0 + } + #[doc = "DMA request signal enabled for USB OTG HS"] + #[inline(always)] + pub fn set_dmareq(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 30usize)) | (((val as u32) & 0x01) << 30usize); + } + #[doc = "AHB master idle"] + #[inline(always)] + pub const fn ahbidl(&self) -> bool { + let val = (self.0 >> 31usize) & 0x01; + val != 0 + } + #[doc = "AHB master idle"] + #[inline(always)] + pub fn set_ahbidl(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 31usize)) | (((val as u32) & 0x01) << 31usize); + } + } + impl Default for Grstctl { + #[inline(always)] + fn default() -> Grstctl { + Grstctl(0) + } + } + #[doc = "Receive FIFO size register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Grxfsiz(pub u32); + impl Grxfsiz { + #[doc = "RxFIFO depth"] + #[inline(always)] + pub const fn rxfd(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "RxFIFO depth"] + #[inline(always)] + pub fn set_rxfd(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + } + impl Default for Grxfsiz { + #[inline(always)] + fn default() -> Grxfsiz { + Grxfsiz(0) + } + } + #[doc = "Status read and pop register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Grxsts(pub u32); + impl Grxsts { + #[doc = "Endpoint number (device mode) / Channel number (host mode)"] + #[inline(always)] + pub const fn epnum(&self) -> u8 { + let val = (self.0 >> 0usize) & 0x0f; + val as u8 + } + #[doc = "Endpoint number (device mode) / Channel number (host mode)"] + #[inline(always)] + pub fn set_epnum(&mut self, val: u8) { + self.0 = (self.0 & !(0x0f << 0usize)) | (((val as u32) & 0x0f) << 0usize); + } + #[doc = "Byte count"] + #[inline(always)] + pub const fn bcnt(&self) -> u16 { + let val = (self.0 >> 4usize) & 0x07ff; + val as u16 + } + #[doc = "Byte count"] + #[inline(always)] + pub fn set_bcnt(&mut self, val: u16) { + self.0 = (self.0 & !(0x07ff << 4usize)) | (((val as u32) & 0x07ff) << 4usize); + } + #[doc = "Data PID"] + #[inline(always)] + pub const fn dpid(&self) -> super::vals::Dpid { + let val = (self.0 >> 15usize) & 0x03; + super::vals::Dpid::from_bits(val as u8) + } + #[doc = "Data PID"] + #[inline(always)] + pub fn set_dpid(&mut self, val: super::vals::Dpid) { + self.0 = (self.0 & !(0x03 << 15usize)) | (((val.to_bits() as u32) & 0x03) << 15usize); + } + #[doc = "Packet status (device mode)"] + #[inline(always)] + pub const fn pktstsd(&self) -> super::vals::Pktstsd { + let val = (self.0 >> 17usize) & 0x0f; + super::vals::Pktstsd::from_bits(val as u8) + } + #[doc = "Packet status (device mode)"] + #[inline(always)] + pub fn set_pktstsd(&mut self, val: super::vals::Pktstsd) { + self.0 = (self.0 & !(0x0f << 17usize)) | (((val.to_bits() as u32) & 0x0f) << 17usize); + } + #[doc = "Packet status (host mode)"] + #[inline(always)] + pub const fn pktstsh(&self) -> super::vals::Pktstsh { + let val = (self.0 >> 17usize) & 0x0f; + super::vals::Pktstsh::from_bits(val as u8) + } + #[doc = "Packet status (host mode)"] + #[inline(always)] + pub fn set_pktstsh(&mut self, val: super::vals::Pktstsh) { + self.0 = (self.0 & !(0x0f << 17usize)) | (((val.to_bits() as u32) & 0x0f) << 17usize); + } + #[doc = "Frame number (device mode)"] + #[inline(always)] + pub const fn frmnum(&self) -> u8 { + let val = (self.0 >> 21usize) & 0x0f; + val as u8 + } + #[doc = "Frame number (device mode)"] + #[inline(always)] + pub fn set_frmnum(&mut self, val: u8) { + self.0 = (self.0 & !(0x0f << 21usize)) | (((val as u32) & 0x0f) << 21usize); + } + } + impl Default for Grxsts { + #[inline(always)] + fn default() -> Grxsts { + Grxsts(0) + } + } + #[doc = "USB configuration register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Gusbcfg(pub u32); + impl Gusbcfg { + #[doc = "FS timeout calibration"] + #[inline(always)] + pub const fn tocal(&self) -> u8 { + let val = (self.0 >> 0usize) & 0x07; + val as u8 + } + #[doc = "FS timeout calibration"] + #[inline(always)] + pub fn set_tocal(&mut self, val: u8) { + self.0 = (self.0 & !(0x07 << 0usize)) | (((val as u32) & 0x07) << 0usize); + } + #[doc = "Full-speed internal serial transceiver enable"] + #[inline(always)] + pub const fn physel(&self) -> bool { + let val = (self.0 >> 6usize) & 0x01; + val != 0 + } + #[doc = "Full-speed internal serial transceiver enable"] + #[inline(always)] + pub fn set_physel(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 6usize)) | (((val as u32) & 0x01) << 6usize); + } + #[doc = "SRP-capable"] + #[inline(always)] + pub const fn srpcap(&self) -> bool { + let val = (self.0 >> 8usize) & 0x01; + val != 0 + } + #[doc = "SRP-capable"] + #[inline(always)] + pub fn set_srpcap(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 8usize)) | (((val as u32) & 0x01) << 8usize); + } + #[doc = "HNP-capable"] + #[inline(always)] + pub const fn hnpcap(&self) -> bool { + let val = (self.0 >> 9usize) & 0x01; + val != 0 + } + #[doc = "HNP-capable"] + #[inline(always)] + pub fn set_hnpcap(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 9usize)) | (((val as u32) & 0x01) << 9usize); + } + #[doc = "USB turnaround time"] + #[inline(always)] + pub const fn trdt(&self) -> u8 { + let val = (self.0 >> 10usize) & 0x0f; + val as u8 + } + #[doc = "USB turnaround time"] + #[inline(always)] + pub fn set_trdt(&mut self, val: u8) { + self.0 = (self.0 & !(0x0f << 10usize)) | (((val as u32) & 0x0f) << 10usize); + } + #[doc = "PHY Low-power clock select"] + #[inline(always)] + pub const fn phylpcs(&self) -> bool { + let val = (self.0 >> 15usize) & 0x01; + val != 0 + } + #[doc = "PHY Low-power clock select"] + #[inline(always)] + pub fn set_phylpcs(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 15usize)) | (((val as u32) & 0x01) << 15usize); + } + #[doc = "ULPI FS/LS select"] + #[inline(always)] + pub const fn ulpifsls(&self) -> bool { + let val = (self.0 >> 17usize) & 0x01; + val != 0 + } + #[doc = "ULPI FS/LS select"] + #[inline(always)] + pub fn set_ulpifsls(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 17usize)) | (((val as u32) & 0x01) << 17usize); + } + #[doc = "ULPI Auto-resume"] + #[inline(always)] + pub const fn ulpiar(&self) -> bool { + let val = (self.0 >> 18usize) & 0x01; + val != 0 + } + #[doc = "ULPI Auto-resume"] + #[inline(always)] + pub fn set_ulpiar(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 18usize)) | (((val as u32) & 0x01) << 18usize); + } + #[doc = "ULPI Clock SuspendM"] + #[inline(always)] + pub const fn ulpicsm(&self) -> bool { + let val = (self.0 >> 19usize) & 0x01; + val != 0 + } + #[doc = "ULPI Clock SuspendM"] + #[inline(always)] + pub fn set_ulpicsm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 19usize)) | (((val as u32) & 0x01) << 19usize); + } + #[doc = "ULPI External VBUS Drive"] + #[inline(always)] + pub const fn ulpievbusd(&self) -> bool { + let val = (self.0 >> 20usize) & 0x01; + val != 0 + } + #[doc = "ULPI External VBUS Drive"] + #[inline(always)] + pub fn set_ulpievbusd(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 20usize)) | (((val as u32) & 0x01) << 20usize); + } + #[doc = "ULPI external VBUS indicator"] + #[inline(always)] + pub const fn ulpievbusi(&self) -> bool { + let val = (self.0 >> 21usize) & 0x01; + val != 0 + } + #[doc = "ULPI external VBUS indicator"] + #[inline(always)] + pub fn set_ulpievbusi(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 21usize)) | (((val as u32) & 0x01) << 21usize); + } + #[doc = "TermSel DLine pulsing selection"] + #[inline(always)] + pub const fn tsdps(&self) -> bool { + let val = (self.0 >> 22usize) & 0x01; + val != 0 + } + #[doc = "TermSel DLine pulsing selection"] + #[inline(always)] + pub fn set_tsdps(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 22usize)) | (((val as u32) & 0x01) << 22usize); + } + #[doc = "Indicator complement"] + #[inline(always)] + pub const fn pcci(&self) -> bool { + let val = (self.0 >> 23usize) & 0x01; + val != 0 + } + #[doc = "Indicator complement"] + #[inline(always)] + pub fn set_pcci(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 23usize)) | (((val as u32) & 0x01) << 23usize); + } + #[doc = "Indicator pass through"] + #[inline(always)] + pub const fn ptci(&self) -> bool { + let val = (self.0 >> 24usize) & 0x01; + val != 0 + } + #[doc = "Indicator pass through"] + #[inline(always)] + pub fn set_ptci(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 24usize)) | (((val as u32) & 0x01) << 24usize); + } + #[doc = "ULPI interface protect disable"] + #[inline(always)] + pub const fn ulpiipd(&self) -> bool { + let val = (self.0 >> 25usize) & 0x01; + val != 0 + } + #[doc = "ULPI interface protect disable"] + #[inline(always)] + pub fn set_ulpiipd(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 25usize)) | (((val as u32) & 0x01) << 25usize); + } + #[doc = "Force host mode"] + #[inline(always)] + pub const fn fhmod(&self) -> bool { + let val = (self.0 >> 29usize) & 0x01; + val != 0 + } + #[doc = "Force host mode"] + #[inline(always)] + pub fn set_fhmod(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 29usize)) | (((val as u32) & 0x01) << 29usize); + } + #[doc = "Force device mode"] + #[inline(always)] + pub const fn fdmod(&self) -> bool { + let val = (self.0 >> 30usize) & 0x01; + val != 0 + } + #[doc = "Force device mode"] + #[inline(always)] + pub fn set_fdmod(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 30usize)) | (((val as u32) & 0x01) << 30usize); + } + #[doc = "Corrupt Tx packet"] + #[inline(always)] + pub const fn ctxpkt(&self) -> bool { + let val = (self.0 >> 31usize) & 0x01; + val != 0 + } + #[doc = "Corrupt Tx packet"] + #[inline(always)] + pub fn set_ctxpkt(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 31usize)) | (((val as u32) & 0x01) << 31usize); + } + } + impl Default for Gusbcfg { + #[inline(always)] + fn default() -> Gusbcfg { + Gusbcfg(0) + } + } + #[doc = "Host all channels interrupt register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Haint(pub u32); + impl Haint { + #[doc = "Channel interrupts"] + #[inline(always)] + pub const fn haint(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "Channel interrupts"] + #[inline(always)] + pub fn set_haint(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + } + impl Default for Haint { + #[inline(always)] + fn default() -> Haint { + Haint(0) + } + } + #[doc = "Host all channels interrupt mask register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Haintmsk(pub u32); + impl Haintmsk { + #[doc = "Channel interrupt mask"] + #[inline(always)] + pub const fn haintm(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "Channel interrupt mask"] + #[inline(always)] + pub fn set_haintm(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + } + impl Default for Haintmsk { + #[inline(always)] + fn default() -> Haintmsk { + Haintmsk(0) + } + } + #[doc = "Host channel characteristics register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Hcchar(pub u32); + impl Hcchar { + #[doc = "Maximum packet size"] + #[inline(always)] + pub const fn mpsiz(&self) -> u16 { + let val = (self.0 >> 0usize) & 0x07ff; + val as u16 + } + #[doc = "Maximum packet size"] + #[inline(always)] + pub fn set_mpsiz(&mut self, val: u16) { + self.0 = (self.0 & !(0x07ff << 0usize)) | (((val as u32) & 0x07ff) << 0usize); + } + #[doc = "Endpoint number"] + #[inline(always)] + pub const fn epnum(&self) -> u8 { + let val = (self.0 >> 11usize) & 0x0f; + val as u8 + } + #[doc = "Endpoint number"] + #[inline(always)] + pub fn set_epnum(&mut self, val: u8) { + self.0 = (self.0 & !(0x0f << 11usize)) | (((val as u32) & 0x0f) << 11usize); + } + #[doc = "Endpoint direction"] + #[inline(always)] + pub const fn epdir(&self) -> bool { + let val = (self.0 >> 15usize) & 0x01; + val != 0 + } + #[doc = "Endpoint direction"] + #[inline(always)] + pub fn set_epdir(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 15usize)) | (((val as u32) & 0x01) << 15usize); + } + #[doc = "Low-speed device"] + #[inline(always)] + pub const fn lsdev(&self) -> bool { + let val = (self.0 >> 17usize) & 0x01; + val != 0 + } + #[doc = "Low-speed device"] + #[inline(always)] + pub fn set_lsdev(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 17usize)) | (((val as u32) & 0x01) << 17usize); + } + #[doc = "Endpoint type"] + #[inline(always)] + pub const fn eptyp(&self) -> super::vals::Eptyp { + let val = (self.0 >> 18usize) & 0x03; + super::vals::Eptyp::from_bits(val as u8) + } + #[doc = "Endpoint type"] + #[inline(always)] + pub fn set_eptyp(&mut self, val: super::vals::Eptyp) { + self.0 = (self.0 & !(0x03 << 18usize)) | (((val.to_bits() as u32) & 0x03) << 18usize); + } + #[doc = "Multicount"] + #[inline(always)] + pub const fn mcnt(&self) -> u8 { + let val = (self.0 >> 20usize) & 0x03; + val as u8 + } + #[doc = "Multicount"] + #[inline(always)] + pub fn set_mcnt(&mut self, val: u8) { + self.0 = (self.0 & !(0x03 << 20usize)) | (((val as u32) & 0x03) << 20usize); + } + #[doc = "Device address"] + #[inline(always)] + pub const fn dad(&self) -> u8 { + let val = (self.0 >> 22usize) & 0x7f; + val as u8 + } + #[doc = "Device address"] + #[inline(always)] + pub fn set_dad(&mut self, val: u8) { + self.0 = (self.0 & !(0x7f << 22usize)) | (((val as u32) & 0x7f) << 22usize); + } + #[doc = "Odd frame"] + #[inline(always)] + pub const fn oddfrm(&self) -> bool { + let val = (self.0 >> 29usize) & 0x01; + val != 0 + } + #[doc = "Odd frame"] + #[inline(always)] + pub fn set_oddfrm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 29usize)) | (((val as u32) & 0x01) << 29usize); + } + #[doc = "Channel disable"] + #[inline(always)] + pub const fn chdis(&self) -> bool { + let val = (self.0 >> 30usize) & 0x01; + val != 0 + } + #[doc = "Channel disable"] + #[inline(always)] + pub fn set_chdis(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 30usize)) | (((val as u32) & 0x01) << 30usize); + } + #[doc = "Channel enable"] + #[inline(always)] + pub const fn chena(&self) -> bool { + let val = (self.0 >> 31usize) & 0x01; + val != 0 + } + #[doc = "Channel enable"] + #[inline(always)] + pub fn set_chena(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 31usize)) | (((val as u32) & 0x01) << 31usize); + } + } + impl Default for Hcchar { + #[inline(always)] + fn default() -> Hcchar { + Hcchar(0) + } + } + #[doc = "Host configuration register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Hcfg(pub u32); + impl Hcfg { + #[doc = "FS/LS PHY clock select"] + #[inline(always)] + pub const fn fslspcs(&self) -> u8 { + let val = (self.0 >> 0usize) & 0x03; + val as u8 + } + #[doc = "FS/LS PHY clock select"] + #[inline(always)] + pub fn set_fslspcs(&mut self, val: u8) { + self.0 = (self.0 & !(0x03 << 0usize)) | (((val as u32) & 0x03) << 0usize); + } + #[doc = "FS- and LS-only support"] + #[inline(always)] + pub const fn fslss(&self) -> bool { + let val = (self.0 >> 2usize) & 0x01; + val != 0 + } + #[doc = "FS- and LS-only support"] + #[inline(always)] + pub fn set_fslss(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 2usize)) | (((val as u32) & 0x01) << 2usize); + } + } + impl Default for Hcfg { + #[inline(always)] + fn default() -> Hcfg { + Hcfg(0) + } + } + #[doc = "Host channel interrupt register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Hcint(pub u32); + impl Hcint { + #[doc = "Transfer completed"] + #[inline(always)] + pub const fn xfrc(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Transfer completed"] + #[inline(always)] + pub fn set_xfrc(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "Channel halted"] + #[inline(always)] + pub const fn chh(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "Channel halted"] + #[inline(always)] + pub fn set_chh(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "STALL response received interrupt"] + #[inline(always)] + pub const fn stall(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "STALL response received interrupt"] + #[inline(always)] + pub fn set_stall(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "NAK response received interrupt"] + #[inline(always)] + pub const fn nak(&self) -> bool { + let val = (self.0 >> 4usize) & 0x01; + val != 0 + } + #[doc = "NAK response received interrupt"] + #[inline(always)] + pub fn set_nak(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 4usize)) | (((val as u32) & 0x01) << 4usize); + } + #[doc = "ACK response received/transmitted interrupt"] + #[inline(always)] + pub const fn ack(&self) -> bool { + let val = (self.0 >> 5usize) & 0x01; + val != 0 + } + #[doc = "ACK response received/transmitted interrupt"] + #[inline(always)] + pub fn set_ack(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 5usize)) | (((val as u32) & 0x01) << 5usize); + } + #[doc = "Transaction error"] + #[inline(always)] + pub const fn txerr(&self) -> bool { + let val = (self.0 >> 7usize) & 0x01; + val != 0 + } + #[doc = "Transaction error"] + #[inline(always)] + pub fn set_txerr(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 7usize)) | (((val as u32) & 0x01) << 7usize); + } + #[doc = "Babble error"] + #[inline(always)] + pub const fn bberr(&self) -> bool { + let val = (self.0 >> 8usize) & 0x01; + val != 0 + } + #[doc = "Babble error"] + #[inline(always)] + pub fn set_bberr(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 8usize)) | (((val as u32) & 0x01) << 8usize); + } + #[doc = "Frame overrun"] + #[inline(always)] + pub const fn frmor(&self) -> bool { + let val = (self.0 >> 9usize) & 0x01; + val != 0 + } + #[doc = "Frame overrun"] + #[inline(always)] + pub fn set_frmor(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 9usize)) | (((val as u32) & 0x01) << 9usize); + } + #[doc = "Data toggle error"] + #[inline(always)] + pub const fn dterr(&self) -> bool { + let val = (self.0 >> 10usize) & 0x01; + val != 0 + } + #[doc = "Data toggle error"] + #[inline(always)] + pub fn set_dterr(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 10usize)) | (((val as u32) & 0x01) << 10usize); + } + } + impl Default for Hcint { + #[inline(always)] + fn default() -> Hcint { + Hcint(0) + } + } + #[doc = "Host channel mask register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Hcintmsk(pub u32); + impl Hcintmsk { + #[doc = "Transfer completed mask"] + #[inline(always)] + pub const fn xfrcm(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Transfer completed mask"] + #[inline(always)] + pub fn set_xfrcm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "Channel halted mask"] + #[inline(always)] + pub const fn chhm(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "Channel halted mask"] + #[inline(always)] + pub fn set_chhm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "STALL response received interrupt mask"] + #[inline(always)] + pub const fn stallm(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "STALL response received interrupt mask"] + #[inline(always)] + pub fn set_stallm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "NAK response received interrupt mask"] + #[inline(always)] + pub const fn nakm(&self) -> bool { + let val = (self.0 >> 4usize) & 0x01; + val != 0 + } + #[doc = "NAK response received interrupt mask"] + #[inline(always)] + pub fn set_nakm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 4usize)) | (((val as u32) & 0x01) << 4usize); + } + #[doc = "ACK response received/transmitted interrupt mask"] + #[inline(always)] + pub const fn ackm(&self) -> bool { + let val = (self.0 >> 5usize) & 0x01; + val != 0 + } + #[doc = "ACK response received/transmitted interrupt mask"] + #[inline(always)] + pub fn set_ackm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 5usize)) | (((val as u32) & 0x01) << 5usize); + } + #[doc = "Response received interrupt mask"] + #[inline(always)] + pub const fn nyet(&self) -> bool { + let val = (self.0 >> 6usize) & 0x01; + val != 0 + } + #[doc = "Response received interrupt mask"] + #[inline(always)] + pub fn set_nyet(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 6usize)) | (((val as u32) & 0x01) << 6usize); + } + #[doc = "Transaction error mask"] + #[inline(always)] + pub const fn txerrm(&self) -> bool { + let val = (self.0 >> 7usize) & 0x01; + val != 0 + } + #[doc = "Transaction error mask"] + #[inline(always)] + pub fn set_txerrm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 7usize)) | (((val as u32) & 0x01) << 7usize); + } + #[doc = "Babble error mask"] + #[inline(always)] + pub const fn bberrm(&self) -> bool { + let val = (self.0 >> 8usize) & 0x01; + val != 0 + } + #[doc = "Babble error mask"] + #[inline(always)] + pub fn set_bberrm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 8usize)) | (((val as u32) & 0x01) << 8usize); + } + #[doc = "Frame overrun mask"] + #[inline(always)] + pub const fn frmorm(&self) -> bool { + let val = (self.0 >> 9usize) & 0x01; + val != 0 + } + #[doc = "Frame overrun mask"] + #[inline(always)] + pub fn set_frmorm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 9usize)) | (((val as u32) & 0x01) << 9usize); + } + #[doc = "Data toggle error mask"] + #[inline(always)] + pub const fn dterrm(&self) -> bool { + let val = (self.0 >> 10usize) & 0x01; + val != 0 + } + #[doc = "Data toggle error mask"] + #[inline(always)] + pub fn set_dterrm(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 10usize)) | (((val as u32) & 0x01) << 10usize); + } + } + impl Default for Hcintmsk { + #[inline(always)] + fn default() -> Hcintmsk { + Hcintmsk(0) + } + } + #[doc = "Host channel transfer size register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Hctsiz(pub u32); + impl Hctsiz { + #[doc = "Transfer size"] + #[inline(always)] + pub const fn xfrsiz(&self) -> u32 { + let val = (self.0 >> 0usize) & 0x0007_ffff; + val as u32 + } + #[doc = "Transfer size"] + #[inline(always)] + pub fn set_xfrsiz(&mut self, val: u32) { + self.0 = (self.0 & !(0x0007_ffff << 0usize)) | (((val as u32) & 0x0007_ffff) << 0usize); + } + #[doc = "Packet count"] + #[inline(always)] + pub const fn pktcnt(&self) -> u16 { + let val = (self.0 >> 19usize) & 0x03ff; + val as u16 + } + #[doc = "Packet count"] + #[inline(always)] + pub fn set_pktcnt(&mut self, val: u16) { + self.0 = (self.0 & !(0x03ff << 19usize)) | (((val as u32) & 0x03ff) << 19usize); + } + #[doc = "Data PID"] + #[inline(always)] + pub const fn dpid(&self) -> u8 { + let val = (self.0 >> 29usize) & 0x03; + val as u8 + } + #[doc = "Data PID"] + #[inline(always)] + pub fn set_dpid(&mut self, val: u8) { + self.0 = (self.0 & !(0x03 << 29usize)) | (((val as u32) & 0x03) << 29usize); + } + } + impl Default for Hctsiz { + #[inline(always)] + fn default() -> Hctsiz { + Hctsiz(0) + } + } + #[doc = "Host frame interval register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Hfir(pub u32); + impl Hfir { + #[doc = "Frame interval"] + #[inline(always)] + pub const fn frivl(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "Frame interval"] + #[inline(always)] + pub fn set_frivl(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + } + impl Default for Hfir { + #[inline(always)] + fn default() -> Hfir { + Hfir(0) + } + } + #[doc = "Host frame number/frame time remaining register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Hfnum(pub u32); + impl Hfnum { + #[doc = "Frame number"] + #[inline(always)] + pub const fn frnum(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "Frame number"] + #[inline(always)] + pub fn set_frnum(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + #[doc = "Frame time remaining"] + #[inline(always)] + pub const fn ftrem(&self) -> u16 { + let val = (self.0 >> 16usize) & 0xffff; + val as u16 + } + #[doc = "Frame time remaining"] + #[inline(always)] + pub fn set_ftrem(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 16usize)) | (((val as u32) & 0xffff) << 16usize); + } + } + impl Default for Hfnum { + #[inline(always)] + fn default() -> Hfnum { + Hfnum(0) + } + } + #[doc = "Non-periodic transmit FIFO/queue status register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Hnptxsts(pub u32); + impl Hnptxsts { + #[doc = "Non-periodic TxFIFO space available"] + #[inline(always)] + pub const fn nptxfsav(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "Non-periodic TxFIFO space available"] + #[inline(always)] + pub fn set_nptxfsav(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + #[doc = "Non-periodic transmit request queue space available"] + #[inline(always)] + pub const fn nptqxsav(&self) -> u8 { + let val = (self.0 >> 16usize) & 0xff; + val as u8 + } + #[doc = "Non-periodic transmit request queue space available"] + #[inline(always)] + pub fn set_nptqxsav(&mut self, val: u8) { + self.0 = (self.0 & !(0xff << 16usize)) | (((val as u32) & 0xff) << 16usize); + } + #[doc = "Top of the non-periodic transmit request queue"] + #[inline(always)] + pub const fn nptxqtop(&self) -> u8 { + let val = (self.0 >> 24usize) & 0x7f; + val as u8 + } + #[doc = "Top of the non-periodic transmit request queue"] + #[inline(always)] + pub fn set_nptxqtop(&mut self, val: u8) { + self.0 = (self.0 & !(0x7f << 24usize)) | (((val as u32) & 0x7f) << 24usize); + } + } + impl Default for Hnptxsts { + #[inline(always)] + fn default() -> Hnptxsts { + Hnptxsts(0) + } + } + #[doc = "Host port control and status register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Hprt(pub u32); + impl Hprt { + #[doc = "Port connect status"] + #[inline(always)] + pub const fn pcsts(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Port connect status"] + #[inline(always)] + pub fn set_pcsts(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "Port connect detected"] + #[inline(always)] + pub const fn pcdet(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "Port connect detected"] + #[inline(always)] + pub fn set_pcdet(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "Port enable"] + #[inline(always)] + pub const fn pena(&self) -> bool { + let val = (self.0 >> 2usize) & 0x01; + val != 0 + } + #[doc = "Port enable"] + #[inline(always)] + pub fn set_pena(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 2usize)) | (((val as u32) & 0x01) << 2usize); + } + #[doc = "Port enable/disable change"] + #[inline(always)] + pub const fn penchng(&self) -> bool { + let val = (self.0 >> 3usize) & 0x01; + val != 0 + } + #[doc = "Port enable/disable change"] + #[inline(always)] + pub fn set_penchng(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 3usize)) | (((val as u32) & 0x01) << 3usize); + } + #[doc = "Port overcurrent active"] + #[inline(always)] + pub const fn poca(&self) -> bool { + let val = (self.0 >> 4usize) & 0x01; + val != 0 + } + #[doc = "Port overcurrent active"] + #[inline(always)] + pub fn set_poca(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 4usize)) | (((val as u32) & 0x01) << 4usize); + } + #[doc = "Port overcurrent change"] + #[inline(always)] + pub const fn pocchng(&self) -> bool { + let val = (self.0 >> 5usize) & 0x01; + val != 0 + } + #[doc = "Port overcurrent change"] + #[inline(always)] + pub fn set_pocchng(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 5usize)) | (((val as u32) & 0x01) << 5usize); + } + #[doc = "Port resume"] + #[inline(always)] + pub const fn pres(&self) -> bool { + let val = (self.0 >> 6usize) & 0x01; + val != 0 + } + #[doc = "Port resume"] + #[inline(always)] + pub fn set_pres(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 6usize)) | (((val as u32) & 0x01) << 6usize); + } + #[doc = "Port suspend"] + #[inline(always)] + pub const fn psusp(&self) -> bool { + let val = (self.0 >> 7usize) & 0x01; + val != 0 + } + #[doc = "Port suspend"] + #[inline(always)] + pub fn set_psusp(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 7usize)) | (((val as u32) & 0x01) << 7usize); + } + #[doc = "Port reset"] + #[inline(always)] + pub const fn prst(&self) -> bool { + let val = (self.0 >> 8usize) & 0x01; + val != 0 + } + #[doc = "Port reset"] + #[inline(always)] + pub fn set_prst(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 8usize)) | (((val as u32) & 0x01) << 8usize); + } + #[doc = "Port line status"] + #[inline(always)] + pub const fn plsts(&self) -> u8 { + let val = (self.0 >> 10usize) & 0x03; + val as u8 + } + #[doc = "Port line status"] + #[inline(always)] + pub fn set_plsts(&mut self, val: u8) { + self.0 = (self.0 & !(0x03 << 10usize)) | (((val as u32) & 0x03) << 10usize); + } + #[doc = "Port power"] + #[inline(always)] + pub const fn ppwr(&self) -> bool { + let val = (self.0 >> 12usize) & 0x01; + val != 0 + } + #[doc = "Port power"] + #[inline(always)] + pub fn set_ppwr(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 12usize)) | (((val as u32) & 0x01) << 12usize); + } + #[doc = "Port test control"] + #[inline(always)] + pub const fn ptctl(&self) -> u8 { + let val = (self.0 >> 13usize) & 0x0f; + val as u8 + } + #[doc = "Port test control"] + #[inline(always)] + pub fn set_ptctl(&mut self, val: u8) { + self.0 = (self.0 & !(0x0f << 13usize)) | (((val as u32) & 0x0f) << 13usize); + } + #[doc = "Port speed"] + #[inline(always)] + pub const fn pspd(&self) -> u8 { + let val = (self.0 >> 17usize) & 0x03; + val as u8 + } + #[doc = "Port speed"] + #[inline(always)] + pub fn set_pspd(&mut self, val: u8) { + self.0 = (self.0 & !(0x03 << 17usize)) | (((val as u32) & 0x03) << 17usize); + } + } + impl Default for Hprt { + #[inline(always)] + fn default() -> Hprt { + Hprt(0) + } + } + #[doc = "Periodic transmit FIFO/queue status register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Hptxsts(pub u32); + impl Hptxsts { + #[doc = "Periodic transmit data FIFO space available"] + #[inline(always)] + pub const fn ptxfsavl(&self) -> u16 { + let val = (self.0 >> 0usize) & 0xffff; + val as u16 + } + #[doc = "Periodic transmit data FIFO space available"] + #[inline(always)] + pub fn set_ptxfsavl(&mut self, val: u16) { + self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize); + } + #[doc = "Periodic transmit request queue space available"] + #[inline(always)] + pub const fn ptxqsav(&self) -> u8 { + let val = (self.0 >> 16usize) & 0xff; + val as u8 + } + #[doc = "Periodic transmit request queue space available"] + #[inline(always)] + pub fn set_ptxqsav(&mut self, val: u8) { + self.0 = (self.0 & !(0xff << 16usize)) | (((val as u32) & 0xff) << 16usize); + } + #[doc = "Top of the periodic transmit request queue"] + #[inline(always)] + pub const fn ptxqtop(&self) -> u8 { + let val = (self.0 >> 24usize) & 0xff; + val as u8 + } + #[doc = "Top of the periodic transmit request queue"] + #[inline(always)] + pub fn set_ptxqtop(&mut self, val: u8) { + self.0 = (self.0 & !(0xff << 24usize)) | (((val as u32) & 0xff) << 24usize); + } + } + impl Default for Hptxsts { + #[inline(always)] + fn default() -> Hptxsts { + Hptxsts(0) + } + } + #[doc = "Power and clock gating control register"] + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq)] + pub struct Pcgcctl(pub u32); + impl Pcgcctl { + #[doc = "Stop PHY clock"] + #[inline(always)] + pub const fn stppclk(&self) -> bool { + let val = (self.0 >> 0usize) & 0x01; + val != 0 + } + #[doc = "Stop PHY clock"] + #[inline(always)] + pub fn set_stppclk(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize); + } + #[doc = "Gate HCLK"] + #[inline(always)] + pub const fn gatehclk(&self) -> bool { + let val = (self.0 >> 1usize) & 0x01; + val != 0 + } + #[doc = "Gate HCLK"] + #[inline(always)] + pub fn set_gatehclk(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize); + } + #[doc = "PHY Suspended"] + #[inline(always)] + pub const fn physusp(&self) -> bool { + let val = (self.0 >> 4usize) & 0x01; + val != 0 + } + #[doc = "PHY Suspended"] + #[inline(always)] + pub fn set_physusp(&mut self, val: bool) { + self.0 = (self.0 & !(0x01 << 4usize)) | (((val as u32) & 0x01) << 4usize); + } + } + impl Default for Pcgcctl { + #[inline(always)] + fn default() -> Pcgcctl { + Pcgcctl(0) + } + } +} +pub mod vals { + #[repr(u8)] + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] + #[allow(non_camel_case_types)] + pub enum Dpid { + DATA0 = 0x0, + DATA2 = 0x01, + DATA1 = 0x02, + MDATA = 0x03, + } + impl Dpid { + #[inline(always)] + pub const fn from_bits(val: u8) -> Dpid { + unsafe { core::mem::transmute(val & 0x03) } + } + #[inline(always)] + pub const fn to_bits(self) -> u8 { + unsafe { core::mem::transmute(self) } + } + } + impl From<u8> for Dpid { + #[inline(always)] + fn from(val: u8) -> Dpid { + Dpid::from_bits(val) + } + } + impl From<Dpid> for u8 { + #[inline(always)] + fn from(val: Dpid) -> u8 { + Dpid::to_bits(val) + } + } + #[repr(u8)] + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] + #[allow(non_camel_case_types)] + pub enum Dspd { + #[doc = "High speed"] + HIGH_SPEED = 0x0, + #[doc = "Full speed using external ULPI PHY"] + FULL_SPEED_EXTERNAL = 0x01, + _RESERVED_2 = 0x02, + #[doc = "Full speed using internal embedded PHY"] + FULL_SPEED_INTERNAL = 0x03, + } + impl Dspd { + #[inline(always)] + pub const fn from_bits(val: u8) -> Dspd { + unsafe { core::mem::transmute(val & 0x03) } + } + #[inline(always)] + pub const fn to_bits(self) -> u8 { + unsafe { core::mem::transmute(self) } + } + } + impl From<u8> for Dspd { + #[inline(always)] + fn from(val: u8) -> Dspd { + Dspd::from_bits(val) + } + } + impl From<Dspd> for u8 { + #[inline(always)] + fn from(val: Dspd) -> u8 { + Dspd::to_bits(val) + } + } + #[repr(u8)] + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] + #[allow(non_camel_case_types)] + pub enum Eptyp { + CONTROL = 0x0, + ISOCHRONOUS = 0x01, + BULK = 0x02, + INTERRUPT = 0x03, + } + impl Eptyp { + #[inline(always)] + pub const fn from_bits(val: u8) -> Eptyp { + unsafe { core::mem::transmute(val & 0x03) } + } + #[inline(always)] + pub const fn to_bits(self) -> u8 { + unsafe { core::mem::transmute(self) } + } + } + impl From<u8> for Eptyp { + #[inline(always)] + fn from(val: u8) -> Eptyp { + Eptyp::from_bits(val) + } + } + impl From<Eptyp> for u8 { + #[inline(always)] + fn from(val: Eptyp) -> u8 { + Eptyp::to_bits(val) + } + } + #[repr(u8)] + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] + #[allow(non_camel_case_types)] + pub enum Pfivl { + #[doc = "80% of the frame interval"] + FRAME_INTERVAL_80 = 0x0, + #[doc = "85% of the frame interval"] + FRAME_INTERVAL_85 = 0x01, + #[doc = "90% of the frame interval"] + FRAME_INTERVAL_90 = 0x02, + #[doc = "95% of the frame interval"] + FRAME_INTERVAL_95 = 0x03, + } + impl Pfivl { + #[inline(always)] + pub const fn from_bits(val: u8) -> Pfivl { + unsafe { core::mem::transmute(val & 0x03) } + } + #[inline(always)] + pub const fn to_bits(self) -> u8 { + unsafe { core::mem::transmute(self) } + } + } + impl From<u8> for Pfivl { + #[inline(always)] + fn from(val: u8) -> Pfivl { + Pfivl::from_bits(val) + } + } + impl From<Pfivl> for u8 { + #[inline(always)] + fn from(val: Pfivl) -> u8 { + Pfivl::to_bits(val) + } + } + #[repr(u8)] + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] + #[allow(non_camel_case_types)] + pub enum Pktstsd { + _RESERVED_0 = 0x0, + #[doc = "Global OUT NAK (triggers an interrupt)"] + OUT_NAK = 0x01, + #[doc = "OUT data packet received"] + OUT_DATA_RX = 0x02, + #[doc = "OUT transfer completed (triggers an interrupt)"] + OUT_DATA_DONE = 0x03, + #[doc = "SETUP transaction completed (triggers an interrupt)"] + SETUP_DATA_DONE = 0x04, + _RESERVED_5 = 0x05, + #[doc = "SETUP data packet received"] + SETUP_DATA_RX = 0x06, + _RESERVED_7 = 0x07, + _RESERVED_8 = 0x08, + _RESERVED_9 = 0x09, + _RESERVED_a = 0x0a, + _RESERVED_b = 0x0b, + _RESERVED_c = 0x0c, + _RESERVED_d = 0x0d, + _RESERVED_e = 0x0e, + _RESERVED_f = 0x0f, + } + impl Pktstsd { + #[inline(always)] + pub const fn from_bits(val: u8) -> Pktstsd { + unsafe { core::mem::transmute(val & 0x0f) } + } + #[inline(always)] + pub const fn to_bits(self) -> u8 { + unsafe { core::mem::transmute(self) } + } + } + impl From<u8> for Pktstsd { + #[inline(always)] + fn from(val: u8) -> Pktstsd { + Pktstsd::from_bits(val) + } + } + impl From<Pktstsd> for u8 { + #[inline(always)] + fn from(val: Pktstsd) -> u8 { + Pktstsd::to_bits(val) + } + } + #[repr(u8)] + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] + #[allow(non_camel_case_types)] + pub enum Pktstsh { + _RESERVED_0 = 0x0, + _RESERVED_1 = 0x01, + #[doc = "IN data packet received"] + IN_DATA_RX = 0x02, + #[doc = "IN transfer completed (triggers an interrupt)"] + IN_DATA_DONE = 0x03, + _RESERVED_4 = 0x04, + #[doc = "Data toggle error (triggers an interrupt)"] + DATA_TOGGLE_ERR = 0x05, + _RESERVED_6 = 0x06, + #[doc = "Channel halted (triggers an interrupt)"] + CHANNEL_HALTED = 0x07, + _RESERVED_8 = 0x08, + _RESERVED_9 = 0x09, + _RESERVED_a = 0x0a, + _RESERVED_b = 0x0b, + _RESERVED_c = 0x0c, + _RESERVED_d = 0x0d, + _RESERVED_e = 0x0e, + _RESERVED_f = 0x0f, + } + impl Pktstsh { + #[inline(always)] + pub const fn from_bits(val: u8) -> Pktstsh { + unsafe { core::mem::transmute(val & 0x0f) } + } + #[inline(always)] + pub const fn to_bits(self) -> u8 { + unsafe { core::mem::transmute(self) } + } + } + impl From<u8> for Pktstsh { + #[inline(always)] + fn from(val: u8) -> Pktstsh { + Pktstsh::from_bits(val) + } + } + impl From<Pktstsh> for u8 { + #[inline(always)] + fn from(val: Pktstsh) -> u8 { + Pktstsh::to_bits(val) + } + } +} diff --git a/embassy-usb/CHANGELOG.md b/embassy-usb/CHANGELOG.md new file mode 100644 index 000000000..5f665ed25 --- /dev/null +++ b/embassy-usb/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +## 0.2.0 - 2024-05-20 + +- [#2862](https://github.com/embassy-rs/embassy/pull/2862) WebUSB implementation by @chmanie +- Removed dynamically sized `device_descriptor` fields + +## 0.1.0 - 2024-01-11 + +- Initial Release diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml index fe5e36b32..191ed0a6a 100644 --- a/embassy-usb/Cargo.toml +++ b/embassy-usb/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-usb" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "MIT OR Apache-2.0" description = "Async USB device stack for embedded devices in Rust." @@ -48,7 +48,7 @@ max-handler-count-8 = [] [dependencies] embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" } -embassy-sync = { version = "0.5.0", path = "../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../embassy-sync" } embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } defmt = { version = "0.3", optional = true } diff --git a/embassy-usb/README.md b/embassy-usb/README.md index d2adae4f5..400fc6695 100644 --- a/embassy-usb/README.md +++ b/embassy-usb/README.md @@ -34,8 +34,8 @@ They can be set in two ways: - Via Cargo features: enable a feature like `<name>-<value>`. `name` must be in lowercase and use dashes instead of underscores. For example. `max-interface-count-3`. Only a selection of values is available, check `Cargo.toml` for the list. -- Via environment variables at build time: set the variable named `EMBASSY_USB_<value>`. For example -`EMBASSY_USB_MAX_INTERFACE_COUNT=3 cargo build`. You can also set them in the `[env]` section of `.cargo/config.toml`. +- Via environment variables at build time: set the variable named `EMBASSY_USB_<value>`. For example +`EMBASSY_USB_MAX_INTERFACE_COUNT=3 cargo build`. You can also set them in the `[env]` section of `.cargo/config.toml`. Any value can be set, unlike with Cargo features. Environment variables take precedence over Cargo features. If two Cargo features are enabled for the same setting diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index 387b780de..7168e077c 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs @@ -417,6 +417,11 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> { self.builder.config_descriptor.write(descriptor_type, descriptor); } + /// Add a custom Binary Object Store (BOS) descriptor to this alternate setting. + pub fn bos_capability(&mut self, capability_type: u8, capability: &[u8]) { + self.builder.bos_descriptor.capability(capability_type, capability); + } + fn endpoint_in(&mut self, ep_type: EndpointType, max_packet_size: u16, interval_ms: u8) -> D::EndpointIn { let ep = self .builder diff --git a/embassy-usb/src/class/hid.rs b/embassy-usb/src/class/hid.rs index 0000b5b2b..6d9e0aced 100644 --- a/embassy-usb/src/class/hid.rs +++ b/embassy-usb/src/class/hid.rs @@ -37,7 +37,7 @@ pub struct Config<'d> { pub report_descriptor: &'d [u8], /// Handler for control requests. - pub request_handler: Option<&'d dyn RequestHandler>, + pub request_handler: Option<&'d mut dyn RequestHandler>, /// Configures how frequently the host should poll for reading/writing HID reports. /// @@ -299,7 +299,7 @@ impl<'d, D: Driver<'d>, const N: usize> HidReader<'d, D, N> { /// /// If `use_report_ids` is true, the first byte of the report will be used as /// the `ReportId` value. Otherwise the `ReportId` value will be 0. - pub async fn run<T: RequestHandler>(mut self, use_report_ids: bool, handler: &T) -> ! { + pub async fn run<T: RequestHandler>(mut self, use_report_ids: bool, handler: &mut T) -> ! { let offset = self.offset.load(Ordering::Acquire); assert!(offset == 0); let mut buf = [0; N]; @@ -378,13 +378,13 @@ pub trait RequestHandler { /// Reads the value of report `id` into `buf` returning the size. /// /// Returns `None` if `id` is invalid or no data is available. - fn get_report(&self, id: ReportId, buf: &mut [u8]) -> Option<usize> { + fn get_report(&mut self, id: ReportId, buf: &mut [u8]) -> Option<usize> { let _ = (id, buf); None } /// Sets the value of report `id` to `data`. - fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { + fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { let _ = (id, data); OutResponse::Rejected } @@ -394,7 +394,7 @@ pub trait RequestHandler { /// If `id` is `None`, get the idle rate for all reports. Returning `None` /// will reject the control request. Any duration at or above 1.024 seconds /// or below 4ms will be returned as an indefinite idle rate. - fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { + fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { let _ = id; None } @@ -403,7 +403,7 @@ pub trait RequestHandler { /// /// If `id` is `None`, set the idle rate of all input reports to `dur`. If /// an indefinite duration is requested, `dur` will be set to `u32::MAX`. - fn set_idle_ms(&self, id: Option<ReportId>, duration_ms: u32) { + fn set_idle_ms(&mut self, id: Option<ReportId>, duration_ms: u32) { let _ = (id, duration_ms); } } @@ -411,7 +411,7 @@ pub trait RequestHandler { struct Control<'d> { if_num: InterfaceNumber, report_descriptor: &'d [u8], - request_handler: Option<&'d dyn RequestHandler>, + request_handler: Option<&'d mut dyn RequestHandler>, out_report_offset: &'d AtomicUsize, hid_descriptor: [u8; 9], } @@ -420,7 +420,7 @@ impl<'d> Control<'d> { fn new( if_num: InterfaceNumber, report_descriptor: &'d [u8], - request_handler: Option<&'d dyn RequestHandler>, + request_handler: Option<&'d mut dyn RequestHandler>, out_report_offset: &'d AtomicUsize, ) -> Self { Control { @@ -468,7 +468,7 @@ impl<'d> Handler for Control<'d> { trace!("HID control_out {:?} {=[u8]:x}", req, data); match req.request { HID_REQ_SET_IDLE => { - if let Some(handler) = self.request_handler { + if let Some(handler) = self.request_handler.as_mut() { let id = req.value as u8; let id = (id != 0).then_some(ReportId::In(id)); let dur = u32::from(req.value >> 8); @@ -477,7 +477,7 @@ impl<'d> Handler for Control<'d> { } Some(OutResponse::Accepted) } - HID_REQ_SET_REPORT => match (ReportId::try_from(req.value), self.request_handler) { + HID_REQ_SET_REPORT => match (ReportId::try_from(req.value), self.request_handler.as_mut()) { (Ok(id), Some(handler)) => Some(handler.set_report(id, data)), _ => Some(OutResponse::Rejected), }, @@ -513,7 +513,7 @@ impl<'d> Handler for Control<'d> { match req.request { HID_REQ_GET_REPORT => { let size = match ReportId::try_from(req.value) { - Ok(id) => self.request_handler.and_then(|x| x.get_report(id, buf)), + Ok(id) => self.request_handler.as_mut().and_then(|x| x.get_report(id, buf)), Err(_) => None, }; @@ -524,7 +524,7 @@ impl<'d> Handler for Control<'d> { } } HID_REQ_GET_IDLE => { - if let Some(handler) = self.request_handler { + if let Some(handler) = self.request_handler.as_mut() { let id = req.value as u8; let id = (id != 0).then_some(ReportId::In(id)); if let Some(dur) = handler.get_idle_ms(id) { diff --git a/embassy-usb/src/class/mod.rs b/embassy-usb/src/class/mod.rs index 452eedf17..b883ed4e5 100644 --- a/embassy-usb/src/class/mod.rs +++ b/embassy-usb/src/class/mod.rs @@ -3,3 +3,4 @@ pub mod cdc_acm; pub mod cdc_ncm; pub mod hid; pub mod midi; +pub mod web_usb; diff --git a/embassy-usb/src/class/web_usb.rs b/embassy-usb/src/class/web_usb.rs new file mode 100644 index 000000000..10ebf318d --- /dev/null +++ b/embassy-usb/src/class/web_usb.rs @@ -0,0 +1,186 @@ +//! WebUSB API capability implementation. +//! +//! See https://wicg.github.io/webusb + +use core::mem::MaybeUninit; + +use crate::control::{InResponse, Recipient, Request, RequestType}; +use crate::descriptor::capability_type; +use crate::driver::Driver; +use crate::{Builder, Handler}; + +const USB_CLASS_VENDOR: u8 = 0xff; +const USB_SUBCLASS_NONE: u8 = 0x00; +const USB_PROTOCOL_NONE: u8 = 0x00; + +const WEB_USB_REQUEST_GET_URL: u16 = 0x02; +const WEB_USB_DESCRIPTOR_TYPE_URL: u8 = 0x03; + +/// URL descriptor for WebUSB landing page. +/// +/// An ecoded URL descriptor to point to a website that is suggested to the user when the device is connected. +pub struct Url<'d>(&'d str, u8); + +impl<'d> Url<'d> { + /// Create a new WebUSB URL descriptor. + pub fn new(url: &'d str) -> Self { + let (prefix, stripped_url) = if let Some(stripped) = url.strip_prefix("https://") { + (1, stripped) + } else if let Some(stripped) = url.strip_prefix("http://") { + (0, stripped) + } else { + (255, url) + }; + assert!( + stripped_url.len() <= 252, + "URL too long. ({} bytes). Maximum length is 252 bytes.", + stripped_url.len() + ); + Self(stripped_url, prefix) + } + + fn as_bytes(&self) -> &[u8] { + self.0.as_bytes() + } + + fn scheme(&self) -> u8 { + self.1 + } +} + +/// Configuration for WebUSB. +pub struct Config<'d> { + /// Maximum packet size in bytes for the data endpoints. + /// + /// Valid values depend on the speed at which the bus is enumerated. + /// - low speed: 8 + /// - full speed: 8, 16, 32, or 64 + /// - high speed: 64 + pub max_packet_size: u16, + /// URL to navigate to when the device is connected. + /// + /// If defined, shows a landing page which the device manufacturer would like the user to visit in order to control their device. + pub landing_url: Option<Url<'d>>, + /// Vendor code for the WebUSB request. + /// + /// This value defines the request id (bRequest) the device expects the host to use when issuing control transfers these requests. This can be an arbitrary u8 and is not to be confused with the USB Vendor ID. + pub vendor_code: u8, +} + +struct Control<'d> { + ep_buf: [u8; 128], + vendor_code: u8, + landing_url: Option<&'d Url<'d>>, +} + +impl<'d> Control<'d> { + fn new(config: &'d Config<'d>) -> Self { + Control { + ep_buf: [0u8; 128], + vendor_code: config.vendor_code, + landing_url: config.landing_url.as_ref(), + } + } +} + +impl<'d> Handler for Control<'d> { + fn control_in(&mut self, req: Request, _data: &mut [u8]) -> Option<InResponse> { + let landing_value = if self.landing_url.is_some() { 1 } else { 0 }; + if req.request_type == RequestType::Vendor + && req.recipient == Recipient::Device + && req.request == self.vendor_code + && req.value == landing_value + && req.index == WEB_USB_REQUEST_GET_URL + { + if let Some(url) = self.landing_url { + let url_bytes = url.as_bytes(); + let len = url_bytes.len(); + + self.ep_buf[0] = len as u8 + 3; + self.ep_buf[1] = WEB_USB_DESCRIPTOR_TYPE_URL; + self.ep_buf[2] = url.scheme(); + self.ep_buf[3..3 + len].copy_from_slice(url_bytes); + + return Some(InResponse::Accepted(&self.ep_buf[..3 + len])); + } + } + None + } +} + +/// Internal state for WebUSB +pub struct State<'d> { + control: MaybeUninit<Control<'d>>, +} + +impl<'d> Default for State<'d> { + fn default() -> Self { + Self::new() + } +} + +impl<'d> State<'d> { + /// Create a new `State`. + pub const fn new() -> Self { + State { + control: MaybeUninit::uninit(), + } + } +} + +/// WebUSB capability implementation. +/// +/// WebUSB is a W3C standard that allows a web page to communicate with USB devices. +/// See See https://wicg.github.io/webusb for more information and the browser API. +/// This implementation provides one read and one write endpoint. +pub struct WebUsb<'d, D: Driver<'d>> { + _driver: core::marker::PhantomData<&'d D>, +} + +impl<'d, D: Driver<'d>> WebUsb<'d, D> { + /// Builder for the WebUSB capability implementation. + /// + /// Pass in a USB `Builder`, a `State`, which holds the the control endpoint state, and a `Config` for the WebUSB configuration. + pub fn configure(builder: &mut Builder<'d, D>, state: &'d mut State<'d>, config: &'d Config<'d>) { + let mut func = builder.function(USB_CLASS_VENDOR, USB_SUBCLASS_NONE, USB_PROTOCOL_NONE); + let mut iface = func.interface(); + let mut alt = iface.alt_setting(USB_CLASS_VENDOR, USB_SUBCLASS_NONE, USB_PROTOCOL_NONE, None); + + alt.bos_capability( + capability_type::PLATFORM, + &[ + // PlatformCapabilityUUID (3408b638-09a9-47a0-8bfd-a0768815b665) + 0x0, + 0x38, + 0xb6, + 0x08, + 0x34, + 0xa9, + 0x09, + 0xa0, + 0x47, + 0x8b, + 0xfd, + 0xa0, + 0x76, + 0x88, + 0x15, + 0xb6, + 0x65, + // bcdVersion of WebUSB (1.0) + 0x00, + 0x01, + // bVendorCode + config.vendor_code, + // iLandingPage + if config.landing_url.is_some() { 1 } else { 0 }, + ], + ); + + let control = state.control.write(Control::new(config)); + + drop(func); + + builder.handler(control); + } +} diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml index 86f6676cb..f0a710335 100644 --- a/examples/boot/application/nrf/Cargo.toml +++ b/examples/boot/application/nrf/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "integrated-timers", "arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [] } embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", ] } diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml index 70741a0ce..2ddcbffee 100644 --- a/examples/boot/application/rp/Cargo.toml +++ b/examples/boot/application/rp/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "integrated-timers", "arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [] } embassy-rp = { version = "0.1.0", path = "../../../../embassy-rp", features = ["time-driver", ] } diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml index 1cb143820..fe1a6f5b1 100644 --- a/examples/boot/application/stm32f3/Cargo.toml +++ b/examples/boot/application/stm32f3/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f303re", "time-driver-any", "exti"] } diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml index c4ae461a5..37e362824 100644 --- a/examples/boot/application/stm32f7/Cargo.toml +++ b/examples/boot/application/stm32f7/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f767zi", "time-driver-any", "exti"] } diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml index 995487cdd..52cd0b546 100644 --- a/examples/boot/application/stm32h7/Cargo.toml +++ b/examples/boot/application/stm32h7/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32h743zi", "time-driver-any", "exti"] } diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml index b2abc005c..0f3cbe654 100644 --- a/examples/boot/application/stm32l0/Cargo.toml +++ b/examples/boot/application/stm32l0/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l072cz", "time-driver-any", "exti", "memory-x"] } diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml index 7203e6350..3e964df9c 100644 --- a/examples/boot/application/stm32l1/Cargo.toml +++ b/examples/boot/application/stm32l1/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l151cb-a", "time-driver-any", "exti"] } diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml index ec134f394..b154403ac 100644 --- a/examples/boot/application/stm32l4/Cargo.toml +++ b/examples/boot/application/stm32l4/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "time-driver-any", "exti"] } diff --git a/examples/boot/application/stm32wb-dfu/Cargo.toml b/examples/boot/application/stm32wb-dfu/Cargo.toml index 0bdf94331..bb83ae049 100644 --- a/examples/boot/application/stm32wb-dfu/Cargo.toml +++ b/examples/boot/application/stm32wb-dfu/Cargo.toml @@ -5,13 +5,13 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wb55rg", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } -embassy-usb = { version = "0.1.0", path = "../../../../embassy-usb" } +embassy-usb = { version = "0.2.0", path = "../../../../embassy-usb" } embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["application", "cortex-m"] } defmt = { version = "0.3", optional = true } diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml index e38e9f3af..93ead617c 100644 --- a/examples/boot/application/stm32wl/Cargo.toml +++ b/examples/boot/application/stm32wl/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wl55jc-cm4", "time-driver-any", "exti"] } diff --git a/examples/boot/bootloader/nrf/Cargo.toml b/examples/boot/bootloader/nrf/Cargo.toml index 3e41d1479..980149bea 100644 --- a/examples/boot/bootloader/nrf/Cargo.toml +++ b/examples/boot/bootloader/nrf/Cargo.toml @@ -12,7 +12,7 @@ defmt-rtt = { version = "0.4", optional = true } embassy-nrf = { path = "../../../../embassy-nrf", features = [] } embassy-boot-nrf = { path = "../../../../embassy-boot-nrf" } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } cortex-m-rt = { version = "0.7" } cfg-if = "1.0.0" diff --git a/examples/boot/bootloader/rp/Cargo.toml b/examples/boot/bootloader/rp/Cargo.toml index 3cf61a002..7eec3df1b 100644 --- a/examples/boot/bootloader/rp/Cargo.toml +++ b/examples/boot/bootloader/rp/Cargo.toml @@ -11,7 +11,7 @@ defmt-rtt = { version = "0.4", optional = true } embassy-rp = { path = "../../../../embassy-rp", features = [] } embassy-boot-rp = { path = "../../../../embassy-boot-rp" } -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } embassy-time = { path = "../../../../embassy-time", features = [] } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } diff --git a/examples/boot/bootloader/stm32-dual-bank/Cargo.toml b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml index 313187adc..55adf84d7 100644 --- a/examples/boot/bootloader/stm32-dual-bank/Cargo.toml +++ b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml @@ -15,7 +15,7 @@ cortex-m = { version = "0.7.6", features = [ "inline-asm", "critical-section-single-core", ] } -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } cortex-m-rt = { version = "0.7" } embedded-storage = "0.3.1" embedded-storage-async = "0.4.0" diff --git a/examples/boot/bootloader/stm32-dual-bank/README.md b/examples/boot/bootloader/stm32-dual-bank/README.md index 3de3171cd..cd6c0bc84 100644 --- a/examples/boot/bootloader/stm32-dual-bank/README.md +++ b/examples/boot/bootloader/stm32-dual-bank/README.md @@ -2,16 +2,16 @@ ## Overview -This bootloader leverages `embassy-boot` to interact with the flash. -This example targets STM32 devices with dual-bank flash memory, with a primary focus on the STM32H747XI series. +This bootloader leverages `embassy-boot` to interact with the flash. +This example targets STM32 devices with dual-bank flash memory, with a primary focus on the STM32H747XI series. Users must modify the `memory.x` configuration file to match with the memory layout of their specific STM32 device. Additionally, this example can be extended to utilize external flash memory, such as QSPI, for storing partitions. ## Memory Configuration -In this example's `memory.x` file, various symbols are defined to assist in effective memory management within the bootloader environment. -For dual-bank STM32 devices, it's crucial to assign these symbols correctly to their respective memory banks. +In this example's `memory.x` file, various symbols are defined to assist in effective memory management within the bootloader environment. +For dual-bank STM32 devices, it's crucial to assign these symbols correctly to their respective memory banks. ### Symbol Definitions diff --git a/examples/boot/bootloader/stm32/Cargo.toml b/examples/boot/bootloader/stm32/Cargo.toml index 74c01b0f4..ef2b99404 100644 --- a/examples/boot/bootloader/stm32/Cargo.toml +++ b/examples/boot/bootloader/stm32/Cargo.toml @@ -12,7 +12,7 @@ defmt-rtt = { version = "0.4", optional = true } embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } cortex-m-rt = { version = "0.7" } embedded-storage = "0.3.1" embedded-storage-async = "0.4.0" diff --git a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml index 854f94d85..93b5d8b34 100644 --- a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml +++ b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml @@ -12,13 +12,13 @@ defmt-rtt = { version = "0.4", optional = true } embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } -embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } cortex-m-rt = { version = "0.7" } embedded-storage = "0.3.1" embedded-storage-async = "0.4.0" cfg-if = "1.0.0" embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["dfu", "cortex-m"] } -embassy-usb = { version = "0.1.0", path = "../../../../embassy-usb", default-features = false } +embassy-usb = { version = "0.2.0", path = "../../../../embassy-usb", default-features = false } embassy-futures = { version = "0.1.1", path = "../../../../embassy-futures" } [features] diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index 17210994b..147bb40dc 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml @@ -15,7 +15,7 @@ log = [ ] [dependencies] -embassy-sync = { version = "0.5.0", path = "../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync" } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time" } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } @@ -23,7 +23,6 @@ embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf5 cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" panic-probe = { version = "0.3" } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } rand = { version = "0.8.4", default-features = false } serde = { version = "1.0.136", default-features = false } rtos-trace = "0.1.3" diff --git a/examples/nrf52810/.cargo/config.toml b/examples/nrf52810/.cargo/config.toml new file mode 100644 index 000000000..917a5364a --- /dev/null +++ b/examples/nrf52810/.cargo/config.toml @@ -0,0 +1,9 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace nRF82810_xxAA with your chip as listed in `probe-rs chip list` +runner = "probe-rs run --chip nRF52810_xxAA" + +[build] +target = "thumbv7em-none-eabi" + +[env] +DEFMT_LOG = "trace" diff --git a/examples/nrf52810/Cargo.toml b/examples/nrf52810/Cargo.toml new file mode 100644 index 000000000..faec9a263 --- /dev/null +++ b/examples/nrf52810/Cargo.toml @@ -0,0 +1,24 @@ +[package] +edition = "2021" +name = "embassy-nrf52810-examples" +version = "0.1.0" +license = "MIT OR Apache-2.0" + +[dependencies] +embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } +embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } +embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52810", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } + +defmt = "0.3" +defmt-rtt = "0.4" + +fixed = "1.10.0" +static_cell = { version = "2" } +cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } +cortex-m-rt = "0.7.0" +panic-probe = { version = "0.3", features = ["print-defmt"] } + +[profile.release] +debug = 2 diff --git a/examples/nrf52810/build.rs b/examples/nrf52810/build.rs new file mode 100644 index 000000000..30691aa97 --- /dev/null +++ b/examples/nrf52810/build.rs @@ -0,0 +1,35 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/examples/nrf52810/memory.x b/examples/nrf52810/memory.x new file mode 100644 index 000000000..7cf560e44 --- /dev/null +++ b/examples/nrf52810/memory.x @@ -0,0 +1,7 @@ +MEMORY +{ + /* NOTE 1 K = 1 KiBi = 1024 bytes */ + FLASH : ORIGIN = 0x00000000, LENGTH = 256K + RAM : ORIGIN = 0x20000000, LENGTH = 24K + +} diff --git a/examples/nrf52810/src/bin/blinky.rs b/examples/nrf52810/src/bin/blinky.rs new file mode 100644 index 000000000..1da039f7d --- /dev/null +++ b/examples/nrf52810/src/bin/blinky.rs @@ -0,0 +1,20 @@ +#![no_std] +#![no_main] + +use embassy_executor::Spawner; +use embassy_nrf::gpio::{Level, Output, OutputDrive}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_nrf::init(Default::default()); + let mut led = Output::new(p.P0_18, Level::Low, OutputDrive::Standard); + + loop { + led.set_high(); + Timer::after_millis(300).await; + led.set_low(); + Timer::after_millis(300).await; + } +} diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml index d91f58d0e..041c779a5 100644 --- a/examples/nrf52840-rtic/Cargo.toml +++ b/examples/nrf52840-rtic/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" rtic = { version = "2", features = ["thumbv7-backend"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", "generic-queue"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = [ "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } @@ -18,7 +18,6 @@ defmt-rtt = "0.4" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } [profile.release] debug = 2 diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 4ab5c7b7c..79d9e4e1a 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -6,12 +6,12 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } embedded-io = { version = "0.6.0", features = ["defmt-03"] } embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } @@ -25,7 +25,6 @@ static_cell = { version = "2" } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } rand = { version = "0.8.4", default-features = false } embedded-storage = "0.3.1" usbd-hid = "0.7.0" diff --git a/examples/nrf52840/src/bin/gpiote_channel.rs b/examples/nrf52840/src/bin/gpiote_channel.rs index e254d613d..dcfe7723a 100644 --- a/examples/nrf52840/src/bin/gpiote_channel.rs +++ b/examples/nrf52840/src/bin/gpiote_channel.rs @@ -61,5 +61,5 @@ async fn main(_spawner: Spawner) { } }; - futures::join!(button1, button2, button3, button4); + embassy_futures::join::join4(button1, button2, button3, button4).await; } diff --git a/examples/nrf52840/src/bin/usb_hid_keyboard.rs b/examples/nrf52840/src/bin/usb_hid_keyboard.rs index 52f081487..e33ee5866 100644 --- a/examples/nrf52840/src/bin/usb_hid_keyboard.rs +++ b/examples/nrf52840/src/bin/usb_hid_keyboard.rs @@ -54,7 +54,7 @@ async fn main(_spawner: Spawner) { let mut bos_descriptor = [0; 256]; let mut msos_descriptor = [0; 256]; let mut control_buf = [0; 64]; - let request_handler = MyRequestHandler {}; + let mut request_handler = MyRequestHandler {}; let mut device_handler = MyDeviceHandler::new(); let mut state = State::new(); @@ -73,7 +73,7 @@ async fn main(_spawner: Spawner) { // Create classes on the builder. let config = embassy_usb::class::hid::Config { report_descriptor: KeyboardReport::desc(), - request_handler: Some(&request_handler), + request_handler: None, poll_ms: 60, max_packet_size: 64, }; @@ -137,7 +137,7 @@ async fn main(_spawner: Spawner) { }; let out_fut = async { - reader.run(false, &request_handler).await; + reader.run(false, &mut request_handler).await; }; // Run everything concurrently. @@ -148,21 +148,21 @@ async fn main(_spawner: Spawner) { struct MyRequestHandler {} impl RequestHandler for MyRequestHandler { - fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { + fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { info!("Get report for {:?}", id); None } - fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { + fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { info!("Set report for {:?}: {=[u8]}", id, data); OutResponse::Accepted } - fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { + fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { info!("Set idle rate for {:?} to {:?}", id, dur); } - fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { + fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { info!("Get idle rate for {:?}", id); None } diff --git a/examples/nrf52840/src/bin/usb_hid_mouse.rs b/examples/nrf52840/src/bin/usb_hid_mouse.rs index 5d2837793..8076ac283 100644 --- a/examples/nrf52840/src/bin/usb_hid_mouse.rs +++ b/examples/nrf52840/src/bin/usb_hid_mouse.rs @@ -47,7 +47,7 @@ async fn main(_spawner: Spawner) { let mut bos_descriptor = [0; 256]; let mut msos_descriptor = [0; 256]; let mut control_buf = [0; 64]; - let request_handler = MyRequestHandler {}; + let mut request_handler = MyRequestHandler {}; let mut state = State::new(); @@ -63,7 +63,7 @@ async fn main(_spawner: Spawner) { // Create classes on the builder. let config = embassy_usb::class::hid::Config { report_descriptor: MouseReport::desc(), - request_handler: Some(&request_handler), + request_handler: Some(&mut request_handler), poll_ms: 60, max_packet_size: 8, }; @@ -105,21 +105,21 @@ async fn main(_spawner: Spawner) { struct MyRequestHandler {} impl RequestHandler for MyRequestHandler { - fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { + fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { info!("Get report for {:?}", id); None } - fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { + fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { info!("Set report for {:?}: {=[u8]}", id, data); OutResponse::Accepted } - fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { + fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { info!("Set idle rate for {:?} to {:?}", id, dur); } - fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { + fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { info!("Get idle rate for {:?}", id); None } diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 24aa560d5..e560a3dbb 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -6,12 +6,12 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf5340-app-s", "time-driver-rtc1", "gpiote", "unstable-pac"] } embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } embedded-io-async = { version = "0.6.1" } defmt = "0.3" @@ -21,7 +21,6 @@ static_cell = "2" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } rand = { version = "0.8.4", default-features = false } embedded-storage = "0.3.1" usbd-hid = "0.7.0" diff --git a/examples/nrf5340/src/bin/gpiote_channel.rs b/examples/nrf5340/src/bin/gpiote_channel.rs index c0a55142f..23f6fca98 100644 --- a/examples/nrf5340/src/bin/gpiote_channel.rs +++ b/examples/nrf5340/src/bin/gpiote_channel.rs @@ -61,5 +61,5 @@ async fn main(_spawner: Spawner) { } }; - futures::join!(button1, button2, button3, button4); + embassy_futures::join::join4(button1, button2, button3, button4).await; } diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 0f58f143c..726df29cb 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -7,15 +7,15 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal", features = ["defmt"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "raw", "dhcpv4", "medium-ethernet"] } embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger" } +embassy-usb-logger = { version = "0.2.0", path = "../../embassy-usb-logger" } cyw43 = { version = "0.1.0", path = "../../cyw43", features = ["defmt", "firmware-logs"] } cyw43-pio = { version = "0.1.0", path = "../../cyw43-pio", features = ["defmt", "overclock"] } @@ -27,8 +27,8 @@ fixed-macro = "1.2" #cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m = { version = "0.7.6", features = ["inline-asm"] } cortex-m-rt = "0.7.0" +critical-section = "1.1" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await", "cfg-target-has-atomic", "unstable"] } display-interface-spi = "0.4.1" embedded-graphics = "0.7.1" st7789 = "0.6.1" @@ -49,6 +49,7 @@ log = "0.4" pio-proc = "0.2" pio = "0.2.1" rand = { version = "0.8.5", default-features = false } +embedded-sdmmc = "0.7.0" [profile.release] debug = 2 diff --git a/examples/rp/src/bin/interrupt.rs b/examples/rp/src/bin/interrupt.rs new file mode 100644 index 000000000..5b9d7027e --- /dev/null +++ b/examples/rp/src/bin/interrupt.rs @@ -0,0 +1,94 @@ +//! This example shows how you can use raw interrupt handlers alongside embassy. +//! The example also showcases some of the options available for sharing resources/data. +//! +//! In the example, an ADC reading is triggered every time the PWM wraps around. +//! The sample data is sent down a channel, to be processed inside a low priority task. +//! The processed data is then used to adjust the PWM duty cycle, once every second. + +#![no_std] +#![no_main] + +use core::cell::{Cell, RefCell}; + +use defmt::*; +use embassy_executor::Spawner; +use embassy_rp::adc::{self, Adc, Blocking}; +use embassy_rp::gpio::Pull; +use embassy_rp::interrupt; +use embassy_rp::pwm::{Config, Pwm}; +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_sync::blocking_mutex::Mutex; +use embassy_sync::channel::Channel; +use embassy_time::{Duration, Ticker}; +use portable_atomic::{AtomicU32, Ordering}; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +static COUNTER: AtomicU32 = AtomicU32::new(0); +static PWM: Mutex<CriticalSectionRawMutex, RefCell<Option<Pwm>>> = Mutex::new(RefCell::new(None)); +static ADC: Mutex<CriticalSectionRawMutex, RefCell<Option<(Adc<Blocking>, adc::Channel)>>> = + Mutex::new(RefCell::new(None)); +static ADC_VALUES: Channel<CriticalSectionRawMutex, u16, 2048> = Channel::new(); + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + embassy_rp::pac::SIO.spinlock(31).write_value(1); + let p = embassy_rp::init(Default::default()); + + let adc = Adc::new_blocking(p.ADC, Default::default()); + let p26 = adc::Channel::new_pin(p.PIN_26, Pull::None); + ADC.lock(|a| a.borrow_mut().replace((adc, p26))); + + let pwm = Pwm::new_output_b(p.PWM_SLICE4, p.PIN_25, Default::default()); + PWM.lock(|p| p.borrow_mut().replace(pwm)); + + // Enable the interrupt for pwm slice 4 + embassy_rp::pac::PWM.inte().modify(|w| w.set_ch4(true)); + unsafe { + cortex_m::peripheral::NVIC::unmask(interrupt::PWM_IRQ_WRAP); + } + + // Tasks require their resources to have 'static lifetime + // No Mutex needed when sharing within the same executor/prio level + static AVG: StaticCell<Cell<u32>> = StaticCell::new(); + let avg = AVG.init(Default::default()); + spawner.must_spawn(processing(avg)); + + let mut ticker = Ticker::every(Duration::from_secs(1)); + loop { + ticker.next().await; + let freq = COUNTER.swap(0, Ordering::Relaxed); + info!("pwm freq: {:?} Hz", freq); + info!("adc average: {:?}", avg.get()); + + // Update the pwm duty cycle, based on the averaged adc reading + let mut config = Config::default(); + config.compare_b = ((avg.get() as f32 / 4095.0) * config.top as f32) as _; + PWM.lock(|p| p.borrow_mut().as_mut().unwrap().set_config(&config)); + } +} + +#[embassy_executor::task] +async fn processing(avg: &'static Cell<u32>) { + let mut buffer: heapless::HistoryBuffer<u16, 100> = Default::default(); + loop { + let val = ADC_VALUES.receive().await; + buffer.write(val); + let sum: u32 = buffer.iter().map(|x| *x as u32).sum(); + avg.set(sum / buffer.len() as u32); + } +} + +#[interrupt] +fn PWM_IRQ_WRAP() { + critical_section::with(|cs| { + let mut adc = ADC.borrow(cs).borrow_mut(); + let (adc, p26) = adc.as_mut().unwrap(); + let val = adc.blocking_read(p26).unwrap(); + ADC_VALUES.try_send(val).ok(); + + // Clear the interrupt, so we don't immediately re-enter this irq handler + PWM.borrow(cs).borrow_mut().as_mut().unwrap().clear_wrapped(); + }); + COUNTER.fetch_add(1, Ordering::Relaxed); +} diff --git a/examples/rp/src/bin/pio_pwm.rs b/examples/rp/src/bin/pio_pwm.rs new file mode 100644 index 000000000..23d63d435 --- /dev/null +++ b/examples/rp/src/bin/pio_pwm.rs @@ -0,0 +1,118 @@ +//! This example shows how to create a pwm using the PIO module in the RP2040 chip. + +#![no_std] +#![no_main] +use core::time::Duration; + +use embassy_executor::Spawner; +use embassy_rp::gpio::Level; +use embassy_rp::peripherals::PIO0; +use embassy_rp::pio::{Common, Config, Direction, Instance, InterruptHandler, Pio, PioPin, StateMachine}; +use embassy_rp::{bind_interrupts, clocks}; +use embassy_time::Timer; +use pio::InstructionOperands; +use {defmt_rtt as _, panic_probe as _}; + +const REFRESH_INTERVAL: u64 = 20000; + +bind_interrupts!(struct Irqs { + PIO0_IRQ_0 => InterruptHandler<PIO0>; +}); + +pub fn to_pio_cycles(duration: Duration) -> u32 { + (clocks::clk_sys_freq() / 1_000_000) / 3 * duration.as_micros() as u32 // parentheses are required to prevent overflow +} + +pub struct PwmPio<'d, T: Instance, const SM: usize> { + sm: StateMachine<'d, T, SM>, +} + +impl<'d, T: Instance, const SM: usize> PwmPio<'d, T, SM> { + pub fn new(pio: &mut Common<'d, T>, mut sm: StateMachine<'d, T, SM>, pin: impl PioPin) -> Self { + let prg = pio_proc::pio_asm!( + ".side_set 1 opt" + "pull noblock side 0" + "mov x, osr" + "mov y, isr" + "countloop:" + "jmp x!=y noset" + "jmp skip side 1" + "noset:" + "nop" + "skip:" + "jmp y-- countloop" + ); + + pio.load_program(&prg.program); + let pin = pio.make_pio_pin(pin); + sm.set_pins(Level::High, &[&pin]); + sm.set_pin_dirs(Direction::Out, &[&pin]); + + let mut cfg = Config::default(); + cfg.use_program(&pio.load_program(&prg.program), &[&pin]); + + sm.set_config(&cfg); + + Self { sm } + } + + pub fn start(&mut self) { + self.sm.set_enable(true); + } + + pub fn stop(&mut self) { + self.sm.set_enable(false); + } + + pub fn set_period(&mut self, duration: Duration) { + let is_enabled = self.sm.is_enabled(); + while !self.sm.tx().empty() {} // Make sure that the queue is empty + self.sm.set_enable(false); + self.sm.tx().push(to_pio_cycles(duration)); + unsafe { + self.sm.exec_instr( + InstructionOperands::PULL { + if_empty: false, + block: false, + } + .encode(), + ); + self.sm.exec_instr( + InstructionOperands::OUT { + destination: ::pio::OutDestination::ISR, + bit_count: 32, + } + .encode(), + ); + }; + if is_enabled { + self.sm.set_enable(true) // Enable if previously enabled + } + } + + pub fn set_level(&mut self, level: u32) { + self.sm.tx().push(level); + } + + pub fn write(&mut self, duration: Duration) { + self.set_level(to_pio_cycles(duration)); + } +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_rp::init(Default::default()); + let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs); + + // Note that PIN_25 is the led pin on the Pico + let mut pwm_pio = PwmPio::new(&mut common, sm0, p.PIN_25); + pwm_pio.set_period(Duration::from_micros(REFRESH_INTERVAL)); + pwm_pio.start(); + + let mut duration = 0; + loop { + duration = (duration + 1) % 1000; + pwm_pio.write(Duration::from_micros(duration)); + Timer::after_millis(1).await; + } +} diff --git a/examples/rp/src/bin/pio_servo.rs b/examples/rp/src/bin/pio_servo.rs new file mode 100644 index 000000000..a79540479 --- /dev/null +++ b/examples/rp/src/bin/pio_servo.rs @@ -0,0 +1,208 @@ +//! This example shows how to create a pwm using the PIO module in the RP2040 chip. + +#![no_std] +#![no_main] +use core::time::Duration; + +use embassy_executor::Spawner; +use embassy_rp::gpio::Level; +use embassy_rp::peripherals::PIO0; +use embassy_rp::pio::{Common, Config, Direction, Instance, InterruptHandler, Pio, PioPin, StateMachine}; +use embassy_rp::{bind_interrupts, clocks}; +use embassy_time::Timer; +use pio::InstructionOperands; +use {defmt_rtt as _, panic_probe as _}; + +const DEFAULT_MIN_PULSE_WIDTH: u64 = 1000; // uncalibrated default, the shortest duty cycle sent to a servo +const DEFAULT_MAX_PULSE_WIDTH: u64 = 2000; // uncalibrated default, the longest duty cycle sent to a servo +const DEFAULT_MAX_DEGREE_ROTATION: u64 = 160; // 160 degrees is typical +const REFRESH_INTERVAL: u64 = 20000; // The period of each cycle + +bind_interrupts!(struct Irqs { + PIO0_IRQ_0 => InterruptHandler<PIO0>; +}); + +pub fn to_pio_cycles(duration: Duration) -> u32 { + (clocks::clk_sys_freq() / 1_000_000) / 3 * duration.as_micros() as u32 // parentheses are required to prevent overflow +} + +pub struct PwmPio<'d, T: Instance, const SM: usize> { + sm: StateMachine<'d, T, SM>, +} + +impl<'d, T: Instance, const SM: usize> PwmPio<'d, T, SM> { + pub fn new(pio: &mut Common<'d, T>, mut sm: StateMachine<'d, T, SM>, pin: impl PioPin) -> Self { + let prg = pio_proc::pio_asm!( + ".side_set 1 opt" + "pull noblock side 0" + "mov x, osr" + "mov y, isr" + "countloop:" + "jmp x!=y noset" + "jmp skip side 1" + "noset:" + "nop" + "skip:" + "jmp y-- countloop" + ); + + pio.load_program(&prg.program); + let pin = pio.make_pio_pin(pin); + sm.set_pins(Level::High, &[&pin]); + sm.set_pin_dirs(Direction::Out, &[&pin]); + + let mut cfg = Config::default(); + cfg.use_program(&pio.load_program(&prg.program), &[&pin]); + + sm.set_config(&cfg); + + Self { sm } + } + + pub fn start(&mut self) { + self.sm.set_enable(true); + } + + pub fn stop(&mut self) { + self.sm.set_enable(false); + } + + pub fn set_period(&mut self, duration: Duration) { + let is_enabled = self.sm.is_enabled(); + while !self.sm.tx().empty() {} // Make sure that the queue is empty + self.sm.set_enable(false); + self.sm.tx().push(to_pio_cycles(duration)); + unsafe { + self.sm.exec_instr( + InstructionOperands::PULL { + if_empty: false, + block: false, + } + .encode(), + ); + self.sm.exec_instr( + InstructionOperands::OUT { + destination: ::pio::OutDestination::ISR, + bit_count: 32, + } + .encode(), + ); + }; + if is_enabled { + self.sm.set_enable(true) // Enable if previously enabled + } + } + + pub fn set_level(&mut self, level: u32) { + self.sm.tx().push(level); + } + + pub fn write(&mut self, duration: Duration) { + self.set_level(to_pio_cycles(duration)); + } +} + +pub struct ServoBuilder<'d, T: Instance, const SM: usize> { + pwm: PwmPio<'d, T, SM>, + period: Duration, + min_pulse_width: Duration, + max_pulse_width: Duration, + max_degree_rotation: u64, +} + +impl<'d, T: Instance, const SM: usize> ServoBuilder<'d, T, SM> { + pub fn new(pwm: PwmPio<'d, T, SM>) -> Self { + Self { + pwm, + period: Duration::from_micros(REFRESH_INTERVAL), + min_pulse_width: Duration::from_micros(DEFAULT_MIN_PULSE_WIDTH), + max_pulse_width: Duration::from_micros(DEFAULT_MAX_PULSE_WIDTH), + max_degree_rotation: DEFAULT_MAX_DEGREE_ROTATION, + } + } + + pub fn set_period(mut self, duration: Duration) -> Self { + self.period = duration; + self + } + + pub fn set_min_pulse_width(mut self, duration: Duration) -> Self { + self.min_pulse_width = duration; + self + } + + pub fn set_max_pulse_width(mut self, duration: Duration) -> Self { + self.max_pulse_width = duration; + self + } + + pub fn set_max_degree_rotation(mut self, degree: u64) -> Self { + self.max_degree_rotation = degree; + self + } + + pub fn build(mut self) -> Servo<'d, T, SM> { + self.pwm.set_period(self.period); + Servo { + pwm: self.pwm, + min_pulse_width: self.min_pulse_width, + max_pulse_width: self.max_pulse_width, + max_degree_rotation: self.max_degree_rotation, + } + } +} + +pub struct Servo<'d, T: Instance, const SM: usize> { + pwm: PwmPio<'d, T, SM>, + min_pulse_width: Duration, + max_pulse_width: Duration, + max_degree_rotation: u64, +} + +impl<'d, T: Instance, const SM: usize> Servo<'d, T, SM> { + pub fn start(&mut self) { + self.pwm.start(); + } + + pub fn stop(&mut self) { + self.pwm.stop(); + } + + pub fn write_time(&mut self, duration: Duration) { + self.pwm.write(duration); + } + + pub fn rotate(&mut self, degree: u64) { + let degree_per_nano_second = (self.max_pulse_width.as_nanos() as u64 - self.min_pulse_width.as_nanos() as u64) + / self.max_degree_rotation; + let mut duration = + Duration::from_nanos(degree * degree_per_nano_second + self.min_pulse_width.as_nanos() as u64); + if self.max_pulse_width < duration { + duration = self.max_pulse_width; + } + + self.pwm.write(duration); + } +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_rp::init(Default::default()); + let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs); + + let pwm_pio = PwmPio::new(&mut common, sm0, p.PIN_1); + let mut servo = ServoBuilder::new(pwm_pio) + .set_max_degree_rotation(120) // Example of adjusting values for MG996R servo + .set_min_pulse_width(Duration::from_micros(350)) // This value was detemined by a rough experiment. + .set_max_pulse_width(Duration::from_micros(2600)) // Along with this value. + .build(); + + servo.start(); + + let mut degree = 0; + loop { + degree = (degree + 1) % 120; + servo.rotate(degree); + Timer::after_millis(50).await; + } +} diff --git a/examples/rp/src/bin/spi_sdmmc.rs b/examples/rp/src/bin/spi_sdmmc.rs new file mode 100644 index 000000000..4cbc82f7b --- /dev/null +++ b/examples/rp/src/bin/spi_sdmmc.rs @@ -0,0 +1,83 @@ +//! This example shows how to use `embedded-sdmmc` with the RP2040 chip, over SPI. +//! +//! The example will attempt to read a file `MY_FILE.TXT` from the root directory +//! of the SD card and print its contents. + +#![no_std] +#![no_main] + +use defmt::*; +use embassy_embedded_hal::SetConfig; +use embassy_executor::Spawner; +use embassy_rp::spi::Spi; +use embassy_rp::{gpio, spi}; +use embedded_hal_bus::spi::ExclusiveDevice; +use embedded_sdmmc::sdcard::{DummyCsPin, SdCard}; +use gpio::{Level, Output}; +use {defmt_rtt as _, panic_probe as _}; + +struct DummyTimesource(); + +impl embedded_sdmmc::TimeSource for DummyTimesource { + fn get_timestamp(&self) -> embedded_sdmmc::Timestamp { + embedded_sdmmc::Timestamp { + year_since_1970: 0, + zero_indexed_month: 0, + zero_indexed_day: 0, + hours: 0, + minutes: 0, + seconds: 0, + } + } +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + embassy_rp::pac::SIO.spinlock(31).write_value(1); + let p = embassy_rp::init(Default::default()); + + // SPI clock needs to be running at <= 400kHz during initialization + let mut config = spi::Config::default(); + config.frequency = 400_000; + let spi = Spi::new_blocking(p.SPI1, p.PIN_10, p.PIN_11, p.PIN_12, config); + // Use a dummy cs pin here, for embedded-hal SpiDevice compatibility reasons + let spi_dev = ExclusiveDevice::new_no_delay(spi, DummyCsPin); + // Real cs pin + let cs = Output::new(p.PIN_16, Level::High); + + let sdcard = SdCard::new(spi_dev, cs, embassy_time::Delay); + info!("Card size is {} bytes", sdcard.num_bytes().unwrap()); + + // Now that the card is initialized, the SPI clock can go faster + let mut config = spi::Config::default(); + config.frequency = 16_000_000; + sdcard.spi(|dev| dev.bus_mut().set_config(&config)).ok(); + + // Now let's look for volumes (also known as partitions) on our block device. + // To do this we need a Volume Manager. It will take ownership of the block device. + let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, DummyTimesource()); + + // Try and access Volume 0 (i.e. the first partition). + // The volume object holds information about the filesystem on that volume. + let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0)).unwrap(); + info!("Volume 0: {:?}", defmt::Debug2Format(&volume0)); + + // Open the root directory (mutably borrows from the volume). + let mut root_dir = volume0.open_root_dir().unwrap(); + + // Open a file called "MY_FILE.TXT" in the root directory + // This mutably borrows the directory. + let mut my_file = root_dir + .open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly) + .unwrap(); + + // Print the contents of the file + while !my_file.is_eof() { + let mut buf = [0u8; 32]; + if let Ok(n) = my_file.read(&mut buf) { + info!("{:a}", buf[..n]); + } + } + + loop {} +} diff --git a/examples/rp/src/bin/uart_r503.rs b/examples/rp/src/bin/uart_r503.rs new file mode 100644 index 000000000..085be280b --- /dev/null +++ b/examples/rp/src/bin/uart_r503.rs @@ -0,0 +1,158 @@ +#![no_std] +#![no_main] + +use defmt::{debug, error, info}; +use embassy_executor::Spawner; +use embassy_rp::bind_interrupts; +use embassy_rp::peripherals::UART0; +use embassy_rp::uart::{Config, DataBits, InterruptHandler as UARTInterruptHandler, Parity, StopBits, Uart}; +use embassy_time::{with_timeout, Duration, Timer}; +use heapless::Vec; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(pub struct Irqs { + UART0_IRQ => UARTInterruptHandler<UART0>; +}); + +const START: u16 = 0xEF01; +const ADDRESS: u32 = 0xFFFFFFFF; + +// ================================================================================ + +// Data package format +// Name Length Description +// ========================================================================================================== +// Start 2 bytes Fixed value of 0xEF01; High byte transferred first. +// Address 4 bytes Default value is 0xFFFFFFFF, which can be modified by command. +// High byte transferred first and at wrong adder value, module +// will reject to transfer. +// PID 1 byte 01H Command packet; +// 02H Data packet; Data packet shall not appear alone in executing +// processs, must follow command packet or acknowledge packet. +// 07H Acknowledge packet; +// 08H End of Data packet. +// LENGTH 2 bytes Refers to the length of package content (command packets and data packets) +// plus the length of Checksum (2 bytes). Unit is byte. Max length is 256 bytes. +// And high byte is transferred first. +// DATA - It can be commands, data, command’s parameters, acknowledge result, etc. +// (fingerprint character value, template are all deemed as data); +// SUM 2 bytes The arithmetic sum of package identifier, package length and all package +// contens. Overflowing bits are omitted. high byte is transferred first. + +// ================================================================================ + +// Checksum is calculated on 'length (2 bytes) + data (??)'. +fn compute_checksum(buf: Vec<u8, 32>) -> u16 { + let mut checksum = 0u16; + + let check_end = buf.len(); + let checked_bytes = &buf[6..check_end]; + for byte in checked_bytes { + checksum += (*byte) as u16; + } + return checksum; +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("Start"); + + let p = embassy_rp::init(Default::default()); + + // Initialize the fingerprint scanner. + let mut config = Config::default(); + config.baudrate = 57600; + config.stop_bits = StopBits::STOP1; + config.data_bits = DataBits::DataBits8; + config.parity = Parity::ParityNone; + + let (uart, tx_pin, tx_dma, rx_pin, rx_dma) = (p.UART0, p.PIN_16, p.DMA_CH0, p.PIN_17, p.DMA_CH1); + let uart = Uart::new(uart, tx_pin, rx_pin, Irqs, tx_dma, rx_dma, config); + let (mut tx, mut rx) = uart.split(); + + let mut vec_buf: Vec<u8, 32> = heapless::Vec::new(); + let mut data: Vec<u8, 32> = heapless::Vec::new(); + + let mut speeds: Vec<u8, 3> = heapless::Vec::new(); + let _ = speeds.push(0xC8); // Slow + let _ = speeds.push(0x20); // Medium + let _ = speeds.push(0x02); // Fast + + // Cycle through the three colours Red, Blue and Purple forever. + loop { + for colour in 1..=3 { + for speed in &speeds { + // Set the data first, because the length is dependent on that. + // However, we write the length bits before we do the data. + data.clear(); + let _ = data.push(0x01); // ctrl=Breathing light + let _ = data.push(*speed); + let _ = data.push(colour as u8); // colour=Red, Blue, Purple + let _ = data.push(0x00); // times=Infinite + + // Clear buffers + vec_buf.clear(); + + // START + let _ = vec_buf.extend_from_slice(&START.to_be_bytes()[..]); + + // ADDRESS + let _ = vec_buf.extend_from_slice(&ADDRESS.to_be_bytes()[..]); + + // PID + let _ = vec_buf.extend_from_slice(&[0x01]); + + // LENGTH + let len: u16 = (1 + data.len() + 2).try_into().unwrap(); + let _ = vec_buf.extend_from_slice(&len.to_be_bytes()[..]); + + // COMMAND + let _ = vec_buf.push(0x35); // Command: AuraLedConfig + + // DATA + let _ = vec_buf.extend_from_slice(&data); + + // SUM + let chk = compute_checksum(vec_buf.clone()); + let _ = vec_buf.extend_from_slice(&chk.to_be_bytes()[..]); + + // ===== + + // Send command buffer. + let data_write: [u8; 16] = vec_buf.clone().into_array().unwrap(); + debug!(" write='{:?}'", data_write[..]); + match tx.write(&data_write).await { + Ok(..) => info!("Write successful."), + Err(e) => error!("Write error: {:?}", e), + } + + // ===== + + // Read command buffer. + let mut read_buf: [u8; 1] = [0; 1]; // Can only read one byte at a time! + let mut data_read: Vec<u8, 32> = heapless::Vec::new(); // Save buffer. + + info!("Attempting read."); + loop { + // Some commands, like `Img2Tz()` needs longer, but we hard-code this to 200ms + // for this command. + match with_timeout(Duration::from_millis(200), rx.read(&mut read_buf)).await { + Ok(..) => { + // Extract and save read byte. + debug!(" r='{=u8:#04x}H' ({:03}D)", read_buf[0], read_buf[0]); + let _ = data_read.push(read_buf[0]).unwrap(); + } + Err(..) => break, // TimeoutError -> Ignore. + } + } + info!("Read successful"); + debug!(" read='{:?}'", data_read[..]); + + Timer::after_secs(3).await; + info!("Changing speed."); + } + + info!("Changing colour."); + } + } +} diff --git a/examples/rp/src/bin/usb_hid_keyboard.rs b/examples/rp/src/bin/usb_hid_keyboard.rs index 710be8d13..a7cb322d8 100644 --- a/examples/rp/src/bin/usb_hid_keyboard.rs +++ b/examples/rp/src/bin/usb_hid_keyboard.rs @@ -41,7 +41,7 @@ async fn main(_spawner: Spawner) { // You can also add a Microsoft OS descriptor. let mut msos_descriptor = [0; 256]; let mut control_buf = [0; 64]; - let request_handler = MyRequestHandler {}; + let mut request_handler = MyRequestHandler {}; let mut device_handler = MyDeviceHandler::new(); let mut state = State::new(); @@ -60,7 +60,7 @@ async fn main(_spawner: Spawner) { // Create classes on the builder. let config = embassy_usb::class::hid::Config { report_descriptor: KeyboardReport::desc(), - request_handler: Some(&request_handler), + request_handler: None, poll_ms: 60, max_packet_size: 64, }; @@ -114,7 +114,7 @@ async fn main(_spawner: Spawner) { }; let out_fut = async { - reader.run(false, &request_handler).await; + reader.run(false, &mut request_handler).await; }; // Run everything concurrently. @@ -125,21 +125,21 @@ async fn main(_spawner: Spawner) { struct MyRequestHandler {} impl RequestHandler for MyRequestHandler { - fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { + fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { info!("Get report for {:?}", id); None } - fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { + fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { info!("Set report for {:?}: {=[u8]}", id, data); OutResponse::Accepted } - fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { + fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { info!("Set idle rate for {:?} to {:?}", id, dur); } - fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { + fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { info!("Get idle rate for {:?}", id); None } diff --git a/examples/rp/src/bin/usb_hid_mouse.rs b/examples/rp/src/bin/usb_hid_mouse.rs index e8b399cb1..cce344fb0 100644 --- a/examples/rp/src/bin/usb_hid_mouse.rs +++ b/examples/rp/src/bin/usb_hid_mouse.rs @@ -44,7 +44,7 @@ async fn main(_spawner: Spawner) { // You can also add a Microsoft OS descriptor. let mut msos_descriptor = [0; 256]; let mut control_buf = [0; 64]; - let request_handler = MyRequestHandler {}; + let mut request_handler = MyRequestHandler {}; let mut device_handler = MyDeviceHandler::new(); let mut state = State::new(); @@ -63,7 +63,7 @@ async fn main(_spawner: Spawner) { // Create classes on the builder. let config = embassy_usb::class::hid::Config { report_descriptor: MouseReport::desc(), - request_handler: Some(&request_handler), + request_handler: None, poll_ms: 60, max_packet_size: 64, }; @@ -106,7 +106,7 @@ async fn main(_spawner: Spawner) { }; let out_fut = async { - reader.run(false, &request_handler).await; + reader.run(false, &mut request_handler).await; }; // Run everything concurrently. @@ -117,21 +117,21 @@ async fn main(_spawner: Spawner) { struct MyRequestHandler {} impl RequestHandler for MyRequestHandler { - fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { + fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { info!("Get report for {:?}", id); None } - fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { + fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { info!("Set report for {:?}: {=[u8]}", id, data); OutResponse::Accepted } - fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { + fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { info!("Set idle rate for {:?} to {:?}", id, dur); } - fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { + fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { info!("Get idle rate for {:?}", id); None } diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs index 3c9bc96dd..4a802994a 100644 --- a/examples/rp/src/bin/usb_serial.rs +++ b/examples/rp/src/bin/usb_serial.rs @@ -5,15 +5,15 @@ #![no_std] #![no_main] -use defmt::{info, panic}; +use defmt::{info, panic, unwrap}; use embassy_executor::Spawner; -use embassy_futures::join::join; use embassy_rp::bind_interrupts; use embassy_rp::peripherals::USB; use embassy_rp::usb::{Driver, Instance, InterruptHandler}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; -use embassy_usb::{Builder, Config}; +use embassy_usb::UsbDevice; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -21,7 +21,7 @@ bind_interrupts!(struct Irqs { }); #[embassy_executor::main] -async fn main(_spawner: Spawner) { +async fn main(spawner: Spawner) { info!("Hello there!"); let p = embassy_rp::init(Default::default()); @@ -30,59 +30,69 @@ async fn main(_spawner: Spawner) { let driver = Driver::new(p.USB, Irqs); // Create embassy-usb Config - let mut config = Config::new(0xc0de, 0xcafe); - config.manufacturer = Some("Embassy"); - config.product = Some("USB-serial example"); - config.serial_number = Some("12345678"); - config.max_power = 100; - config.max_packet_size_0 = 64; + let config = { + let mut config = embassy_usb::Config::new(0xc0de, 0xcafe); + config.manufacturer = Some("Embassy"); + config.product = Some("USB-serial example"); + config.serial_number = Some("12345678"); + config.max_power = 100; + config.max_packet_size_0 = 64; - // Required for windows compatibility. - // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help - config.device_class = 0xEF; - config.device_sub_class = 0x02; - config.device_protocol = 0x01; - config.composite_with_iads = true; + // Required for windows compatibility. + // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help + config.device_class = 0xEF; + config.device_sub_class = 0x02; + config.device_protocol = 0x01; + config.composite_with_iads = true; + config + }; // Create embassy-usb DeviceBuilder using the driver and config. // It needs some buffers for building the descriptors. - let mut config_descriptor = [0; 256]; - let mut bos_descriptor = [0; 256]; - let mut control_buf = [0; 64]; + let mut builder = { + static CONFIG_DESCRIPTOR: StaticCell<[u8; 256]> = StaticCell::new(); + static BOS_DESCRIPTOR: StaticCell<[u8; 256]> = StaticCell::new(); + static CONTROL_BUF: StaticCell<[u8; 64]> = StaticCell::new(); - let mut state = State::new(); - - let mut builder = Builder::new( - driver, - config, - &mut config_descriptor, - &mut bos_descriptor, - &mut [], // no msos descriptors - &mut control_buf, - ); - - // Create classes on the builder. - let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); - - // Build the builder. - let mut usb = builder.build(); - - // Run the USB device. - let usb_fut = usb.run(); - - // Do stuff with the class! - let echo_fut = async { - loop { - class.wait_connection().await; - info!("Connected"); - let _ = echo(&mut class).await; - info!("Disconnected"); - } + let builder = embassy_usb::Builder::new( + driver, + config, + CONFIG_DESCRIPTOR.init([0; 256]), + BOS_DESCRIPTOR.init([0; 256]), + &mut [], // no msos descriptors + CONTROL_BUF.init([0; 64]), + ); + builder }; - // Run everything concurrently. - // If we had made everything `'static` above instead, we could do this using separate tasks instead. - join(usb_fut, echo_fut).await; + // Create classes on the builder. + let mut class = { + static STATE: StaticCell<State> = StaticCell::new(); + let state = STATE.init(State::new()); + CdcAcmClass::new(&mut builder, state, 64) + }; + + // Build the builder. + let usb = builder.build(); + + // Run the USB device. + unwrap!(spawner.spawn(usb_task(usb))); + + // Do stuff with the class! + loop { + class.wait_connection().await; + info!("Connected"); + let _ = echo(&mut class).await; + info!("Disconnected"); + } +} + +type MyUsbDriver = Driver<'static, USB>; +type MyUsbDevice = UsbDevice<'static, MyUsbDriver>; + +#[embassy_executor::task] +async fn usb_task(mut usb: MyUsbDevice) -> ! { + usb.run().await } struct Disconnected {} diff --git a/examples/rp/src/bin/usb_webusb.rs b/examples/rp/src/bin/usb_webusb.rs new file mode 100644 index 000000000..e73938ac9 --- /dev/null +++ b/examples/rp/src/bin/usb_webusb.rs @@ -0,0 +1,155 @@ +//! This example shows how to use USB (Universal Serial Bus) in the RP2040 chip. +//! +//! This creates a WebUSB capable device that echoes data back to the host. +//! +//! To test this in the browser (ideally host this on localhost:8080, to test the landing page +//! feature): +//! ```js +//! (async () => { +//! const device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0xf569 }] }); +//! await device.open(); +//! await device.claimInterface(1); +//! device.transferIn(1, 64).then(data => console.log(data)); +//! await device.transferOut(1, new Uint8Array([1,2,3])); +//! })(); +//! ``` + +#![no_std] +#![no_main] + +use defmt::info; +use embassy_executor::Spawner; +use embassy_futures::join::join; +use embassy_rp::bind_interrupts; +use embassy_rp::peripherals::USB; +use embassy_rp::usb::{Driver as UsbDriver, InterruptHandler}; +use embassy_usb::class::web_usb::{Config as WebUsbConfig, State, Url, WebUsb}; +use embassy_usb::driver::{Driver, Endpoint, EndpointIn, EndpointOut}; +use embassy_usb::msos::{self, windows_version}; +use embassy_usb::{Builder, Config}; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + USBCTRL_IRQ => InterruptHandler<USB>; +}); + +// This is a randomly generated GUID to allow clients on Windows to find our device +const DEVICE_INTERFACE_GUIDS: &[&str] = &["{AFB9A6FB-30BA-44BC-9232-806CFC875321}"]; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_rp::init(Default::default()); + + // Create the driver, from the HAL. + let driver = UsbDriver::new(p.USB, Irqs); + + // Create embassy-usb Config + let mut config = Config::new(0xf569, 0x0001); + config.manufacturer = Some("Embassy"); + config.product = Some("WebUSB example"); + config.serial_number = Some("12345678"); + config.max_power = 100; + config.max_packet_size_0 = 64; + + // Required for windows compatibility. + // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help + config.device_class = 0xff; + config.device_sub_class = 0x00; + config.device_protocol = 0x00; + + // Create embassy-usb DeviceBuilder using the driver and config. + // It needs some buffers for building the descriptors. + let mut config_descriptor = [0; 256]; + let mut bos_descriptor = [0; 256]; + let mut control_buf = [0; 64]; + let mut msos_descriptor = [0; 256]; + + let webusb_config = WebUsbConfig { + max_packet_size: 64, + vendor_code: 1, + // If defined, shows a landing page which the device manufacturer would like the user to visit in order to control their device. Suggest the user to navigate to this URL when the device is connected. + landing_url: Some(Url::new("http://localhost:8080")), + }; + + let mut state = State::new(); + + let mut builder = Builder::new( + driver, + config, + &mut config_descriptor, + &mut bos_descriptor, + &mut msos_descriptor, + &mut control_buf, + ); + + // Add the Microsoft OS Descriptor (MSOS/MOD) descriptor. + // We tell Windows that this entire device is compatible with the "WINUSB" feature, + // which causes it to use the built-in WinUSB driver automatically, which in turn + // can be used by libusb/rusb software without needing a custom driver or INF file. + // In principle you might want to call msos_feature() just on a specific function, + // if your device also has other functions that still use standard class drivers. + builder.msos_descriptor(windows_version::WIN8_1, 0); + builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); + builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( + "DeviceInterfaceGUIDs", + msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), + )); + + // Create classes on the builder (WebUSB just needs some setup, but doesn't return anything) + WebUsb::configure(&mut builder, &mut state, &webusb_config); + // Create some USB bulk endpoints for testing. + let mut endpoints = WebEndpoints::new(&mut builder, &webusb_config); + + // Build the builder. + let mut usb = builder.build(); + + // Run the USB device. + let usb_fut = usb.run(); + + // Do some WebUSB transfers. + let webusb_fut = async { + loop { + endpoints.wait_connected().await; + info!("Connected"); + endpoints.echo().await; + } + }; + + // Run everything concurrently. + // If we had made everything `'static` above instead, we could do this using separate tasks instead. + join(usb_fut, webusb_fut).await; +} + +struct WebEndpoints<'d, D: Driver<'d>> { + write_ep: D::EndpointIn, + read_ep: D::EndpointOut, +} + +impl<'d, D: Driver<'d>> WebEndpoints<'d, D> { + fn new(builder: &mut Builder<'d, D>, config: &'d WebUsbConfig<'d>) -> Self { + let mut func = builder.function(0xff, 0x00, 0x00); + let mut iface = func.interface(); + let mut alt = iface.alt_setting(0xff, 0x00, 0x00, None); + + let write_ep = alt.endpoint_bulk_in(config.max_packet_size); + let read_ep = alt.endpoint_bulk_out(config.max_packet_size); + + WebEndpoints { write_ep, read_ep } + } + + // Wait until the device's endpoints are enabled. + async fn wait_connected(&mut self) { + self.read_ep.wait_enabled().await + } + + // Echo data back to the host. + async fn echo(&mut self) { + let mut buf = [0; 64]; + loop { + let n = self.read_ep.read(&mut buf).await.unwrap(); + let data = &buf[..n]; + info!("Data read: {:x}", data); + self.write_ep.write(data).await.unwrap(); + } + } +} diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index f05565e84..77c479d3b 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["log"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["log"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-std", "executor-thread", "log", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["log", "std", ] } embassy-net = { version = "0.4.0", path = "../../embassy-net", features=[ "std", "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index 7a3e03b75..6fdcdce5f 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32c031c6 to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } @@ -18,7 +18,6 @@ cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } [profile.release] diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index c74980dc4..5b648e58a 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml @@ -4,8 +4,6 @@ version = "0.1.0" edition = "2021" license = "MIT OR Apache-2.0" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] # Change stm32f091rc to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "memory-x", "stm32f091rc", "time-driver-any", "exti", "unstable-pac"] } @@ -14,7 +12,7 @@ cortex-m-rt = "0.7.0" defmt = "0.3" defmt-rtt = "0.4" panic-probe = { version = "0.3", features = ["print-defmt"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } static_cell = "2" diff --git a/examples/stm32f0/src/bin/adc.rs b/examples/stm32f0/src/bin/adc.rs index c2fb143cd..8825e2687 100644 --- a/examples/stm32f0/src/bin/adc.rs +++ b/examples/stm32f0/src/bin/adc.rs @@ -4,13 +4,13 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; -use embassy_stm32::peripherals::ADC; +use embassy_stm32::peripherals::ADC1; use embassy_stm32::{adc, bind_interrupts}; -use embassy_time::{Delay, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { - ADC1_COMP => adc::InterruptHandler<ADC>; + ADC1_COMP => adc::InterruptHandler<ADC1>; }); #[embassy_executor::main] @@ -18,11 +18,11 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut adc = Adc::new(p.ADC, Irqs, &mut Delay); + let mut adc = Adc::new(p.ADC1, Irqs); adc.set_sample_time(SampleTime::CYCLES71_5); let mut pin = p.PA1; - let mut vrefint = adc.enable_vref(&mut Delay); + let mut vrefint = adc.enable_vref(); let vrefint_sample = adc.read(&mut vrefint).await; let convert_to_millivolts = |sample| { // From https://www.st.com/resource/en/datasheet/stm32f031c6.pdf diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 4f282f326..51723ac6d 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml @@ -7,10 +7,10 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32f103c8 to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any" ] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" @@ -20,7 +20,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" static_cell = "2.0.0" diff --git a/examples/stm32f1/src/bin/adc.rs b/examples/stm32f1/src/bin/adc.rs index 1440460a9..541ff159e 100644 --- a/examples/stm32f1/src/bin/adc.rs +++ b/examples/stm32f1/src/bin/adc.rs @@ -6,7 +6,7 @@ use embassy_executor::Spawner; use embassy_stm32::adc::Adc; use embassy_stm32::peripherals::ADC1; use embassy_stm32::{adc, bind_interrupts}; -use embassy_time::{Delay, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut adc = Adc::new(p.ADC1, &mut Delay); + let mut adc = Adc::new(p.ADC1); let mut pin = p.PB1; - let mut vrefint = adc.enable_vref(&mut Delay); + let mut vrefint = adc.enable_vref(); let vrefint_sample = adc.read(&mut vrefint).await; let convert_to_millivolts = |sample| { // From http://www.st.com/resource/en/datasheet/CD00161566.pdf diff --git a/examples/stm32f1/src/bin/can.rs b/examples/stm32f1/src/bin/can.rs index 1c13d623d..ad0c8a5a5 100644 --- a/examples/stm32f1/src/bin/can.rs +++ b/examples/stm32f1/src/bin/can.rs @@ -85,7 +85,7 @@ async fn main(_spawner: Spawner) { defmt::println!("Error {}", err); } } - i += 1; + i = i.wrapping_add(1); } */ @@ -135,6 +135,6 @@ async fn main(_spawner: Spawner) { defmt::println!("Error {}", err); } } - i += 1; + i = i.wrapping_add(1); } } diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml index 4cbf1dc84..5d07b0e04 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32f207zg to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } @@ -18,7 +18,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 64bb2e560..848a6b331 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml @@ -7,10 +7,10 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32f303ze to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" @@ -20,7 +20,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" embedded-storage = "0.3.1" diff --git a/examples/stm32f3/src/bin/usart_dma.rs b/examples/stm32f3/src/bin/usart_dma.rs index 5234e53b9..573a49f19 100644 --- a/examples/stm32f3/src/bin/usart_dma.rs +++ b/examples/stm32f3/src/bin/usart_dma.rs @@ -5,7 +5,6 @@ use core::fmt::Write; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::{bind_interrupts, peripherals, usart}; use heapless::String; @@ -21,7 +20,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let config = Config::default(); - let mut usart = Uart::new(p.USART1, p.PE1, p.PE0, Irqs, p.DMA1_CH4, NoDma, config).unwrap(); + let mut usart = Uart::new(p.USART1, p.PE1, p.PE0, Irqs, p.DMA1_CH4, p.DMA1_CH5, config).unwrap(); for n in 0u32.. { let mut s: String<128> = String::new(); diff --git a/examples/stm32f334/.cargo/config.toml b/examples/stm32f334/.cargo/config.toml index caf947be6..f38c90a31 100644 --- a/examples/stm32f334/.cargo/config.toml +++ b/examples/stm32f334/.cargo/config.toml @@ -1,6 +1,6 @@ [target.'cfg(all(target_arch = "arm", target_os = "none"))'] # replace STM32F429ZITx with your chip as listed in `probe-rs-cli chip list` -runner = "probe-run --chip STM32F334R8" +runner = "probe-rs run --chip STM32F334R8" [build] target = "thumbv7em-none-eabihf" diff --git a/examples/stm32f334/Cargo.toml b/examples/stm32f334/Cargo.toml index 3e5a7cc8c..50046de56 100644 --- a/examples/stm32f334/Cargo.toml +++ b/examples/stm32f334/Cargo.toml @@ -5,11 +5,11 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" @@ -19,7 +19,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" embedded-storage = "0.3.1" diff --git a/examples/stm32f334/src/bin/adc.rs b/examples/stm32f334/src/bin/adc.rs index bd126ce68..0528a9637 100644 --- a/examples/stm32f334/src/bin/adc.rs +++ b/examples/stm32f334/src/bin/adc.rs @@ -7,7 +7,7 @@ use embassy_stm32::adc::{Adc, SampleTime}; use embassy_stm32::peripherals::ADC1; use embassy_stm32::time::mhz; use embassy_stm32::{adc, bind_interrupts, Config}; -use embassy_time::{Delay, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -38,13 +38,13 @@ async fn main(_spawner: Spawner) -> ! { info!("create adc..."); - let mut adc = Adc::new(p.ADC1, Irqs, &mut Delay); + let mut adc = Adc::new(p.ADC1, Irqs); adc.set_sample_time(SampleTime::CYCLES601_5); info!("enable vrefint..."); - let mut vrefint = adc.enable_vref(&mut Delay); + let mut vrefint = adc.enable_vref(); let mut temperature = adc.enable_temperature(); loop { diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs index a5c710aa2..2dbf1bdab 100644 --- a/examples/stm32f334/src/bin/opamp.rs +++ b/examples/stm32f334/src/bin/opamp.rs @@ -8,7 +8,7 @@ use embassy_stm32::opamp::{OpAmp, OpAmpGain}; use embassy_stm32::peripherals::ADC2; use embassy_stm32::time::mhz; use embassy_stm32::{adc, bind_interrupts, Config}; -use embassy_time::{Delay, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -39,14 +39,14 @@ async fn main(_spawner: Spawner) -> ! { info!("create adc..."); - let mut adc = Adc::new(p.ADC2, Irqs, &mut Delay); + let mut adc = Adc::new(p.ADC2, Irqs); let mut opamp = OpAmp::new(p.OPAMP2); adc.set_sample_time(SampleTime::CYCLES601_5); info!("enable vrefint..."); - let mut vrefint = adc.enable_vref(&mut Delay); + let mut vrefint = adc.enable_vref(); let mut temperature = adc.enable_temperature(); let mut buffer = opamp.buffer_ext(&mut p.PA7, &mut p.PA6, OpAmpGain::Mul1); diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 512158bef..52b7ce9e8 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -6,12 +6,13 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32f429zi to your chip name, if necessary. -embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt" ] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt" ] } embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } +embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" defmt-rtt = "0.4" @@ -22,7 +23,7 @@ embedded-hal = "0.2.6" embedded-io = { version = "0.6.0" } embedded-io-async = { version = "0.6.1" } panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } +futures-util = { version = "0.3.30", default-features = false } heapless = { version = "0.8", default-features = false } nb = "1.0.0" embedded-storage = "0.3.1" diff --git a/examples/stm32f4/src/bin/adc.rs b/examples/stm32f4/src/bin/adc.rs index 699c29c05..9473b7b7f 100644 --- a/examples/stm32f4/src/bin/adc.rs +++ b/examples/stm32f4/src/bin/adc.rs @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut delay = Delay; - let mut adc = Adc::new(p.ADC1, &mut delay); + let mut adc = Adc::new(p.ADC1); let mut pin = p.PC1; let mut vrefint = adc.enable_vrefint(); diff --git a/examples/stm32f4/src/bin/can.rs b/examples/stm32f4/src/bin/can.rs index cedc057a7..8e3beee24 100644 --- a/examples/stm32f4/src/bin/can.rs +++ b/examples/stm32f4/src/bin/can.rs @@ -63,6 +63,6 @@ async fn main(_spawner: Spawner) { envelope.frame.data()[0], latency.as_micros() ); - i += 1; + i = i.wrapping_add(1); } } diff --git a/examples/stm32f4/src/bin/dac.rs b/examples/stm32f4/src/bin/dac.rs index 9c7754c4f..dd2a45718 100644 --- a/examples/stm32f4/src/bin/dac.rs +++ b/examples/stm32f4/src/bin/dac.rs @@ -12,7 +12,7 @@ async fn main(_spawner: Spawner) -> ! { let p = embassy_stm32::init(Default::default()); info!("Hello World, dude!"); - let mut dac = DacCh1::new(p.DAC, NoDma, p.PA4); + let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); loop { for v in 0..=255 { diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index 7f5c8fdb1..648c45bbd 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs @@ -62,9 +62,9 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; - static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); + static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); let device = Ethernet::new( - PACKETS.init(PacketQueue::<16, 16>::new()), + PACKETS.init(PacketQueue::<4, 4>::new()), p.ETH, Irqs, p.PA1, diff --git a/examples/stm32f4/src/bin/i2c.rs b/examples/stm32f4/src/bin/i2c.rs index 4b5da774d..4a96357a4 100644 --- a/examples/stm32f4/src/bin/i2c.rs +++ b/examples/stm32f4/src/bin/i2c.rs @@ -3,35 +3,19 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::i2c::{Error, I2c}; use embassy_stm32::time::Hertz; -use embassy_stm32::{bind_interrupts, i2c, peripherals}; use {defmt_rtt as _, panic_probe as _}; const ADDRESS: u8 = 0x5F; const WHOAMI: u8 = 0x0F; -bind_interrupts!(struct Irqs { - I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>; - I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; -}); - #[embassy_executor::main] async fn main(_spawner: Spawner) { info!("Hello world!"); let p = embassy_stm32::init(Default::default()); - let mut i2c = I2c::new( - p.I2C2, - p.PB10, - p.PB11, - Irqs, - NoDma, - NoDma, - Hertz(100_000), - Default::default(), - ); + let mut i2c = I2c::new_blocking(p.I2C2, p.PB10, p.PB11, Hertz(100_000), Default::default()); let mut data = [0u8; 1]; diff --git a/examples/stm32f4/src/bin/i2c_comparison.rs b/examples/stm32f4/src/bin/i2c_comparison.rs index 30cfbdf57..55c4891e3 100644 --- a/examples/stm32f4/src/bin/i2c_comparison.rs +++ b/examples/stm32f4/src/bin/i2c_comparison.rs @@ -13,7 +13,7 @@ use embassy_stm32::i2c::I2c; use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, i2c, peripherals}; use embassy_time::Instant; -use futures::future::try_join3; +use futures_util::future::try_join3; use {defmt_rtt as _, panic_probe as _}; const ADDRESS: u8 = 96; diff --git a/examples/stm32f4/src/bin/input_capture.rs b/examples/stm32f4/src/bin/input_capture.rs new file mode 100644 index 000000000..49de33d2b --- /dev/null +++ b/examples/stm32f4/src/bin/input_capture.rs @@ -0,0 +1,52 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::time::khz; +use embassy_stm32::timer::input_capture::{CapturePin, InputCapture}; +use embassy_stm32::timer::{self, Channel}; +use embassy_stm32::{bind_interrupts, peripherals}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +/// Connect PB2 and PB10 with a 1k Ohm resistor + +#[embassy_executor::task] +async fn blinky(led: peripherals::PB2) { + let mut led = Output::new(led, Level::High, Speed::Low); + + loop { + info!("high"); + led.set_high(); + Timer::after_millis(300).await; + + info!("low"); + led.set_low(); + Timer::after_millis(300).await; + } +} + +bind_interrupts!(struct Irqs { + TIM2 => timer::CaptureCompareInterruptHandler<peripherals::TIM2>; +}); + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + unwrap!(spawner.spawn(blinky(p.PB2))); + + let ch3 = CapturePin::new_ch3(p.PB10, Pull::None); + let mut ic = InputCapture::new(p.TIM2, None, None, Some(ch3), None, Irqs, khz(1000), Default::default()); + + loop { + info!("wait for risign edge"); + ic.wait_for_rising_edge(Channel::Ch3).await; + + let capture_value = ic.get_capture_value(Channel::Ch3); + info!("new capture! {}", capture_value); + } +} diff --git a/examples/stm32f4/src/bin/spi.rs b/examples/stm32f4/src/bin/spi.rs index dc9141c62..970d819fc 100644 --- a/examples/stm32f4/src/bin/spi.rs +++ b/examples/stm32f4/src/bin/spi.rs @@ -3,7 +3,6 @@ use cortex_m_rt::entry; use defmt::*; -use embassy_stm32::dma::NoDma; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::time::Hertz; @@ -18,7 +17,7 @@ fn main() -> ! { let mut spi_config = Config::default(); spi_config.frequency = Hertz(1_000_000); - let mut spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, NoDma, NoDma, spi_config); + let mut spi = Spi::new_blocking(p.SPI3, p.PC10, p.PC12, p.PC11, spi_config); let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh); diff --git a/examples/stm32f4/src/bin/usart.rs b/examples/stm32f4/src/bin/usart.rs index 40d9d70f1..991bf6673 100644 --- a/examples/stm32f4/src/bin/usart.rs +++ b/examples/stm32f4/src/bin/usart.rs @@ -3,7 +3,6 @@ use cortex_m_rt::entry; use defmt::*; -use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::{bind_interrupts, peripherals, usart}; use {defmt_rtt as _, panic_probe as _}; @@ -19,7 +18,7 @@ fn main() -> ! { let p = embassy_stm32::init(Default::default()); let config = Config::default(); - let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, Irqs, NoDma, NoDma, config).unwrap(); + let mut usart = Uart::new_blocking(p.USART3, p.PD9, p.PD8, config).unwrap(); unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); info!("wrote Hello, starting echo"); diff --git a/examples/stm32f4/src/bin/usart_dma.rs b/examples/stm32f4/src/bin/usart_dma.rs index dd6de599c..aaf8d6c4f 100644 --- a/examples/stm32f4/src/bin/usart_dma.rs +++ b/examples/stm32f4/src/bin/usart_dma.rs @@ -5,7 +5,6 @@ use core::fmt::Write; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::{bind_interrupts, peripherals, usart}; use heapless::String; @@ -21,7 +20,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let config = Config::default(); - let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, Irqs, p.DMA1_CH3, NoDma, config).unwrap(); + let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, Irqs, p.DMA1_CH3, p.DMA1_CH1, config).unwrap(); for n in 0u32.. { let mut s: String<128> = String::new(); diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index d2cbeea1b..19ae16e8b 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs @@ -40,6 +40,11 @@ bind_interrupts!(struct Irqs { HASH_RNG => rng::InterruptHandler<peripherals::RNG>; }); +// If you are trying this and your USB device doesn't connect, the most +// common issues are the RCC config and vbus_detection +// +// See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure +// for more information. #[embassy_executor::main] async fn main(spawner: Spawner) { info!("Hello World!"); @@ -71,7 +76,13 @@ async fn main(spawner: Spawner) { static OUTPUT_BUFFER: StaticCell<[u8; 256]> = StaticCell::new(); let ep_out_buffer = &mut OUTPUT_BUFFER.init([0; 256])[..]; let mut config = embassy_stm32::usb::Config::default(); - config.vbus_detection = true; + + // Do not enable vbus_detection. This is a safe default that works in all boards. + // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need + // to enable vbus_detection to comply with the USB spec. If you enable it, the board + // has to support it or USB won't work at all. See docs on `vbus_detection` for details. + config.vbus_detection = false; + let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, ep_out_buffer, config); // Create embassy-usb Config diff --git a/examples/stm32f4/src/bin/usb_hid_keyboard.rs b/examples/stm32f4/src/bin/usb_hid_keyboard.rs index d6e0be5ea..537ff63ea 100644 --- a/examples/stm32f4/src/bin/usb_hid_keyboard.rs +++ b/examples/stm32f4/src/bin/usb_hid_keyboard.rs @@ -5,6 +5,7 @@ use core::sync::atomic::{AtomicBool, Ordering}; use defmt::*; use embassy_executor::Spawner; +use embassy_futures::join::join; use embassy_stm32::exti::ExtiInput; use embassy_stm32::gpio::Pull; use embassy_stm32::time::Hertz; @@ -13,7 +14,6 @@ use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; use embassy_usb::{Builder, Handler}; -use futures::future::join; use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; use {defmt_rtt as _, panic_probe as _}; @@ -21,6 +21,11 @@ bind_interrupts!(struct Irqs { OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); +// If you are trying this and your USB device doesn't connect, the most +// common issues are the RCC config and vbus_detection +// +// See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure +// for more information. #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); @@ -49,8 +54,13 @@ async fn main(_spawner: Spawner) { // Create the driver, from the HAL. let mut ep_out_buffer = [0u8; 256]; let mut config = embassy_stm32::usb::Config::default(); - // If the board you’re using doesn’t have the VBUS pin wired up correctly for detecting the USB bus voltage (e.g. on the f4 blackpill board), set this to false - config.vbus_detection = true; + + // Do not enable vbus_detection. This is a safe default that works in all boards. + // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need + // to enable vbus_detection to comply with the USB spec. If you enable it, the board + // has to support it or USB won't work at all. See docs on `vbus_detection` for details. + config.vbus_detection = false; + let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); // Create embassy-usb Config @@ -76,7 +86,7 @@ async fn main(_spawner: Spawner) { let mut msos_descriptor = [0; 256]; let mut control_buf = [0; 64]; - let request_handler = MyRequestHandler {}; + let mut request_handler = MyRequestHandler {}; let mut device_handler = MyDeviceHandler::new(); let mut state = State::new(); @@ -95,7 +105,7 @@ async fn main(_spawner: Spawner) { // Create classes on the builder. let config = embassy_usb::class::hid::Config { report_descriptor: KeyboardReport::desc(), - request_handler: Some(&request_handler), + request_handler: None, poll_ms: 60, max_packet_size: 8, }; @@ -148,7 +158,7 @@ async fn main(_spawner: Spawner) { }; let out_fut = async { - reader.run(false, &request_handler).await; + reader.run(false, &mut request_handler).await; }; // Run everything concurrently. @@ -159,21 +169,21 @@ async fn main(_spawner: Spawner) { struct MyRequestHandler {} impl RequestHandler for MyRequestHandler { - fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { + fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { info!("Get report for {:?}", id); None } - fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { + fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { info!("Set report for {:?}: {=[u8]}", id, data); OutResponse::Accepted } - fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { + fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { info!("Set idle rate for {:?} to {:?}", id, dur); } - fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { + fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { info!("Get idle rate for {:?}", id); None } diff --git a/examples/stm32f4/src/bin/usb_hid_mouse.rs b/examples/stm32f4/src/bin/usb_hid_mouse.rs index 0bc236119..df4b7426c 100644 --- a/examples/stm32f4/src/bin/usb_hid_mouse.rs +++ b/examples/stm32f4/src/bin/usb_hid_mouse.rs @@ -3,6 +3,7 @@ use defmt::*; use embassy_executor::Spawner; +use embassy_futures::join::join; use embassy_stm32::time::Hertz; use embassy_stm32::usb::Driver; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; @@ -10,7 +11,6 @@ use embassy_time::Timer; use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; use embassy_usb::Builder; -use futures::future::join; use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; use {defmt_rtt as _, panic_probe as _}; @@ -18,6 +18,11 @@ bind_interrupts!(struct Irqs { OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); +// If you are trying this and your USB device doesn't connect, the most +// common issues are the RCC config and vbus_detection +// +// See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure +// for more information. #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); @@ -46,7 +51,13 @@ async fn main(_spawner: Spawner) { // Create the driver, from the HAL. let mut ep_out_buffer = [0u8; 256]; let mut config = embassy_stm32::usb::Config::default(); - config.vbus_detection = true; + + // Do not enable vbus_detection. This is a safe default that works in all boards. + // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need + // to enable vbus_detection to comply with the USB spec. If you enable it, the board + // has to support it or USB won't work at all. See docs on `vbus_detection` for details. + config.vbus_detection = false; + let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); // Create embassy-usb Config @@ -68,7 +79,7 @@ async fn main(_spawner: Spawner) { let mut bos_descriptor = [0; 256]; let mut control_buf = [0; 64]; - let request_handler = MyRequestHandler {}; + let mut request_handler = MyRequestHandler {}; let mut state = State::new(); @@ -84,7 +95,7 @@ async fn main(_spawner: Spawner) { // Create classes on the builder. let config = embassy_usb::class::hid::Config { report_descriptor: MouseReport::desc(), - request_handler: Some(&request_handler), + request_handler: Some(&mut request_handler), poll_ms: 60, max_packet_size: 8, }; @@ -126,21 +137,21 @@ async fn main(_spawner: Spawner) { struct MyRequestHandler {} impl RequestHandler for MyRequestHandler { - fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { + fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { info!("Get report for {:?}", id); None } - fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { + fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { info!("Set report for {:?}: {=[u8]}", id, data); OutResponse::Accepted } - fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { + fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { info!("Set idle rate for {:?} to {:?}", id, dur); } - fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { + fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { info!("Get idle rate for {:?}", id); None } diff --git a/examples/stm32f4/src/bin/usb_raw.rs b/examples/stm32f4/src/bin/usb_raw.rs index 4e583aeb8..1452e7c5f 100644 --- a/examples/stm32f4/src/bin/usb_raw.rs +++ b/examples/stm32f4/src/bin/usb_raw.rs @@ -69,6 +69,11 @@ bind_interrupts!(struct Irqs { OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); +// If you are trying this and your USB device doesn't connect, the most +// common issues are the RCC config and vbus_detection +// +// See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure +// for more information. #[embassy_executor::main] async fn main(_spawner: Spawner) { info!("Hello World!"); @@ -99,7 +104,13 @@ async fn main(_spawner: Spawner) { // Create the driver, from the HAL. let mut ep_out_buffer = [0u8; 256]; let mut config = embassy_stm32::usb::Config::default(); - config.vbus_detection = true; + + // Do not enable vbus_detection. This is a safe default that works in all boards. + // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need + // to enable vbus_detection to comply with the USB spec. If you enable it, the board + // has to support it or USB won't work at all. See docs on `vbus_detection` for details. + config.vbus_detection = false; + let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); // Create embassy-usb Config diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs index f3a375d31..b2bd390b6 100644 --- a/examples/stm32f4/src/bin/usb_serial.rs +++ b/examples/stm32f4/src/bin/usb_serial.rs @@ -3,19 +3,24 @@ use defmt::{panic, *}; use embassy_executor::Spawner; +use embassy_futures::join::join; use embassy_stm32::time::Hertz; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; -use futures::future::join; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); +// If you are trying this and your USB device doesn't connect, the most +// common issues are the RCC config and vbus_detection +// +// See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure +// for more information. #[embassy_executor::main] async fn main(_spawner: Spawner) { info!("Hello World!"); @@ -46,7 +51,13 @@ async fn main(_spawner: Spawner) { // Create the driver, from the HAL. let mut ep_out_buffer = [0u8; 256]; let mut config = embassy_stm32::usb::Config::default(); - config.vbus_detection = true; + + // Do not enable vbus_detection. This is a safe default that works in all boards. + // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need + // to enable vbus_detection to comply with the USB spec. If you enable it, the board + // has to support it or USB won't work at all. See docs on `vbus_detection` for details. + config.vbus_detection = false; + let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); // Create embassy-usb Config diff --git a/examples/stm32f4/src/bin/ws2812_spi.rs b/examples/stm32f4/src/bin/ws2812_spi.rs index a280a3b77..e00d14327 100644 --- a/examples/stm32f4/src/bin/ws2812_spi.rs +++ b/examples/stm32f4/src/bin/ws2812_spi.rs @@ -8,13 +8,13 @@ // If you want to save SPI for other purpose, you may want to take a look at `ws2812_pwm_dma.rs` file, which make use of TIM and DMA. // // Warning: -// DO NOT stare at ws2812 directy (especially after each MCU Reset), its (max) brightness could easily make your eyes feel burn. +// DO NOT stare at ws2812 directly (especially after each MCU Reset), its (max) brightness could easily make your eyes feel burn. #![no_std] #![no_main] +use embassy_stm32::spi; use embassy_stm32::time::khz; -use embassy_stm32::{dma, spi}; use embassy_time::{Duration, Ticker, Timer}; use {defmt_rtt as _, panic_probe as _}; @@ -78,7 +78,7 @@ async fn main(_spawner: embassy_executor::Spawner) { spi_config.frequency = khz(12_800); // Since we only output waveform, then the Rx and Sck and RxDma it is not considered - let mut ws2812_spi = spi::Spi::new_txonly_nosck(dp.SPI1, dp.PB5, dp.DMA2_CH3, dma::NoDma, spi_config); + let mut ws2812_spi = spi::Spi::new_txonly_nosck(dp.SPI1, dp.PB5, dp.DMA2_CH3, spi_config); // flip color at 2 Hz let mut ticker = Ticker::every(Duration::from_millis(500)); diff --git a/examples/stm32f469/.cargo/config.toml b/examples/stm32f469/.cargo/config.toml new file mode 100644 index 000000000..05250954f --- /dev/null +++ b/examples/stm32f469/.cargo/config.toml @@ -0,0 +1,9 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace STM32F429ZITx with your chip as listed in `probe-rs chip list` +runner = "probe-rs run --chip STM32F469NIHx" + +[build] +target = "thumbv7em-none-eabi" + +[env] +DEFMT_LOG = "trace" diff --git a/examples/stm32f469/Cargo.toml b/examples/stm32f469/Cargo.toml new file mode 100644 index 000000000..7718a46c1 --- /dev/null +++ b/examples/stm32f469/Cargo.toml @@ -0,0 +1,22 @@ +[package] +edition = "2021" +name = "embassy-stm32f469-examples" +version = "0.1.0" +license = "MIT OR Apache-2.0" + +[dependencies] +# Specific examples only for stm32f469 +embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f469ni", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] } +embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } +embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } + +defmt = "0.3" +defmt-rtt = "0.4" + +cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } +cortex-m-rt = "0.7.0" +embedded-hal = "1.0.0" +panic-probe = { version = "0.3", features = ["print-defmt"] } + +[profile.release] +debug = 2 diff --git a/examples/stm32f469/build.rs b/examples/stm32f469/build.rs new file mode 100644 index 000000000..8cd32d7ed --- /dev/null +++ b/examples/stm32f469/build.rs @@ -0,0 +1,5 @@ +fn main() { + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/examples/stm32f469/src/bin/dsi_bsp.rs b/examples/stm32f469/src/bin/dsi_bsp.rs new file mode 100644 index 000000000..e4e9e9c01 --- /dev/null +++ b/examples/stm32f469/src/bin/dsi_bsp.rs @@ -0,0 +1,694 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::dsihost::{blocking_delay_ms, DsiHost, PacketType}; +use embassy_stm32::gpio::{Level, Output, Speed}; +use embassy_stm32::ltdc::Ltdc; +use embassy_stm32::pac::dsihost::regs::{Ier0, Ier1}; +use embassy_stm32::pac::ltdc::vals::{Bf1, Bf2, Depol, Hspol, Imr, Pcpol, Pf, Vspol}; +use embassy_stm32::pac::{DSIHOST, LTDC}; +use embassy_stm32::rcc::{ + AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllMul, PllPDiv, PllPreDiv, PllQDiv, PllRDiv, PllSource, Sysclk, +}; +use embassy_stm32::time::mhz; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +enum _Orientation { + Landscape, + Portrait, +} + +const _LCD_ORIENTATION: _Orientation = _Orientation::Landscape; +const LCD_X_SIZE: u16 = 800; +const LCD_Y_SIZE: u16 = 480; + +static FERRIS_IMAGE: &[u8; 1536000] = include_bytes!("ferris.bin"); + +// This example allows to display an image on the STM32F469NI-DISCO boards +// with the Revision C, that is at least the boards marked DK32F469I$AU1. +// These boards have the NT35510 display driver. This example does not work +// for the older revisions with OTM8009A, though there are lots of C-examples +// available online where the correct config for the OTM8009A could be gotten from. +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut config = embassy_stm32::Config::default(); + config.rcc.sys = Sysclk::PLL1_P; + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + + // HSE is on and ready + config.rcc.hse = Some(Hse { + freq: mhz(8), + mode: HseMode::Oscillator, + }); + config.rcc.pll_src = PllSource::HSE; + + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV8, // PLLM + mul: PllMul::MUL360, // PLLN + divp: Some(PllPDiv::DIV2), + divq: Some(PllQDiv::DIV7), // was DIV4, but STM BSP example uses 7 + divr: Some(PllRDiv::DIV6), + }); + + // This seems to be working, the values in the RCC.PLLSAICFGR are correct according to the debugger. Also on and ready according to CR + config.rcc.pllsai = Some(Pll { + prediv: PllPreDiv::DIV8, // Actually ignored + mul: PllMul::MUL384, // PLLN + divp: None, // PLLP + divq: None, // PLLQ + divr: Some(PllRDiv::DIV7), // PLLR (Sai actually has special clockdiv register) + }); + + let p = embassy_stm32::init(config); + info!("Starting..."); + + let mut led = Output::new(p.PG6, Level::High, Speed::Low); + + // According to UM for the discovery kit, PH7 is an active-low reset for the LCD and touchsensor + let mut reset = Output::new(p.PH7, Level::Low, Speed::High); + + // CubeMX example waits 20 ms before de-asserting reset + embassy_time::block_for(embassy_time::Duration::from_millis(20)); + + // Disable the reset signal and wait 140ms as in the Linux driver (CubeMX waits only 20) + reset.set_high(); + embassy_time::block_for(embassy_time::Duration::from_millis(140)); + + let mut ltdc = Ltdc::new(p.LTDC); + let mut dsi = DsiHost::new(p.DSIHOST, p.PJ2); + let version = dsi.get_version(); + defmt::warn!("en: {:x}", version); + + // Disable the DSI wrapper + dsi.disable_wrapper_dsi(); + + // Disable the DSI host + dsi.disable(); + + // D-PHY clock and digital disable + DSIHOST.pctlr().modify(|w| { + w.set_cke(false); + w.set_den(false) + }); + + // Turn off the DSI PLL + DSIHOST.wrpcr().modify(|w| w.set_pllen(false)); + + // Disable the regulator + DSIHOST.wrpcr().write(|w| w.set_regen(false)); + + // Enable regulator + info!("DSIHOST: enabling regulator"); + DSIHOST.wrpcr().write(|w| w.set_regen(true)); + + for _ in 1..1000 { + // The regulator status (ready or not) can be monitored with the RRS flag in the DSI_WISR register. + // Once it is set, we stop waiting. + if DSIHOST.wisr().read().rrs() { + info!("DSIHOST Regulator ready"); + break; + } + embassy_time::block_for(embassy_time::Duration::from_millis(1)); + } + + if !DSIHOST.wisr().read().rrs() { + defmt::panic!("DSIHOST: enabling regulator FAILED"); + } + + // Set up PLL and enable it + DSIHOST.wrpcr().modify(|w| { + w.set_pllen(true); + w.set_ndiv(125); // PLL loop division factor set to 125 + w.set_idf(2); // PLL input divided by 2 + w.set_odf(0); // PLL output divided by 1 + }); + + /* 500 MHz / 8 = 62.5 MHz = 62500 kHz */ + const LANE_BYTE_CLK_K_HZ: u16 = 62500; // https://github.com/STMicroelectronics/32f469idiscovery-bsp/blob/ec051de2bff3e1b73a9ccd49c9b85abf7320add9/stm32469i_discovery_lcd.c#L224C21-L224C26 + + const _LCD_CLOCK: u16 = 27429; // https://github.com/STMicroelectronics/32f469idiscovery-bsp/blob/ec051de2bff3e1b73a9ccd49c9b85abf7320add9/stm32469i_discovery_lcd.c#L183 + + /* TX_ESCAPE_CKDIV = f(LaneByteClk)/15.62 = 4 */ + const TX_ESCAPE_CKDIV: u8 = (LANE_BYTE_CLK_K_HZ / 15620) as u8; // https://github.com/STMicroelectronics/32f469idiscovery-bsp/blob/ec051de2bff3e1b73a9ccd49c9b85abf7320add9/stm32469i_discovery_lcd.c#L230 + + for _ in 1..1000 { + embassy_time::block_for(embassy_time::Duration::from_millis(1)); + // The PLL status (lock or unlock) can be monitored with the PLLLS flag in the DSI_WISR register. + // Once it is set, we stop waiting. + if DSIHOST.wisr().read().pllls() { + info!("DSIHOST PLL locked"); + break; + } + } + + if !DSIHOST.wisr().read().pllls() { + defmt::panic!("DSIHOST: enabling PLL FAILED"); + } + + // Set the PHY parameters + + // D-PHY clock and digital enable + DSIHOST.pctlr().write(|w| { + w.set_cke(true); + w.set_den(true); + }); + + // Set Clock lane to high-speed mode and disable automatic clock lane control + DSIHOST.clcr().modify(|w| { + w.set_dpcc(true); + w.set_acr(false); + }); + + // Set number of active data lanes to two (lanes 0 and 1) + DSIHOST.pconfr().modify(|w| w.set_nl(1)); + + // Set the DSI clock parameters + + // Set the TX escape clock division factor to 4 + DSIHOST.ccr().modify(|w| w.set_txeckdiv(TX_ESCAPE_CKDIV)); + + // Calculate the bit period in high-speed mode in unit of 0.25 ns (UIX4) + // The equation is : UIX4 = IntegerPart( (1000/F_PHY_Mhz) * 4 ) + // Where : F_PHY_Mhz = (NDIV * HSE_Mhz) / (IDF * ODF) + // Set the bit period in high-speed mode + DSIHOST.wpcr0().modify(|w| w.set_uix4(8)); // 8 is set in the BSP example (confirmed with Debugger) + + // Disable all error interrupts and reset the Error Mask + DSIHOST.ier0().write_value(Ier0(0)); + DSIHOST.ier1().write_value(Ier1(0)); + + // Enable this to fix read timeout + DSIHOST.pcr().modify(|w| w.set_btae(true)); + + const DSI_PIXEL_FORMAT_RGB888: u8 = 0x05; + const _DSI_PIXEL_FORMAT_ARGB888: u8 = 0x00; + + const HACT: u16 = LCD_X_SIZE; + const VACT: u16 = LCD_Y_SIZE; + + const VSA: u16 = 120; + const VBP: u16 = 150; + const VFP: u16 = 150; + const HSA: u16 = 2; + const HBP: u16 = 34; + const HFP: u16 = 34; + + const VIRTUAL_CHANNEL_ID: u8 = 0; + + const COLOR_CODING: u8 = DSI_PIXEL_FORMAT_RGB888; + const VS_POLARITY: bool = false; // DSI_VSYNC_ACTIVE_HIGH == 0 + const HS_POLARITY: bool = false; // DSI_HSYNC_ACTIVE_HIGH == 0 + const DE_POLARITY: bool = false; // DSI_DATA_ENABLE_ACTIVE_HIGH == 0 + const MODE: u8 = 2; // DSI_VID_MODE_BURST; /* Mode Video burst ie : one LgP per line */ + const NULL_PACKET_SIZE: u16 = 0xFFF; + const NUMBER_OF_CHUNKS: u16 = 0; + const PACKET_SIZE: u16 = HACT; /* Value depending on display orientation choice portrait/landscape */ + const HORIZONTAL_SYNC_ACTIVE: u16 = 4; // ((HSA as u32 * LANE_BYTE_CLK_K_HZ as u32 ) / LCD_CLOCK as u32 ) as u16; + const HORIZONTAL_BACK_PORCH: u16 = 77; //((HBP as u32 * LANE_BYTE_CLK_K_HZ as u32 ) / LCD_CLOCK as u32) as u16; + const HORIZONTAL_LINE: u16 = 1982; //(((HACT + HSA + HBP + HFP) as u32 * LANE_BYTE_CLK_K_HZ as u32 ) / LCD_CLOCK as u32 ) as u16; /* Value depending on display orientation choice portrait/landscape */ + // FIXME: Make depend on orientation + const VERTICAL_SYNC_ACTIVE: u16 = VSA; + const VERTICAL_BACK_PORCH: u16 = VBP; + const VERTICAL_FRONT_PORCH: u16 = VFP; + const VERTICAL_ACTIVE: u16 = VACT; + const LP_COMMAND_ENABLE: bool = true; /* Enable sending commands in mode LP (Low Power) */ + + /* Largest packet size possible to transmit in LP mode in VSA, VBP, VFP regions */ + /* Only useful when sending LP packets is allowed while streaming is active in video mode */ + const LP_LARGEST_PACKET_SIZE: u8 = 16; + + /* Largest packet size possible to transmit in LP mode in HFP region during VACT period */ + /* Only useful when sending LP packets is allowed while streaming is active in video mode */ + const LPVACT_LARGEST_PACKET_SIZE: u8 = 0; + + const LPHORIZONTAL_FRONT_PORCH_ENABLE: bool = true; /* Allow sending LP commands during HFP period */ + const LPHORIZONTAL_BACK_PORCH_ENABLE: bool = true; /* Allow sending LP commands during HBP period */ + const LPVERTICAL_ACTIVE_ENABLE: bool = true; /* Allow sending LP commands during VACT period */ + const LPVERTICAL_FRONT_PORCH_ENABLE: bool = true; /* Allow sending LP commands during VFP period */ + const LPVERTICAL_BACK_PORCH_ENABLE: bool = true; /* Allow sending LP commands during VBP period */ + const LPVERTICAL_SYNC_ACTIVE_ENABLE: bool = true; /* Allow sending LP commands during VSync = VSA period */ + const FRAME_BTAACKNOWLEDGE_ENABLE: bool = false; /* Frame bus-turn-around acknowledge enable => false according to debugger */ + + /* Select video mode by resetting CMDM and DSIM bits */ + DSIHOST.mcr().modify(|w| w.set_cmdm(false)); + DSIHOST.wcfgr().modify(|w| w.set_dsim(false)); + + /* Configure the video mode transmission type */ + DSIHOST.vmcr().modify(|w| w.set_vmt(MODE)); + + /* Configure the video packet size */ + DSIHOST.vpcr().modify(|w| w.set_vpsize(PACKET_SIZE)); + + /* Set the chunks number to be transmitted through the DSI link */ + DSIHOST.vccr().modify(|w| w.set_numc(NUMBER_OF_CHUNKS)); + + /* Set the size of the null packet */ + DSIHOST.vnpcr().modify(|w| w.set_npsize(NULL_PACKET_SIZE)); + + /* Select the virtual channel for the LTDC interface traffic */ + DSIHOST.lvcidr().modify(|w| w.set_vcid(VIRTUAL_CHANNEL_ID)); + + /* Configure the polarity of control signals */ + DSIHOST.lpcr().modify(|w| { + w.set_dep(DE_POLARITY); + w.set_hsp(HS_POLARITY); + w.set_vsp(VS_POLARITY); + }); + + /* Select the color coding for the host */ + DSIHOST.lcolcr().modify(|w| w.set_colc(COLOR_CODING)); + + /* Select the color coding for the wrapper */ + DSIHOST.wcfgr().modify(|w| w.set_colmux(COLOR_CODING)); + + /* Set the Horizontal Synchronization Active (HSA) in lane byte clock cycles */ + DSIHOST.vhsacr().modify(|w| w.set_hsa(HORIZONTAL_SYNC_ACTIVE)); + + /* Set the Horizontal Back Porch (HBP) in lane byte clock cycles */ + DSIHOST.vhbpcr().modify(|w| w.set_hbp(HORIZONTAL_BACK_PORCH)); + + /* Set the total line time (HLINE=HSA+HBP+HACT+HFP) in lane byte clock cycles */ + DSIHOST.vlcr().modify(|w| w.set_hline(HORIZONTAL_LINE)); + + /* Set the Vertical Synchronization Active (VSA) */ + DSIHOST.vvsacr().modify(|w| w.set_vsa(VERTICAL_SYNC_ACTIVE)); + + /* Set the Vertical Back Porch (VBP)*/ + DSIHOST.vvbpcr().modify(|w| w.set_vbp(VERTICAL_BACK_PORCH)); + + /* Set the Vertical Front Porch (VFP)*/ + DSIHOST.vvfpcr().modify(|w| w.set_vfp(VERTICAL_FRONT_PORCH)); + + /* Set the Vertical Active period*/ + DSIHOST.vvacr().modify(|w| w.set_va(VERTICAL_ACTIVE)); + + /* Configure the command transmission mode */ + DSIHOST.vmcr().modify(|w| w.set_lpce(LP_COMMAND_ENABLE)); + + /* Low power largest packet size */ + DSIHOST.lpmcr().modify(|w| w.set_lpsize(LP_LARGEST_PACKET_SIZE)); + + /* Low power VACT largest packet size */ + DSIHOST.lpmcr().modify(|w| w.set_lpsize(LP_LARGEST_PACKET_SIZE)); + DSIHOST.lpmcr().modify(|w| w.set_vlpsize(LPVACT_LARGEST_PACKET_SIZE)); + + /* Enable LP transition in HFP period */ + DSIHOST.vmcr().modify(|w| w.set_lphfpe(LPHORIZONTAL_FRONT_PORCH_ENABLE)); + + /* Enable LP transition in HBP period */ + DSIHOST.vmcr().modify(|w| w.set_lphbpe(LPHORIZONTAL_BACK_PORCH_ENABLE)); + + /* Enable LP transition in VACT period */ + DSIHOST.vmcr().modify(|w| w.set_lpvae(LPVERTICAL_ACTIVE_ENABLE)); + + /* Enable LP transition in VFP period */ + DSIHOST.vmcr().modify(|w| w.set_lpvfpe(LPVERTICAL_FRONT_PORCH_ENABLE)); + + /* Enable LP transition in VBP period */ + DSIHOST.vmcr().modify(|w| w.set_lpvbpe(LPVERTICAL_BACK_PORCH_ENABLE)); + + /* Enable LP transition in vertical sync period */ + DSIHOST.vmcr().modify(|w| w.set_lpvsae(LPVERTICAL_SYNC_ACTIVE_ENABLE)); + + /* Enable the request for an acknowledge response at the end of a frame */ + DSIHOST.vmcr().modify(|w| w.set_fbtaae(FRAME_BTAACKNOWLEDGE_ENABLE)); + + /* Configure DSI PHY HS2LP and LP2HS timings */ + const CLOCK_LANE_HS2_LPTIME: u16 = 35; + const CLOCK_LANE_LP2_HSTIME: u16 = 35; + const DATA_LANE_HS2_LPTIME: u8 = 35; + const DATA_LANE_LP2_HSTIME: u8 = 35; + const DATA_LANE_MAX_READ_TIME: u16 = 0; + const STOP_WAIT_TIME: u8 = 10; + + const MAX_TIME: u16 = if CLOCK_LANE_HS2_LPTIME > CLOCK_LANE_LP2_HSTIME { + CLOCK_LANE_HS2_LPTIME + } else { + CLOCK_LANE_LP2_HSTIME + }; + + /* Clock lane timer configuration */ + + /* In Automatic Clock Lane control mode, the DSI Host can turn off the clock lane between two + High-Speed transmission. + To do so, the DSI Host calculates the time required for the clock lane to change from HighSpeed + to Low-Power and from Low-Power to High-Speed. + This timings are configured by the HS2LP_TIME and LP2HS_TIME in the DSI Host Clock Lane Timer Configuration + Register (DSI_CLTCR). + But the DSI Host is not calculating LP2HS_TIME + HS2LP_TIME but 2 x HS2LP_TIME. + + Workaround : Configure HS2LP_TIME and LP2HS_TIME with the same value being the max of HS2LP_TIME or LP2HS_TIME. + */ + + DSIHOST.cltcr().modify(|w| { + w.set_hs2lp_time(MAX_TIME); + w.set_lp2hs_time(MAX_TIME) + }); + + // Data lane timer configuration + DSIHOST.dltcr().modify(|w| { + w.set_hs2lp_time(DATA_LANE_HS2_LPTIME); + w.set_lp2hs_time(DATA_LANE_LP2_HSTIME); + w.set_mrd_time(DATA_LANE_MAX_READ_TIME); + }); + + // Configure the wait period to request HS transmission after a stop state + DSIHOST.pconfr().modify(|w| w.set_sw_time(STOP_WAIT_TIME)); + + const _PCPOLARITY: bool = false; // LTDC_PCPOLARITY_IPC == 0 + + const LTDC_DE_POLARITY: Depol = if !DE_POLARITY { + Depol::ACTIVELOW + } else { + Depol::ACTIVEHIGH + }; + const LTDC_VS_POLARITY: Vspol = if !VS_POLARITY { + Vspol::ACTIVEHIGH + } else { + Vspol::ACTIVELOW + }; + + const LTDC_HS_POLARITY: Hspol = if !HS_POLARITY { + Hspol::ACTIVEHIGH + } else { + Hspol::ACTIVELOW + }; + + /* Timing Configuration */ + const HORIZONTAL_SYNC: u16 = HSA - 1; + const VERTICAL_SYNC: u16 = VERTICAL_SYNC_ACTIVE - 1; + const ACCUMULATED_HBP: u16 = HSA + HBP - 1; + const ACCUMULATED_VBP: u16 = VERTICAL_SYNC_ACTIVE + VERTICAL_BACK_PORCH - 1; + const ACCUMULATED_ACTIVE_W: u16 = LCD_X_SIZE + HSA + HBP - 1; + const ACCUMULATED_ACTIVE_H: u16 = VERTICAL_SYNC_ACTIVE + VERTICAL_BACK_PORCH + VERTICAL_ACTIVE - 1; + const TOTAL_WIDTH: u16 = LCD_X_SIZE + HSA + HBP + HFP - 1; + const TOTAL_HEIGHT: u16 = VERTICAL_SYNC_ACTIVE + VERTICAL_BACK_PORCH + VERTICAL_ACTIVE + VERTICAL_FRONT_PORCH - 1; + + // DISABLE LTDC before making changes + ltdc.disable(); + + // Configure the HS, VS, DE and PC polarity + LTDC.gcr().modify(|w| { + w.set_hspol(LTDC_HS_POLARITY); + w.set_vspol(LTDC_VS_POLARITY); + w.set_depol(LTDC_DE_POLARITY); + w.set_pcpol(Pcpol::RISINGEDGE); + }); + + // Set Synchronization size + LTDC.sscr().modify(|w| { + w.set_hsw(HORIZONTAL_SYNC); + w.set_vsh(VERTICAL_SYNC) + }); + + // Set Accumulated Back porch + LTDC.bpcr().modify(|w| { + w.set_ahbp(ACCUMULATED_HBP); + w.set_avbp(ACCUMULATED_VBP); + }); + + // Set Accumulated Active Width + LTDC.awcr().modify(|w| { + w.set_aah(ACCUMULATED_ACTIVE_H); + w.set_aaw(ACCUMULATED_ACTIVE_W); + }); + + // Set Total Width + LTDC.twcr().modify(|w| { + w.set_totalh(TOTAL_HEIGHT); + w.set_totalw(TOTAL_WIDTH); + }); + + // Set the background color value + LTDC.bccr().modify(|w| { + w.set_bcred(0); + w.set_bcgreen(0); + w.set_bcblue(0) + }); + + // Enable the Transfer Error and FIFO underrun interrupts + LTDC.ier().modify(|w| { + w.set_terrie(true); + w.set_fuie(true); + }); + + // ENABLE LTDC after making changes + ltdc.enable(); + + dsi.enable(); + dsi.enable_wrapper_dsi(); + + // First, delay 120 ms (reason unknown, STM32 Cube Example does it) + blocking_delay_ms(120); + + // 1 to 26 + dsi.write_cmd(0, NT35510_WRITES_0[0], &NT35510_WRITES_0[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_1[0], &NT35510_WRITES_1[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_2[0], &NT35510_WRITES_2[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_3[0], &NT35510_WRITES_3[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_4[0], &NT35510_WRITES_4[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_5[0], &NT35510_WRITES_5[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_6[0], &NT35510_WRITES_6[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_7[0], &NT35510_WRITES_7[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_8[0], &NT35510_WRITES_8[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_9[0], &NT35510_WRITES_9[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_10[0], &NT35510_WRITES_10[1..]).unwrap(); + // 11 missing + dsi.write_cmd(0, NT35510_WRITES_12[0], &NT35510_WRITES_12[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_13[0], &NT35510_WRITES_13[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_14[0], &NT35510_WRITES_14[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_15[0], &NT35510_WRITES_15[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_16[0], &NT35510_WRITES_16[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_17[0], &NT35510_WRITES_17[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_18[0], &NT35510_WRITES_18[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_19[0], &NT35510_WRITES_19[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_20[0], &NT35510_WRITES_20[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_21[0], &NT35510_WRITES_21[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_22[0], &NT35510_WRITES_22[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_23[0], &NT35510_WRITES_23[1..]).unwrap(); + dsi.write_cmd(0, NT35510_WRITES_24[0], &NT35510_WRITES_24[1..]).unwrap(); + + // Tear on + dsi.write_cmd(0, NT35510_WRITES_26[0], &NT35510_WRITES_26[1..]).unwrap(); + + // Set Pixel color format to RGB888 + dsi.write_cmd(0, NT35510_WRITES_37[0], &NT35510_WRITES_37[1..]).unwrap(); + + // Add a delay, otherwise MADCTL not taken + blocking_delay_ms(200); + + // Configure orientation as landscape + dsi.write_cmd(0, NT35510_MADCTL_LANDSCAPE[0], &NT35510_MADCTL_LANDSCAPE[1..]) + .unwrap(); + dsi.write_cmd(0, NT35510_CASET_LANDSCAPE[0], &NT35510_CASET_LANDSCAPE[1..]) + .unwrap(); + dsi.write_cmd(0, NT35510_RASET_LANDSCAPE[0], &NT35510_RASET_LANDSCAPE[1..]) + .unwrap(); + + // Sleep out + dsi.write_cmd(0, NT35510_WRITES_27[0], &NT35510_WRITES_27[1..]).unwrap(); + + // Wait for sleep out exit + blocking_delay_ms(120); + + // Configure COLOR_CODING + dsi.write_cmd(0, NT35510_WRITES_37[0], &NT35510_WRITES_37[1..]).unwrap(); + + /* CABC : Content Adaptive Backlight Control section start >> */ + /* Note : defaut is 0 (lowest Brightness), 0xFF is highest Brightness, try 0x7F : intermediate value */ + dsi.write_cmd(0, NT35510_WRITES_31[0], &NT35510_WRITES_31[1..]).unwrap(); + /* defaut is 0, try 0x2C - Brightness Control Block, Display Dimming & BackLight on */ + dsi.write_cmd(0, NT35510_WRITES_32[0], &NT35510_WRITES_32[1..]).unwrap(); + /* defaut is 0, try 0x02 - image Content based Adaptive Brightness [Still Picture] */ + dsi.write_cmd(0, NT35510_WRITES_33[0], &NT35510_WRITES_33[1..]).unwrap(); + /* defaut is 0 (lowest Brightness), 0xFF is highest Brightness */ + dsi.write_cmd(0, NT35510_WRITES_34[0], &NT35510_WRITES_34[1..]).unwrap(); + /* CABC : Content Adaptive Backlight Control section end << */ + /* Display on */ + dsi.write_cmd(0, NT35510_WRITES_30[0], &NT35510_WRITES_30[1..]).unwrap(); + + /* Send Command GRAM memory write (no parameters) : this initiates frame write via other DSI commands sent by */ + /* DSI host from LTDC incoming pixels in video mode */ + dsi.write_cmd(0, NT35510_WRITES_35[0], &NT35510_WRITES_35[1..]).unwrap(); + + /* Initialize the LCD pixel width and pixel height */ + const WINDOW_X0: u16 = 0; + const WINDOW_X1: u16 = LCD_X_SIZE; // 480 for ferris + const WINDOW_Y0: u16 = 0; + const WINDOW_Y1: u16 = LCD_Y_SIZE; // 800 for ferris + const PIXEL_FORMAT: Pf = Pf::ARGB8888; + //const FBStartAdress: u16 = FB_Address; + const ALPHA: u8 = 255; + const ALPHA0: u8 = 0; + const BACKCOLOR_BLUE: u8 = 0; + const BACKCOLOR_GREEN: u8 = 0; + const BACKCOLOR_RED: u8 = 0; + const IMAGE_WIDTH: u16 = LCD_X_SIZE; // 480 for ferris + const IMAGE_HEIGHT: u16 = LCD_Y_SIZE; // 800 for ferris + + const PIXEL_SIZE: u8 = match PIXEL_FORMAT { + Pf::ARGB8888 => 4, + Pf::RGB888 => 3, + Pf::ARGB4444 | Pf::RGB565 | Pf::ARGB1555 | Pf::AL88 => 2, + _ => 1, + }; + + // Configure the horizontal start and stop position + LTDC.layer(0).whpcr().write(|w| { + w.set_whstpos(LTDC.bpcr().read().ahbp() + 1 + WINDOW_X0); + w.set_whsppos(LTDC.bpcr().read().ahbp() + WINDOW_X1); + }); + + // Configures the vertical start and stop position + LTDC.layer(0).wvpcr().write(|w| { + w.set_wvstpos(LTDC.bpcr().read().avbp() + 1 + WINDOW_Y0); + w.set_wvsppos(LTDC.bpcr().read().avbp() + WINDOW_Y1); + }); + + // Specify the pixel format + LTDC.layer(0).pfcr().write(|w| w.set_pf(PIXEL_FORMAT)); + + // Configures the default color values as zero + LTDC.layer(0).dccr().modify(|w| { + w.set_dcblue(BACKCOLOR_BLUE); + w.set_dcgreen(BACKCOLOR_GREEN); + w.set_dcred(BACKCOLOR_RED); + w.set_dcalpha(ALPHA0); + }); + + // Specifies the constant ALPHA value + LTDC.layer(0).cacr().write(|w| w.set_consta(ALPHA)); + + // Specifies the blending factors + LTDC.layer(0).bfcr().write(|w| { + w.set_bf1(Bf1::CONSTANT); + w.set_bf2(Bf2::CONSTANT); + }); + + // Configure the color frame buffer start address + let fb_start_address: u32 = &FERRIS_IMAGE[0] as *const _ as u32; + info!("Setting Framebuffer Start Address: {:010x}", fb_start_address); + LTDC.layer(0).cfbar().write(|w| w.set_cfbadd(fb_start_address)); + + // Configures the color frame buffer pitch in byte + LTDC.layer(0).cfblr().write(|w| { + w.set_cfbp(IMAGE_WIDTH * PIXEL_SIZE as u16); + w.set_cfbll(((WINDOW_X1 - WINDOW_X0) * PIXEL_SIZE as u16) + 3); + }); + + // Configures the frame buffer line number + LTDC.layer(0).cfblnr().write(|w| w.set_cfblnbr(IMAGE_HEIGHT)); + + // Enable LTDC_Layer by setting LEN bit + LTDC.layer(0).cr().modify(|w| w.set_len(true)); + + //LTDC->SRCR = LTDC_SRCR_IMR; + LTDC.srcr().modify(|w| w.set_imr(Imr::RELOAD)); + + blocking_delay_ms(5000); + + const READ_SIZE: u16 = 1; + let mut data = [1u8; READ_SIZE as usize]; + dsi.read(0, PacketType::DcsShortPktRead(0xDA), READ_SIZE, &mut data) + .unwrap(); + info!("Display ID1: {:#04x}", data); + + dsi.read(0, PacketType::DcsShortPktRead(0xDB), READ_SIZE, &mut data) + .unwrap(); + info!("Display ID2: {:#04x}", data); + + dsi.read(0, PacketType::DcsShortPktRead(0xDC), READ_SIZE, &mut data) + .unwrap(); + info!("Display ID3: {:#04x}", data); + + blocking_delay_ms(500); + + info!("Config done, start blinking LED"); + loop { + led.set_high(); + Timer::after_millis(1000).await; + + // Increase screen brightness + dsi.write_cmd(0, NT35510_CMD_WRDISBV, &[0xFF]).unwrap(); + + led.set_low(); + Timer::after_millis(1000).await; + + // Reduce screen brightness + dsi.write_cmd(0, NT35510_CMD_WRDISBV, &[0x50]).unwrap(); + } +} + +const NT35510_WRITES_0: &[u8] = &[0xF0, 0x55, 0xAA, 0x52, 0x08, 0x01]; // LV2: Page 1 enable +const NT35510_WRITES_1: &[u8] = &[0xB0, 0x03, 0x03, 0x03]; // AVDD: 5.2V +const NT35510_WRITES_2: &[u8] = &[0xB6, 0x46, 0x46, 0x46]; // AVDD: Ratio +const NT35510_WRITES_3: &[u8] = &[0xB1, 0x03, 0x03, 0x03]; // AVEE: -5.2V +const NT35510_WRITES_4: &[u8] = &[0xB7, 0x36, 0x36, 0x36]; // AVEE: Ratio +const NT35510_WRITES_5: &[u8] = &[0xB2, 0x00, 0x00, 0x02]; // VCL: -2.5V +const NT35510_WRITES_6: &[u8] = &[0xB8, 0x26, 0x26, 0x26]; // VCL: Ratio +const NT35510_WRITES_7: &[u8] = &[0xBF, 0x01]; // VGH: 15V (Free Pump) +const NT35510_WRITES_8: &[u8] = &[0xB3, 0x09, 0x09, 0x09]; +const NT35510_WRITES_9: &[u8] = &[0xB9, 0x36, 0x36, 0x36]; // VGH: Ratio +const NT35510_WRITES_10: &[u8] = &[0xB5, 0x08, 0x08, 0x08]; // VGL_REG: -10V +const NT35510_WRITES_12: &[u8] = &[0xBA, 0x26, 0x26, 0x26]; // VGLX: Ratio +const NT35510_WRITES_13: &[u8] = &[0xBC, 0x00, 0x80, 0x00]; // VGMP/VGSP: 4.5V/0V +const NT35510_WRITES_14: &[u8] = &[0xBD, 0x00, 0x80, 0x00]; // VGMN/VGSN:-4.5V/0V +const NT35510_WRITES_15: &[u8] = &[0xBE, 0x00, 0x50]; // VCOM: -1.325V +const NT35510_WRITES_16: &[u8] = &[0xF0, 0x55, 0xAA, 0x52, 0x08, 0x00]; // LV2: Page 0 enable +const NT35510_WRITES_17: &[u8] = &[0xB1, 0xFC, 0x00]; // Display control +const NT35510_WRITES_18: &[u8] = &[0xB6, 0x03]; // Src hold time +const NT35510_WRITES_19: &[u8] = &[0xB5, 0x51]; +const NT35510_WRITES_20: &[u8] = &[0x00, 0x00, 0xB7]; // Gate EQ control +const NT35510_WRITES_21: &[u8] = &[0xB8, 0x01, 0x02, 0x02, 0x02]; // Src EQ control(Mode2) +const NT35510_WRITES_22: &[u8] = &[0xBC, 0x00, 0x00, 0x00]; // Inv. mode(2-dot) +const NT35510_WRITES_23: &[u8] = &[0xCC, 0x03, 0x00, 0x00]; +const NT35510_WRITES_24: &[u8] = &[0xBA, 0x01]; + +const _NT35510_MADCTL_PORTRAIT: &[u8] = &[NT35510_CMD_MADCTL, 0x00]; +const _NT35510_CASET_PORTRAIT: &[u8] = &[NT35510_CMD_CASET, 0x00, 0x00, 0x01, 0xDF]; +const _NT35510_RASET_PORTRAIT: &[u8] = &[NT35510_CMD_RASET, 0x00, 0x00, 0x03, 0x1F]; +const NT35510_MADCTL_LANDSCAPE: &[u8] = &[NT35510_CMD_MADCTL, 0x60]; +const NT35510_CASET_LANDSCAPE: &[u8] = &[NT35510_CMD_CASET, 0x00, 0x00, 0x03, 0x1F]; +const NT35510_RASET_LANDSCAPE: &[u8] = &[NT35510_CMD_RASET, 0x00, 0x00, 0x01, 0xDF]; + +const NT35510_WRITES_26: &[u8] = &[NT35510_CMD_TEEON, 0x00]; // Tear on +const NT35510_WRITES_27: &[u8] = &[NT35510_CMD_SLPOUT, 0x00]; // Sleep out + // 28,29 missing +const NT35510_WRITES_30: &[u8] = &[NT35510_CMD_DISPON, 0x00]; // Display on + +const NT35510_WRITES_31: &[u8] = &[NT35510_CMD_WRDISBV, 0x7F]; +const NT35510_WRITES_32: &[u8] = &[NT35510_CMD_WRCTRLD, 0x2C]; +const NT35510_WRITES_33: &[u8] = &[NT35510_CMD_WRCABC, 0x02]; +const NT35510_WRITES_34: &[u8] = &[NT35510_CMD_WRCABCMB, 0xFF]; +const NT35510_WRITES_35: &[u8] = &[NT35510_CMD_RAMWR, 0x00]; + +//const NT35510_WRITES_36: &[u8] = &[NT35510_CMD_COLMOD, NT35510_COLMOD_RGB565]; // FIXME: Example sets it to 888 but rest of the code seems to configure DSI for 565 +const NT35510_WRITES_37: &[u8] = &[NT35510_CMD_COLMOD, NT35510_COLMOD_RGB888]; + +// More of these: https://elixir.bootlin.com/linux/latest/source/include/video/mipi_display.h#L83 +const _NT35510_CMD_TEEON_GET_DISPLAY_ID: u8 = 0x04; + +const NT35510_CMD_TEEON: u8 = 0x35; +const NT35510_CMD_MADCTL: u8 = 0x36; + +const NT35510_CMD_SLPOUT: u8 = 0x11; +const NT35510_CMD_DISPON: u8 = 0x29; +const NT35510_CMD_CASET: u8 = 0x2A; +const NT35510_CMD_RASET: u8 = 0x2B; +const NT35510_CMD_RAMWR: u8 = 0x2C; /* Memory write */ +const NT35510_CMD_COLMOD: u8 = 0x3A; + +const NT35510_CMD_WRDISBV: u8 = 0x51; /* Write display brightness */ +const _NT35510_CMD_RDDISBV: u8 = 0x52; /* Read display brightness */ +const NT35510_CMD_WRCTRLD: u8 = 0x53; /* Write CTRL display */ +const _NT35510_CMD_RDCTRLD: u8 = 0x54; /* Read CTRL display value */ +const NT35510_CMD_WRCABC: u8 = 0x55; /* Write content adaptative brightness control */ +const NT35510_CMD_WRCABCMB: u8 = 0x5E; /* Write CABC minimum brightness */ + +const _NT35510_COLMOD_RGB565: u8 = 0x55; +const NT35510_COLMOD_RGB888: u8 = 0x77; diff --git a/examples/stm32f469/src/bin/ferris.bin b/examples/stm32f469/src/bin/ferris.bin new file mode 100644 index 000000000..ae1c466be --- /dev/null +++ b/examples/stm32f469/src/bin/ferris.bin @@ -0,0 +1,70 @@ +��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������f���2������������������H���x�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������$�����������������������������������$��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-���������������������������������������������������'�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������e�����������������������������������������������������������d������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������V����������������������~���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-�������������������������������������������������������������������R�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%�������������������a�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������_�����������������������������������5�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������}�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+�����������������������������������l�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������D������������������������������������������� ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������`�����������������������������������������������E�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������M��������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������]�����������������������������������������������������������������������������������h���������������������������������������������������������������������������������������������������������������������������������������������������������������������������c�������������������������������������������������������d���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������u�����������������������������������������������������������+��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������h���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������4���������������������������������������������������������������0�������������������������������������������������������������������������������������������������������������������������������������������������������������������@�������������������������������������������������������������������������������������������N������������������������������������������������������������������������������������������������������������������������������������������������������������������� +���������������������������������������������������������������7�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@��������������������������������������������������������������������������������������������������������������������������������������������������������������� ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������R���������������������������������������������������������������������������S������������������������������������������������������������������������������������������������������������������������������������������������������� ���������������������������������������������������������������������������������������������������-����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������^�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������X�����������������������������������������������������������������������������������������������������������������������������������������������W�����������������������������������������������������������������������������������������������������������s�����������������������������������������������������������������������������������������������������������������������������������������������(�������������������������������������������������������������������������������9�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������y���������������������������������������������������������������������������������������e������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������=�������������������������������������������������������������������������������������������w�����������������������������������������������������������������������������������������������������������������������������������F�������������������������������������������������������������������������������������������������������������������F�����������������������������������������������������������������������������������������������������������������������������������@�������������������������������������������������������������������������������������������m�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ���{�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +�������������������������������������������������������������������������������������������������������������������������������I���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ���������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������V�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������A��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������c�����������������������������������������������������������������������������������������������������������������������������������n���������������������������������������������������������������������������������������������������������������n��� +�������������������������������������������������������������������������������������������������������E�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������|���������������������������������������������������������������������������������������������������������������!�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������e�������������������������������������������������������������������������������������������������������������������5�������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������O����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%�����������������������������������������������������������������������������������������������������������������������.�����������������������������������������������������������������������������������������������x��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +�����������������������������������������������������������������������������������������������������������������������[������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������K�������������������������������������������������������������������������������������������)���������������������������������������������������������������������������������������������������������������������������������������������������/������������������������������������������������������������������������������������������� +������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P���G���J���a�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������g�����������������������������������������������������������������������������������������������������������������������������������U�����������������������������������������������������������������������������������g�����������������������������������������������������������������������������������������������������������������������������������������������������������g�����������������������������������������������������������������������������������0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Y���T���_�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{�������������������������������������������������������������������������������������������������������������������������������������������������������������������3���������������������������������������������������������������������������������������������������������������������������������������b��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������7���������������������������������������������������������������������������������������������������������������������������������������)�������������������������������������������������������������������������������������������������������������������������������������������������������������������n�������������������������������|���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������]������������������������������������������C������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ���u�����������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������X�����������������������������������������������������������������������J�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������:���������������������������������������0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������V���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������]���������������������������������������������������������������������������������������������������������������������������������������������������n���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������i��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ���������������������������������������������������������������)���������������������������������������������������������������������������������������������������������������������������������������������������������������������������*�����������������������������������������������������������h�������������������������������������������������������������������������������������������������������������������������������������������������������F�����������������������������������������������������������������������������������������������������������������������������������������������_�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������=����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������p���������������������������������������������������v��� +���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2�������������������������������������������������������������������F�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������p��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������M��������������������������������������������������������������������������������������������������������������������������������������������������������������� ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������u�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������F����������������������������������������������������������������������������������c���������������������������������������������������������������������������������������������������������������������������$�������������������������������������������������������������������������������������������������������������������������������������������������������������������5�������������������������������������������H�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +���������������������������������������������������������������������������������������������������������������������������T�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������3���������������������������������������������������������������������������������������C�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������v���b���;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���f���������������������������$��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������0���������������������������������������������������������������������������������������������������������������C������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-���I���-�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������V�����������������������������������������������������������������������������������������������������������x��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������m�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1�������������������������������������������������������������������������������������������������������H�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������O�����������������������������������������������������������������������������������������������k��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +���������������������������������������������������������������������������������������������������2�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������j���������������������������������������������������������������������������������������������������������������)�������������������������������������������������������������������������������������������5�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������e���������������������������������������������������������������������������������������q������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������J�����������������������������������������������������������������������������������������������������������������������u������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������T�����������������������������������������������������������������������������������������������������������������������m��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���������������������������������������������������������������������������r�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/���������������������������������������������������������������������������������������������������������������������������G������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �����������������������������������������������������������������������7���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������4�������������������������������������������������������������������q�����������������������������������������������������������������������������������������������������������������������������������<��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������t����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������N���������������������������������������������������������������������������������������������������������������������������������������0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������z����������������������������������������������������������������������������������������������������������������������������������������������N�������������������������������������������������������Y�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Q���������������������������������������������������������������������������������������������������������������������������������������������������6��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������N�����������������������������������������������t����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1����������������������������������������������������������������������������������������������������������������������������������������������������������y�����������������������������������P���.��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +���=���c�����������������������������������G���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(���������������������������������������������������������������������������������������������������������������������������������������������������������������\�������������������D���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������v����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<���W���,����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������A�����������������������������������������������������������������������������������������������������������������������������������������������������������������������[������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������m�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������X�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������=�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������n�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������w���g���c���o���������������������������������������������������������������������������������������������������������������������������������������������������������������l����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���s���u�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������?�������������������������)���m���������������������������������������������������������������������������������������������������������������������������������������������������>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������p���+�������������������������Q�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������q��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������x�������������������������������������������������������������������������������������������������������������������������������������������}���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������t������������������������������������������������������)���Z������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������g�����������������������������������������������������������������������������������������������������������������������������������_���'���������������������������������������������������'����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������X����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������R���������������������������������������������������������������������������������������������������������������������������\�������������������������������������������������������������������F�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Q������������������������������������������������������������������������������R���������������������������������������������������������������������������������������������������������������~�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������5�������������������������������������������������������������������������������������������������������������������`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������7�������������������������������������������������������������������������������������������������������d�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������=��������������������������������������������������������������������������������������7�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������h���������������������������������������������������������������������������������������������������G�����������������������������������������������������������������������������������������������V���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������E����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.����������������������������������������������������������������������������������������������������������-���y�����������������������������������������������������������������������������������E�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������8������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������!�������������������������������������������������������������������������������������������������������������������"���x���������������������������������������������������������������������������.���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������n����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������!���������������������������������������������������������������������������������������������������������������������������0���f�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2�������������������������������������������������������������������m���3�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������!��������������������������������������������������������������������������������������������������������������������������������������e������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������0�������������������������������������������������������j�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#����������������������������������������������������������������������������������������������������������������������������������������������_���������������������������������������H���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Y���������������������������������������m������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#������������������������������������������������������������������������������������������������������������������������������������������������������F�����������������������K�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������X�����������������������F��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������&���������������������������������������������������������������������������������������������������������������������������������������������������������������M�������e����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������|�������W����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������&������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������,������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������:������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������G������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������R������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������c���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������j�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������q����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������x��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������}�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~��*������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~��*����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~��.����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~��.����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}��0����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}��1��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}��3����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}��3��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|��6������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|��6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|��8���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|��8���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{��;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{��;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{��=�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������d���0����������������2���F���r�������������������������������������������������������������������������������������������������������������������������������������������%���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{��=���������������������������������������������������������������������������������������������������������������������������������������~���N���9���|���z���z���z��|��A�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(������������������������������������������� ���U���z���������������������������������������������������������������������������������������������������������������������������/�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{��;���������������������������������������������������������������������������������������������������������������������������^����z���z���z���z���z���z���z���z���z���z���z���z��G����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2���K���b��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z��|������������������������������������������������������������������������������������������������������~���a���@����z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y��.������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-���i���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z��{��������������������������������������������������������������������������������������J���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y��:���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������I����������������������������������������������������������������������������������������������������������H���d���}�����������������������������������������������������������t������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z������������������������������������������������������������������j���4����y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y��|�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%���H���|���������������������������������������_�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y��z����������������������������������������������?���*~��{���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y��z������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������a�����������������������������������������������������������������������������������������������������������������������������������������������'���\���|�������������������S�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y��t�����������������������h���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x��y������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������!��������������������������������������������������������������������������������������������������������������������������������������������������������������1���A���-������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y��z��E���Q���=���{���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x��x����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w��x��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������J������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w��x������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������w����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w��x���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w��${����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v��p�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������M�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������e����������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~��� ����������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v��>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u��n�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������$�������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������K�������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u��w����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������z����~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u��+{���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t��9~��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������&����~���~���~���~���~���~���~���~���~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t��i���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������V����~���~���~���~���~���~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������s����}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s��+y����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������*����}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s��r�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������8����}���}���}���}���}���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S����|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s��u��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~����|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r��9|�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r��Q�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������!���|���|���|���|���|���|���|���|���|���|���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r��l�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Z����{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~����{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q��r��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������4����{���{���{���{���{���{���{���{���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q��k���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������K����z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������a����z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p��;{����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������z���z���z���z���z���z���z���z���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p��a�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#|���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p��|�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������^����y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p��q��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������j����y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o��p��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������y���y���y���y���y���y���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o��;z������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+|���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o��G����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<����x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o��l���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������U����x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n��p����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������}���y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������d���3~���x���x���x���x���x���x���x���x���x��y�� z��,|��2}��9��@���E���J���N���T���W���[���_���b���f���i���m���r���y���~���������������������������%{���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n��1v������������������������������������������������������������������|���z���v���s���p���j���e���c���\���V���R���J~��D|��<y��.t��(s��o��q��L���y�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������${���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x��x��x��y��x��x��x��x��y��x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n��q��r��q��q��q��o��o��n��n��n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m��o��r�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������y���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l��n�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@����x���x���x���x���x���x���x���x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������z����x���x���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l��m��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+{���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l��v�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l��<x������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������r����w���w���w���w���w���w���w���w���w���w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[����w���w���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������W����v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������c����v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j��+q����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������w���v���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j��l�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������h����u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j��k������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������w���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j��9u������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[����u���u���u���u���u���u���u���u���u���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������v���u���u���u���u���u���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i��7t��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������8{���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i��'o����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������6{���t���t���t���t���t���t���t���t���t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h��Q~����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������t���t���t���t���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+x���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h��Fy������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������U����s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h��;t��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Q����r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g��n�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������s���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������C}���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g��X�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������s���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f��Mz������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������k����q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������s���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f��j��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������^����q���q���q���q���q���q���q���q���q���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f��l�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������s���q���q���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������>y���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e��a����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e��f������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������6w���p���p���p���p���p���p���p���p���p���p���p���p���p���p���p���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e��;r������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������w����o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d��}�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.t���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[����o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d��u�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������o���o���o���o���o���o���o���o���o���o���o���o���o���o���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d��f����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������R���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d��X~���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������G{���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c��#h������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������J{���n���n���n���n���n���n���n���n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c��As��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~����n���n���n���n���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'q���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b��k�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������c����m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b��'h������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+r���m���m���m���m���m���m���m���m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b��z�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������k����m���m���m���m���m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������n���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a��q�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������u���Gy���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a��e��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������s���X��'p���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a��Cr��}���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������m���^���N{��8t��m���l���l���l���l���l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`��c��Nw��l�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���d���9t��o��n��m��l���l���l���l���l���l���l���l���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`��a��c��#f��.i��Ku������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������}���o���[���Bw��m���l���l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`��b��U{��}�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������i���Gy��7t��,q�� n��l���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_��`��+g��@o��Mv��d�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Y��m���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_��Dq������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������W}��m���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_��Hs������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Hx���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^��b����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������c����k���k���k���k���k���k���k���k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^��b�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������k���k���k���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^��Vz����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ly���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^��c����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-p���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������!m���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]��`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������l���j���j���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]��.f������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������k���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������k���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\��7i������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%m���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\��j�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������5q���i���i���i���i���i���i���i���i���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���b���b���a���[���T���Q���O���N���O���Q���U���[���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������k����h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���a���U���I���?���7���0{��,s��+q��)o��*p��+r��-v��2��9���D���S���`���b���b���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���[���C���1���'m��Y��C��4��)��'�� -��6��E��[��)p��3���J���]���_���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\��@m��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+n���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���_���X���T���E���.u��B������������������������������������������������������������������H��8���R���X���a���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���^���T���D��� U�������������������������������������������������������������������.y��O���X���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���i���h���h���h���h���h���h���h���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���`���K���7���&t�� =��������������������������������������������������������������������������������������������������;��0���C���^���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���]���F���.���.�������������������������������������������������������������������������������������� [��;���W���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[��z�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������X|���h���h���h���h���h���h���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���]��+_��iv������������������������������[[[��������������������������������������������������������������������������������������������3��=���Z���a���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���b��N{����������������������������������OOO���������������������������������������������������������������������������� +��?���Z���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[��Dn������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������8p���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���^���;��|�����������������������������������������������RRR��������������������������������������������������������������������������������������������������6��@���Z���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_��,q��������������������������������������������������(((������������������������������������������������������������������������������ [��F���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������i���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b��1Q������������������������������������������������������������������������������������������������������������������������������������������������������������ ��D��K���`���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`��`��]�����������������������������������������������������������TTT���������������������������������������������������������������������������#��/}��X���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[��v���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������i���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a��Hu���������������������������������������������������������������������� + + +������������������������������������������������������������������������������������������������������5���Z���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���]����������������������������������������������������������������������uuu����������������������������������������������������������������������������������V��N���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z��Mr����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������?r���g���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b��C|������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#a��S���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���Y��o{��������������������������������������������������������������������������fff����������������������������������������������������������������������������������4��B���\���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z��_������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������!j���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b��'n�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������B��N���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���M��PUp���������������������������������������������������������������������������������UUU��������������������������������������������������������������������������������������=���Z���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z��{�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������u���g���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���^������������������������������������������������������������������������������������������qqq����������������������������������������������������������������������������������������������������������:��H���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���B��!>�����������������������������������������������������������������������������������������&&&�������������������������������������������������������������������������������������4���Z���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z��Pt��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mv���f���f���f���f���f���f���f���f���f���f���f���f���f���f���f���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a��j�����������������������������������������������������������������������������������������������555����������������������������������������������������������������������������������������������������������6��L���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���\���?����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.��Z���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y��'`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/l���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a��*m����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������K��S���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���[���:������,,,�������������������������������������������������������������������������������������������������$$$������������������������������������������������������������������������������������������2���X���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������g���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a��p�������������������������������������������������������������������������������������������������������333��������������������������������������������������������������������������������������������������������������T��X���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������8���\���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y��Kp������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������_}���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���_������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������0���\���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���P���%�����������������������������������������������������������������������������������������������������������������000���������������������������������������������������������������������������������������������S���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y��.c��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������5m���e���e���e���e���e���e���e���e���e���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_��=����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������E���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���'k���������sss���������������������������������������������������������������������������������������������������������hhh����������������������������������������������������������������������������������������������-{��]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X��Y����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������h���e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���^������������������������������������������������������������������������������������������������������������������ccc������������������������������������������������������������������������������������������������������������������ ��U���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���B��� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������:��P���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X��Uu����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������m��� +e���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���^�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-|��\���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���V���\���������+++�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��;���[���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X��*a������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Dq���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`��Ik���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��K���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���E�������������MMM���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������K��V���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X��[��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(i���d���d���d���d���d���d���d���d���d���d���d���d���d���d���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���^��x}����������������������������������������������������������������������������������������������������������������������999����������������������������������������������������������������������������������������������������������������������$d��\���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���Y���@�������������bbb�����������������������������������������������������������������������������������������������������������������[[[��������������������������������������������������������������������������������������������������D���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X��]z��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������z���e���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_��I��������������������������������������������������������������������������������������������������������������������������TTT��������������������������������������������������������������������������������������������������������������������������G���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���]���:������������������uuu����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������N��[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W��[����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ux���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���]��)m�������������������������������������������������������������������������������������������������������������������������bbb��������������������������������������������������������������������������������������������������������������������������X��Z���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���V���N��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������I���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W��Z������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.j���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���N�� /�������������������������������������������������������������������������������������������������������������������������mmm��������������������������������������������������������������������������������������������������������������������������"��G���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���B������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W��e~����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������e���c���c���c���c���c���c���c���c���c���c���c���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���\���7���������������������������������������������������������������������������������������������������������������������������vvv������������������������������������������������������������������������������������������������������������������������������2���[���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���X���#d��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P��R���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W��0b��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������d��b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���Z���!��������������������������������������������������������������������������������������������������������������������������}}}������������������������������������������������������������������������������������������������������������������������������$��V���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���N����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������I���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������8l���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���?�������������������������������������������������������������������������������������������������������������������������������{{{����������������������������������������������������������������������������������������������������������������������������������=���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���)q����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-��Y���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V��v���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#f���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���\���R������������������������������������������������������������������������������������������������������������������������������ttt����������������������������������������������������������������������������������������������������������������������������������E��[���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���R���,������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������V���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V��5c������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������r���c���b���b���b���b���b���b���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���I��� &����� + + +�������������������������������������������������������������������������������������������������������������������������hhh����������������������������������������������������������������������������������������������������������������������������������!��L���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���<����������������������������zzz����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������A���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Kr���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���\���8����������������������������������������������������������������������������������������������������������������������������������^^^������������������������������������������������������������������������������������������������������������������������������������9���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���X���+}�����������������������������fff�����������������������������������������������������������������������������������������������������������������iii��������������������������������������������������������������������������������������������������������������*x��Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V��W�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���W���V�������������������������������������������������������������������������������������������������������������������������������������LLL��������������������������������������������������������������������������������������������������������������������������������������)v��X���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���P��� -�����������������������������SSS�����������������������������������������������������������������������������������������������������������������+++��������������������������������������������������������������������������������������������������������������T��R���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U��"[������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������k����a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���R������������������kkk���������������������������������������������������������������������������������������������������������������������000��������������������������������������������������������������������������������������������������������������������������������������:��Q���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���G����������������������������������444����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������$��G���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U��X������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1i���a���a���a���a���a���a���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���8������������������888��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������N���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���)t�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������>���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������6j���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���?��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������D���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���#�������������������������������������������������������������������������������������������������������������������������������������������������rrr����������������������������������������������������������������������������������������������������������������������*|��V���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U��r�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������9k���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���O����������������������������������������������������������������������������������������������������������������������������������������FFF����������������������������������������������������������������������������������������������������������������������������������������������2���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���K������������������������������������������###���������������������������������������������������������������������������������������������������������???����������������������������������������������������������������������������������������������������������������������2��T���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T��Y��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Cn���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���]���<�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� [��Y���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Z���7��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������N���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Gp���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���1�������������������������������������������������������������������������������������������������������������������������������������eee��������������������������������������������������������������������������������������������������������������������������������������������������1��Y���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Z���*{���������������������������������������������;;;�������������������������������������������������������������������������������������������������EEE������������������������������������������������������������������������������������������������������������������������������:���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T��Ch��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Os���`���`���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���V���#i�����������������������������ZZZ�����������������������������������������������������������������������������������������������������###����������������������������������������������������������������������������������������������������������������������������������������������������Y���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���W���"j��������������������������������������������� ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(u��X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S��-]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tu���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���O���7����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���N���L�������������������������������������������������;;;�����������������������������������������������������������������������������������������888����������������������������������������������������������������������������������������������������������������������������������Q��X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S��V��i������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\x���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���L������������������������������������FFF�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������J���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���J��� 2�����������������������������������������������������www���������������������������������������������������������������������������������xxx��������������������������������������������������������������������������������������������������������������������������������������?��S���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S��Jk����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������_z��_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���I������������������������������������������vvv�������������������������������������������������������������������������������������BBB��������������������������������������������������������������������������������������������������������������������������������������������������������������D���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���G���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ,��F���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S��*\��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������h���_���_���_���_���_���_���_���_���_���_���_���_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Y���:���������������������������������������������������������������������������������������������������������������������������ooo������������������������������������������������������������������������������������������������������������������������������������������������������������������?���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���E�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R��i��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������g~��^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���)u���������������������������������������������***����������������������������������������������������������������������������� ������������������������������������������������������������������������������������������������������������������������������������������������������������������9���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���D�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R��Af������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������s��� +_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���S������������������������������������������������������������������������������������������������������������������xxx��������������������������������������������������������������������������������������������������������������������������������������������������������������������������6���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���A�����������������������������������������������������������������������YYY�������������������������������������������������RRR�����������������������������������������������������������������������������������������������������������������������������������������������������8���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������r��� +_���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���X���?����������������������������������������������������� ���������������������������������������������������������ggg������������������������������������������������������������������������������������������������������������������������������������������������������������������������������6���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������5���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R��by����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������y���a���^���^���^���^���^���^���^���^���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���W���,����������������������������������������������������������<<<�����������������������������������������xxx�)))����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������7���Y���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���=���������������������������������������������������������������������������������������444�FFF�PPP�PPP�FFF�333�����������������������������������������������������������������������������������������������������������������������������������������������������������������������0���T���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q��0]��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������}���`���^���^���^���^���^���^���^���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���W����������������������������������������������������������������������������qqq���������������������YYY����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������7���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���=�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-���S���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~��� a���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���W�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������7���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���A�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������*���R���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q��Qn����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'c���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���W��� ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������=���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���C�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������)���R���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q��R��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������*d���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���W��� %��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������D���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���D�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������*���Q���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P��Q��r���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1e���]���]���]���]���]���]���]���]���]���]���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���V���3��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���E�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-���R���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P��6^������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������7g���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���P��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������R���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���H���:��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P��&X����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������6f���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���*z������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������U���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���N���W�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������5���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O��P��^v����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ck���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���8�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������>��U���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���$t���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +��7���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O��=a��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Aj���\���\���\���\���\���\���\���\���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���F�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%m��U���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���V���0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O��U������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Kn���\���\���\���\���\���\���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���J���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������7���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���B����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ,��D���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O��Wq������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Qp���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���O���T������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������G���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���Q���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������A��O���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N��8^����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Sq���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���U���*��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +(��J���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���&s������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������]��S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N��Q��|�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������_w��[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���W���8��� +���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� f��P���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���B�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������3���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N��]t��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\v��[���[���[���[���[���[���[���[���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���O���$���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���K���B��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������J���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N��3\������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������g{�� \���[���[���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���#i��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���Q���,����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������^��O���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M��}�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������j}��\���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���G�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1��P���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���B���!������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������8���P���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M��Pk����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������p��� [���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���Q���!j��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(z��T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���\��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@��F���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������v���]���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������H���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���C���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������&z��Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L��o���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������|��� [���Z���Z���Z���Z���Z���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���R���X������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������d��O���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���O���&{�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������H���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L��6[���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������]���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���U���D�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���C��� /��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Q��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������]���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���R���.�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P��N���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���*�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Z��I���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��N��^t��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������]���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���K���N������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������9���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���M���P����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������=���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��-X������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������0a���Y���Y���Y���Y���Y���Y���Y���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���B������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� h��O���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���@���(����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������3���O���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Q����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������*`���Y���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���R���6����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +.��D���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���2����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'���L���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Kg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������:d���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���Q���,��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������0���Q���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���N���+����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� k��J���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��1Y��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<e���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���Q���#m�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Z��P���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���K���%z���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� l��K���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O��q���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ch���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���P���(}����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������R��H���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���H���D�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2���K���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Pk������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Jk��X���X���X���X���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���O���$q�� ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +1��A���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���E�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L��B���N���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��.X����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Om���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���/�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;��=���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���:���'������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ,��-���I���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��p�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tp���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���P���:���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������3��>���P���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���5���������������������������������������������������������������������������������������������������������������������������������������������������������������������������c��B���M���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Ge��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\s���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���F���Z��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P��A���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���4���'���������������������������������������������������������������������������������������������������������������������������������������������������������V��8���M���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��N������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������^u���W���W���W���W���W���W���W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���K���0��������������������������������������������������������������������������������������������������������������������������������������������������������������������������� j��G���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���9�������������������������������������������������������������������������������������������������������������������������������������������������B��7���G���O���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��k~������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������hz�� W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���@���U�� ����������������������������������������������������������������������������������������������������������������������������������������������������� ,��1���N���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���M���A���G������������������������������������������������������������������������������������������������������������������������������D��0���K���M���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Jf����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������j{���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���M���4���A���������������������������������������������������������������������������������������������������������������������������������������������� n��A���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���F���-���������������������������������������������������������������������������������������������������������������������k��6���H���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��x���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������m}��X���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���O���J���-���#��������������������������������������������������������������������������������������������������������������������������I��>���L���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���L���@���Z��������������������������������������������������������������������������������������������� +-��%|��B���I���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������v��� W���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���R���J���>���J���Q���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���G���.���U������������������������������������������������������������������������������������������������������������k��6���M���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���:���$�� 8�������������������������������������������������������������������������M��&���5���I���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���K���J���I���I���I���I���I���J���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��q���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������t���Y���V���V���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���S���F���6���,���+���,���5���B���Q���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���I���9���C������������������������������������������������������������������������������������������)��,���B���J���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���K���D���:���$x��(���������������������������������������������� ,�� j��5���A���E���L���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���G���C���>���:���7���6���5���3���3���3���3���3���3���4���6���8���:���=���A���E���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��R����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������}���Y���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���L���5���,���+���+���+���+���+���,���.���>���N���R���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���N���?���%x��J�������������������������������������������������������� +��6��^��%{��=���M���N���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���H���:���2���,���*���*���*���.���4���>���J���L���L���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���E���5���-���,���,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���,���,���1���:���D���H���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������|��� Z���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���N���=���,���+���+���+���+���+���+���+���+���+���*���-���:���F���Q���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���F���<���-���;���������������������������������C��#t��3���<���B���L���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���N���N���N���N���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���D���,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���*���-���4���;���C���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(\���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���R���C���/���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���0���@���O���R���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���L���G���2���&x��-���6���?���H���K���L���M���N���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���9���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���-���/���:���G���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��N��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-]���U���U���U���U���U���U���U���U���U���U���U���U���U���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���M���9���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���-���<���H���O���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���N���N���P���Q���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���P���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���I���1���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���5���A���H���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1^���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S��T��H���0���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���-���2���?���N���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���Q���L���L���M���M���O���P���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���D���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+�� +.���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���0���<���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Bd���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S��1]��{���Y`���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���9���I���N���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���N���L���L���L���L���L���L���N���P���Q���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���7���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��4C������3���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���/���@���I���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��'U��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������o~���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S��Hg����������x{��/���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���2���=���I���R���R���R���R���R���R���R���R���R���R���R���R���R���R���M���L���L���L���L���L���L���L���M���M���N���P���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���G���,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��8G�����������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���3��A\��"S���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��h|��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%Z���T���T���T���T���T���T���T���T���T���T���T���T���T���T���T���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S�� T��Ql������������������->���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���-���3���D���N���Q���R���R���R���R���R���R���R���R���R���R���P���L���L���L���L���L���L���L���L���L���L���L���M���N���P���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���9���+���+���+���+���+���+���+���+���+���+���+���+���+���+�� +.��Yb���������������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��/@����������\s��O���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ U���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���S��S��at����������������������]d���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���*���/���;���F���N���R���Q���Q���Q���Q���Q���Q���Q���Q���N���L���L���L���L���L���L���L���L���L���L���L���L���L���M���N���O���P���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���H���0���+���+���+���+���+���+���+���+���+���+���+���+���+���+������������������U^���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��fm������������������ +M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��#S��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������q~��S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R��S��`t������������������������������1���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���-���0���;���J���P���Q���Q���Q���Q���Q���Q���Q���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���N���O���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���?���+���+���+���+���+���+���+���+���+���+���+���+���+��3C����������������������8G���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��������������������������9]���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��q���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gx��S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R�� S��`t����������������������������������in���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���3���B���J���O���Q���Q���Q���Q���N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���M���N���O���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���3���+���+���+���+���+���+���+���+���+���+���+���+��el���������������������������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��rx������������������������������,W���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������hy��S���S���S���S���S���S���S���S���S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R��Nj������������������������������������������5D���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���.���6���A���M���Q���P���P���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���N���O���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���C���+���+���+���+���+���+���+���+���+���+���+��!7������������������������������pv���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��/@����������������������������������Tm���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��8]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������r~��S���S���S���S���S���S���S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R��S����������������������������������������������rw��,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���-���7���E���L���N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���N���O���O���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���1���+���+���+���+���+���+���+���+���+�� +.��S]���������������������������������� +.���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��}����������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� S���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q��+Y��������������������������������������������������U]���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���0���9���E���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���N���N���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���A���,���+���+���+���+���+���+���+���+���+�������������������������������������������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��4D�������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Ed��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������U���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q��+Y������������������������������������������������������6E���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���0���H���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���M���N���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���J���J���J���J���J���J���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���5���+���+���+���+���+���+���+��0��Zb������������������������������������������OY���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+�����������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��N������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ni���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q��R������������������������������������������������������|���/���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��0��6E���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���9���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���M���N���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���M���I���B���=���:���8���5���.���)���&���#y��${��'���*���/���6���8���:���>���D���L���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���C���+���+���+���+���+���+���+��:H��������������������������������������������������+>���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��gn�����������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Oj������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������|����R���R���R���R���R���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q����������������������������������������������������������`f���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��4��|���sw��4��,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���D���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���K���K���K���K���K���K���K���K���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���J���?���-��� q��^��A��)����������������������������������������������������� 0��J��f��&��6���F���K���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���3���+���+���+���+���+��3��tz������������������������������������������������������ +.���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��%:����������������������������������������������h{���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������7^���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P��o|����������������������������������������������������������BN���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��ag����������Za��0���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���1���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���K���E���B���@���>���7���.���(���"t�� l��h��a�� l��#u��'���/���7���>���@���B���E���J���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���I���B���:���"t������������������������������������������������������������������������������������������������������������?��.���@���E���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���?���+���+���+���+���+��fm����������������������������������������������������������ai���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��������������������������������������������������Lh���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��k~��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ev��Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P��If��������������������������������������������������������������%9���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��%9������������������?L���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���;���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���C���5���,���$���V��0���������������������������������������������������������������� +-��T��!y��*���3���A���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���D���/���!t��/��������������������������������������������������������������������������������������������������������������������������������V��(���:���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���H���1���+���+���+��CO������������������������������������������������������������������ +.���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��]d��������������������������������������������������Ed���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��5[����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������&X���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P��0Z��������������������������������������������������������������uy�� +.���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��qu������������������uy��6E��,���+���+���+���+���+���+���+���+���+���+���+���+���.���E���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���G���A���+���A���������������������������������������������������������������������������������������������������� ����:��&���=���F���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���H���A���$y��#�������������������������������������������������������������$��3�� :��@��@��=��6��+���������������������������������������������������@��4���E���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���=���+���+��CO���������������������������������������������������������������������������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��%:������������������������������������������������������9]���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��N��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ix���Q���Q���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P��Q��~���������������������������������������������������������������ci���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��.?��������������������������tw��%9���+���+���+���+���+���+���+���+���+���+���+���+���4���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���H���8���)���D������������������������������������������������������������������������������������������������������������������������������������������ 5��'���5���D���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���E���4���h���������������������������������������������������������Q��'���4���:���<���>���@���@���B���B���A���@���>���=���;���8���.���h��,������������������������������������������ 4��,���@���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���G���?���C���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���G���-��-?������������������������������������������������������������������������������.?���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��~�������������������������������������������������������%T���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��If������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������>`���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O��[o������������������������������������������������������������������FQ���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+�� +.��v{������������������������������_f��%9��,���+���+���+���+���+���+���+���+���+���+���;���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���D���(���G��������������������������������������������������������������������������������������������������������������������������������������������������������������>��"r��@���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���I���1���B�����������������������������������������=��Z��+���A���I���J���J���K���L���L���L���L���L���L���L���L���L���L���L���L���L���K���J���I���E���3���j��F��#��������������������������� +5��$z��D���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���J���B���5���.���:���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��2I�������������������������������������������������������������������������������������� +.���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��AM�����������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{���S���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O��R����������������������������������������������������������������������';���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��IS��������������������������������������fk��#8���+���+���+���+���+���+���+���+���+���.���E���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���H���;���#x������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������`��8���D���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���F���4���=������������������������������������������A��+���6���D���L���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���H���:���/���T���������������������������������-���C���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���I���C���;���0���+���+���8���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��l{��������������������������������������������������������������������������������������jp���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��!8���������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��N������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ym���P���P���P���P���P���P���P���P���P���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O��n{���������������������������������������������������������������������� .���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��/����������������������������������������������bh��3���+���+���+���+���+���+���+���+���4���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���3���`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������O��,���H���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���7���Y��������������������������������������`��;���F���J���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���F���>���g��������������������������I��-���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���E���9���1���,���+���+���+���7���I���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K��Fc������������������������������������������������������������������������������������������3C���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��sx����������������������������������������������������������]s���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��<_����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<_���P���P���P���P���P���P���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O��0Z����������������������������������������������������������������������dj��,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��T\��������������������������������������������������]d��+=���+���+���+���+���+���+���+���=���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���H���:���E���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'��1���D���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���A���`��������������������������������������M��)���>���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���A���+���O��������������������������Y��>���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���I���E���>���2���+���+���+���+���+���+���5���H���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K�� +L�����������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��:H���������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������)W���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N��Q��}�����������������������������������������������������������������������GR���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��,����������������������������������������������������������pt��%9���+���+���+���+���+���-���E���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���8���n����������������������������������������������������������������������*��Y��&���1���9���?���@���@���@���@���@���@���@���?���8���.���$x��O��������������������������������������������������������������������������������������������I��0���H���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���F���+���5���������������������������������� 1��5���C���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���D���2��� "������������������������+���G���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���C���:���3���-���+���+���+���+���+���+���+���6���H���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K����������������������������������������������������������������������������������������������BN���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+�������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��~�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������t��R���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N��Tk��������������������������������������������������������������������������2B���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��RZ��������������������������������������������������������������pt��7E��/���+���+���+���5���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���E���!q���������������������������������������������������&��T��o��+���;���H���K���K���K���L���L���L���L���L���L���L���L���L���L���L���L���K���K���K���K���F���8���(���l��M��!������������������������������������������������������������������������>��:���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���=���K������������������������������N��.���H���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���F���*���@��������������������>��?���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���E���:���/���,���+���+���+���+���+���+���+���+���+���4���H���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K��Lg�����������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+�� +.��|�������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Bb��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mz��O���O���O���O���O���O���O���O���O���O���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N��R������������������������������������������������������������������������������ 7���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��&:����������������������������������������������������������������������~���LU���+���+���+���<���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���I���F���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���G���/��� +-������������������������������������������������o��5���<���F���L���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���L���D���<���5���i�������������������������������������������������������������������������$~��>���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���E���-������������������������������������1���D���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���L���@���(������������������������.���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���I���C���;���2���+���+���+���+���+���+���+���+���+���+���+���+���6���H���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K����������������������������������������������������������������������������������������������dk���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��8F������������������������������������������������������������������9]���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������_q��P���O���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N��]p��������������������������������������������������������������������������pt�� +.���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��fk������������������������������������������������������������������������������T]��6��-���C���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���8���0���8���C���J���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���=���W��������������������������������������/��[��8���H���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���I���G���4���W��/�� ����������������������������������������������������������4��.���H���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���A���M�� +��������������������������!��${��D���J���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���I���;���D�� ����������������a��C���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���J���A���5���/���-���+���+���+���+���+���+���+���+���+���+���+���+���+���5���H���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K��������������������������������������������������������������������������������������������������5D���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+����������������������������������������������������������������������R���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��l~��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tj���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M��O������������������������������������������������������������������������������_e���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��4��������������������������������������������������������������������������������������ns��AQ���I���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���H���/���+���*���-���5���>���D���H���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���F���0�����������������������������������������h��1���@���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���@���1���X��������������������������������������������������������������U��?���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���I���3���������������������������������b��7���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���E���-��� +������������������I��;���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���E���@���6���-���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���6���H���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J��^r���������������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��{����������������������������������������������������������������������� +M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��<_����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Og���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M��N��_q������������������������������������������������������������������������������FQ���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��^e������������������������������������������������������������������������������������������pz��N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���A���,���+���+���+���+���-���0���4���;���C���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���@���^�����������������������������������g��?���H���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���G���<���^������������������������������������������������������� +3��,���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���G���"u������������������������������-���F���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���I���<���G����������������� ,��0���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���C���9���2���.���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���8���H���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J��*T��������������������������������������������������������������������������������������������������JU���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��DP����������������������������������������������������������������������s����L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ca���N���N���N���N���N���N���N���N���N���N���N���N���N���N���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M��1X����������������������������������������������������������������������������������,=���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��#8����������������������������������������������������������������������������������������������eu���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���8���+���+���+���+���+���+���+���+���+���+���3���<���E���H���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���5���������������������������������;��'���>���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���?���$��� +-�����������������������������������������������������^��B���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���@���R������������������������������\��<���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���D���$������������������,���H���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���G���B���8���.���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���8���I���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J�� K�������������������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��������������������������������������������������������������������������Lh���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��]s����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<]���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L��mz����������������������������������������������������������������������������������1���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��,��io����������������������������������������������������������������������������������������������Gb���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���I���1���+���+���+���+���+���+���+���+���+���+���+���+���/���5���:���@���G���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���G���&��������������������������������'���B���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���@���*������������������������������������������������������B��4���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���5���;�����������������������������-���D���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���H���2���$������������������$}��E���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���B���:���4���.���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���;���I���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J��~���������������������������������������������������������������������������������������������������W_���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��~����������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��,W������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������8[���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L��R����������������������������������������������������������������������������������mr��/���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��2B��������������������������������������������������������������������������������������������������%S���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���E���-���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���-���1���9���C���I���J���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���A���T�������������������������)��!s��C���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���B��� o��"������������������������������������������������*���G���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���1��� ��������������������������@��5���I���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���;���C����������������]��E���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���J���H���?���4���-���,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���;���I���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J��Wn������������������������������������������������������������������������������������������������������ 7���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��JU�������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1X���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��et����������������������������������������������������������������������������������U]���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��qu����������������������������������������������������������������������������������������������v����L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���=���,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���*���,���2���9���>���C���G���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���:���H��������������������������k��;���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���:���g��������������������������������������������������n��A���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���G���*�������������������������������o��>���J���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���@���a������������������N��A���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���F���@���:���2���,���*���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���-���>���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I��<\�����������������������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+������������������������������������������������������������������������������=_���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��cw������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-W���M���M���M���M���M���M���M���M���M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��/W��������������������������������������������������������������������������������������AL���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��#8��������������������������������������������������������������������������������������������������]p���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���4���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���-���.���2���8���@���I���K���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���1���,�������������������� +0��2���I���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���I���1��� +2��������������������������������������������C��=���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���F��� s��������������������������#y��F���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���F���l���������������H��B���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���J���B���7���0���.���,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���-���@���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I��#Q����������������������������������������������������������������������������������������������������������CO���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��z�������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��"S��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������)U���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��iw��������������������������������������������������������������������������������������.?���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��,��in��������������������������������������������������������������������������������������������������:\���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���H���0���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���*���0���8���?���D���G���K���L���L���L���L���L���L���L���L���L���L���L���L���I���0�������������������������&���D���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���C���$~������������������������������������������������7���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���C���`�������������������������� /��/���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���F���(�����������������2��A���L���L���L���L���L���L���L���L���L���L���L���L���L���J���F���C���<���3���,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���0���B���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���������������������������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��OY�����������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Q���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��%S�����������������������������������������������������������������������������������������,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��3B������������������������������������������������������������������������������������������������������M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���A���-���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���0���3���8���>���D���K���L���L���L���L���L���L���L���H���'����������������������3��;���I���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���I���;���2��������������������������������������������-���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���@���T��������������������������%��:���H���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���F���-�������������������D��@���L���L���L���L���L���L���L���L���K���F���>���7���2���/���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���2���E���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I��������������������������������������������������������������������������������������������������������������AM���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��$9����������������������������������������������������������������������������������Wo���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��h{����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������}���#S���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��br��������������������������������������������������������������������������������������ns�� .���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��pt��������������������������������������������������������������������������������������������������o|��M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���:���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���2���8���@���G���H���J���G���%�������������������#x��C���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���D���#{��������������������������������������������$x��H���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���A���8��������������������������J��>���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���H���/�����������������:��B���L���L���J���H���F���@���6���.���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���6���G���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I�� J��n}���������������������������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��|�����������������������������������������������������������������������������������.X���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��2Z������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������y��� N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Q������������������������������������������������������������������������������������������Y`��,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��#8������������������������������������������������������������������������������������������������������Sj���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���7���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���*���,���0���1���n������������������!��3���J���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���6���5������������������������������������������ o��G���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���>��� 7��������������������������W��@���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���F���/�������������������H��9���:���5���0���+���*���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���:���G���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H��Vl��������������������������������������������������������������������������������������������������������������dl���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��V_���������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������x���O���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��\n������������������������������������������������������������������������������������������<I���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��`g������������������������������������������������������������������������������������������������������0X���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���H���1���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���'���F���������������I��?���K���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���A���U����������������������������������������R��F���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���?���0�����������������������g��D���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���G���/����������������@��'���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���-���=���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H��Fb������������������������������������������������������������������������������������������������������������������-?���+���+���+���+���+���+���+���+���+���+���+���+���+���+��(;��������������������������������������������������������������������������������������Yp���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��v�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������r|�� N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��R����������������������������������������������������������������������������������������������1A���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��)<����������������������������������������������������������������������������������������������������������Q���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���D���.���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���'���H������������������%}��F���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���G���(������������������������������������������W��B���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���=���"��������������������������"y��C���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���F���+�������������������H��(���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���0���A���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H��<[�����������������������������������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+���+���+���+���+���+���+�������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��4[��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������t��M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Nf����������������������������������������������������������������������������������������������6���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��,��in������������������������������������������������������������������������������������������������������t���M���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���B���,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���'���I������������� ��/���H���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���I���5�����������������������������������������J��C���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���?���=������������������������&���E���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���F���(������������������X��)���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���3���E���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H��O����������������������������������������������������������������������������������������������������������������������5���+���+���+���+���+���+���+���+���+���+���+���+���+���+��NY�������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������oz��O���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��M����������������������������������������������������������������������������������������������lq���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��!7����������������������������������������������������������������������������������������������������������Wk���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���J���<���,���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���)���U�������������� +.��6���J���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���<���F��������������������������������������E��@���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���A��� +'��������������������������'���E���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���E���#z���������������o��+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���,���8���F���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H��3W���������������������������������������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+���+���+���+���+���+��-?������������������������������������������������������������������������������������������>`���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��y���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nz���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Gb����������������������������������������������������������������������������������������������ah���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��]d����������������������������������������������������������������������������������������������������������@^���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���J���8���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���)���Y�������������� 3��?���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���C���[��������������������������������������L��A���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���A���D��������������������������(���D���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���C���V����������������r��+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���-���=���F���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G��K��������������������������������������������������������������������������������������������������������������������������=J���+���+���+���+���+���+���+���+���+���+���+���+���+�� +.����������������������������������������������������������������������������������������������%T���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Bb����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������o{��O���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L�� M��{�����������������������������������������������������������������������������������������������IS���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��6��������������������������������������������������������������������������������������������������������������.V���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���J���6���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���*���i������������V��@���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���F���$}������������������������������������=��B���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���D���L�����������������������&���D���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���B���N�������������� ��"���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��"8��CO��U^��^h��Ja���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G��&P������������������������������������������������������������������������������������������������������������������������������0���+���+���+���+���+���+���+���+���+���+���+���+���+��V_�����������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L�� +M������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������lx���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��7[��������������������������������������������������������������������������������������������������0@���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��,��]d���������������������������������������������������������������������������������������������������������������K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���H���3���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���n�������������m��B���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���K���G���-���������������������������������������T��C���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���D���]��������������������������%���D���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���<���@�������������� +6��'���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��AM��uz������������������Rh���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G��N������������������������������������������������������������������������������������������������������������������������������T]���+���+���+���+���+���+���+���+���+���+���+���+���+��2C����������������������������������������������������������������������������������������������Vo���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������jw�� M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��hv�������������������������������������������������������������������������������������������������� 7���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��3��������������������������������������������������������������������������������������������������������������p~���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J��&Q��kr��R[��2B��)<��3��-���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���v���������� q��D���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���H���/�������������������������������������E��D���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���G��� s����������������������"v��D���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���3�����������������B��*���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+�� -��6��1B��EQ��z~������������������������������%P���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G��N�����������������������������������������������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+���+���+���+���+��3���������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Rl������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gu�� M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��&T��������������������������������������������������������������������������������������������������wz��/���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��PX��������������������������������������������������������������������������������������������������������������Zn��K���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J��Me������������������sx��`g��HR��5���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���$���%����������"z��D���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���3�������������������������������������X��E���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���J���)���������������������������k��B���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���,������������������d��*���+���+���+���+���+���+���+���+���+���+���+���+���+���+��*=��[d��x}������������������������������������������v����G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G��.T����������������������������������������������������������������������������������������������������������������������������������Q[���+���+���+���+���+���+���+���+���+���+���+���+���+��gm���������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L�� +M��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fu���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��M��ar��������������������������������������������������������������������������������������������������dj���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+��,������������������������������������������������������������������������������������������������������������������:Z���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J��Nf����������������������������������rv��KT��3��1��.��-���+���+���+���+���+���+���+���+���+���'��� +3��������$��E���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���I���7���%����������������������������������b��I���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���K���+��������������������������X��C���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���D���!v���������������!���+���+���+���+���+���+���+��-��0��4��7F��pv����������������������������������������������������������Jc���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G��L��������������������������������������������������������������������������������������������������������������������������������������2���+���+���+���+���+���+���+���+���+���+���+���+��-?��������������������������������������������������������������������������������������������������.X���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ds��N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O������������������������������������������������������������������������������������������������������SZ��,���+���+���+���+���+���+���+���+���+���+���+���+���+���+��DO������������������������������������������������������������������������������������������������������������������3W���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J��Nf��������������������������������������������������ns��Ya��IS��2B��-���+���+���+���+���)���H����������!t��E���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���5���2����������������������������������k��H���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���5��� ����������������������S��@���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���>���B����������������'���+���+��4��AN��Zb��ms��������������������������������������������������������������������������"N���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F��?\��������������������������������������������������������������������������������������������������������������������������������������ms���+���+���+���+���+���+���+���+���+���+���+���+��5������������������������������������������������������������������������������������������������������ +M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Zq��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������br���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��C`������������������������������������������������������������������������������������������������������9F���+���+���+���+���+���+���+���+���+���+���+���+���+���+��/��~�������������������������������������������������������������������������������������������������������������������$Q���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J��Me����������������������������������������������������������������������kp��IS��/���g��������"y��E���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���J���:��� +/��������������������������������'���H���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���M���9�������������������������0��=���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���9�����������������7:X�����������������������������������������������������������������������������������������gw���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F��?\������������������������������������������������������������������������������������������������������������������������������������������#9���+���+���+���+���+���+���+���+���+���+���+���+��rx��������������������������������������������������������������������������������������������������n����L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��)V����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ar�� N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L�� N��t������������������������������������������������������������������������������������������������������$9���+���+���+���+���+���+���+���+���+���+���+���+���+���+��8F������������������������������������������������������������������������������������������������������������������y���L���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I��@]������������������������������������������������������������������������������������g��C���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���7��� +2��������������������������������o��,���-���.���.���0���0���1���2���3���4���4���4���5���5���5���5���5���5���6���7���7���5���5���5���5���5���4���4���4���,��� 2���������������������� -��:���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���E���,��� ���������]]]�������������������������������������������������������������������������������������3U���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F�� G��Qg������������������������������������������������������������������������������������������������������������������������������������������}����+���+���+���+���+���+���+���+���+���+���+���+��;I������������������������������������������������������������������������������������������������������:]���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������br���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��7[���������������������������������������������������������������������������������������������������������5���+���+���+���+���+���+���+���+���+���+���+���+���+���+��ot������������������������������������������������������������������������������������������������������������������q}�� +J���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I��>\�������������������������������������������������������������������������������S��A���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���J���8��� +��������������������������������v��+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���(��� ?����������������������'��4���E���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���A���O���������\]]�����������������������������������������������������������������������������x����F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F��ct����������������������������������������������������������������������������������������������������������������������������������������������2���+���+���+���+���+���+���+���+���+���+���+��5�����������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��fz����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������br��M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��hv������������������������������������������������������������������������������������������������������ko�� +.���+���+���+���+���+���+���+���+���+���+���+���+���+��0@����������������������������������������������������������������������������������������������������������������������]n��J���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I��'R�����������������������������������������������������������������������A��@���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���7���,��������������������������������"���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���*���D������������������������+���E���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���=��������\\\�������������������������������������������������������������������������=Z�� G���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F�� G��u�����������������������������������������������������������������������������������������������������������������������������������������������}����+���+���+���+���+���+���+���+���+���+���+�� +.����������������������������������������������������������������������������������������������������������Sl���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��9]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cr�� M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L�� M����������������������������������������������������������������������������������������������������������Za���+���+���+���+���+���+���+���+���+���+���+���+���+��,��hm����������������������������������������������������������������������������������������������������������������������Ui���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I��O��z����������������������������������������������������������������:���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���I���J���4�����������������������������������%���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���*���a�������������������������%���D���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���D���-�����\\\���������������������������������������������������������������������I���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E������������������������������������������������������������������������������������������������������������������������������������������������������>K���+���+���+���+���+���+���+���+���+���+���+��LV�����������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������br���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Ke����������������������������������������������������������������������������������������������������������IS���+���+���+���+���+���+���+���+���+���+���+���+���+��3��������������������������������������������������������������������������������������������������������������������������Kc���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H��J��Xk������������������������������������������������������[j���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���4���������������������������������<��'���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���!�����������������������g��A���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���A���a�\\\�����������������������������������������������������`q��Jb��'O���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E��"M�����������������������������������������������������������������������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+���+���+��0����������������������������������������������������������������������������������������������������������x����L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��j}������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������bs��N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O��|�����������������������������������������������������������������������������������������������������������1A���+���+���+���+���+���+���+���+���+���+���+���+���+��?K��������������������������������������������������������������������������������������������������������������������������;Z���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H��>[����������������������������������������������~���L���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���G���.���������������������������������W��)���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���%�������������������������I��>���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���6��\]_�������������������������������������Rg��H��F���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E��G`����������������������������������������������������������������������������������������������������������������������������������������������������������5���+���+���+���+���+���+���+���+���+���+��0��������������������������������������������������������������������������������������������������������������Ed���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��?`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������`q���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��9[��������������������������������������������������������������������������������������������������������������2���+���+���+���+���+���+���+���+���+���+���+���+��,��pu��������������������������������������������������������������������������������������������������������������������������0U���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H��L��iw��������������������������������������#P���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���G���.�����������������������������������c��+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���'���9���������������������� *��9���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E��\d������������������y���]o��3T���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E��bs����������������������������������������������������������������������������������������������������������������������������������������������������������pv���+���+���+���+���+���+���+���+���+���+���+��T]��������������������������������������������������������������������������������������������������������������P���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������br�� M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��gv����������������������������������������������������������������������������������������������������������wz��0���+���+���+���+���+���+���+���+���+���+���+���+��0@������������������������������������������������������������������������������������������������������������������������������,S���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H��I��1U������������������������������.T���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���E���&�������������������������������v��+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���*���_�����������������������/���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E��.P��\m��3T��$N��I���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E��J��u���������������������������������������������������������������������������������������������������������������������������������������������������������������*=���+���+���+���+���+���+���+���+���+���+�� 7��������������������������������������������������������������������������������������������������������������y����L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��o���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������br��M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��R��������������������������������������������������������������������������������������������������������������`g���+���+���+���+���+���+���+���+���+���+���+���+���+��_e������������������������������������������������������������������������������������������������������������������������������N���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H��Md������������������Vj���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���H���C���i������������������������������(��$���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���+���v��������������������������&���C���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E��+Q������������������������������������������������������������������������������������������������������������������������������������������������������������������y���+���+���+���+���+���+���+���+���+���+�� .������������������������������������������������������������������������������������������������������������������!S���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Pj����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������br��M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��M��Wl��������������������������������������������������������������������������������������������������������������NW���+���+���+���+���+���+���+���+���+���+���+���+��/����������������������������������������������������������������������������������������������������������������������������������M���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G��K��<Z��v���q}��H���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���B���P������������������������������5��(���+���+���+���+���+���+���+���+���+���+���+���+���+���+���"��� ����������������������c��@���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D�� E��<Y����������������������������������������������������������������������������������������������������������������������������������������������������������������������5���+���+���+���+���+���+���+���+���+���+��el�������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��%T������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cr�� N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L�����������������������������������������������������������������������������������������������������������������<I���+���+���+���+���+���+���+���+���+���+���+���+��CO������������������������������������������������������������������������������������������������������������������������������~���K���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���=���?�����������������������������R�+=��/@��)<��#8��#8��#8��.?��/A��/A��0A��0A��5D��;H��3A���E���������������������� :��;���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D�� E��r����������������������������������������������������������������������������������������������������������������������������������������������������������������������sy���+���+���+���+���+���+���+���+���+���+��2B������������������������������������������������������������������������������������������������������������������<^���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������br���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��0W������������������������������������������������������������������������������������������������������������������3���+���+���+���+���+���+���+���+���+���+���+��/��{~��������������������������������������������������������������������������������������������������������������������������������� +H���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G��>��MMN�efe�sts�����������������������������������������������������������������������������������������������������5K���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D��G������������������������������������������������������������������������������������������������������������������������������������������������������������������������������5���+���+���+���+���+���+���+���+���+���+����������������������������������������������������������������������������������������������������������������������P���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��\r������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������br��N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��M��^p��������������������������������������������������������������������������������������������������������������}��1���+���+���+���+���+���+���+���+���+���+���+��5D����������������������������������������������������������������������������������������������������������������������������������{���L���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G��H��x���������������������������������������������������������������������������������������������������������������G���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D��Rg������������������������������������������������������������������������������������������������������������������������������������������������������������������������������v{���+���+���+���+���+���+���+���+���+�� .��w|������������������������������������������������������������������������������������������������������������������u����L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��1Y��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ar���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��!R������������������������������������������������������������������������������������������������������������������mr��/���+���+���+���+���+���+���+���+���+���+���+��ko����������������������������������������������������������������������������������������������������������������������������������}���H���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G���G�� N����������������������������������������������������������������������������������������������������������8U���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C�� D��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������6E���+���+���+���+���+���+���+���+���+��8G����������������������������������������������������������������������������������������������������������������������-W���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cs�� M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��B_������������������������������������������������������������������������������������������������������������������T\���+���+���+���+���+���+���+���+���+���+���+��)<��������������������������������������������������������������������������������������������������������������������������������������}���K���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F��"N��������������������������������������������������������������������������������������������������Rf���C���C���C���C���C���C���C���C���C���C��G��&M��.P��6T��=X��C\��Tg��ft��v���������������������������������������������������������������u���cq��Nb��A[��>Y��:V��5T��/Q��'M��H��D���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C��<X�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+�� .���������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��ex��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������et��M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��ly������������������������������������������������������������������������������������������������������������������KT���+���+���+���+���+���+���+���+���+���+��,��fl��������������������������������������������������������������������������������������������������������������������������������������{���J���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F��E^������������������������������������������������������������������������������������������w����C���C���C���C���C���C���C��7U��[l��r}�����������������������������������������������������������������������������������������������������������������������������������������������������s~��br��Nc��2R���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C�� D��q~������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#9���+���+���+���+���+���+���+���+�� .��������������������������������������������������������������������������������������������������������������������������;^���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Dc����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������et���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��,V����������������������������������������������������������������������������������������������������������������������6D���+���+���+���+���+���+���+���+���+���+�� 7���������������������������������������������������������������������������������������������������������������������������������������������� M���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F��G��et��������������������������������������������������������������������������������������%L���C��D��G��&L��Zl������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mz��?Z��"K��I��G��D���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C��(N���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+���+��NX�������������������������������������������������������������������������������������������������������������������������� +M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��P������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������hv��N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Xl���������������������������������������������������������������������������������������������������������������������� 7���+���+���+���+���+���+���+���+���+���+��_e����������������������������������������������������������������������������������������������������������������������������������������������*Q���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F���F����������������������������������������������������������������������������������D]��#K��Wi��y�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mz��Yk��<X���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C�� D��m{��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������FR���+���+���+���+���+���+���+���+��7��������������������������������������������������������������������������������������������������������������������������i|���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��x�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������iv���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��M��|�������������������������������������������������������������������������������������������������������������������|��/���+���+���+���+���+���+���+���+���+��1��������������������������������������������������������������������������������������������������������������������������������������������������,P���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E��K��7V��������������������������������������������������������������������������o|�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������t��B[���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C��:W����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2���+���+���+���+���+���+���+���+������������������������������������������������������������������������������������������������������������������������������5[���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Um������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������jw��N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��,V����������������������������������������������������������������������������������������������������������������������hm�� +.���+���+���+���+���+���+���+���+���+��Za��������������������������������������������������������������������������������������������������������������������������������������������������;X���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E��I��$M��.R��6V��=Z��B\��G_��Kb��Pe��Uh��aq��nz��x�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������]m��I_��0Q���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B��%K��n{����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fm���+���+���+���+���+���+���+���+��el�������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��(U��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ly���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��M��br����������������������������������������������������������������������������������������������������������������������U]���+���+���+���+���+���+���+���+���+��)<������������������������������������������������������������������������������������������������������������������������������������������������������Ja���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E��3T��G_��Wj��es��o|��z����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Vi��C���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B��Nc�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+���+���+���+���+���+���+���+��#9������������������������������������������������������������������������������������������������������������������������������=_���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nz�� M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O��������������������������������������������������������������������������������������������������������������������������EP���+���+���+���+���+���+���+���+���+��in������������������������������������������������������������������������������������������������������������������������������������������������������Rf��F���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E��G��J��K��&N��,P��/R��4T��8V��Nc��cr��u�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������w���@Y��-O��G���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B��-O����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������w|���+���+���+���+���+���+���+���+�����������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��]s��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������nz�� N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��8[��������������������������������������������������������������������������������������������������������������������������.?���+���+���+���+���+���+���+���+��4����������������������������������������������������������������������������������������������������������������������������������������������������������fs��G���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E���E��%N��B\��Rf��_o��jx��t�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(M���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B��F��t���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������,>���+���+���+���+���+���+���+��sy������������������������������������������������������������������������������������������������������������������������������Rl���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��7\����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������r|���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��^q��������������������������������������������������������������������������������������������������������������������������/���+���+���+���+���+���+���+���+��di����������������������������������������������������������������������������������������������������������������������������������������������������������w���I���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D��E��F��G��H��I��I��?Z��Zk��my����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������G���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B��C��F^����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������0���+���+���+���+���+���+��:H����������������������������������������������������������������������������������������������������������������������������������$T���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L�� +M������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������q|��O���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Q��������������������������������������������������������������������������������������������������������������������������v{��1���+���+���+���+���+���+���+��1A������������������������������������������������������������������������������������������������������������������������������������������������������������������2R���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D�� K��7U��E]��Re��[l��gt��x���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(L���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A��>X��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dk���+���+���+���+���+���+��0����������������������������������������������������������������������������������������������������������������������������������}����L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��l~����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������r}���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��>^��������������������������������������������������������������������������������������������������������������������������bh��,���+���+���+���+���+���+��,��ux������������������������������������������������������������������������������������������������������������������������������������������������������������������F]���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D��1R��Sf��es��x�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������K`���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A��E��|�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2���+���+���+���+���+���+��������������������������������������������������������������������������������������������������������������������������������������'U���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Jf������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������u��P���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��br��������������������������������������������������������������������������������������������������������������������������NW���+���+���+���+���+���+���+��=J����������������������������������������������������������������������������������������������������������������������������������������������������������������������\l��G���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D�� K��z�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ly���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A��'L��dr���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+���+���+���+���+���+��S\���������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Q��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������t~�� N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Q������������������������������������������������������������������������������������������������������������������������������BN���+���+���+���+���+���+���+��������������������������������������������������������������������������������������������������������������������������������������������������������������������������z���I���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D���D��`o�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A��ap������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������&:���+���+���+���+���+�� .��������������������������������������������������������������������������������������������������������������������������������������4[���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������x���O���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Ea������������������������������������������������������������������������������������������������������������������������������';���+���+���+���+���+���+��CN������������������������������������������������������������������������������������������������������������������������������������������������������������������������������C[��D���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C��D��H^��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������F���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A��E��F]�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� .���+���+���+���+���+������������������������������������������������������������������������������������������������������������������������������������������O���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Rk��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������w���P���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��jx�����������������������������������������������������������������������������������������������������������������������������0���+���+���+���+���+��5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fs��F���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C��-P������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.O���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A��Ug������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������kq���+���+���+���+���+��`h��������������������������������������������������������������������������������������������������������������������������������������dw���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��-W����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������y��� N���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��P������������������������������������������������������������������������������������������������������������������������������jn���+���+���+���+���+��,��ek��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������5S���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C��&L��{�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������4Q���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@��A��D[��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@M���+���+���+���+��7������������������������������������������������������������������������������������������������������������������������������������������P���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������y���Q���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��B_������������������������������������������������������������������������������������������������������������������������������CO���+���+���+���+���+��8F������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������]l��I���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C��D��lx����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������9T���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@��D��Uf�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+���+���+���+���+��}���������������������������������������������������������������������������������������������������������������������������������������bw���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��_u����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{���O���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Wk������������������������������������������������������������������������������������������������������������������������������1���+���+���+���+���+�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������?Y���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C���C��Re��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������M`���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@��dr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������kq���+���+���+���+��JU�������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��?`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~��� R���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��M��kx��������������������������������������������������������������������������������������������������������������������������x{��,���+���+���+���+��JT��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������jv��+N���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B��.O������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CZ���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@��.N��]l�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+���+���+���+��2������������������������������������������������������������������������������������������������������������������������������������������Zq���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������|���P���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��!R������������������������������������������������������������������������������������������������������������������������������RZ���+���+���+���+��,����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������_m��D���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B��D��p{������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Pb���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@��=W�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+���+���+���+��\d������������������������������������������������������������������������������������������������������������������������������������������Q���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��u�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��2X������������������������������������������������������������������������������������������������������������������������������$9���+���+���+��,��jo��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������E[��E���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B��C��G]����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������F[���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?��F��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������]e���+���+���+�� .������������������������������������������������������������������������������������������������������������������������������������������Wo���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��If��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������}���%S���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Nf�����������������������������������������������������������������������������������������������������������������������������1���+���+���+��FP����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Rd��E���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B���B��G��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������H]���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?��F������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;I���+���+���+�����������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L�� R��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L�� N��p{��������������������������������������������������������������������������������������������������������������������������ek��,���+���+��6������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Te���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A��C��Qc��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CZ���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?��C����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������4���+���+��LV������������������������������������������������������������������������������������������������������������������������������������������Ni���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������*U���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Q������������������������������������������������������������������������������������������������������������������������������CN���+���+���+��tx����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[i��6R��B���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A�� H������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������,L���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?��w������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+���+�� .����������������������������������������������������������������������������������������������������������������������������������������������Q���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��\s��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"R���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��>]������������������������������������������������������������������������������������������������������������������������������*=���+���+��HR����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Se���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A��[j������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.M���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?��v�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������W_���+���+��ou������������������������������������������������������������������������������������������������������������������������������������������ey���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��9]����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'T���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��M��_p��������������������������������������������������������������������������������������������������������������������������}���1���+���+����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Pb��.N��"I��D���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A��$J��t~������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������F���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>��cp���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+���+��9G�����������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L�� +M������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(T���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��P������������������������������������������������������������������������������������������������������������������������������_f���+���+��vz����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������s|��&K���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A���A��H]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������t~��?���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>��cp�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+��0����������������������������������������������������������������������������������������������������������������������������������������������\r���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��v�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+U���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��-V������������������������������������������������������������������������������������������������������������������������������JT���+��MW������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������D���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@�� H��_l������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Rc���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>��Xh������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ns���+��R[����������������������������������������������������������������������������������������������������������������������������������������������P���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Pj������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2X���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Vk������������������������������������������������������������������������������������������������������������������������������;H��6E������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������hs���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@��'J��~�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������7Q���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>��Oa����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2C��0A����������������������������������������������������������������������������������������������������������������������������������������������s����L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��P��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/W���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O��|�������������������������������������������������������������������������������������������������������������������������������2B����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ue���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@��E[����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������$H���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>��Oa��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.?��������������������������������������������������������������������������������������������������������������������������������������������������6[���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������6Z���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��4Y����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������>V���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@��B��M`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������`m���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=��H\������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������lr���������������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��dw��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������4Y���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Ym����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������G���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@���@��E��dp������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������>U���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=��G[����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1Y���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��2Y����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������8[��M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��P��}�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������A���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?�� G��[j��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������kv��E���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=��DY���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������=]���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��C`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������qz��B���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?��C��ox��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������FZ���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=��G[��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Sl���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��z�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@^���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��my����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Yh���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?��.M��_l����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ht��E���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=��H\������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������)V���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Pj������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������A_���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��N��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������I]���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?���?��@��Te����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������&H���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=��K^�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L��Q��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������C`���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Pg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������:S���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>��B��Vf������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Wf��=���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<��Td����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.X���L���L���L���L���L���L���L���L���L���L���L���L���L���L����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Fb���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L�� N������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(I���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>��A��,K��v����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������co��A���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<��Td���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L���L���L��i{��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Kd���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��<]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"G���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>��D��bo������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������y���!E���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<��gs��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Pj���L���L���L���L���L���L���L���L���L���L���L���L���L��,W����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Le��M���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��hv��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������z���C���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>��D��<T��x�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������qz��.K��=���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<��=��hs������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������&T���L���L���L���L���L���L���L���L���L���L���L���L���L������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Me���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��*U������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mw���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>���>��^l������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������x���D���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<��=��w���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� M���L���L���L���L���L���L���L���L���L���L���L�� M��}�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Qh���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��M��cs������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������jt��>���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=��9Q��Xf����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������`l��.J���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;��A��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Xo���L���L���L���L���L���L���L���L���L���L���L���L��Jf������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Rh���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��O����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Xg���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=��A��\i��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������N_��<���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;��+H�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L��R��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Wl���L���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Og����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ud���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=��'H��Ve��s|����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������s|��EX���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;��1L�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L���L���L����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Xk��M���L���L���L���L���L���L���L���L���L���L���L���L���L��P��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������J\���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=��>��B��#F��M_��}�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������=S��A���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;��<��BV����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.X���L���L���L���L���L���L���L���L���L���L���L��hz��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\n���L���L���L���L���L���L���L���L���L���L���L���L���L���L��Pg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������EY���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=���=��'H��[i��v~������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Xf���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;��`l�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� M���L���L���L���L���L���L���L���L���L���L��1Y����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������]o��M���L���L���L���L���L���L���L���L���L���L���L���L�� M������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@U���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<��>��(H��8P��BW��Zh��{���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fq��AU��(F���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��<��v��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������z����L���L���L���L���L���L���L���L���L���L���L������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\o���L���L���L���L���L���L���L���L���L���L���L���L���L��Le������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;R���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<��;R��ep��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������}���Tc���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��*G����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Vn���L���L���L���L���L���L���L���L���L�� M�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dt���L���L���L���L���L���L���L���L���L���L���L���L��M����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;R���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<��}�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������rz��\i��J[��/J���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��?T��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������&T���L���L���L���L���L���L���L���L���L��6[������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������^p��M���L���L���L���L���L���L���L���L���L���L���L��Jd����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������>S���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<���<��@U����������������������������������������������������������������������������������������������������������������������������������������������������������������������u|��We��)G��>�� =��;���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��;��`m�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L���L��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Xk���L���L���L���L���L���L���L���L���L���L���L��Q��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������8P���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;��������������������������������������������������������������������������������������������������������������|���[g��[h��[g��[h��Vd��P_��IZ��?T��7O��"C���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��B����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������`u���L���L���L���L���L���L���L���L���L��ey������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Kd��M���L���L���L���L���L���L���L���L���L���L��\n��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<R���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;��N^������������������������������������������������������������������������������������������������������������������I[���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��;Q���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L��)V��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������:\���L���L���L���L���L���L���L���L���L���L�� M������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������DW���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;��'G��������������������������������������������������������������������������������������������������������������������������Sb���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��;��mw�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L���L���L��x�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������*U���L���L���L���L���L���L���L���L���L���L��Ym������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������K[���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;��<��py������������������������������������������������������������������������������������������������������������������������������Vd���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��B����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������p����L���L���L���L���L���L���L���L��.X��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������$S���L���L���L���L���L���L���L���L���L��*U����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ra���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;���;��@U��������������������������������������������������������������������������������������������������������������������������������������cn��;���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��_k��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������He���L���L���L���L���L���L���L�� M������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������z����L���L���L���L���L���L���L���L���L�� M��q|����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������al���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��?����������������������������������������������������������������������������������������������������������������������������������������������qz��;���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��)G����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������3Z���L���L���L���L���L���L���L��`t����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������p|��N���L���L���L���L���L���L���L���L��Fb��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cn��=���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��<��z�������������������������������������������������������������������������������������������������������������������������������������������������������$E���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��@��Xf��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������N���L���L���L���L���L���L��R������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������br��M���L���L���L���L���L���L���L���L������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������u}��=���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��Uc��������������������������������������������������������������������������������������������������������������������������������������������������������������<R���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��5N�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L���L��{�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Qh���L���L���L���L���L���L���L���L��Vk������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���$D���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��2L����������������������������������������������������������������������������������������������������������������������������������������������������������������������Yf�� =���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��B��kv����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dx���L���L���L���L���L���L��Dc������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Pg��M���L���L���L���L���L���L��P��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<R���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��)G����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+H���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��^k������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.X���L���L���L���L���L��Q��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������?^���L���L���L���L���L���L�� M��o{��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������DW���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��<������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L\��;���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��;��7O���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L���L��av������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������>]���L���L���L���L���L���L��Of������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������`k��>���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��<��t|����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������}���5N���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��@T�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������L���L���L���L���L��.X��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������5Z���L���L���L���L���L��&S����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{���<���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��;��kt����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cn���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��-I��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������}����L���L���L���L���L����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������)T���L���L���L���L���L��x���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<Q��;���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��;��Zh����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������J[��>���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��;��:P��z�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Nh���L���L���L���L��[r��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+U���L���L���L���L��Nf������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dn���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��dn����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������K\���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��EX������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.W���L���L���L���L������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������|���Q���L���L���L�� N����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~���(F���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��;��\h����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������9P��>���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��B��K\��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(U���L���L���L��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{���"R���L���L���L��}���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Sa���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��=��jt����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[h��>���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��BV��u~����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"S���L���L��Xo������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{���Q���L���L��^p������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������y��?���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��<��v}����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������lv��A��;���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��;��?��`l����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������R���L��"S��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������y���&S���L��Da��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tb��=���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��*G������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Xe��4M���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��;��:Q��\i����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P���L��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������+U��;\����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;P���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��;Q����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������lu��'F���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��@T��x�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P��q�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ti��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������hr��(F���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��>��\h��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������z���M^��9P��'F�� =���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��;��!C��4M��AU��bn��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Zp����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fp��=���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��7N����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������py��Zh��?T�� C���:���:���:���:���:���:���:���:���:���:���:���:���:��=��;Q��Vd��jt��|�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Uc��@���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��@��\h������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������`k��'F���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��Q`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������t{��)G���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��BU�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������N]��,H���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��"C��N^��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ye��;���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��@T��v}����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[g��4L��)G��@��;���:���:���:���:���:���:���:���:���:���:���:���:���:���:���:��@��*G��=R��jt��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������y���ks��[g��M]��<Q��-H��@��=��=��?��(F��8O��K[��Zf��js��y������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� \ No newline at end of file diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 305816a2b..b55c4e127 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -7,12 +7,13 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32f777zi to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f777zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } embedded-io-async = { version = "0.6.1" } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" defmt-rtt = "0.4" @@ -21,7 +22,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" rand_core = "0.6.3" diff --git a/examples/stm32f7/src/bin/adc.rs b/examples/stm32f7/src/bin/adc.rs index f8d7b691f..641157960 100644 --- a/examples/stm32f7/src/bin/adc.rs +++ b/examples/stm32f7/src/bin/adc.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::Adc; -use embassy_time::{Delay, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -12,7 +12,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut adc = Adc::new(p.ADC1, &mut Delay); + let mut adc = Adc::new(p.ADC1); let mut pin = p.PA3; let mut vrefint = adc.enable_vrefint(); diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 9a608e909..41e2a6061 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -63,9 +63,9 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; - static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); + static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); let device = Ethernet::new( - PACKETS.init(PacketQueue::<16, 16>::new()), + PACKETS.init(PacketQueue::<4, 4>::new()), p.ETH, Irqs, p.PA1, diff --git a/examples/stm32f7/src/bin/qspi.rs b/examples/stm32f7/src/bin/qspi.rs new file mode 100644 index 000000000..90d319b7a --- /dev/null +++ b/examples/stm32f7/src/bin/qspi.rs @@ -0,0 +1,301 @@ +#![no_std] +#![no_main] +#![allow(dead_code)] // Allow dead code as not all commands are used in the example + +use defmt::info; +use embassy_executor::Spawner; +use embassy_stm32::mode::Async; +use embassy_stm32::qspi::enums::{AddressSize, ChipSelectHighTime, FIFOThresholdLevel, MemorySize, *}; +use embassy_stm32::qspi::{Config as QspiCfg, Instance, Qspi, TransferConfig}; +use embassy_stm32::time::mhz; +use embassy_stm32::Config as StmCfg; +use {defmt_rtt as _, panic_probe as _}; + +const MEMORY_PAGE_SIZE: usize = 256; + +const CMD_READ: u8 = 0x03; +const CMD_HS_READ: u8 = 0x0B; +const CMD_QUAD_READ: u8 = 0x6B; + +const CMD_WRITE_PG: u8 = 0xF2; +const CMD_QUAD_WRITE_PG: u8 = 0x32; + +const CMD_READ_ID: u8 = 0x9F; +const CMD_READ_UUID: u8 = 0x4B; + +const CMD_ENABLE_RESET: u8 = 0x66; +const CMD_RESET: u8 = 0x99; + +const CMD_WRITE_ENABLE: u8 = 0x06; +const CMD_WRITE_DISABLE: u8 = 0x04; + +const CMD_CHIP_ERASE: u8 = 0xC7; +const CMD_SECTOR_ERASE: u8 = 0x20; +const CMD_BLOCK_ERASE_32K: u8 = 0x52; +const CMD_BLOCK_ERASE_64K: u8 = 0xD8; + +const CMD_READ_SR: u8 = 0x05; +const CMD_READ_CR: u8 = 0x35; + +const CMD_WRITE_SR: u8 = 0x01; +const CMD_WRITE_CR: u8 = 0x31; +const MEMORY_ADDR: u32 = 0x00000000u32; + +/// Implementation of access to flash chip. +/// Chip commands are hardcoded as it depends on used chip. +/// This implementation is using chip GD25Q64C from Giga Device +pub struct FlashMemory<I: Instance> { + qspi: Qspi<'static, I, Async>, +} + +impl<I: Instance> FlashMemory<I> { + pub fn new(qspi: Qspi<'static, I, Async>) -> Self { + let mut memory = Self { qspi }; + + memory.reset_memory(); + memory.enable_quad(); + + memory + } + + fn enable_quad(&mut self) { + let cr = self.read_cr(); + self.write_cr(cr | 0x02); + } + + fn exec_command(&mut self, cmd: u8) { + let transaction = TransferConfig { + iwidth: QspiWidth::SING, + awidth: QspiWidth::NONE, + dwidth: QspiWidth::NONE, + instruction: cmd, + address: None, + dummy: DummyCycles::_0, + }; + self.qspi.command(transaction); + } + + pub fn reset_memory(&mut self) { + self.exec_command(CMD_ENABLE_RESET); + self.exec_command(CMD_RESET); + self.wait_write_finish(); + } + + pub fn enable_write(&mut self) { + self.exec_command(CMD_WRITE_ENABLE); + } + + pub fn read_id(&mut self) -> [u8; 3] { + let mut buffer = [0; 3]; + let transaction: TransferConfig = TransferConfig { + iwidth: QspiWidth::SING, + awidth: QspiWidth::NONE, + dwidth: QspiWidth::SING, + instruction: CMD_READ_ID, + address: None, + dummy: DummyCycles::_0, + }; + self.qspi.blocking_read(&mut buffer, transaction); + buffer + } + + pub fn read_uuid(&mut self) -> [u8; 16] { + let mut buffer = [0; 16]; + let transaction: TransferConfig = TransferConfig { + iwidth: QspiWidth::SING, + awidth: QspiWidth::SING, + dwidth: QspiWidth::SING, + instruction: CMD_READ_UUID, + address: Some(0), + dummy: DummyCycles::_8, + }; + self.qspi.blocking_read(&mut buffer, transaction); + buffer + } + + pub fn read_memory(&mut self, addr: u32, buffer: &mut [u8], use_dma: bool) { + let transaction = TransferConfig { + iwidth: QspiWidth::SING, + awidth: QspiWidth::SING, + dwidth: QspiWidth::QUAD, + instruction: CMD_QUAD_READ, + address: Some(addr), + dummy: DummyCycles::_8, + }; + if use_dma { + self.qspi.blocking_read_dma(buffer, transaction); + } else { + self.qspi.blocking_read(buffer, transaction); + } + } + + fn wait_write_finish(&mut self) { + while (self.read_sr() & 0x01) != 0 {} + } + + fn perform_erase(&mut self, addr: u32, cmd: u8) { + let transaction = TransferConfig { + iwidth: QspiWidth::SING, + awidth: QspiWidth::SING, + dwidth: QspiWidth::NONE, + instruction: cmd, + address: Some(addr), + dummy: DummyCycles::_0, + }; + self.enable_write(); + self.qspi.command(transaction); + self.wait_write_finish(); + } + + pub fn erase_sector(&mut self, addr: u32) { + self.perform_erase(addr, CMD_SECTOR_ERASE); + } + + pub fn erase_block_32k(&mut self, addr: u32) { + self.perform_erase(addr, CMD_BLOCK_ERASE_32K); + } + + pub fn erase_block_64k(&mut self, addr: u32) { + self.perform_erase(addr, CMD_BLOCK_ERASE_64K); + } + + pub fn erase_chip(&mut self) { + self.exec_command(CMD_CHIP_ERASE); + } + + fn write_page(&mut self, addr: u32, buffer: &[u8], len: usize, use_dma: bool) { + assert!( + (len as u32 + (addr & 0x000000ff)) <= MEMORY_PAGE_SIZE as u32, + "write_page(): page write length exceeds page boundary (len = {}, addr = {:X}", + len, + addr + ); + + let transaction = TransferConfig { + iwidth: QspiWidth::SING, + awidth: QspiWidth::SING, + dwidth: QspiWidth::QUAD, + instruction: CMD_QUAD_WRITE_PG, + address: Some(addr), + dummy: DummyCycles::_0, + }; + self.enable_write(); + if use_dma { + self.qspi.blocking_write_dma(buffer, transaction); + } else { + self.qspi.blocking_write(buffer, transaction); + } + self.wait_write_finish(); + } + + pub fn write_memory(&mut self, addr: u32, buffer: &[u8], use_dma: bool) { + let mut left = buffer.len(); + let mut place = addr; + let mut chunk_start = 0; + + while left > 0 { + let max_chunk_size = MEMORY_PAGE_SIZE - (place & 0x000000ff) as usize; + let chunk_size = if left >= max_chunk_size { max_chunk_size } else { left }; + let chunk = &buffer[chunk_start..(chunk_start + chunk_size)]; + self.write_page(place, chunk, chunk_size, use_dma); + place += chunk_size as u32; + left -= chunk_size; + chunk_start += chunk_size; + } + } + + fn read_register(&mut self, cmd: u8) -> u8 { + let mut buffer = [0; 1]; + let transaction: TransferConfig = TransferConfig { + iwidth: QspiWidth::SING, + awidth: QspiWidth::NONE, + dwidth: QspiWidth::SING, + instruction: cmd, + address: None, + dummy: DummyCycles::_0, + }; + self.qspi.blocking_read(&mut buffer, transaction); + buffer[0] + } + + fn write_register(&mut self, cmd: u8, value: u8) { + let buffer = [value; 1]; + let transaction: TransferConfig = TransferConfig { + iwidth: QspiWidth::SING, + awidth: QspiWidth::NONE, + dwidth: QspiWidth::SING, + instruction: cmd, + address: None, + dummy: DummyCycles::_0, + }; + self.qspi.blocking_write(&buffer, transaction); + } + + pub fn read_sr(&mut self) -> u8 { + self.read_register(CMD_READ_SR) + } + + pub fn read_cr(&mut self) -> u8 { + self.read_register(CMD_READ_CR) + } + + pub fn write_sr(&mut self, value: u8) { + self.write_register(CMD_WRITE_SR, value); + } + + pub fn write_cr(&mut self, value: u8) { + self.write_register(CMD_WRITE_CR, value); + } +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + let mut config = StmCfg::default(); + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: mhz(8), + mode: HseMode::Oscillator, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL216, + divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz + divq: None, + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } + let p = embassy_stm32::init(config); + info!("Embassy initialized"); + + let config = QspiCfg { + memory_size: MemorySize::_8MiB, + address_size: AddressSize::_24bit, + prescaler: 16, + cs_high_time: ChipSelectHighTime::_1Cycle, + fifo_threshold: FIFOThresholdLevel::_16Bytes, + }; + let driver = Qspi::new_bank1( + p.QUADSPI, p.PF8, p.PF9, p.PE2, p.PF6, p.PF10, p.PB10, p.DMA2_CH7, config, + ); + let mut flash = FlashMemory::new(driver); + let flash_id = flash.read_id(); + info!("FLASH ID: {:?}", flash_id); + let mut wr_buf = [0u8; 256]; + for i in 0..256 { + wr_buf[i] = i as u8; + } + let mut rd_buf = [0u8; 256]; + flash.erase_sector(MEMORY_ADDR); + flash.write_memory(MEMORY_ADDR, &wr_buf, true); + flash.read_memory(MEMORY_ADDR, &mut rd_buf, true); + info!("WRITE BUF: {:?}", wr_buf); + info!("READ BUF: {:?}", rd_buf); + info!("End of Program, proceed to empty endless loop"); + loop {} +} diff --git a/examples/stm32f7/src/bin/usart_dma.rs b/examples/stm32f7/src/bin/usart_dma.rs index fb604b34f..47456adf2 100644 --- a/examples/stm32f7/src/bin/usart_dma.rs +++ b/examples/stm32f7/src/bin/usart_dma.rs @@ -5,7 +5,6 @@ use core::fmt::Write; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::{bind_interrupts, peripherals, usart}; use heapless::String; @@ -19,7 +18,7 @@ bind_interrupts!(struct Irqs { async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); let config = Config::default(); - let mut usart = Uart::new(p.UART7, p.PA8, p.PA15, Irqs, p.DMA1_CH1, NoDma, config).unwrap(); + let mut usart = Uart::new(p.UART7, p.PA8, p.PA15, Irqs, p.DMA1_CH1, p.DMA1_CH3, config).unwrap(); for n in 0u32.. { let mut s: String<128> = String::new(); diff --git a/examples/stm32f7/src/bin/usb_serial.rs b/examples/stm32f7/src/bin/usb_serial.rs index 39a5512f4..0e5cc7c5c 100644 --- a/examples/stm32f7/src/bin/usb_serial.rs +++ b/examples/stm32f7/src/bin/usb_serial.rs @@ -3,19 +3,24 @@ use defmt::{panic, *}; use embassy_executor::Spawner; +use embassy_futures::join::join; use embassy_stm32::time::Hertz; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; -use futures::future::join; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); +// If you are trying this and your USB device doesn't connect, the most +// common issues are the RCC config and vbus_detection +// +// See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure +// for more information. #[embassy_executor::main] async fn main(_spawner: Spawner) { info!("Hello World!"); @@ -46,7 +51,13 @@ async fn main(_spawner: Spawner) { // Create the driver, from the HAL. let mut ep_out_buffer = [0u8; 256]; let mut config = embassy_stm32::usb::Config::default(); - config.vbus_detection = true; + + // Do not enable vbus_detection. This is a safe default that works in all boards. + // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need + // to enable vbus_detection to comply with the USB spec. If you enable it, the board + // has to support it or USB won't work at all. See docs on `vbus_detection` for details. + config.vbus_detection = false; + let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); // Create embassy-usb Config diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index 6ce3418e5..122a996e5 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml @@ -7,10 +7,10 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32g0b1re to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g0b1re", "memory-x", "unstable-pac", "exti"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" @@ -20,7 +20,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } diff --git a/examples/stm32g0/src/bin/i2c_async.rs b/examples/stm32g0/src/bin/i2c_async.rs new file mode 100644 index 000000000..7e3189b05 --- /dev/null +++ b/examples/stm32g0/src/bin/i2c_async.rs @@ -0,0 +1,48 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::i2c::{self, I2c}; +use embassy_stm32::time::Hertz; +use embassy_stm32::{bind_interrupts, peripherals}; +use embassy_time::{Duration, Timer}; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + I2C1 => i2c::EventInterruptHandler<peripherals::I2C1>, i2c::ErrorInterruptHandler<peripherals::I2C1>; +}); + +const TMP117_ADDR: u8 = 0x48; +const TMP117_TEMP_RESULT: u8 = 0x00; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("Hello world"); + + let p = embassy_stm32::init(Default::default()); + + let mut data = [0u8; 2]; + let mut i2c = I2c::new( + p.I2C1, + p.PB8, + p.PB9, + Irqs, + p.DMA1_CH1, + p.DMA1_CH2, + Hertz(100_000), + Default::default(), + ); + + loop { + match i2c.write_read(TMP117_ADDR, &[TMP117_TEMP_RESULT], &mut data).await { + Ok(()) => { + let temp = f32::from(i16::from_be_bytes(data)) * 7.8125 / 1000.0; + info!("Temperature {}", temp); + } + Err(_) => error!("I2C Error"), + } + + Timer::after(Duration::from_millis(1000)).await; + } +} diff --git a/examples/stm32g0/src/bin/spi_neopixel.rs b/examples/stm32g0/src/bin/spi_neopixel.rs index c5ea51721..2deee271d 100644 --- a/examples/stm32g0/src/bin/spi_neopixel.rs +++ b/examples/stm32g0/src/bin/spi_neopixel.rs @@ -4,7 +4,6 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::dma::word::U5; -use embassy_stm32::dma::NoDma; use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::time::Hertz; use embassy_time::Timer; @@ -77,7 +76,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.frequency = Hertz(4_000_000); - let mut spi = Spi::new_txonly_nosck(p.SPI1, p.PB5, p.DMA1_CH3, NoDma, config); + let mut spi = Spi::new_txonly_nosck(p.SPI1, p.PB5, p.DMA1_CH3, config); let mut neopixels = Ws2812::new(); diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 64c749b9b..9a34ba19d 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml @@ -7,10 +7,10 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32g491re to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } usbd-hid = "0.7.0" @@ -22,7 +22,6 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" embedded-can = { version = "0.4" } panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } static_cell = "2.0.0" diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs index ae64bc8e4..3de38cbd6 100644 --- a/examples/stm32g4/src/bin/adc.rs +++ b/examples/stm32g4/src/bin/adc.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; use embassy_stm32::Config; -use embassy_time::{Delay, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -28,8 +28,8 @@ async fn main(_spawner: Spawner) { let mut p = embassy_stm32::init(config); info!("Hello World!"); - let mut adc = Adc::new(p.ADC2, &mut Delay); - adc.set_sample_time(SampleTime::CYCLES32_5); + let mut adc = Adc::new(p.ADC2); + adc.set_sample_time(SampleTime::CYCLES24_5); loop { let measured = adc.read(&mut p.PA7); diff --git a/examples/stm32g4/src/bin/can.rs b/examples/stm32g4/src/bin/can.rs index 2ed632a93..90004f874 100644 --- a/examples/stm32g4/src/bin/can.rs +++ b/examples/stm32g4/src/bin/can.rs @@ -38,7 +38,7 @@ async fn main(_spawner: Spawner) { let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); - can.set_extended_filter( + can.properties().set_extended_filter( can::filter::ExtendedFilterSlot::_0, can::filter::ExtendedFilter::accept_all_into_fifo1(), ); @@ -128,7 +128,7 @@ async fn main(_spawner: Spawner) { } } i = 0; - let (mut tx, mut rx) = can.split(); + let (mut tx, mut rx, _props) = can.split(); // With split loop { let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); @@ -192,7 +192,7 @@ async fn main(_spawner: Spawner) { Timer::after_millis(250).await; - i += 1; + i = i.wrapping_add(1); } } else { static TX_BUF: StaticCell<can::TxBuf<8>> = StaticCell::new(); @@ -228,7 +228,7 @@ async fn main(_spawner: Spawner) { Timer::after_millis(250).await; - i += 1; + i = i.wrapping_add(1); } } } diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs index dbe8f27c1..ed2ac7fac 100644 --- a/examples/stm32g4/src/bin/usb_serial.rs +++ b/examples/stm32g4/src/bin/usb_serial.rs @@ -3,13 +3,13 @@ use defmt::{panic, *}; use embassy_executor::Spawner; +use embassy_futures::join::join; use embassy_stm32::time::Hertz; use embassy_stm32::usb::{self, Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; -use futures::future::join; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index c9f08d24e..87de9f3a4 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -6,12 +6,13 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32h563zi to your chip name, if necessary. -embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "low-power"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" defmt-rtt = "0.4" @@ -24,7 +25,6 @@ embedded-hal-async = { version = "1.0" } embedded-io-async = { version = "0.6.1" } embedded-nal-async = { version = "0.7.1" } panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } rand_core = "0.6.3" critical-section = "1.1" diff --git a/examples/stm32h5/src/bin/can.rs b/examples/stm32h5/src/bin/can.rs index dd625c90a..194239d47 100644 --- a/examples/stm32h5/src/bin/can.rs +++ b/examples/stm32h5/src/bin/can.rs @@ -67,7 +67,7 @@ async fn main(_spawner: Spawner) { } } - let (mut tx, mut rx) = can.split(); + let (mut tx, mut rx, _props) = can.split(); // With split loop { let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); @@ -93,6 +93,6 @@ async fn main(_spawner: Spawner) { Timer::after_millis(250).await; - i += 1; + i = i.wrapping_add(1); } } diff --git a/examples/stm32h5/src/bin/stop.rs b/examples/stm32h5/src/bin/stop.rs new file mode 100644 index 000000000..0d14c0668 --- /dev/null +++ b/examples/stm32h5/src/bin/stop.rs @@ -0,0 +1,71 @@ +// Notice: +// the MCU might need an extra reset to make the code actually running + +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; +use embassy_stm32::low_power::Executor; +use embassy_stm32::rcc::{HSIPrescaler, LsConfig}; +use embassy_stm32::rtc::{Rtc, RtcConfig}; +use embassy_stm32::Config; +use embassy_time::Timer; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +#[cortex_m_rt::entry] +fn main() -> ! { + Executor::take().run(|spawner| { + unwrap!(spawner.spawn(async_main(spawner))); + }) +} + +#[embassy_executor::task] +async fn async_main(spawner: Spawner) { + defmt::info!("Program Start"); + + let mut config = Config::default(); + + // System Clock seems need to be equal or lower than 16 MHz + config.rcc.hsi = Some(HSIPrescaler::DIV4); + + config.rcc.ls = LsConfig::default_lsi(); + // when enabled the power-consumption is much higher during stop, but debugging and RTT is working + // if you wan't to measure the power-consumption, or for production: uncomment this line + // config.enable_debug_during_sleep = false; + let p = embassy_stm32::init(config); + + // give the RTC to the executor... + let rtc = Rtc::new(p.RTC, RtcConfig::default()); + static RTC: StaticCell<Rtc> = StaticCell::new(); + let rtc = RTC.init(rtc); + embassy_stm32::low_power::stop_with_rtc(rtc); + + unwrap!(spawner.spawn(blinky(p.PB4.into()))); + unwrap!(spawner.spawn(timeout())); +} + +#[embassy_executor::task] +async fn blinky(led: AnyPin) { + let mut led = Output::new(led, Level::Low, Speed::Low); + loop { + info!("high"); + led.set_high(); + Timer::after_millis(300).await; + + info!("low"); + led.set_low(); + Timer::after_millis(300).await; + } +} + +// when enable_debug_during_sleep is false, it is more difficult to reprogram the MCU +// therefore we block the MCU after 30s to be able to reprogram it easily +#[embassy_executor::task] +async fn timeout() -> ! { + Timer::after_secs(30).await; + #[allow(clippy::empty_loop)] + loop {} +} diff --git a/examples/stm32h5/src/bin/usart.rs b/examples/stm32h5/src/bin/usart.rs index f9cbad6af..cc49c2fdb 100644 --- a/examples/stm32h5/src/bin/usart.rs +++ b/examples/stm32h5/src/bin/usart.rs @@ -4,22 +4,16 @@ use cortex_m_rt::entry; use defmt::*; use embassy_executor::Executor; -use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; -use embassy_stm32::{bind_interrupts, peripherals, usart}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; -bind_interrupts!(struct Irqs { - UART7 => usart::InterruptHandler<peripherals::UART7>; -}); - #[embassy_executor::task] async fn main_task() { let p = embassy_stm32::init(Default::default()); let config = Config::default(); - let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, NoDma, NoDma, config).unwrap(); + let mut usart = Uart::new_blocking(p.UART7, p.PF6, p.PF7, config).unwrap(); unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); info!("wrote Hello, starting echo"); diff --git a/examples/stm32h5/src/bin/usart_dma.rs b/examples/stm32h5/src/bin/usart_dma.rs index caae0dd18..c644e84bd 100644 --- a/examples/stm32h5/src/bin/usart_dma.rs +++ b/examples/stm32h5/src/bin/usart_dma.rs @@ -6,7 +6,6 @@ use core::fmt::Write; use cortex_m_rt::entry; use defmt::*; use embassy_executor::Executor; -use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::{bind_interrupts, peripherals, usart}; use heapless::String; @@ -22,7 +21,7 @@ async fn main_task() { let p = embassy_stm32::init(Default::default()); let config = Config::default(); - let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.GPDMA1_CH0, NoDma, config).unwrap(); + let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.GPDMA1_CH0, p.GPDMA1_CH1, config).unwrap(); for n in 0u32.. { let mut s: String<128> = String::new(); diff --git a/examples/stm32h5/src/bin/usart_split.rs b/examples/stm32h5/src/bin/usart_split.rs index 92047de8d..d26c5003c 100644 --- a/examples/stm32h5/src/bin/usart_split.rs +++ b/examples/stm32h5/src/bin/usart_split.rs @@ -3,8 +3,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; -use embassy_stm32::peripherals::{GPDMA1_CH1, UART7}; +use embassy_stm32::mode::Async; use embassy_stm32::usart::{Config, Uart, UartRx}; use embassy_stm32::{bind_interrupts, peripherals, usart}; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; @@ -15,18 +14,6 @@ bind_interrupts!(struct Irqs { UART7 => usart::InterruptHandler<peripherals::UART7>; }); -#[embassy_executor::task] -async fn writer(mut usart: Uart<'static, UART7, NoDma, NoDma>) { - unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); - info!("wrote Hello, starting echo"); - - let mut buf = [0u8; 1]; - loop { - unwrap!(usart.blocking_read(&mut buf)); - unwrap!(usart.blocking_write(&buf)); - } -} - static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); #[embassy_executor::main] @@ -50,7 +37,7 @@ async fn main(spawner: Spawner) -> ! { } #[embassy_executor::task] -async fn reader(mut rx: UartRx<'static, UART7, GPDMA1_CH1>) { +async fn reader(mut rx: UartRx<'static, Async>) { let mut buf = [0; 8]; loop { info!("reading..."); diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs index 4f86bb342..fbcbdb5f9 100644 --- a/examples/stm32h5/src/bin/usb_serial.rs +++ b/examples/stm32h5/src/bin/usb_serial.rs @@ -3,13 +3,13 @@ use defmt::{panic, *}; use embassy_executor::Spawner; +use embassy_futures::join::join; use embassy_stm32::time::Hertz; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; -use futures::future::join; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 84a89b378..14125f819 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -7,11 +7,13 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32h743bi to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" defmt-rtt = "0.4" @@ -24,7 +26,6 @@ embedded-hal-async = { version = "1.0" } embedded-nal-async = { version = "0.7.1" } embedded-io-async = { version = "0.6.1" } panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } rand_core = "0.6.3" critical-section = "1.1" diff --git a/examples/stm32h7/build.rs b/examples/stm32h7/build.rs index 8cd32d7ed..30691aa97 100644 --- a/examples/stm32h7/build.rs +++ b/examples/stm32h7/build.rs @@ -1,4 +1,34 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); + println!("cargo:rustc-link-arg-bins=--nmagic"); println!("cargo:rustc-link-arg-bins=-Tlink.x"); println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); diff --git a/examples/stm32h7/memory.x b/examples/stm32h7/memory.x new file mode 100644 index 000000000..e5ab1f62c --- /dev/null +++ b/examples/stm32h7/memory.x @@ -0,0 +1,14 @@ +MEMORY +{ + FLASH : ORIGIN = 0x08000000, LENGTH = 2048K /* BANK_1 + BANK_2 */ + RAM : ORIGIN = 0x24000000, LENGTH = 512K /* SRAM */ + RAM_D3 : ORIGIN = 0x38000000, LENGTH = 64K /* SRAM4 */ +} + +SECTIONS +{ + .ram_d3 : + { + *(.ram_d3) + } > RAM_D3 +} \ No newline at end of file diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs index a5594d10c..e9a857a74 100644 --- a/examples/stm32h7/src/bin/adc.rs +++ b/examples/stm32h7/src/bin/adc.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; use embassy_stm32::Config; -use embassy_time::{Delay, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -44,14 +44,14 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); - let mut adc = Adc::new(p.ADC3, &mut Delay); + let mut adc = Adc::new(p.ADC3); adc.set_sample_time(SampleTime::CYCLES32_5); let mut vrefint_channel = adc.enable_vrefint(); loop { - let vrefint = adc.read_internal(&mut vrefint_channel); + let vrefint = adc.read(&mut vrefint_channel); info!("vrefint: {}", vrefint); let measured = adc.read(&mut p.PC0); info!("measured: {}", measured); diff --git a/examples/stm32h7/src/bin/can.rs b/examples/stm32h7/src/bin/can.rs index 22cb27481..0af11ef3e 100644 --- a/examples/stm32h7/src/bin/can.rs +++ b/examples/stm32h7/src/bin/can.rs @@ -67,7 +67,7 @@ async fn main(_spawner: Spawner) { } } - let (mut tx, mut rx) = can.split(); + let (mut tx, mut rx, _props) = can.split(); // With split loop { let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); @@ -93,6 +93,6 @@ async fn main(_spawner: Spawner) { Timer::after_millis(250).await; - i += 1; + i = i.wrapping_add(1); } } diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index aeb169e19..0639fb99f 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -64,10 +64,10 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; - static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); + static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); let device = Ethernet::new( - PACKETS.init(PacketQueue::<16, 16>::new()), + PACKETS.init(PacketQueue::<4, 4>::new()), p.ETH, Irqs, p.PA1, diff --git a/examples/stm32h7/src/bin/eth_client_mii.rs b/examples/stm32h7/src/bin/eth_client_mii.rs index de6ea522a..9a52e8d3b 100644 --- a/examples/stm32h7/src/bin/eth_client_mii.rs +++ b/examples/stm32h7/src/bin/eth_client_mii.rs @@ -64,10 +64,10 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; - static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); + static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); let device = Ethernet::new_mii( - PACKETS.init(PacketQueue::<16, 16>::new()), + PACKETS.init(PacketQueue::<4, 4>::new()), p.ETH, Irqs, p.PA1, diff --git a/examples/stm32h7/src/bin/i2c_shared.rs b/examples/stm32h7/src/bin/i2c_shared.rs new file mode 100644 index 000000000..6f4815582 --- /dev/null +++ b/examples/stm32h7/src/bin/i2c_shared.rs @@ -0,0 +1,111 @@ +#![no_std] +#![no_main] + +use core::cell::RefCell; + +use defmt::*; +use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice; +use embassy_executor::Spawner; +use embassy_stm32::i2c::{self, I2c}; +use embassy_stm32::mode::Async; +use embassy_stm32::time::Hertz; +use embassy_stm32::{bind_interrupts, peripherals}; +use embassy_sync::blocking_mutex::NoopMutex; +use embassy_time::{Duration, Timer}; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +const TMP117_ADDR: u8 = 0x48; +const TMP117_TEMP_RESULT: u8 = 0x00; + +const SHTC3_ADDR: u8 = 0x70; +const SHTC3_WAKEUP: [u8; 2] = [0x35, 0x17]; +const SHTC3_MEASURE_RH_FIRST: [u8; 2] = [0x5c, 0x24]; +const SHTC3_SLEEP: [u8; 2] = [0xb0, 0x98]; + +static I2C_BUS: StaticCell<NoopMutex<RefCell<I2c<'static, Async>>>> = StaticCell::new(); + +bind_interrupts!(struct Irqs { + I2C1_EV => i2c::EventInterruptHandler<peripherals::I2C1>; + I2C1_ER => i2c::ErrorInterruptHandler<peripherals::I2C1>; +}); + +#[embassy_executor::task] +async fn temperature(mut i2c: impl embedded_hal_1::i2c::I2c + 'static) { + let mut data = [0u8; 2]; + + loop { + match i2c.write_read(TMP117_ADDR, &[TMP117_TEMP_RESULT], &mut data) { + Ok(()) => { + let temp = f32::from(i16::from_be_bytes(data)) * 7.8125 / 1000.0; + info!("Temperature {}", temp); + } + Err(_) => error!("I2C Error"), + } + + Timer::after(Duration::from_millis(1000)).await; + } +} + +#[embassy_executor::task] +async fn humidity(mut i2c: impl embedded_hal_1::i2c::I2c + 'static) { + let mut data = [0u8; 6]; + + loop { + // Wakeup + match i2c.write(SHTC3_ADDR, &SHTC3_WAKEUP) { + Ok(()) => Timer::after(Duration::from_millis(20)).await, + Err(_) => error!("I2C Error"), + } + + // Measurement + match i2c.write(SHTC3_ADDR, &SHTC3_MEASURE_RH_FIRST) { + Ok(()) => Timer::after(Duration::from_millis(5)).await, + Err(_) => error!("I2C Error"), + } + + // Result + match i2c.read(SHTC3_ADDR, &mut data) { + Ok(()) => Timer::after(Duration::from_millis(5)).await, + Err(_) => error!("I2C Error"), + } + + // Sleep + match i2c.write(SHTC3_ADDR, &SHTC3_SLEEP) { + Ok(()) => { + let (bytes, _) = data.split_at(core::mem::size_of::<i16>()); + let rh = f32::from(u16::from_be_bytes(bytes.try_into().unwrap())) * 100.0 / 65536.0; + info!("Humidity: {}", rh); + } + Err(_) => error!("I2C Error"), + } + + Timer::after(Duration::from_millis(1000)).await; + } +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_stm32::init(Default::default()); + + let i2c = I2c::new( + p.I2C1, + p.PB8, + p.PB9, + Irqs, + p.DMA1_CH4, + p.DMA1_CH5, + Hertz(100_000), + Default::default(), + ); + let i2c_bus = NoopMutex::new(RefCell::new(i2c)); + let i2c_bus = I2C_BUS.init(i2c_bus); + + // Device 1, using embedded-hal-async compatible driver for TMP117 + let i2c_dev1 = I2cDevice::new(i2c_bus); + spawner.spawn(temperature(i2c_dev1)).unwrap(); + + // Device 2, using embedded-hal-async compatible driver for SHTC3 + let i2c_dev2 = I2cDevice::new(i2c_bus); + spawner.spawn(humidity(i2c_dev2)).unwrap(); +} diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs index aed27723a..ad4a8aaf7 100644 --- a/examples/stm32h7/src/bin/spi.rs +++ b/examples/stm32h7/src/bin/spi.rs @@ -7,8 +7,7 @@ use core::str::from_utf8; use cortex_m_rt::entry; use defmt::*; use embassy_executor::Executor; -use embassy_stm32::dma::NoDma; -use embassy_stm32::peripherals::SPI3; +use embassy_stm32::mode::Blocking; use embassy_stm32::time::mhz; use embassy_stm32::{spi, Config}; use heapless::String; @@ -16,7 +15,7 @@ use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] -async fn main_task(mut spi: spi::Spi<'static, SPI3, NoDma, NoDma>) { +async fn main_task(mut spi: spi::Spi<'static, Blocking>) { for n in 0u32.. { let mut write: String<128> = String::new(); core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); @@ -62,7 +61,7 @@ fn main() -> ! { let mut spi_config = spi::Config::default(); spi_config.frequency = mhz(1); - let spi = spi::Spi::new(p.SPI3, p.PB3, p.PB5, p.PB4, NoDma, NoDma, spi_config); + let spi = spi::Spi::new_blocking(p.SPI3, p.PB3, p.PB5, p.PB4, spi_config); let executor = EXECUTOR.init(Executor::new()); diff --git a/examples/stm32h7/src/bin/spi_bdma.rs b/examples/stm32h7/src/bin/spi_bdma.rs new file mode 100644 index 000000000..b2e941078 --- /dev/null +++ b/examples/stm32h7/src/bin/spi_bdma.rs @@ -0,0 +1,78 @@ +#![no_std] +#![no_main] + +use core::fmt::Write; +use core::str::from_utf8; + +use cortex_m_rt::entry; +use defmt::*; +use embassy_executor::Executor; +use embassy_stm32::mode::Async; +use embassy_stm32::time::mhz; +use embassy_stm32::{spi, Config}; +use heapless::String; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +// Defined in memory.x +#[link_section = ".ram_d3"] +static mut RAM_D3: [u8; 64 * 1024] = [0u8; 64 * 1024]; + +#[embassy_executor::task] +async fn main_task(mut spi: spi::Spi<'static, Async>) { + let read_buffer = unsafe { &mut RAM_D3[0..128] }; + let write_buffer = unsafe { &mut RAM_D3[128..256] }; + + for n in 0u32.. { + let mut write: String<128> = String::new(); + core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); + let read_buffer = &mut read_buffer[..write.len()]; + let write_buffer = &mut write_buffer[..write.len()]; + // copy data to write_buffer which is located in D3 domain, accessable by BDMA + write_buffer.clone_from_slice(write.as_bytes()); + + spi.transfer(read_buffer, write_buffer).await.ok(); + info!("read via spi+dma: {}", from_utf8(read_buffer).unwrap()); + } +} + +static EXECUTOR: StaticCell<Executor> = StaticCell::new(); + +#[entry] +fn main() -> ! { + info!("Hello World!"); + + let mut config = Config::default(); + { + use embassy_stm32::rcc::*; + config.rcc.hsi = Some(HSIPrescaler::DIV1); + config.rcc.csi = true; + config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV8), // used by SPI3. 100Mhz. + divr: None, + }); + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz + config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz + config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz + config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz + config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz + config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz + config.rcc.voltage_scale = VoltageScale::Scale1; + } + let p = embassy_stm32::init(config); + + let mut spi_config = spi::Config::default(); + spi_config.frequency = mhz(1); + + let spi = spi::Spi::new(p.SPI6, p.PA5, p.PA7, p.PA6, p.BDMA_CH1, p.BDMA_CH0, spi_config); + + let executor = EXECUTOR.init(Executor::new()); + + executor.run(|spawner| { + unwrap!(spawner.spawn(main_task(spi))); + }) +} diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs index 54d4d7656..731c7fef5 100644 --- a/examples/stm32h7/src/bin/spi_dma.rs +++ b/examples/stm32h7/src/bin/spi_dma.rs @@ -7,7 +7,7 @@ use core::str::from_utf8; use cortex_m_rt::entry; use defmt::*; use embassy_executor::Executor; -use embassy_stm32::peripherals::{DMA1_CH3, DMA1_CH4, SPI3}; +use embassy_stm32::mode::Async; use embassy_stm32::time::mhz; use embassy_stm32::{spi, Config}; use heapless::String; @@ -15,7 +15,7 @@ use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] -async fn main_task(mut spi: spi::Spi<'static, SPI3, DMA1_CH3, DMA1_CH4>) { +async fn main_task(mut spi: spi::Spi<'static, Async>) { for n in 0u32.. { let mut write: String<128> = String::new(); let mut read = [0; 128]; diff --git a/examples/stm32h7/src/bin/usart.rs b/examples/stm32h7/src/bin/usart.rs index f9cbad6af..cc49c2fdb 100644 --- a/examples/stm32h7/src/bin/usart.rs +++ b/examples/stm32h7/src/bin/usart.rs @@ -4,22 +4,16 @@ use cortex_m_rt::entry; use defmt::*; use embassy_executor::Executor; -use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; -use embassy_stm32::{bind_interrupts, peripherals, usart}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; -bind_interrupts!(struct Irqs { - UART7 => usart::InterruptHandler<peripherals::UART7>; -}); - #[embassy_executor::task] async fn main_task() { let p = embassy_stm32::init(Default::default()); let config = Config::default(); - let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, NoDma, NoDma, config).unwrap(); + let mut usart = Uart::new_blocking(p.UART7, p.PF6, p.PF7, config).unwrap(); unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); info!("wrote Hello, starting echo"); diff --git a/examples/stm32h7/src/bin/usart_dma.rs b/examples/stm32h7/src/bin/usart_dma.rs index ae1f3a2e9..6f340d40a 100644 --- a/examples/stm32h7/src/bin/usart_dma.rs +++ b/examples/stm32h7/src/bin/usart_dma.rs @@ -6,7 +6,6 @@ use core::fmt::Write; use cortex_m_rt::entry; use defmt::*; use embassy_executor::Executor; -use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::{bind_interrupts, peripherals, usart}; use heapless::String; @@ -22,7 +21,7 @@ async fn main_task() { let p = embassy_stm32::init(Default::default()); let config = Config::default(); - let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.DMA1_CH0, NoDma, config).unwrap(); + let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.DMA1_CH0, p.DMA1_CH1, config).unwrap(); for n in 0u32.. { let mut s: String<128> = String::new(); diff --git a/examples/stm32h7/src/bin/usart_split.rs b/examples/stm32h7/src/bin/usart_split.rs index b98c40877..2bb58be5e 100644 --- a/examples/stm32h7/src/bin/usart_split.rs +++ b/examples/stm32h7/src/bin/usart_split.rs @@ -3,8 +3,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; -use embassy_stm32::peripherals::{DMA1_CH1, UART7}; +use embassy_stm32::mode::Async; use embassy_stm32::usart::{Config, Uart, UartRx}; use embassy_stm32::{bind_interrupts, peripherals, usart}; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; @@ -15,18 +14,6 @@ bind_interrupts!(struct Irqs { UART7 => usart::InterruptHandler<peripherals::UART7>; }); -#[embassy_executor::task] -async fn writer(mut usart: Uart<'static, UART7, NoDma, NoDma>) { - unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); - info!("wrote Hello, starting echo"); - - let mut buf = [0u8; 1]; - loop { - unwrap!(usart.blocking_read(&mut buf)); - unwrap!(usart.blocking_write(&buf)); - } -} - static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); #[embassy_executor::main] @@ -50,7 +37,7 @@ async fn main(spawner: Spawner) -> ! { } #[embassy_executor::task] -async fn reader(mut rx: UartRx<'static, UART7, DMA1_CH1>) { +async fn reader(mut rx: UartRx<'static, Async>) { let mut buf = [0; 8]; loop { info!("reading..."); diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs index 576506ad3..1c50fc1c8 100644 --- a/examples/stm32h7/src/bin/usb_serial.rs +++ b/examples/stm32h7/src/bin/usb_serial.rs @@ -3,18 +3,23 @@ use defmt::{panic, *}; use embassy_executor::Spawner; +use embassy_futures::join::join; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; -use futures::future::join; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); +// If you are trying this and your USB device doesn't connect, the most +// common issues are the RCC config and vbus_detection +// +// See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure +// for more information. #[embassy_executor::main] async fn main(_spawner: Spawner) { info!("Hello World!"); @@ -47,7 +52,13 @@ async fn main(_spawner: Spawner) { // Create the driver, from the HAL. let mut ep_out_buffer = [0u8; 256]; let mut config = embassy_stm32::usb::Config::default(); - config.vbus_detection = true; + + // Do not enable vbus_detection. This is a safe default that works in all boards. + // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need + // to enable vbus_detection to comply with the USB spec. If you enable it, the board + // has to support it or USB won't work at all. See docs on `vbus_detection` for details. + config.vbus_detection = false; + let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); // Create embassy-usb Config diff --git a/examples/stm32h7rs/.cargo/config.toml b/examples/stm32h7rs/.cargo/config.toml new file mode 100644 index 000000000..44dbda94f --- /dev/null +++ b/examples/stm32h7rs/.cargo/config.toml @@ -0,0 +1,8 @@ +[target.thumbv7em-none-eabihf] +runner = 'probe-rs run --chip STM32H7S3L8Hx' + +[build] +target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) + +[env] +DEFMT_LOG = "trace" diff --git a/examples/stm32h7rs/Cargo.toml b/examples/stm32h7rs/Cargo.toml new file mode 100644 index 000000000..f8c49f3d1 --- /dev/null +++ b/examples/stm32h7rs/Cargo.toml @@ -0,0 +1,73 @@ +[package] +edition = "2021" +name = "embassy-stm32h7rs-examples" +version = "0.1.0" +license = "MIT OR Apache-2.0" + +[dependencies] +# Change stm32h743bi to your chip name, if necessary. +embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h7s3l8", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } +embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } + +defmt = "0.3" +defmt-rtt = "0.4" + +cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } +cortex-m-rt = "0.7.0" +embedded-hal = "0.2.6" +embedded-hal-1 = { package = "embedded-hal", version = "1.0" } +embedded-hal-async = { version = "1.0" } +embedded-nal-async = { version = "0.7.1" } +embedded-io-async = { version = "0.6.1" } +panic-probe = { version = "0.3", features = ["print-defmt"] } +heapless = { version = "0.8", default-features = false } +rand_core = "0.6.3" +critical-section = "1.1" +micromath = "2.0.0" +stm32-fmc = "0.3.0" +embedded-storage = "0.3.1" +static_cell = "2" +chrono = { version = "^0.4", default-features = false } + +# cargo build/run +[profile.dev] +codegen-units = 1 +debug = 2 +debug-assertions = true # <- +incremental = false +opt-level = 3 # <- +overflow-checks = true # <- + +# cargo test +[profile.test] +codegen-units = 1 +debug = 2 +debug-assertions = true # <- +incremental = false +opt-level = 3 # <- +overflow-checks = true # <- + +# cargo build/run --release +[profile.release] +codegen-units = 1 +debug = 2 +debug-assertions = false # <- +incremental = false +lto = 'fat' +opt-level = 3 # <- +overflow-checks = false # <- + +# cargo test --release +[profile.bench] +codegen-units = 1 +debug = 2 +debug-assertions = false # <- +incremental = false +lto = 'fat' +opt-level = 3 # <- +overflow-checks = false # <- diff --git a/examples/stm32h7rs/build.rs b/examples/stm32h7rs/build.rs new file mode 100644 index 000000000..8cd32d7ed --- /dev/null +++ b/examples/stm32h7rs/build.rs @@ -0,0 +1,5 @@ +fn main() { + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/examples/stm32h7rs/src/bin/blinky.rs b/examples/stm32h7rs/src/bin/blinky.rs new file mode 100644 index 000000000..137c585b7 --- /dev/null +++ b/examples/stm32h7rs/src/bin/blinky.rs @@ -0,0 +1,51 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::gpio::{Level, Output, Speed}; +use embassy_stm32::time::Hertz; +use embassy_stm32::Config; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut config = Config::default(); + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(24_000_000), + mode: HseMode::Oscillator, + }); + config.rcc.pll1 = Some(Pll { + source: PllSource::HSE, + prediv: PllPreDiv::DIV3, + mul: PllMul::MUL150, + divp: Some(PllDiv::DIV2), + divq: None, + divr: None, + }); + config.rcc.sys = Sysclk::PLL1_P; // 600 Mhz + config.rcc.ahb_pre = AHBPrescaler::DIV2; // 300 Mhz + config.rcc.apb1_pre = APBPrescaler::DIV2; // 150 Mhz + config.rcc.apb2_pre = APBPrescaler::DIV2; // 150 Mhz + config.rcc.apb4_pre = APBPrescaler::DIV2; // 150 Mhz + config.rcc.apb5_pre = APBPrescaler::DIV2; // 150 Mhz + config.rcc.voltage_scale = VoltageScale::HIGH; + } + let p = embassy_stm32::init(config); + info!("Hello World!"); + + let mut led = Output::new(p.PD10, Level::High, Speed::Low); + + loop { + info!("high"); + led.set_high(); + Timer::after_millis(500).await; + + info!("low"); + led.set_low(); + Timer::after_millis(500).await; + } +} diff --git a/examples/stm32h7rs/src/bin/button_exti.rs b/examples/stm32h7rs/src/bin/button_exti.rs new file mode 100644 index 000000000..34a08bbc6 --- /dev/null +++ b/examples/stm32h7rs/src/bin/button_exti.rs @@ -0,0 +1,25 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::exti::ExtiInput; +use embassy_stm32::gpio::Pull; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + + info!("Press the USER button..."); + + loop { + button.wait_for_falling_edge().await; + info!("Pressed!"); + button.wait_for_rising_edge().await; + info!("Released!"); + } +} diff --git a/examples/stm32h7rs/src/bin/can.rs b/examples/stm32h7rs/src/bin/can.rs new file mode 100644 index 000000000..0af11ef3e --- /dev/null +++ b/examples/stm32h7rs/src/bin/can.rs @@ -0,0 +1,98 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::peripherals::*; +use embassy_stm32::{bind_interrupts, can, rcc, Config}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>; + FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut config = Config::default(); + config.rcc.hse = Some(rcc::Hse { + freq: embassy_stm32::time::Hertz(25_000_000), + mode: rcc::HseMode::Oscillator, + }); + config.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE; + + let peripherals = embassy_stm32::init(config); + + let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); + + // 250k bps + can.set_bitrate(250_000); + + //let mut can = can.into_internal_loopback_mode(); + let mut can = can.into_normal_mode(); + + info!("CAN Configured"); + + let mut i = 0; + let mut last_read_ts = embassy_time::Instant::now(); + + loop { + let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); + info!("Writing frame"); + _ = can.write(&frame).await; + + match can.read().await { + Ok(envelope) => { + let (rx_frame, ts) = envelope.parts(); + let delta = (ts - last_read_ts).as_millis(); + last_read_ts = ts; + info!( + "Rx: {:x} {:x} {:x} {:x} --- NEW {}", + rx_frame.data()[0], + rx_frame.data()[1], + rx_frame.data()[2], + rx_frame.data()[3], + delta, + ) + } + Err(_err) => error!("Error in frame"), + } + + Timer::after_millis(250).await; + + i += 1; + if i > 3 { + break; + } + } + + let (mut tx, mut rx, _props) = can.split(); + // With split + loop { + let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); + info!("Writing frame"); + _ = tx.write(&frame).await; + + match rx.read().await { + Ok(envelope) => { + let (rx_frame, ts) = envelope.parts(); + let delta = (ts - last_read_ts).as_millis(); + last_read_ts = ts; + info!( + "Rx: {:x} {:x} {:x} {:x} --- NEW {}", + rx_frame.data()[0], + rx_frame.data()[1], + rx_frame.data()[2], + rx_frame.data()[3], + delta, + ) + } + Err(_err) => error!("Error in frame"), + } + + Timer::after_millis(250).await; + + i = i.wrapping_add(1); + } +} diff --git a/examples/stm32h7rs/src/bin/i2c.rs b/examples/stm32h7rs/src/bin/i2c.rs new file mode 100644 index 000000000..31e83cbb5 --- /dev/null +++ b/examples/stm32h7rs/src/bin/i2c.rs @@ -0,0 +1,42 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::i2c::{Error, I2c}; +use embassy_stm32::time::Hertz; +use embassy_stm32::{bind_interrupts, i2c, peripherals}; +use {defmt_rtt as _, panic_probe as _}; + +const ADDRESS: u8 = 0x5F; +const WHOAMI: u8 = 0x0F; + +bind_interrupts!(struct Irqs { + I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>; + I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("Hello world!"); + let p = embassy_stm32::init(Default::default()); + + let mut i2c = I2c::new( + p.I2C2, + p.PB10, + p.PB11, + Irqs, + p.GPDMA1_CH4, + p.GPDMA1_CH5, + Hertz(100_000), + Default::default(), + ); + + let mut data = [0u8; 1]; + + match i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) { + Ok(()) => info!("Whoami: {}", data[0]), + Err(Error::Timeout) => error!("Operation timed out"), + Err(e) => error!("I2c Error: {:?}", e), + } +} diff --git a/examples/stm32h7rs/src/bin/mco.rs b/examples/stm32h7rs/src/bin/mco.rs new file mode 100644 index 000000000..a6ee27625 --- /dev/null +++ b/examples/stm32h7rs/src/bin/mco.rs @@ -0,0 +1,29 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::gpio::{Level, Output, Speed}; +use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + let mut led = Output::new(p.PB14, Level::High, Speed::Low); + + let _mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV8); + + loop { + info!("high"); + led.set_high(); + Timer::after_millis(500).await; + + info!("low"); + led.set_low(); + Timer::after_millis(500).await; + } +} diff --git a/examples/stm32h7rs/src/bin/multiprio.rs b/examples/stm32h7rs/src/bin/multiprio.rs new file mode 100644 index 000000000..fcbb6c653 --- /dev/null +++ b/examples/stm32h7rs/src/bin/multiprio.rs @@ -0,0 +1,150 @@ +//! This example showcases how to create multiple Executor instances to run tasks at +//! different priority levels. +//! +//! Low priority executor runs in thread mode (not interrupt), and uses `sev` for signaling +//! there's work in the queue, and `wfe` for waiting for work. +//! +//! Medium and high priority executors run in two interrupts with different priorities. +//! Signaling work is done by pending the interrupt. No "waiting" needs to be done explicitly, since +//! when there's work the interrupt will trigger and run the executor. +//! +//! Sample output below. Note that high priority ticks can interrupt everything else, and +//! medium priority computations can interrupt low priority computations, making them to appear +//! to take significantly longer time. +//! +//! ```not_rust +//! [med] Starting long computation +//! [med] done in 992 ms +//! [high] tick! +//! [low] Starting long computation +//! [med] Starting long computation +//! [high] tick! +//! [high] tick! +//! [med] done in 993 ms +//! [med] Starting long computation +//! [high] tick! +//! [high] tick! +//! [med] done in 993 ms +//! [low] done in 3972 ms +//! [med] Starting long computation +//! [high] tick! +//! [high] tick! +//! [med] done in 993 ms +//! ``` +//! +//! For comparison, try changing the code so all 3 tasks get spawned on the low priority executor. +//! You will get an output like the following. Note that no computation is ever interrupted. +//! +//! ```not_rust +//! [high] tick! +//! [med] Starting long computation +//! [med] done in 496 ms +//! [low] Starting long computation +//! [low] done in 992 ms +//! [med] Starting long computation +//! [med] done in 496 ms +//! [high] tick! +//! [low] Starting long computation +//! [low] done in 992 ms +//! [high] tick! +//! [med] Starting long computation +//! [med] done in 496 ms +//! [high] tick! +//! ``` +//! + +#![no_std] +#![no_main] + +use cortex_m_rt::entry; +use defmt::*; +use embassy_executor::{Executor, InterruptExecutor}; +use embassy_stm32::interrupt; +use embassy_stm32::interrupt::{InterruptExt, Priority}; +use embassy_time::{Instant, Timer}; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::task] +async fn run_high() { + loop { + info!(" [high] tick!"); + Timer::after_ticks(27374).await; + } +} + +#[embassy_executor::task] +async fn run_med() { + loop { + let start = Instant::now(); + info!(" [med] Starting long computation"); + + // Spin-wait to simulate a long CPU computation + cortex_m::asm::delay(128_000_000); // ~1 second + + let end = Instant::now(); + let ms = end.duration_since(start).as_ticks() / 33; + info!(" [med] done in {} ms", ms); + + Timer::after_ticks(23421).await; + } +} + +#[embassy_executor::task] +async fn run_low() { + loop { + let start = Instant::now(); + info!("[low] Starting long computation"); + + // Spin-wait to simulate a long CPU computation + cortex_m::asm::delay(256_000_000); // ~2 seconds + + let end = Instant::now(); + let ms = end.duration_since(start).as_ticks() / 33; + info!("[low] done in {} ms", ms); + + Timer::after_ticks(32983).await; + } +} + +static EXECUTOR_HIGH: InterruptExecutor = InterruptExecutor::new(); +static EXECUTOR_MED: InterruptExecutor = InterruptExecutor::new(); +static EXECUTOR_LOW: StaticCell<Executor> = StaticCell::new(); + +#[interrupt] +unsafe fn UART4() { + EXECUTOR_HIGH.on_interrupt() +} + +#[interrupt] +unsafe fn UART5() { + EXECUTOR_MED.on_interrupt() +} + +#[entry] +fn main() -> ! { + info!("Hello World!"); + + let _p = embassy_stm32::init(Default::default()); + + // STM32s don’t have any interrupts exclusively for software use, but they can all be triggered by software as well as + // by the peripheral, so we can just use any free interrupt vectors which aren’t used by the rest of your application. + // In this case we’re using UART4 and UART5, but there’s nothing special about them. Any otherwise unused interrupt + // vector would work exactly the same. + + // High-priority executor: UART4, priority level 6 + interrupt::UART4.set_priority(Priority::P6); + let spawner = EXECUTOR_HIGH.start(interrupt::UART4); + unwrap!(spawner.spawn(run_high())); + + // Medium-priority executor: UART5, priority level 7 + interrupt::UART5.set_priority(Priority::P7); + let spawner = EXECUTOR_MED.start(interrupt::UART5); + unwrap!(spawner.spawn(run_med())); + + // Low priority executor: runs in thread mode, using WFE/SEV + let executor = EXECUTOR_LOW.init(Executor::new()); + executor.run(|spawner| { + unwrap!(spawner.spawn(run_low())); + }); +} diff --git a/examples/stm32h7rs/src/bin/rng.rs b/examples/stm32h7rs/src/bin/rng.rs new file mode 100644 index 000000000..a9ef7200d --- /dev/null +++ b/examples/stm32h7rs/src/bin/rng.rs @@ -0,0 +1,26 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::rng::Rng; +use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + RNG => rng::InterruptHandler<peripherals::RNG>; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut config = Config::default(); + config.rcc.hsi48 = Some(Default::default()); // needed for RNG + let p = embassy_stm32::init(config); + info!("Hello World!"); + + let mut rng = Rng::new(p.RNG, Irqs); + + let mut buf = [0u8; 16]; + unwrap!(rng.async_fill_bytes(&mut buf).await); + info!("random bytes: {:02x}", buf); +} diff --git a/examples/stm32h7rs/src/bin/rtc.rs b/examples/stm32h7rs/src/bin/rtc.rs new file mode 100644 index 000000000..0adb48877 --- /dev/null +++ b/examples/stm32h7rs/src/bin/rtc.rs @@ -0,0 +1,36 @@ +#![no_std] +#![no_main] + +use chrono::{NaiveDate, NaiveDateTime}; +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::rcc::LsConfig; +use embassy_stm32::rtc::{Rtc, RtcConfig}; +use embassy_stm32::Config; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut config = Config::default(); + config.rcc.ls = LsConfig::default_lse(); + + let p = embassy_stm32::init(config); + info!("Hello World!"); + + let now = NaiveDate::from_ymd_opt(2020, 5, 15) + .unwrap() + .and_hms_opt(10, 30, 15) + .unwrap(); + + let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); + info!("Got RTC! {:?}", now.and_utc().timestamp()); + + rtc.set_datetime(now.into()).expect("datetime not set"); + + // In reality the delay would be much longer + Timer::after_millis(20000).await; + + let then: NaiveDateTime = rtc.now().unwrap().into(); + info!("Got RTC! {:?}", then.and_utc().timestamp()); +} diff --git a/examples/stm32h7rs/src/bin/signal.rs b/examples/stm32h7rs/src/bin/signal.rs new file mode 100644 index 000000000..b73360f32 --- /dev/null +++ b/examples/stm32h7rs/src/bin/signal.rs @@ -0,0 +1,36 @@ +#![no_std] +#![no_main] + +use defmt::{info, unwrap}; +use embassy_executor::Spawner; +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_sync::signal::Signal; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +static SIGNAL: Signal<CriticalSectionRawMutex, u32> = Signal::new(); + +#[embassy_executor::task] +async fn my_sending_task() { + let mut counter: u32 = 0; + + loop { + Timer::after_secs(1).await; + + SIGNAL.signal(counter); + + counter = counter.wrapping_add(1); + } +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let _p = embassy_stm32::init(Default::default()); + unwrap!(spawner.spawn(my_sending_task())); + + loop { + let received_counter = SIGNAL.wait().await; + + info!("signalled, counter: {}", received_counter); + } +} diff --git a/examples/stm32h7rs/src/bin/spi.rs b/examples/stm32h7rs/src/bin/spi.rs new file mode 100644 index 000000000..8d6ccc58b --- /dev/null +++ b/examples/stm32h7rs/src/bin/spi.rs @@ -0,0 +1,49 @@ +#![no_std] +#![no_main] + +use core::fmt::Write; +use core::str::from_utf8; + +use cortex_m_rt::entry; +use defmt::*; +use embassy_executor::Executor; +use embassy_stm32::mode::Blocking; +use embassy_stm32::spi; +use embassy_stm32::time::mhz; +use heapless::String; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::task] +async fn main_task(mut spi: spi::Spi<'static, Blocking>) { + for n in 0u32.. { + let mut write: String<128> = String::new(); + core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); + unsafe { + let result = spi.blocking_transfer_in_place(write.as_bytes_mut()); + if let Err(_) = result { + defmt::panic!("crap"); + } + } + info!("read via spi: {}", from_utf8(write.as_bytes()).unwrap()); + } +} + +static EXECUTOR: StaticCell<Executor> = StaticCell::new(); + +#[entry] +fn main() -> ! { + info!("Hello World!"); + let p = embassy_stm32::init(Default::default()); + + let mut spi_config = spi::Config::default(); + spi_config.frequency = mhz(1); + + let spi = spi::Spi::new_blocking(p.SPI3, p.PB3, p.PB5, p.PB4, spi_config); + + let executor = EXECUTOR.init(Executor::new()); + + executor.run(|spawner| { + unwrap!(spawner.spawn(main_task(spi))); + }) +} diff --git a/examples/stm32h7rs/src/bin/spi_dma.rs b/examples/stm32h7rs/src/bin/spi_dma.rs new file mode 100644 index 000000000..cb305351b --- /dev/null +++ b/examples/stm32h7rs/src/bin/spi_dma.rs @@ -0,0 +1,46 @@ +#![no_std] +#![no_main] + +use core::fmt::Write; +use core::str::from_utf8; + +use cortex_m_rt::entry; +use defmt::*; +use embassy_executor::Executor; +use embassy_stm32::mode::Async; +use embassy_stm32::spi; +use embassy_stm32::time::mhz; +use heapless::String; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::task] +async fn main_task(mut spi: spi::Spi<'static, Async>) { + for n in 0u32.. { + let mut write: String<128> = String::new(); + let mut read = [0; 128]; + core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); + // transfer will slice the &mut read down to &write's actual length. + spi.transfer(&mut read, write.as_bytes()).await.ok(); + info!("read via spi+dma: {}", from_utf8(&read).unwrap()); + } +} + +static EXECUTOR: StaticCell<Executor> = StaticCell::new(); + +#[entry] +fn main() -> ! { + info!("Hello World!"); + let p = embassy_stm32::init(Default::default()); + + let mut spi_config = spi::Config::default(); + spi_config.frequency = mhz(1); + + let spi = spi::Spi::new(p.SPI3, p.PB3, p.PB5, p.PB4, p.GPDMA1_CH0, p.GPDMA1_CH1, spi_config); + + let executor = EXECUTOR.init(Executor::new()); + + executor.run(|spawner| { + unwrap!(spawner.spawn(main_task(spi))); + }) +} diff --git a/examples/stm32h7rs/src/bin/usart.rs b/examples/stm32h7rs/src/bin/usart.rs new file mode 100644 index 000000000..cc49c2fdb --- /dev/null +++ b/examples/stm32h7rs/src/bin/usart.rs @@ -0,0 +1,39 @@ +#![no_std] +#![no_main] + +use cortex_m_rt::entry; +use defmt::*; +use embassy_executor::Executor; +use embassy_stm32::usart::{Config, Uart}; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::task] +async fn main_task() { + let p = embassy_stm32::init(Default::default()); + + let config = Config::default(); + let mut usart = Uart::new_blocking(p.UART7, p.PF6, p.PF7, config).unwrap(); + + unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); + info!("wrote Hello, starting echo"); + + let mut buf = [0u8; 1]; + loop { + unwrap!(usart.blocking_read(&mut buf)); + unwrap!(usart.blocking_write(&buf)); + } +} + +static EXECUTOR: StaticCell<Executor> = StaticCell::new(); + +#[entry] +fn main() -> ! { + info!("Hello World!"); + + let executor = EXECUTOR.init(Executor::new()); + + executor.run(|spawner| { + unwrap!(spawner.spawn(main_task())); + }) +} diff --git a/examples/stm32h7rs/src/bin/usart_dma.rs b/examples/stm32h7rs/src/bin/usart_dma.rs new file mode 100644 index 000000000..c644e84bd --- /dev/null +++ b/examples/stm32h7rs/src/bin/usart_dma.rs @@ -0,0 +1,47 @@ +#![no_std] +#![no_main] + +use core::fmt::Write; + +use cortex_m_rt::entry; +use defmt::*; +use embassy_executor::Executor; +use embassy_stm32::usart::{Config, Uart}; +use embassy_stm32::{bind_interrupts, peripherals, usart}; +use heapless::String; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + UART7 => usart::InterruptHandler<peripherals::UART7>; +}); + +#[embassy_executor::task] +async fn main_task() { + let p = embassy_stm32::init(Default::default()); + + let config = Config::default(); + let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.GPDMA1_CH0, p.GPDMA1_CH1, config).unwrap(); + + for n in 0u32.. { + let mut s: String<128> = String::new(); + core::write!(&mut s, "Hello DMA World {}!\r\n", n).unwrap(); + + usart.write(s.as_bytes()).await.ok(); + + info!("wrote DMA"); + } +} + +static EXECUTOR: StaticCell<Executor> = StaticCell::new(); + +#[entry] +fn main() -> ! { + info!("Hello World!"); + + let executor = EXECUTOR.init(Executor::new()); + + executor.run(|spawner| { + unwrap!(spawner.spawn(main_task())); + }) +} diff --git a/examples/stm32h7rs/src/bin/usart_split.rs b/examples/stm32h7rs/src/bin/usart_split.rs new file mode 100644 index 000000000..d26c5003c --- /dev/null +++ b/examples/stm32h7rs/src/bin/usart_split.rs @@ -0,0 +1,47 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::mode::Async; +use embassy_stm32::usart::{Config, Uart, UartRx}; +use embassy_stm32::{bind_interrupts, peripherals, usart}; +use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; +use embassy_sync::channel::Channel; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + UART7 => usart::InterruptHandler<peripherals::UART7>; +}); + +static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); + +#[embassy_executor::main] +async fn main(spawner: Spawner) -> ! { + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + let config = Config::default(); + let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.GPDMA1_CH0, p.GPDMA1_CH1, config).unwrap(); + unwrap!(usart.blocking_write(b"Type 8 chars to echo!\r\n")); + + let (mut tx, rx) = usart.split(); + + unwrap!(spawner.spawn(reader(rx))); + + loop { + let buf = CHANNEL.receive().await; + info!("writing..."); + unwrap!(tx.write(&buf).await); + } +} + +#[embassy_executor::task] +async fn reader(mut rx: UartRx<'static, Async>) { + let mut buf = [0; 8]; + loop { + info!("reading..."); + unwrap!(rx.read(&mut buf).await); + CHANNEL.send(buf).await; + } +} diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index dd9097c9b..b6de182e1 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32l072cz to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "memory-x"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } @@ -21,7 +21,6 @@ embedded-io-async = { version = "0.6.1" } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } embedded-hal = "0.2.6" static_cell = { version = "2" } diff --git a/examples/stm32l0/src/bin/adc.rs b/examples/stm32l0/src/bin/adc.rs index 97d41ca4b..9dd09bc45 100644 --- a/examples/stm32l0/src/bin/adc.rs +++ b/examples/stm32l0/src/bin/adc.rs @@ -4,13 +4,13 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; -use embassy_stm32::peripherals::ADC; +use embassy_stm32::peripherals::ADC1; use embassy_stm32::{adc, bind_interrupts}; -use embassy_time::{Delay, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { - ADC1_COMP => adc::InterruptHandler<ADC>; + ADC1_COMP => adc::InterruptHandler<ADC1>; }); #[embassy_executor::main] @@ -18,11 +18,11 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut adc = Adc::new(p.ADC, Irqs, &mut Delay); + let mut adc = Adc::new(p.ADC1, Irqs); adc.set_sample_time(SampleTime::CYCLES79_5); let mut pin = p.PA1; - let mut vrefint = adc.enable_vref(&mut Delay); + let mut vrefint = adc.enable_vref(); let vrefint_sample = adc.read(&mut vrefint).await; let convert_to_millivolts = |sample| { // From https://www.st.com/resource/en/datasheet/stm32l051c6.pdf diff --git a/examples/stm32l0/src/bin/spi.rs b/examples/stm32l0/src/bin/spi.rs index f23a537b8..8e0cfdedb 100644 --- a/examples/stm32l0/src/bin/spi.rs +++ b/examples/stm32l0/src/bin/spi.rs @@ -3,7 +3,6 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::time::Hertz; @@ -17,7 +16,7 @@ async fn main(_spawner: Spawner) { let mut spi_config = Config::default(); spi_config.frequency = Hertz(1_000_000); - let mut spi = Spi::new(p.SPI1, p.PB3, p.PA7, p.PA6, NoDma, NoDma, spi_config); + let mut spi = Spi::new_blocking(p.SPI1, p.PB3, p.PA7, p.PA6, spi_config); let mut cs = Output::new(p.PA15, Level::High, Speed::VeryHigh); diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml index 322c41262..17887bc14 100644 --- a/examples/stm32l1/Cargo.toml +++ b/examples/stm32l1/Cargo.toml @@ -5,11 +5,12 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" defmt-rtt = "0.4" @@ -18,7 +19,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } embedded-storage = "0.3.1" diff --git a/examples/stm32l1/src/bin/spi.rs b/examples/stm32l1/src/bin/spi.rs index 8be686c5a..eabf1bac2 100644 --- a/examples/stm32l1/src/bin/spi.rs +++ b/examples/stm32l1/src/bin/spi.rs @@ -3,7 +3,6 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::time::Hertz; @@ -17,7 +16,7 @@ async fn main(_spawner: Spawner) { let mut spi_config = Config::default(); spi_config.frequency = Hertz(1_000_000); - let mut spi = Spi::new(p.SPI1, p.PA5, p.PA7, p.PA6, NoDma, NoDma, spi_config); + let mut spi = Spi::new_blocking(p.SPI1, p.PA5, p.PA7, p.PA6, spi_config); let mut cs = Output::new(p.PA4, Level::High, Speed::VeryHigh); diff --git a/examples/stm32l1/src/bin/usb_serial.rs b/examples/stm32l1/src/bin/usb_serial.rs index 653bbd6d2..837f7fa57 100644 --- a/examples/stm32l1/src/bin/usb_serial.rs +++ b/examples/stm32l1/src/bin/usb_serial.rs @@ -3,12 +3,12 @@ use defmt::{panic, *}; use embassy_executor::Spawner; +use embassy_futures::join::join; use embassy_stm32::usb::{self, Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; -use futures::future::join; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { diff --git a/examples/stm32l4/.cargo/config.toml b/examples/stm32l4/.cargo/config.toml index db3a7ceff..83fc6d6f8 100644 --- a/examples/stm32l4/.cargo/config.toml +++ b/examples/stm32l4/.cargo/config.toml @@ -2,7 +2,7 @@ # replace STM32F429ZITx with your chip as listed in `probe-rs chip list` #runner = "probe-rs run --chip STM32L475VGT6" #runner = "probe-rs run --chip STM32L475VG" -runner = "probe-run --chip STM32L4S5QI" +runner = "probe-rs run --chip STM32L4S5QI" [build] target = "thumbv7em-none-eabi" diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index d42e69578..37f09bbcc 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -7,11 +7,11 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32l4s5vi to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l4s5qi", "memory-x", "time-driver-any", "exti", "chrono"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", ] } embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } embassy-net-adin1110 = { version = "0.2.0", path = "../../embassy-net-adin1110" } embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "udp", "tcp", "dhcpv4", "medium-ethernet"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } @@ -28,7 +28,6 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-hal-bus = { version = "0.1", features = ["async"] } panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } chrono = { version = "^0.4", default-features = false } rand = { version = "0.8.5", default-features = false } diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs index a9f4604aa..7a89334e0 100644 --- a/examples/stm32l4/src/bin/adc.rs +++ b/examples/stm32l4/src/bin/adc.rs @@ -4,7 +4,6 @@ use defmt::*; use embassy_stm32::adc::{Adc, Resolution}; use embassy_stm32::Config; -use embassy_time::Delay; use {defmt_rtt as _, panic_probe as _}; #[cortex_m_rt::entry] @@ -18,7 +17,7 @@ fn main() -> ! { } let p = embassy_stm32::init(config); - let mut adc = Adc::new(p.ADC1, &mut Delay); + let mut adc = Adc::new(p.ADC1); //adc.enable_vref(); adc.set_resolution(Resolution::BITS8); let mut channel = p.PC0; diff --git a/examples/stm32l4/src/bin/can.rs b/examples/stm32l4/src/bin/can.rs new file mode 100644 index 000000000..3c4cdac24 --- /dev/null +++ b/examples/stm32l4/src/bin/can.rs @@ -0,0 +1,68 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::can::filter::Mask32; +use embassy_stm32::can::{ + Can, Fifo, Frame, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler, +}; +use embassy_stm32::peripherals::CAN1; +use embassy_stm32::{bind_interrupts, Config}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + CAN1_RX0 => Rx0InterruptHandler<CAN1>; + CAN1_RX1 => Rx1InterruptHandler<CAN1>; + CAN1_SCE => SceInterruptHandler<CAN1>; + CAN1_TX => TxInterruptHandler<CAN1>; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(Config::default()); + + let mut can = Can::new(p.CAN1, p.PA11, p.PA12, Irqs); + + can.modify_filters().enable_bank(0, Fifo::Fifo0, Mask32::accept_all()); + + can.modify_config() + .set_loopback(true) // Receive own frames + .set_silent(true) + .set_bitrate(250_000); + + can.enable().await; + println!("CAN enabled"); + + let mut i = 0; + let mut last_read_ts = embassy_time::Instant::now(); + loop { + let frame = Frame::new_extended(0x123456F, &[i; 8]).unwrap(); + info!("Writing frame"); + + _ = can.write(&frame).await; + + match can.read().await { + Ok(envelope) => { + let (ts, rx_frame) = (envelope.ts, envelope.frame); + let delta = (ts - last_read_ts).as_millis(); + last_read_ts = ts; + info!( + "Rx: {} {:02x} --- {}ms", + rx_frame.header().len(), + rx_frame.data()[0..rx_frame.header().len() as usize], + delta, + ) + } + Err(err) => error!("Error in frame: {}", err), + } + + Timer::after_millis(250).await; + + i += 1; + if i > 2 { + break; + } + } +} diff --git a/examples/stm32l4/src/bin/i2c.rs b/examples/stm32l4/src/bin/i2c.rs index f553deb82..2861bc091 100644 --- a/examples/stm32l4/src/bin/i2c.rs +++ b/examples/stm32l4/src/bin/i2c.rs @@ -3,33 +3,17 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::i2c::I2c; use embassy_stm32::time::Hertz; -use embassy_stm32::{bind_interrupts, i2c, peripherals}; use {defmt_rtt as _, panic_probe as _}; const ADDRESS: u8 = 0x5F; const WHOAMI: u8 = 0x0F; -bind_interrupts!(struct Irqs { - I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>; - I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; -}); - #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let mut i2c = I2c::new( - p.I2C2, - p.PB10, - p.PB11, - Irqs, - NoDma, - NoDma, - Hertz(100_000), - Default::default(), - ); + let mut i2c = I2c::new_blocking(p.I2C2, p.PB10, p.PB11, Hertz(100_000), Default::default()); let mut data = [0u8; 1]; unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data)); diff --git a/examples/stm32l4/src/bin/i2c_blocking_async.rs b/examples/stm32l4/src/bin/i2c_blocking_async.rs index 1b8652bcc..a014b23e0 100644 --- a/examples/stm32l4/src/bin/i2c_blocking_async.rs +++ b/examples/stm32l4/src/bin/i2c_blocking_async.rs @@ -4,34 +4,18 @@ use defmt::*; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::i2c::I2c; use embassy_stm32::time::Hertz; -use embassy_stm32::{bind_interrupts, i2c, peripherals}; use embedded_hal_async::i2c::I2c as I2cTrait; use {defmt_rtt as _, panic_probe as _}; const ADDRESS: u8 = 0x5F; const WHOAMI: u8 = 0x0F; -bind_interrupts!(struct Irqs { - I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>; - I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; -}); - #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let i2c = I2c::new( - p.I2C2, - p.PB10, - p.PB11, - Irqs, - NoDma, - NoDma, - Hertz(100_000), - Default::default(), - ); + let i2c = I2c::new_blocking(p.I2C2, p.PB10, p.PB11, Hertz(100_000), Default::default()); let mut i2c = BlockingAsync::new(i2c); let mut data = [0u8; 1]; diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 77aa929ab..33149144c 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -23,18 +23,23 @@ use embassy_futures::select::{select, Either}; use embassy_futures::yield_now; use embassy_net::tcp::TcpSocket; use embassy_net::{Ipv4Address, Ipv4Cidr, Stack, StackResources, StaticConfigV4}; +use embassy_net_adin1110::{Device, Runner, ADIN1110}; +use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; +use embassy_stm32::i2c::{self, Config as I2C_Config, I2c}; +use embassy_stm32::mode::Async; +use embassy_stm32::rng::{self, Rng}; +use embassy_stm32::spi::{Config as SPI_Config, Spi}; +use embassy_stm32::time::Hertz; +use embassy_stm32::{bind_interrupts, exti, pac, peripherals}; use embassy_time::{Delay, Duration, Ticker, Timer}; use embedded_hal_async::i2c::I2c as I2cBus; +use embedded_hal_bus::spi::ExclusiveDevice; use embedded_io::Write as bWrite; use embedded_io_async::Write; -use hal::gpio::{Input, Level, Output, Speed}; -use hal::i2c::{self, I2c}; -use hal::rng::{self, Rng}; -use hal::{bind_interrupts, exti, pac, peripherals}; use heapless::Vec; +use panic_probe as _; use rand::RngCore; use static_cell::StaticCell; -use {embassy_stm32 as hal, panic_probe as _}; bind_interrupts!(struct Irqs { I2C3_EV => i2c::EventInterruptHandler<peripherals::I2C3>; @@ -42,13 +47,6 @@ bind_interrupts!(struct Irqs { RNG => rng::InterruptHandler<peripherals::RNG>; }); -use embassy_net_adin1110::{Device, Runner, ADIN1110}; -use embedded_hal_bus::spi::ExclusiveDevice; -use hal::gpio::Pull; -use hal::i2c::Config as I2C_Config; -use hal::spi::{Config as SPI_Config, Spi}; -use hal::time::Hertz; - // Basic settings // MAC-address used by the adin1110 const MAC: [u8; 6] = [0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]; @@ -57,12 +55,12 @@ const IP_ADDRESS: Ipv4Cidr = Ipv4Cidr::new(Ipv4Address([192, 168, 1, 5]), 24); // Listen port for the webserver const HTTP_LISTEN_PORT: u16 = 80; -pub type SpeSpi = Spi<'static, peripherals::SPI2, peripherals::DMA1_CH1, peripherals::DMA1_CH2>; +pub type SpeSpi = Spi<'static, Async>; pub type SpeSpiCs = ExclusiveDevice<SpeSpi, Output<'static>, Delay>; pub type SpeInt = exti::ExtiInput<'static>; pub type SpeRst = Output<'static>; pub type Adin1110T = ADIN1110<SpeSpiCs>; -pub type TempSensI2c = I2c<'static, peripherals::I2C3, peripherals::DMA1_CH6, peripherals::DMA1_CH7>; +pub type TempSensI2c = I2c<'static, Async>; static TEMP: AtomicI32 = AtomicI32::new(0); diff --git a/examples/stm32l4/src/bin/spi.rs b/examples/stm32l4/src/bin/spi.rs index 6653e4516..5693a3765 100644 --- a/examples/stm32l4/src/bin/spi.rs +++ b/examples/stm32l4/src/bin/spi.rs @@ -2,7 +2,6 @@ #![no_main] use defmt::*; -use embassy_stm32::dma::NoDma; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::time::Hertz; @@ -17,7 +16,7 @@ fn main() -> ! { let mut spi_config = Config::default(); spi_config.frequency = Hertz(1_000_000); - let mut spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, NoDma, NoDma, spi_config); + let mut spi = Spi::new_blocking(p.SPI3, p.PC10, p.PC12, p.PC11, spi_config); let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh); diff --git a/examples/stm32l4/src/bin/spi_blocking_async.rs b/examples/stm32l4/src/bin/spi_blocking_async.rs index 68dbb70ad..1f1089101 100644 --- a/examples/stm32l4/src/bin/spi_blocking_async.rs +++ b/examples/stm32l4/src/bin/spi_blocking_async.rs @@ -4,7 +4,6 @@ use defmt::*; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::time::Hertz; @@ -19,7 +18,7 @@ async fn main(_spawner: Spawner) { let mut spi_config = Config::default(); spi_config.frequency = Hertz(1_000_000); - let spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, NoDma, NoDma, spi_config); + let spi = Spi::new_blocking(p.SPI3, p.PC10, p.PC12, p.PC11, spi_config); let mut spi = BlockingAsync::new(spi); diff --git a/examples/stm32l4/src/bin/usart.rs b/examples/stm32l4/src/bin/usart.rs index 7bab23950..d9b388026 100644 --- a/examples/stm32l4/src/bin/usart.rs +++ b/examples/stm32l4/src/bin/usart.rs @@ -2,7 +2,6 @@ #![no_main] use defmt::*; -use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::{bind_interrupts, peripherals, usart}; use {defmt_rtt as _, panic_probe as _}; @@ -18,7 +17,7 @@ fn main() -> ! { let p = embassy_stm32::init(Default::default()); let config = Config::default(); - let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, Irqs, NoDma, NoDma, config).unwrap(); + let mut usart = Uart::new_blocking(p.UART4, p.PA1, p.PA0, config).unwrap(); unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); info!("wrote Hello, starting echo"); diff --git a/examples/stm32l4/src/bin/usart_dma.rs b/examples/stm32l4/src/bin/usart_dma.rs index 031888f70..b4f7a1643 100644 --- a/examples/stm32l4/src/bin/usart_dma.rs +++ b/examples/stm32l4/src/bin/usart_dma.rs @@ -5,7 +5,6 @@ use core::fmt::Write; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::{bind_interrupts, peripherals, usart}; use heapless::String; @@ -21,7 +20,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let config = Config::default(); - let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, Irqs, p.DMA1_CH3, NoDma, config).unwrap(); + let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, Irqs, p.DMA1_CH3, p.DMA1_CH4, config).unwrap(); for n in 0u32.. { let mut s: String<128> = String::new(); diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index 198504b59..ed9671d0f 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs @@ -4,18 +4,23 @@ use defmt::{panic, *}; use defmt_rtt as _; // global logger use embassy_executor::Spawner; +use embassy_futures::join::join; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; -use futures::future::join; use panic_probe as _; bind_interrupts!(struct Irqs { OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; }); +// If you are trying this and your USB device doesn't connect, the most +// common issues are the RCC config and vbus_detection +// +// See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure +// for more information. #[embassy_executor::main] async fn main(_spawner: Spawner) { info!("Hello World!"); @@ -41,7 +46,13 @@ async fn main(_spawner: Spawner) { // Create the driver, from the HAL. let mut ep_out_buffer = [0u8; 256]; let mut config = embassy_stm32::usb::Config::default(); - config.vbus_detection = true; + + // Do not enable vbus_detection. This is a safe default that works in all boards. + // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need + // to enable vbus_detection to comply with the USB spec. If you enable it, the board + // has to support it or USB won't work at all. See docs on `vbus_detection` for details. + config.vbus_detection = false; + let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); // Create embassy-usb Config diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 5bcee178f..910b8e6d1 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -7,10 +7,10 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32l552ze to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "memory-x", "low-power"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } usbd-hid = "0.7.0" @@ -22,7 +22,6 @@ panic-probe = { version = "0.3", features = ["print-defmt"] } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } rand_core = { version = "0.6.3", default-features = false } embedded-io-async = { version = "0.6.1" } diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index 9d30205bb..3f8c52b82 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs @@ -54,7 +54,7 @@ async fn main(_spawner: Spawner) { let mut config_descriptor = [0; 256]; let mut bos_descriptor = [0; 256]; let mut control_buf = [0; 64]; - let request_handler = MyRequestHandler {}; + let mut request_handler = MyRequestHandler {}; let mut state = State::new(); @@ -70,7 +70,7 @@ async fn main(_spawner: Spawner) { // Create classes on the builder. let config = embassy_usb::class::hid::Config { report_descriptor: MouseReport::desc(), - request_handler: Some(&request_handler), + request_handler: Some(&mut request_handler), poll_ms: 60, max_packet_size: 8, }; @@ -112,21 +112,21 @@ async fn main(_spawner: Spawner) { struct MyRequestHandler {} impl RequestHandler for MyRequestHandler { - fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { + fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { info!("Get report for {:?}", id); None } - fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { + fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { info!("Set report for {:?}: {=[u8]}", id, data); OutResponse::Accepted } - fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { + fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { info!("Set idle rate for {:?} to {:?}", id, dur); } - fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { + fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { info!("Get idle rate for {:?}", id); None } diff --git a/examples/stm32u0/.cargo/config.toml b/examples/stm32u0/.cargo/config.toml new file mode 100644 index 000000000..688347084 --- /dev/null +++ b/examples/stm32u0/.cargo/config.toml @@ -0,0 +1,9 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace stm32u083rctx with your chip as listed in `probe-rs chip list` +runner = "probe-rs run --chip stm32u083rctx" + +[build] +target = "thumbv6m-none-eabi" + +[env] +DEFMT_LOG = "trace" diff --git a/examples/stm32u0/Cargo.toml b/examples/stm32u0/Cargo.toml new file mode 100644 index 000000000..e67856853 --- /dev/null +++ b/examples/stm32u0/Cargo.toml @@ -0,0 +1,29 @@ +[package] +edition = "2021" +name = "embassy-stm32u0-examples" +version = "0.1.0" +license = "MIT OR Apache-2.0" + +[dependencies] +# Change stm32u083rc to your chip name, if necessary. +embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32u083rc", "memory-x", "unstable-pac", "exti", "chrono"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] } +embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } + +defmt = "0.3" +defmt-rtt = "0.4" + +cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } +cortex-m-rt = "0.7.0" +embedded-hal = "0.2.6" +panic-probe = { version = "0.3", features = ["print-defmt"] } +heapless = { version = "0.8", default-features = false } + +micromath = "2.0.0" +chrono = { version = "0.4.38", default-features = false } + +[profile.release] +debug = 2 diff --git a/examples/stm32u0/build.rs b/examples/stm32u0/build.rs new file mode 100644 index 000000000..8cd32d7ed --- /dev/null +++ b/examples/stm32u0/build.rs @@ -0,0 +1,5 @@ +fn main() { + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/examples/stm32u0/src/bin/adc.rs b/examples/stm32u0/src/bin/adc.rs new file mode 100644 index 000000000..4410448f1 --- /dev/null +++ b/examples/stm32u0/src/bin/adc.rs @@ -0,0 +1,30 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_stm32::adc::{Adc, Resolution}; +use embassy_stm32::Config; +use embassy_time::Duration; +use {defmt_rtt as _, panic_probe as _}; + +#[cortex_m_rt::entry] +fn main() -> ! { + info!("Hello World!"); + + let mut config = Config::default(); + { + use embassy_stm32::rcc::*; + config.rcc.mux.adcsel = mux::Adcsel::SYS; + } + let p = embassy_stm32::init(config); + + let mut adc = Adc::new(p.ADC1); + adc.set_resolution(Resolution::BITS8); + let mut channel = p.PC0; + + loop { + let v = adc.read(&mut channel); + info!("--> {}", v); + embassy_time::block_for(Duration::from_millis(200)); + } +} diff --git a/examples/stm32u0/src/bin/blinky.rs b/examples/stm32u0/src/bin/blinky.rs new file mode 100644 index 000000000..90e479aae --- /dev/null +++ b/examples/stm32u0/src/bin/blinky.rs @@ -0,0 +1,26 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::gpio::{Level, Output, Speed}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + let mut led = Output::new(p.PA5, Level::High, Speed::Low); + + loop { + info!("high"); + led.set_high(); + Timer::after_millis(300).await; + + info!("low"); + led.set_low(); + Timer::after_millis(300).await; + } +} diff --git a/examples/stm32u0/src/bin/button.rs b/examples/stm32u0/src/bin/button.rs new file mode 100644 index 000000000..8017f0274 --- /dev/null +++ b/examples/stm32u0/src/bin/button.rs @@ -0,0 +1,24 @@ +#![no_std] +#![no_main] + +use cortex_m_rt::entry; +use defmt::*; +use embassy_stm32::gpio::{Input, Pull}; +use {defmt_rtt as _, panic_probe as _}; + +#[entry] +fn main() -> ! { + info!("Hello World!"); + + let p = embassy_stm32::init(Default::default()); + + let button = Input::new(p.PC13, Pull::Up); + + loop { + if button.is_high() { + info!("high"); + } else { + info!("low"); + } + } +} diff --git a/examples/stm32u0/src/bin/button_exti.rs b/examples/stm32u0/src/bin/button_exti.rs new file mode 100644 index 000000000..34a08bbc6 --- /dev/null +++ b/examples/stm32u0/src/bin/button_exti.rs @@ -0,0 +1,25 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::exti::ExtiInput; +use embassy_stm32::gpio::Pull; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); + + info!("Press the USER button..."); + + loop { + button.wait_for_falling_edge().await; + info!("Pressed!"); + button.wait_for_rising_edge().await; + info!("Released!"); + } +} diff --git a/examples/stm32u0/src/bin/crc.rs b/examples/stm32u0/src/bin/crc.rs new file mode 100644 index 000000000..d1b545d5b --- /dev/null +++ b/examples/stm32u0/src/bin/crc.rs @@ -0,0 +1,31 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::crc::{Config, Crc, InputReverseConfig, PolySize}; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + // Setup for: https://crccalc.com/?crc=Life, it never dieWomen are my favorite guy&method=crc32&datatype=ascii&outtype=0 + let mut crc = Crc::new( + p.CRC, + unwrap!(Config::new( + InputReverseConfig::Byte, + true, + PolySize::Width32, + 0xFFFFFFFF, + 0x04C11DB7 + )), + ); + + let output = crc.feed_bytes(b"Life, it never die\nWomen are my favorite guy") ^ 0xFFFFFFFF; + + defmt::assert_eq!(output, 0x33F0E26B); + + cortex_m::asm::bkpt(); +} diff --git a/examples/stm32u0/src/bin/dac.rs b/examples/stm32u0/src/bin/dac.rs new file mode 100644 index 000000000..fdbf1d374 --- /dev/null +++ b/examples/stm32u0/src/bin/dac.rs @@ -0,0 +1,35 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_stm32::dac::{DacCh1, Value}; +use embassy_stm32::dma::NoDma; +use {defmt_rtt as _, panic_probe as _}; + +#[cortex_m_rt::entry] +fn main() -> ! { + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); + + loop { + for v in 0..=255 { + dac.set(Value::Bit8(to_sine_wave(v))); + } + } +} + +use micromath::F32Ext; + +fn to_sine_wave(v: u8) -> u8 { + if v >= 128 { + // top half + let r = 3.14 * ((v - 128) as f32 / 128.0); + (r.sin() * 128.0 + 127.0) as u8 + } else { + // bottom half + let r = 3.14 + 3.14 * (v as f32 / 128.0); + (r.sin() * 128.0 + 127.0) as u8 + } +} diff --git a/examples/stm32u0/src/bin/flash.rs b/examples/stm32u0/src/bin/flash.rs new file mode 100644 index 000000000..01b80a76b --- /dev/null +++ b/examples/stm32u0/src/bin/flash.rs @@ -0,0 +1,43 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::flash::Flash; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + let addr: u32 = 0x40000 - 2 * 1024; + + let mut f = Flash::new_blocking(p.FLASH).into_blocking_regions().bank1_region; + + info!("Reading..."); + let mut buf = [0u8; 32]; + unwrap!(f.blocking_read(addr, &mut buf)); + info!("Read: {=[u8]:x}", buf); + info!("Erasing..."); + unwrap!(f.blocking_erase(addr, addr + 2 * 1024)); + + info!("Reading..."); + let mut buf = [0u8; 32]; + unwrap!(f.blocking_read(addr, &mut buf)); + info!("Read after erase: {=[u8]:x}", buf); + + info!("Writing..."); + unwrap!(f.blocking_write( + addr, + &[ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32 + ] + )); + + info!("Reading..."); + let mut buf = [0u8; 32]; + unwrap!(f.blocking_read(addr, &mut buf)); + info!("Read: {=[u8]:x}", buf); +} diff --git a/examples/stm32u0/src/bin/i2c.rs b/examples/stm32u0/src/bin/i2c.rs new file mode 100644 index 000000000..2861bc091 --- /dev/null +++ b/examples/stm32u0/src/bin/i2c.rs @@ -0,0 +1,21 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::i2c::I2c; +use embassy_stm32::time::Hertz; +use {defmt_rtt as _, panic_probe as _}; + +const ADDRESS: u8 = 0x5F; +const WHOAMI: u8 = 0x0F; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(Default::default()); + let mut i2c = I2c::new_blocking(p.I2C2, p.PB10, p.PB11, Hertz(100_000), Default::default()); + + let mut data = [0u8; 1]; + unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data)); + info!("Whoami: {}", data[0]); +} diff --git a/examples/stm32u0/src/bin/rng.rs b/examples/stm32u0/src/bin/rng.rs new file mode 100644 index 000000000..89445b042 --- /dev/null +++ b/examples/stm32u0/src/bin/rng.rs @@ -0,0 +1,43 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::rcc::mux::Clk48sel; +use embassy_stm32::rng::Rng; +use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + RNG_CRYP => rng::InterruptHandler<peripherals::RNG>; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut config = Config::default(); + { + use embassy_stm32::rcc::*; + config.rcc.hsi = true; + config.rcc.pll = Some(Pll { + source: PllSource::HSI, // 16 MHz + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL7, // 16 * 7 = 112 MHz + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // 112 / 2 = 56 MHz + }); + config.rcc.sys = Sysclk::PLL1_R; + config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: false }); // needed for RNG + config.rcc.mux.clk48sel = Clk48sel::HSI48; // needed for RNG (or use MSI or PLLQ if you want) + } + + let p = embassy_stm32::init(config); + + info!("Hello World!"); + + let mut rng = Rng::new(p.RNG, Irqs); + + let mut buf = [0u8; 16]; + unwrap!(rng.async_fill_bytes(&mut buf).await); + info!("random bytes: {:02x}", buf); +} diff --git a/examples/stm32u0/src/bin/rtc.rs b/examples/stm32u0/src/bin/rtc.rs new file mode 100644 index 000000000..72fa0fde4 --- /dev/null +++ b/examples/stm32u0/src/bin/rtc.rs @@ -0,0 +1,49 @@ +#![no_std] +#![no_main] + +use chrono::{NaiveDate, NaiveDateTime}; +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::rtc::{Rtc, RtcConfig}; +use embassy_stm32::Config; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut config = Config::default(); + { + use embassy_stm32::rcc::*; + config.rcc.sys = Sysclk::PLL1_R; + config.rcc.hsi = true; + config.rcc.pll = Some(Pll { + source: PllSource::HSI, // 16 MHz + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL7, // 16 * 7 = 112 MHz + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // 112 / 2 = 56 MHz + }); + config.rcc.ls = LsConfig::default(); + } + + let p = embassy_stm32::init(config); + + info!("Hello World!"); + + let now = NaiveDate::from_ymd_opt(2020, 5, 15) + .unwrap() + .and_hms_opt(10, 30, 15) + .unwrap(); + + let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); + info!("Got RTC! {:?}", now.and_utc().timestamp()); + + rtc.set_datetime(now.into()).expect("datetime not set"); + + // In reality the delay would be much longer + Timer::after_millis(20000).await; + + let then: NaiveDateTime = rtc.now().unwrap().into(); + info!("Got RTC! {:?}", then.and_utc().timestamp()); +} diff --git a/examples/stm32u0/src/bin/spi.rs b/examples/stm32u0/src/bin/spi.rs new file mode 100644 index 000000000..5693a3765 --- /dev/null +++ b/examples/stm32u0/src/bin/spi.rs @@ -0,0 +1,30 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_stm32::gpio::{Level, Output, Speed}; +use embassy_stm32::spi::{Config, Spi}; +use embassy_stm32::time::Hertz; +use {defmt_rtt as _, panic_probe as _}; + +#[cortex_m_rt::entry] +fn main() -> ! { + info!("Hello World!"); + + let p = embassy_stm32::init(Default::default()); + + let mut spi_config = Config::default(); + spi_config.frequency = Hertz(1_000_000); + + let mut spi = Spi::new_blocking(p.SPI3, p.PC10, p.PC12, p.PC11, spi_config); + + let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh); + + loop { + let mut buf = [0x0Au8; 4]; + cs.set_low(); + unwrap!(spi.blocking_transfer_in_place(&mut buf)); + cs.set_high(); + info!("xfer {=[u8]:x}", buf); + } +} diff --git a/examples/stm32u0/src/bin/usart.rs b/examples/stm32u0/src/bin/usart.rs new file mode 100644 index 000000000..037a5c833 --- /dev/null +++ b/examples/stm32u0/src/bin/usart.rs @@ -0,0 +1,25 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_stm32::usart::{Config, Uart}; +use {defmt_rtt as _, panic_probe as _}; + +#[cortex_m_rt::entry] +fn main() -> ! { + info!("Hello World!"); + + let p = embassy_stm32::init(Default::default()); + + let config = Config::default(); + let mut usart = Uart::new_blocking(p.USART2, p.PA3, p.PA2, config).unwrap(); + + unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); + info!("wrote Hello, starting echo"); + + let mut buf = [0u8; 1]; + loop { + unwrap!(usart.blocking_read(&mut buf)); + unwrap!(usart.blocking_write(&buf)); + } +} diff --git a/examples/stm32u0/src/bin/usb_serial.rs b/examples/stm32u0/src/bin/usb_serial.rs new file mode 100644 index 000000000..273f40643 --- /dev/null +++ b/examples/stm32u0/src/bin/usb_serial.rs @@ -0,0 +1,109 @@ +#![no_std] +#![no_main] + +use defmt::{panic, *}; +use defmt_rtt as _; // global logger +use embassy_executor::Spawner; +use embassy_futures::join::join; +use embassy_stm32::usb::{Driver, Instance}; +use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; +use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; +use embassy_usb::driver::EndpointError; +use embassy_usb::Builder; +use panic_probe as _; + +bind_interrupts!(struct Irqs { + USB_DRD_FS => usb::InterruptHandler<peripherals::USB>; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut config = Config::default(); + { + use embassy_stm32::rcc::*; + config.rcc.hsi = true; + config.rcc.pll = Some(Pll { + source: PllSource::HSI, // 16 MHz + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL7, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // 56 MHz + }); + config.rcc.sys = Sysclk::PLL1_R; + config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB + config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; // USB uses ICLK + } + + let p = embassy_stm32::init(config); + + info!("Hello World!"); + + // Create the driver, from the HAL. + let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11); + + // Create embassy-usb Config + let config = embassy_usb::Config::new(0xc0de, 0xcafe); + //config.max_packet_size_0 = 64; + + // Create embassy-usb DeviceBuilder using the driver and config. + // It needs some buffers for building the descriptors. + let mut config_descriptor = [0; 256]; + let mut bos_descriptor = [0; 256]; + let mut control_buf = [0; 7]; + + let mut state = State::new(); + + let mut builder = Builder::new( + driver, + config, + &mut config_descriptor, + &mut bos_descriptor, + &mut [], // no msos descriptors + &mut control_buf, + ); + + // Create classes on the builder. + let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); + + // Build the builder. + let mut usb = builder.build(); + + // Run the USB device. + let usb_fut = usb.run(); + + // Do stuff with the class! + let echo_fut = async { + loop { + class.wait_connection().await; + info!("Connected"); + let _ = echo(&mut class).await; + info!("Disconnected"); + } + }; + + // Run everything concurrently. + // If we had made everything `'static` above instead, we could do this using separate tasks instead. + join(usb_fut, echo_fut).await; +} + +struct Disconnected {} + +impl From<EndpointError> for Disconnected { + fn from(val: EndpointError) -> Self { + match val { + EndpointError::BufferOverflow => panic!("Buffer overflow"), + EndpointError::Disabled => Disconnected {}, + } + } +} + +async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { + let mut buf = [0; 64]; + loop { + let n = class.read_packet(&mut buf).await?; + let data = &buf[..n]; + info!("data: {:x}", data); + class.write_packet(data).await?; + } +} diff --git a/examples/stm32u0/src/bin/wdt.rs b/examples/stm32u0/src/bin/wdt.rs new file mode 100644 index 000000000..f6276e2e9 --- /dev/null +++ b/examples/stm32u0/src/bin/wdt.rs @@ -0,0 +1,41 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::gpio::{Level, Output, Speed}; +use embassy_stm32::wdg::IndependentWatchdog; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + let mut led = Output::new(p.PA5, Level::High, Speed::Low); + + let mut wdt = IndependentWatchdog::new(p.IWDG, 1_000_000); + wdt.unleash(); + + let mut i = 0; + + loop { + info!("high"); + led.set_high(); + Timer::after_millis(300).await; + + info!("low"); + led.set_low(); + Timer::after_millis(300).await; + + // Pet watchdog for 5 iterations and then stop. + // MCU should restart in 1 second after the last pet. + if i < 5 { + info!("Petting watchdog"); + wdt.pet(); + } + + i += 1; + } +} diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index 03294339d..24c9263a3 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml @@ -7,10 +7,11 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32u585ai to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" defmt-rtt = "0.4" @@ -19,10 +20,13 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } micromath = "2.0.0" +[features] +## Use secure registers when TrustZone is enabled +trustzone-secure = ["embassy-stm32/trustzone-secure"] + [profile.release] debug = 2 diff --git a/examples/stm32u5/src/bin/i2c.rs b/examples/stm32u5/src/bin/i2c.rs index e376c6bc8..19a78eac9 100644 --- a/examples/stm32u5/src/bin/i2c.rs +++ b/examples/stm32u5/src/bin/i2c.rs @@ -3,33 +3,17 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::i2c::I2c; use embassy_stm32::time::Hertz; -use embassy_stm32::{bind_interrupts, i2c, peripherals}; use {defmt_rtt as _, panic_probe as _}; const HTS221_ADDRESS: u8 = 0x5F; const WHOAMI: u8 = 0x0F; -bind_interrupts!(struct Irqs { - I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>; - I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; -}); - #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let mut i2c = I2c::new( - p.I2C2, - p.PH4, - p.PH5, - Irqs, - NoDma, - NoDma, - Hertz(100_000), - Default::default(), - ); + let mut i2c = I2c::new_blocking(p.I2C2, p.PH4, p.PH5, Hertz(100_000), Default::default()); let mut data = [0u8; 1]; unwrap!(i2c.blocking_write_read(HTS221_ADDRESS, &[WHOAMI], &mut data)); diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index 6a313efb0..4d56395da 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs @@ -4,12 +4,12 @@ use defmt::{panic, *}; use defmt_rtt as _; // global logger use embassy_executor::Spawner; +use embassy_futures::join::join; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; -use futures::future::join; use panic_probe as _; bind_interrupts!(struct Irqs { @@ -43,6 +43,10 @@ async fn main(_spawner: Spawner) { // Create the driver, from the HAL. let mut ep_out_buffer = [0u8; 256]; let mut config = embassy_stm32::usb::Config::default(); + // Do not enable vbus_detection. This is a safe default that works in all boards. + // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need + // to enable vbus_detection to comply with the USB spec. If you enable it, the board + // has to support it or USB won't work at all. See docs on `vbus_detection` for details. config.vbus_detection = false; let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); diff --git a/examples/stm32wb/.cargo/config.toml b/examples/stm32wb/.cargo/config.toml index 51c499ee7..8b6d6d754 100644 --- a/examples/stm32wb/.cargo/config.toml +++ b/examples/stm32wb/.cargo/config.toml @@ -1,6 +1,6 @@ [target.'cfg(all(target_arch = "arm", target_os = "none"))'] # replace STM32WB55CCUx with your chip as listed in `probe-rs chip list` -# runner = "probe-run --chip STM32WB55RGVx --speed 1000 --connect-under-reset" +# runner = "probe-rs run --chip STM32WB55RGVx --speed 1000 --connect-under-reset" runner = "teleprobe local run --chip STM32WB55RG --elf" [build] diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 94a5141f5..92865b41c 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32wb55rg to your chip name in both dependencies, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"] } embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } @@ -20,7 +20,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } static_cell = "2" diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index 47279a012..60f6e9201 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } @@ -18,7 +18,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } static_cell = "2" diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index 4cb55930b..29cd4d466 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32wl55jc-cm4 to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } @@ -20,7 +20,6 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" embedded-storage = "0.3.1" panic-probe = { version = "0.3", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.8", default-features = false } chrono = { version = "^0.4", default-features = false } diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml index 3d2300b59..e7840d52e 100644 --- a/examples/wasm/Cargo.toml +++ b/examples/wasm/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" crate-type = ["cdylib"] [dependencies] -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["log"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["log"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-wasm", "executor-thread", "log", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["log", "wasm", ] } diff --git a/rust-toolchain-nightly.toml b/rust-toolchain-nightly.toml index 98696fd2b..ac160b995 100644 --- a/rust-toolchain-nightly.toml +++ b/rust-toolchain-nightly.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "nightly-2024-03-20" +channel = "nightly-2024-04-14" components = [ "rust-src", "rustfmt", "llvm-tools", "miri" ] targets = [ "thumbv7em-none-eabi", diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 2f5d17069..57185e217 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "1.77" +channel = "1.78" components = [ "rust-src", "rustfmt", "llvm-tools" ] targets = [ "thumbv7em-none-eabi", diff --git a/tests/nrf51422/Cargo.toml b/tests/nrf51422/Cargo.toml index 07236987b..70de9d321 100644 --- a/tests/nrf51422/Cargo.toml +++ b/tests/nrf51422/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" teleprobe-meta = "1" embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt", ] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt", ] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-128", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf51", "time-driver-rtc1", "unstable-pac", "time", "gpiote"] } diff --git a/tests/nrf52840/Cargo.toml b/tests/nrf52840/Cargo.toml index 84ca99f1f..4b89ec569 100644 --- a/tests/nrf52840/Cargo.toml +++ b/tests/nrf52840/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" teleprobe-meta = "1" embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt", ] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt", ] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-16384", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } diff --git a/tests/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml index 4390a6da1..a347608b3 100644 --- a/tests/perf-client/Cargo.toml +++ b/tests/perf-client/Cargo.toml @@ -3,8 +3,6 @@ name = "perf-client" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", ] } diff --git a/tests/riscv32/Cargo.toml b/tests/riscv32/Cargo.toml index 38fb2deec..909f9a72c 100644 --- a/tests/riscv32/Cargo.toml +++ b/tests/riscv32/Cargo.toml @@ -6,13 +6,13 @@ license = "MIT OR Apache-2.0" [dependencies] critical-section = { version = "1.1.1", features = ["restore-state-bool"] } -embassy-sync = { version = "0.5.0", path = "../../embassy-sync" } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync" } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-riscv32", "executor-thread"] } embassy-time = { version = "0.3.0", path = "../../embassy-time" } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -riscv-rt = "0.11" -riscv = { version = "0.10", features = ["critical-section-single-hart"] } +riscv-rt = "0.12.2" +riscv = { version = "0.11.1", features = ["critical-section-single-hart"] } [profile.dev] diff --git a/tests/riscv32/link.x b/tests/riscv32/link.x new file mode 100644 index 000000000..4076b0c68 --- /dev/null +++ b/tests/riscv32/link.x @@ -0,0 +1,214 @@ +/* # EMBASSY notes + This file is a workaround for https://github.com/rust-embedded/riscv/issues/196 + Remove when fixed upstream. +*/ +/* # Developer notes + +- Symbols that start with a double underscore (__) are considered "private" + +- Symbols that start with a single underscore (_) are considered "semi-public"; they can be + overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" { + static mut _heap_size }`). + +- `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a + symbol if not dropped if it appears in or near the front of the linker arguments and "it's not + needed" by any of the preceding objects (linker arguments) + +- `PROVIDE` is used to provide default values that can be overridden by a user linker script + +- In this linker script, you may find symbols that look like `${...}` (e.g., `4`). + These are wildcards used by the `build.rs` script to adapt to different target particularities. + Check `build.rs` for more details about these symbols. + +- On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and* + the LMA of .data are all `4`-byte aligned. These alignments are assumed by the RAM + initialization routine. There's also a second benefit: `4`-byte aligned boundaries + means that you won't see "Address (..) is out of bounds" in the disassembly produced by `objdump`. +*/ + +PROVIDE(_stext = ORIGIN(REGION_TEXT)); +PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK)); +PROVIDE(_max_hart_id = 0); +PROVIDE(_hart_stack_size = 2K); +PROVIDE(_heap_size = 0); + +PROVIDE(InstructionMisaligned = ExceptionHandler); +PROVIDE(InstructionFault = ExceptionHandler); +PROVIDE(IllegalInstruction = ExceptionHandler); +PROVIDE(Breakpoint = ExceptionHandler); +PROVIDE(LoadMisaligned = ExceptionHandler); +PROVIDE(LoadFault = ExceptionHandler); +PROVIDE(StoreMisaligned = ExceptionHandler); +PROVIDE(StoreFault = ExceptionHandler);; +PROVIDE(UserEnvCall = ExceptionHandler); +PROVIDE(SupervisorEnvCall = ExceptionHandler); +PROVIDE(MachineEnvCall = ExceptionHandler); +PROVIDE(InstructionPageFault = ExceptionHandler); +PROVIDE(LoadPageFault = ExceptionHandler); +PROVIDE(StorePageFault = ExceptionHandler); + +PROVIDE(SupervisorSoft = DefaultHandler); +PROVIDE(MachineSoft = DefaultHandler); +PROVIDE(SupervisorTimer = DefaultHandler); +PROVIDE(MachineTimer = DefaultHandler); +PROVIDE(SupervisorExternal = DefaultHandler); +PROVIDE(MachineExternal = DefaultHandler); + +PROVIDE(DefaultHandler = DefaultInterruptHandler); +PROVIDE(ExceptionHandler = DefaultExceptionHandler); + +/* # Pre-initialization function */ +/* If the user overrides this using the `#[pre_init]` attribute or by creating a `__pre_init` function, + then the function this points to will be called before the RAM is initialized. */ +PROVIDE(__pre_init = default_pre_init); + +/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */ +PROVIDE(_setup_interrupts = default_setup_interrupts); + +/* # Multi-processing hook function + fn _mp_hook() -> bool; + + This function is called from all the harts and must return true only for one hart, + which will perform memory initialization. For other harts it must return false + and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt). +*/ +PROVIDE(_mp_hook = default_mp_hook); + +/* # Start trap function override + By default uses the riscv crates default trap handler + but by providing the `_start_trap` symbol external crates can override. +*/ +PROVIDE(_start_trap = default_start_trap); + +SECTIONS +{ + .text.dummy (NOLOAD) : + { + /* This section is intended to make _stext address work */ + . = ABSOLUTE(_stext); + } > REGION_TEXT + + .text _stext : + { + /* Put reset handler first in .text section so it ends up as the entry */ + /* point of the program. */ + KEEP(*(.init)); + KEEP(*(.init.rust)); + . = ALIGN(4); + *(.trap); + *(.trap.rust); + *(.text.abort); + *(.text .text.*); + } > REGION_TEXT + + .eh_frame : { KEEP(*(.eh_frame)) } > REGION_TEXT + .eh_frame_hdr : { *(.eh_frame_hdr) } > REGION_TEXT + + .rodata : ALIGN(4) + { + *(.srodata .srodata.*); + *(.rodata .rodata.*); + + /* 4-byte align the end (VMA) of this section. + This is required by LLD to ensure the LMA of the following .data + section will have the correct alignment. */ + . = ALIGN(4); + } > REGION_RODATA + + .data : ALIGN(4) + { + _sidata = LOADADDR(.data); + _sdata = .; + /* Must be called __global_pointer$ for linker relaxations to work. */ + PROVIDE(__global_pointer$ = . + 0x800); + *(.sdata .sdata.* .sdata2 .sdata2.*); + *(.data .data.*); + . = ALIGN(4); + _edata = .; + } > REGION_DATA AT > REGION_RODATA + + .bss (NOLOAD) : ALIGN(4) + { + _sbss = .; + *(.sbss .sbss.* .bss .bss.*); + . = ALIGN(4); + _ebss = .; + } > REGION_BSS + + /* fictitious region that represents the memory available for the heap */ + .heap (NOLOAD) : + { + _sheap = .; + . += _heap_size; + . = ALIGN(4); + _eheap = .; + } > REGION_HEAP + + /* fictitious region that represents the memory available for the stack */ + .stack (NOLOAD) : + { + _estack = .; + . = ABSOLUTE(_stack_start); + _sstack = .; + } > REGION_STACK + + /* fake output .got section */ + /* Dynamic relocations are unsupported. This section is only used to detect + relocatable code in the input files and raise an error if relocatable code + is found */ + .got (INFO) : + { + KEEP(*(.got .got.*)); + } +} + +/* Do not exceed this mark in the error messages above | */ +ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, " +ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned"); + +ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, " +ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned"); + +ASSERT(ORIGIN(REGION_DATA) % 4 == 0, " +ERROR(riscv-rt): the start of the REGION_DATA must be 4-byte aligned"); + +ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, " +ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned"); + +ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, " +ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned"); + +ASSERT(ORIGIN(REGION_STACK) % 4 == 0, " +ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned"); + +ASSERT(_stext % 4 == 0, " +ERROR(riscv-rt): `_stext` must be 4-byte aligned"); + +ASSERT(_sdata % 4 == 0 && _edata % 4 == 0, " +BUG(riscv-rt): .data is not 4-byte aligned"); + +ASSERT(_sidata % 4 == 0, " +BUG(riscv-rt): the LMA of .data is not 4-byte aligned"); + +ASSERT(_sbss % 4 == 0 && _ebss % 4 == 0, " +BUG(riscv-rt): .bss is not 4-byte aligned"); + +ASSERT(_sheap % 4 == 0, " +BUG(riscv-rt): start of .heap is not 4-byte aligned"); + +ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), " +ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region. +Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'"); + +ASSERT(SIZEOF(.stack) > (_max_hart_id + 1) * _hart_stack_size, " +ERROR(riscv-rt): .stack section is too small for allocating stacks for all the harts. +Consider changing `_max_hart_id` or `_hart_stack_size`."); + +ASSERT(SIZEOF(.got) == 0, " +.got section detected in the input files. Dynamic relocations are not +supported. If you are linking to C code compiled using the `gcc` crate +then modify your build script to compile the C code _without_ the +-fPIC flag. See the documentation of the `gcc::Config.fpic` method for +details."); + +/* Do not exceed this mark in the error messages above | */ diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index e67f2117d..b7eee92e8 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] teleprobe-meta = "1.1" -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", ] } embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = [ "defmt", "unstable-pac", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } @@ -29,7 +29,6 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-hal-bus = { version = "0.1", features = ["async"] } panic-probe = { version = "0.3.0", features = ["print-defmt"] } -futures = { version = "0.3.17", default-features = false, features = ["async-await"] } embedded-io-async = { version = "0.6.1" } embedded-storage = { version = "0.3" } static_cell = "2" diff --git a/tests/stm32/.cargo/config.toml b/tests/stm32/.cargo/config.toml index 528bd3451..8752da59b 100644 --- a/tests/stm32/.cargo/config.toml +++ b/tests/stm32/.cargo/config.toml @@ -4,7 +4,7 @@ [target.'cfg(all(target_arch = "arm", target_os = "none"))'] runner = "teleprobe client run" -#runner = "teleprobe local run --chip STM32F103C8 --elf" +#runner = "teleprobe local run --chip STM32H7S3L8Hx --elf" rustflags = [ # Code-size optimizations. diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index e09083111..f6d1d98eb 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -15,7 +15,7 @@ stm32f446re = ["embassy-stm32/stm32f446re", "chrono", "stop", "can", "not-gpdma" stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"] stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan", "cordic"] -stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng", "hash", "cordic"] +stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng", "fdcan", "hash", "cordic", "stop"] stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"] stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"] stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng", "fdcan"] @@ -31,7 +31,9 @@ stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" stm32wba52cg = ["embassy-stm32/stm32wba52cg", "chrono", "rng", "hash"] stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"] -stm32h503rb = ["embassy-stm32/stm32h503rb", "rng"] +stm32h503rb = ["embassy-stm32/stm32h503rb", "rng", "stop"] +stm32h7s3l8 = ["embassy-stm32/stm32h7s3l8", "rng", "cordic", "hash"] # TODO: fdcan crashes, cryp dma hangs. +stm32u083rc = ["embassy-stm32/stm32u083rc", "cm0", "rng", "chrono"] cryp = [] hash = [] @@ -55,7 +57,7 @@ cm0 = ["portable-atomic/unsafe-assume-single-core"] [dependencies] teleprobe-meta = "1" -embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"] } diff --git a/tests/stm32/src/bin/cordic.rs b/tests/stm32/src/bin/cordic.rs index 400e10207..e09226de8 100644 --- a/tests/stm32/src/bin/cordic.rs +++ b/tests/stm32/src/bin/cordic.rs @@ -67,7 +67,12 @@ async fn main(_spawner: Spawner) { #[cfg(feature = "stm32g491re")] let (mut write_dma, mut read_dma) = (dp.DMA1_CH4, dp.DMA1_CH5); - #[cfg(any(feature = "stm32h563zi", feature = "stm32u585ai", feature = "stm32u5a5zj"))] + #[cfg(any( + feature = "stm32h563zi", + feature = "stm32u585ai", + feature = "stm32u5a5zj", + feature = "stm32h7s3l8" + ))] let (mut write_dma, mut read_dma) = (dp.GPDMA1_CH0, dp.GPDMA1_CH1); // calculate first result using blocking mode diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs index 9d64742df..06501ab14 100644 --- a/tests/stm32/src/bin/dac.rs +++ b/tests/stm32/src/bin/dac.rs @@ -13,7 +13,7 @@ use embassy_executor::Spawner; use embassy_stm32::adc::Adc; use embassy_stm32::dac::{DacCh1, Value}; use embassy_stm32::dma::NoDma; -use embassy_time::{Delay, Timer}; +use embassy_time::Timer; use micromath::F32Ext; use {defmt_rtt as _, panic_probe as _}; @@ -28,7 +28,7 @@ async fn main(_spawner: Spawner) { let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; let mut dac = DacCh1::new(dac, NoDma, dac_pin); - let mut adc = Adc::new(adc, &mut Delay); + let mut adc = Adc::new(adc); #[cfg(feature = "stm32h755zi")] let normalization_factor = 256; diff --git a/tests/stm32/src/bin/dac_l1.rs b/tests/stm32/src/bin/dac_l1.rs index f8b00aaef..d5e9c9722 100644 --- a/tests/stm32/src/bin/dac_l1.rs +++ b/tests/stm32/src/bin/dac_l1.rs @@ -19,7 +19,7 @@ use micromath::F32Ext; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { - ADC1 => embassy_stm32::adc::InterruptHandler<peripherals::ADC>; + ADC1 => embassy_stm32::adc::InterruptHandler<peripherals::ADC1>; }); #[embassy_executor::main] diff --git a/tests/stm32/src/bin/fdcan.rs b/tests/stm32/src/bin/fdcan.rs index 27bdd038a..20bd3f7e3 100644 --- a/tests/stm32/src/bin/fdcan.rs +++ b/tests/stm32/src/bin/fdcan.rs @@ -24,7 +24,19 @@ bind_interrupts!(struct Irqs1 { FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>; }); -#[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi", feature = "stm32h563zi"))] +#[cfg(feature = "stm32h563zi")] +fn options() -> (Config, TestOptions) { + info!("H563 config"); + ( + config(), + TestOptions { + max_latency: Duration::from_micros(1200), + max_buffered: 3, + }, + ) +} + +#[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] fn options() -> (Config, TestOptions) { use embassy_stm32::rcc; info!("H75 config"); @@ -62,6 +74,20 @@ fn options() -> (Config, TestOptions) { ) } +#[cfg(any(feature = "stm32h7s3l8"))] +fn options() -> (Config, TestOptions) { + use embassy_stm32::rcc; + let mut c = config(); + c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE; + ( + c, + TestOptions { + max_latency: Duration::from_micros(1200), + max_buffered: 3, + }, + ) +} + #[cfg(any(feature = "stm32g491re", feature = "stm32g431cb"))] fn options() -> (Config, TestOptions) { info!("G4 config"); @@ -88,11 +114,11 @@ async fn main(_spawner: Spawner) { can.set_bitrate(250_000); can2.set_bitrate(250_000); - can.set_extended_filter( + can.properties().set_extended_filter( can::filter::ExtendedFilterSlot::_0, can::filter::ExtendedFilter::accept_all_into_fifo1(), ); - can2.set_extended_filter( + can2.properties().set_extended_filter( can::filter::ExtendedFilterSlot::_0, can::filter::ExtendedFilter::accept_all_into_fifo1(), ); @@ -106,8 +132,8 @@ async fn main(_spawner: Spawner) { info!("CAN Configured"); // Test again with a split - let (mut tx, mut rx) = can.split(); - let (mut tx2, mut rx2) = can2.split(); + let (mut tx, mut rx, _props) = can.split(); + let (mut tx2, mut rx2, _props) = can2.split(); run_split_can_tests(&mut tx, &mut rx, &options).await; run_split_can_tests(&mut tx2, &mut rx2, &options).await; diff --git a/tests/stm32/src/bin/gpio.rs b/tests/stm32/src/bin/gpio.rs index c4e2fe161..dfa299ab5 100644 --- a/tests/stm32/src/bin/gpio.rs +++ b/tests/stm32/src/bin/gpio.rs @@ -216,7 +216,12 @@ async fn main(_spawner: Spawner) { } fn delay() { - #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi", feature = "stm32h7a3zi"))] + #[cfg(any( + feature = "stm32h755zi", + feature = "stm32h753zi", + feature = "stm32h7a3zi", + feature = "stm32h7s3l8" + ))] cortex_m::asm::delay(9000); cortex_m::asm::delay(1000); } diff --git a/tests/stm32/src/bin/hash.rs b/tests/stm32/src/bin/hash.rs index 8cc5d593f..5f54ea435 100644 --- a/tests/stm32/src/bin/hash.rs +++ b/tests/stm32/src/bin/hash.rs @@ -26,7 +26,8 @@ bind_interrupts!(struct Irqs { feature = "stm32h563zi", feature = "stm32h503rb", feature = "stm32u5a5zj", - feature = "stm32u585ai" + feature = "stm32u585ai", + feature = "stm32h7s3l8" ))] bind_interrupts!(struct Irqs { HASH => hash::InterruptHandler<peripherals::HASH>; diff --git a/tests/stm32/src/bin/rng.rs b/tests/stm32/src/bin/rng.rs index 7f2023d4d..15ef4fb60 100644 --- a/tests/stm32/src/bin/rng.rs +++ b/tests/stm32/src/bin/rng.rs @@ -23,12 +23,17 @@ bind_interrupts!(struct Irqs { bind_interrupts!(struct Irqs { RNG_LPUART1 => rng::InterruptHandler<peripherals::RNG>; }); +#[cfg(any(feature = "stm32u083rc"))] +bind_interrupts!(struct Irqs { + RNG_CRYP => rng::InterruptHandler<peripherals::RNG>; +}); #[cfg(not(any( feature = "stm32l4a6zg", feature = "stm32l073rz", feature = "stm32h755zi", feature = "stm32h753zi", - feature = "stm32f429zi" + feature = "stm32f429zi", + feature = "stm32u083rc" )))] bind_interrupts!(struct Irqs { RNG => rng::InterruptHandler<peripherals::RNG>; diff --git a/tests/stm32/src/bin/spi.rs b/tests/stm32/src/bin/spi.rs index b0bdd477f..c1576bfeb 100644 --- a/tests/stm32/src/bin/spi.rs +++ b/tests/stm32/src/bin/spi.rs @@ -6,7 +6,6 @@ mod common; use common::*; use defmt::assert_eq; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::spi::{self, Spi}; use embassy_stm32::time::Hertz; @@ -23,11 +22,11 @@ async fn main(_spawner: Spawner) { let mut spi_config = spi::Config::default(); spi_config.frequency = Hertz(1_000_000); - let mut spi = Spi::new( + let mut spi = Spi::new_blocking( spi, sck, // Arduino D13 mosi, // Arduino D11 miso, // Arduino D12 - NoDma, NoDma, spi_config, + spi_config, ); let data: [u8; 9] = [0x00, 0xFF, 0xAA, 0x55, 0xC0, 0xFF, 0xEE, 0xC0, 0xDE]; @@ -59,6 +58,14 @@ async fn main(_spawner: Spawner) { spi.blocking_read::<u8>(&mut []).unwrap(); spi.blocking_write::<u8>(&[]).unwrap(); + // Assert the RCC bit gets disabled on drop. + #[cfg(feature = "stm32f429zi")] + { + defmt::assert!(embassy_stm32::pac::RCC.apb2enr().read().spi1en()); + drop(spi); + defmt::assert!(!embassy_stm32::pac::RCC.apb2enr().read().spi1en()); + } + info!("Test OK"); cortex_m::asm::bkpt(); } diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index 000296d46..c1106bb2f 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs @@ -51,6 +51,13 @@ async fn async_main(spawner: Spawner) { let mut config = Config::default(); config.rcc.ls = LsConfig::default_lse(); + // System Clock seems cannot be greater than 16 MHz + #[cfg(any(feature = "stm32h563zi", feature = "stm32h503rb"))] + { + use embassy_stm32::rcc::HSIPrescaler; + config.rcc.hsi = Some(HSIPrescaler::DIV4); // 64 MHz HSI will need a /4 + } + let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/tests/stm32/src/bin/usart.rs b/tests/stm32/src/bin/usart.rs index 9b20eb784..a6e34674d 100644 --- a/tests/stm32/src/bin/usart.rs +++ b/tests/stm32/src/bin/usart.rs @@ -6,7 +6,6 @@ mod common; use common::*; use defmt::{assert, assert_eq, unreachable}; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, ConfigError, Error, Uart}; use embassy_time::{block_for, Duration, Instant}; @@ -20,11 +19,10 @@ async fn main(_spawner: Spawner) { let mut usart = peri!(p, UART); let mut rx = peri!(p, UART_RX); let mut tx = peri!(p, UART_TX); - let irq = irqs!(UART); { let config = Config::default(); - let mut usart = Uart::new(&mut usart, &mut rx, &mut tx, irq, NoDma, NoDma, config).unwrap(); + let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap(); // We can't send too many bytes, they have to fit in the FIFO. // This is because we aren't sending+receiving at the same time. @@ -40,7 +38,7 @@ async fn main(_spawner: Spawner) { // Test error handling with with an overflow error { let config = Config::default(); - let mut usart = Uart::new(&mut usart, &mut rx, &mut tx, irq, NoDma, NoDma, config).unwrap(); + let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap(); // Send enough bytes to fill the RX FIFOs off all USART versions. let data = [0; 64]; @@ -70,7 +68,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.baudrate = baudrate; - let mut usart = match Uart::new(&mut usart, &mut rx, &mut tx, irq, NoDma, NoDma, config) { + let mut usart = match Uart::new_blocking(&mut usart, &mut rx, &mut tx, config) { Ok(x) => x, Err(ConfigError::BaudrateTooHigh) => { info!("baudrate too high"); diff --git a/tests/stm32/src/bin/usart_rx_ringbuffered.rs b/tests/stm32/src/bin/usart_rx_ringbuffered.rs index 0c110421d..ea1e52358 100644 --- a/tests/stm32/src/bin/usart_rx_ringbuffered.rs +++ b/tests/stm32/src/bin/usart_rx_ringbuffered.rs @@ -8,6 +8,7 @@ mod common; use common::*; use defmt::{assert_eq, panic}; use embassy_executor::Spawner; +use embassy_stm32::mode::Async; use embassy_stm32::usart::{Config, DataBits, Parity, RingBufferedUartRx, StopBits, Uart, UartTx}; use embassy_time::Timer; use rand_chacha::ChaCha8Rng; @@ -51,7 +52,7 @@ async fn main(spawner: Spawner) { } #[embassy_executor::task] -async fn transmit_task(mut tx: UartTx<'static, peris::UART, peris::UART_TX_DMA>) { +async fn transmit_task(mut tx: UartTx<'static, Async>) { // workaround https://github.com/embassy-rs/embassy/issues/1426 Timer::after_millis(100).await; @@ -74,7 +75,7 @@ async fn transmit_task(mut tx: UartTx<'static, peris::UART, peris::UART_TX_DMA>) } #[embassy_executor::task] -async fn receive_task(mut rx: RingBufferedUartRx<'static, peris::UART>) { +async fn receive_task(mut rx: RingBufferedUartRx<'static>) { info!("Ready to receive..."); let mut rng = ChaCha8Rng::seed_from_u64(1337); diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 0e555efc8..4e0231858 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -60,6 +60,10 @@ teleprobe_meta::target!(b"nucleo-stm32wba52cg"); teleprobe_meta::target!(b"nucleo-stm32f091rc"); #[cfg(feature = "stm32h503rb")] teleprobe_meta::target!(b"nucleo-stm32h503rb"); +#[cfg(feature = "stm32h7s3l8")] +teleprobe_meta::target!(b"nucleo-stm32h7s3l8"); +#[cfg(feature = "stm32u083rc")] +teleprobe_meta::target!(b"nucleo-stm32u083rc"); macro_rules! define_peris { ($($name:ident = $peri:ident,)* $(@irq $irq_name:ident = $irq_code:tt,)*) => { @@ -120,7 +124,7 @@ define_peris!( define_peris!( UART = USART6, UART_TX = PG14, UART_RX = PG9, UART_TX_DMA = DMA2_CH6, UART_RX_DMA = DMA2_CH1, SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2, - ADC = ADC1, DAC = DAC, DAC_PIN = PA4, + ADC = ADC1, DAC = DAC1, DAC_PIN = PA4, CAN = CAN1, CAN_RX = PD0, CAN_TX = PD1, @irq UART = {USART6 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART6>;}, ); @@ -128,7 +132,7 @@ define_peris!( define_peris!( UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA2_CH7, UART_RX_DMA = DMA2_CH5, SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2, - ADC = ADC1, DAC = DAC, DAC_PIN = PA4, + ADC = ADC1, DAC = DAC1, DAC_PIN = PA4, CAN = CAN1, CAN_RX = PA11, CAN_TX = PA12, @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, ); @@ -210,7 +214,7 @@ define_peris!( define_peris!( UART = USART3, UART_TX = PB10, UART_RX = PB11, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3, SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, - ADC = ADC, DAC = DAC, DAC_PIN = PA4, + ADC = ADC1, DAC = DAC1, DAC_PIN = PA4, @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;}, ); #[cfg(feature = "stm32l552ze")] @@ -249,6 +253,19 @@ define_peris!( SPI = SPI1, SPI_SCK = PB4, SPI_MOSI = PA15, SPI_MISO = PB3, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::LPUART1>;}, ); +#[cfg(feature = "stm32h7s3l8")] +define_peris!( + CRYP_IN_DMA = GPDMA1_CH0, CRYP_OUT_DMA = GPDMA1_CH1, + UART = USART1, UART_TX = PB14, UART_RX = PA10, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, + SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, + @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, +); +#[cfg(feature = "stm32u083rc")] +define_peris!( + UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2, + SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2, + @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, +); pub fn config() -> Config { #[allow(unused_mut)] @@ -641,6 +658,44 @@ pub fn config() -> Config { }); config.rcc.sys = Sysclk::PLL1_R; } + #[cfg(any(feature = "stm32h7s3l8"))] + { + config.rcc.hse = Some(Hse { + freq: Hertz(24_000_000), + mode: HseMode::Oscillator, + }); + config.rcc.pll1 = Some(Pll { + source: PllSource::HSE, + prediv: PllPreDiv::DIV3, + mul: PllMul::MUL150, + divp: Some(PllDiv::DIV2), // 600Mhz + divq: Some(PllDiv::DIV25), // 48Mhz + divr: None, + }); + config.rcc.sys = Sysclk::PLL1_P; // 600 Mhz + config.rcc.ahb_pre = AHBPrescaler::DIV2; // 300 Mhz + config.rcc.apb1_pre = APBPrescaler::DIV2; // 150 Mhz + config.rcc.apb2_pre = APBPrescaler::DIV2; // 150 Mhz + config.rcc.apb4_pre = APBPrescaler::DIV2; // 150 Mhz + config.rcc.apb5_pre = APBPrescaler::DIV2; // 150 Mhz + config.rcc.voltage_scale = VoltageScale::HIGH; + config.rcc.mux.spi1sel = mux::Spi123sel::PLL1_Q; + } + #[cfg(any(feature = "stm32u083rc"))] + { + config.rcc.hsi = true; + config.rcc.pll = Some(Pll { + source: PllSource::HSI, // 16 MHz + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL7, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // 56 MHz + }); + config.rcc.sys = Sysclk::PLL1_R; + config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB + config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; // USB uses ICLK + } config } diff --git a/tests/utils/Cargo.toml b/tests/utils/Cargo.toml index 7d66fd586..7b54a4f52 100644 --- a/tests/utils/Cargo.toml +++ b/tests/utils/Cargo.toml @@ -3,8 +3,6 @@ name = "test-utils" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] rand = "0.8" serial = "0.4"