Repository: rp-rs/rp-hal-boards Branch: main Commit: 5135e3dafe3e Files: 201 Total size: 762.5 KB Directory structure: gitextract_xdh1uctv/ ├── .cargo/ │ └── config.toml ├── .github/ │ └── workflows/ │ ├── build_and_test.yml │ ├── clippy.yml │ └── rustfmt.yml ├── .gitignore ├── APACHE2.0 ├── CODE_OF_CONDUCT.md ├── Cargo.toml ├── MIT ├── README.md ├── boards/ │ ├── adafruit-feather-rp2040/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ ├── adafruit_feather_blinky.rs │ │ │ └── adafruit_feather_neopixel_rainbow.rs │ │ └── src/ │ │ └── lib.rs │ ├── adafruit-itsy-bitsy-rp2040/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ ├── adafruit_itsy_bitsy_blinky.rs │ │ │ └── adafruit_itsy_bitsy_rainbow.rs │ │ └── src/ │ │ └── lib.rs │ ├── adafruit-kb2040/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ ├── adafruit_kb2040_rainbow.rs │ │ │ └── adafruit_kb2040_usb_serial.rs │ │ └── src/ │ │ └── lib.rs │ ├── adafruit-macropad/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── adafruit-macropad_blinky.rs │ │ └── src/ │ │ └── lib.rs │ ├── adafruit-metro-rp2040/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ ├── adafruit_metro_blinky.rs │ │ │ └── adafruit_metro_rainbow.rs │ │ └── src/ │ │ └── lib.rs │ ├── adafruit-qt-py-rp2040/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── adafruit_qt_py_rp2040_rainbow.rs │ │ └── src/ │ │ └── lib.rs │ ├── adafruit-trinkey-qt2040/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── adafruit_trinkey_qt2040_rainbow.rs │ │ └── src/ │ │ └── lib.rs │ ├── arduino_nano_connect/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── nano_blinky.rs │ │ └── src/ │ │ └── lib.rs │ ├── boardsource-blok/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ ├── blok_rainbow.rs │ │ │ ├── blok_reset_to_usb_boot.rs │ │ │ └── blok_usb_keyboard_input.rs │ │ └── src/ │ │ └── lib.rs │ ├── framework-ledmatrix/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── build.rs │ │ ├── examples/ │ │ │ └── ledtest.rs │ │ └── src/ │ │ └── lib.rs │ ├── framework16-keyboard/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── build.rs │ │ ├── examples/ │ │ │ ├── capslock.rs │ │ │ └── white_backlight.rs │ │ └── src/ │ │ └── lib.rs │ ├── pimoroni-pico-explorer/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── pimoroni_pico_explorer_showcase.rs │ │ └── src/ │ │ └── lib.rs │ ├── pimoroni-pico-lipo-16mb/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── pimoroni_pico_lipo_16mb_blinky.rs │ │ └── src/ │ │ └── lib.rs │ ├── pimoroni-plasma-2040/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── build.rs │ │ ├── examples/ │ │ │ ├── pimoroni_plasma_2040_blinky.rs │ │ │ └── pimoroni_plasma_2040_ws2812_led.rs │ │ └── src/ │ │ └── lib.rs │ ├── pimoroni-servo2040/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── build.rs │ │ ├── examples/ │ │ │ ├── pimoroni_servo2040_pwm_servo.rs │ │ │ └── pimoroni_servo2040_rainbow.rs │ │ └── src/ │ │ └── lib.rs │ ├── pimoroni-tiny2040/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── build.rs │ │ ├── examples/ │ │ │ └── tiny2040_blinky.rs │ │ └── src/ │ │ └── lib.rs │ ├── pimoroni-tufty2040/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── tufty_demo.rs │ │ └── src/ │ │ ├── lib.rs │ │ └── st7789_parallel.pio │ ├── pimoroni_badger2040/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── badger_blinky.rs │ │ └── src/ │ │ └── lib.rs │ ├── rp-pico/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── build.rs │ │ ├── examples/ │ │ │ ├── pico_blinky.rs │ │ │ ├── pico_countdown_blinky.rs │ │ │ ├── pico_gpio_in_out.rs │ │ │ ├── pico_hd44780_display.rs │ │ │ ├── pico_i2c_oled_display_ssd1306.rs │ │ │ ├── pico_i2c_pio.rs │ │ │ ├── pico_interpolator.rs │ │ │ ├── pico_pio_pwm.rs │ │ │ ├── pico_pwm_blink.rs │ │ │ ├── pico_pwm_servo.rs │ │ │ ├── pico_rtic.rs │ │ │ ├── pico_rtic_monotonic.rs │ │ │ ├── pico_spi_sd_card.rs │ │ │ ├── pico_uart_irq_buffer.rs │ │ │ ├── pico_uart_irq_echo.rs │ │ │ ├── pico_usb_serial.rs │ │ │ ├── pico_usb_serial_interrupt.rs │ │ │ ├── pico_usb_twitchy_mouse.rs │ │ │ ├── pico_ws2812_led.rs │ │ │ └── pwm.pio │ │ └── src/ │ │ └── lib.rs │ ├── seeeduino-xiao-rp2040/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ ├── seeeduino_xiao_rp2040_blinky.rs │ │ │ └── seeeduino_xiao_rp2040_neopixel_rainbow.rs │ │ └── src/ │ │ └── lib.rs │ ├── solderparty-rp2040-stamp/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── solderparty_stamp_neopixel_rainbow.rs │ │ └── src/ │ │ └── lib.rs │ ├── sparkfun-micromod-rp2040/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── build.rs │ │ ├── examples/ │ │ │ ├── sparkfun_micromod_battery_voltage.rs │ │ │ └── sparkfun_micromod_blinky.rs │ │ └── src/ │ │ └── lib.rs │ ├── sparkfun-pro-micro-rp2040/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── sparkfun_pro_micro_rainbow.rs │ │ └── src/ │ │ └── lib.rs │ ├── sparkfun-thing-plus-rp2040/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── sparkfun_thing_plus_rainbow.rs │ │ └── src/ │ │ └── lib.rs │ ├── vcc-gnd-yd-rp2040/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ ├── yd_rp2040_blinky.rs │ │ │ └── yd_rp2040_neopixel_rainbow.rs │ │ └── src/ │ │ └── lib.rs │ ├── waveshare-rp2040-lcd-0-96/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── waveshare_rp2040_lcd_demo.rs │ │ └── src/ │ │ └── lib.rs │ ├── waveshare-rp2040-lcd-1-28/ │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples/ │ │ │ └── waveshare_rp2040_lcd_demo.rs │ │ └── src/ │ │ └── lib.rs │ └── waveshare-rp2040-zero/ │ ├── CHANGELOG.md │ ├── Cargo.toml │ ├── README.md │ ├── examples/ │ │ └── waveshare_rp2040_zero_neopixel_rainbow.rs │ └── src/ │ └── lib.rs └── memory.x ================================================ FILE CONTENTS ================================================ ================================================ FILE: .cargo/config.toml ================================================ # # Cargo Configuration for the https://github.com/rp-rs/rp-hal.git repository. # # Copyright (c) The RP-RS Developers, 2021 # # You might want to make a similar file in your own repository if you are # writing programs for Raspberry Silicon microcontrollers. # # This file is MIT or Apache-2.0 as per the repository README.md file # [build] # Set the default target to match the Cortex-M0+ in the RP2040 target = "thumbv6m-none-eabi" # Target specific options [target.thumbv6m-none-eabi] # Pass some extra options to rustc, some of which get passed on to the linker. # # * linker argument --nmagic turns off page alignment of sections (which saves # flash space) # * linker argument -Tlink.x tells the linker to use link.x as the linker # script. This is usually provided by the cortex-m-rt crate, and by default # the version in that crate will include a file called `memory.x` which # describes the particular memory layout for your specific chip. # * no-vectorize-loops turns off the loop vectorizer (seeing as the M0+ doesn't # have SIMD) rustflags = [ "-C", "link-arg=--nmagic", "-C", "link-arg=-Tlink.x", "-C", "no-vectorize-loops", ] # This runner will make a UF2 file and then copy it to a mounted RP2040 in USB # Bootloader mode: runner = "elf2uf2-rs -d" # This runner will find a supported SWD debug probe and flash your RP2040 over # SWD: # runner = "probe-rs run --chip RP2040" ================================================ FILE: .github/workflows/build_and_test.yml ================================================ on: [push, pull_request] name: Build and Test check jobs: builds: name: Build checks runs-on: ubuntu-24.04 strategy: matrix: features: ["--features rp2040-hal/rtic-monotonic", "--features rp2040-e5"] mode: ["", "--release"] steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@stable with: target: thumbv6m-none-eabi - name: Build workspace run: cargo build ${{ matrix.mode }} --workspace ${{ matrix.features }} - name: Build workspace and examples run: cargo build ${{ matrix.mode }} --workspace --examples ${{ matrix.features }} - name: List built examples and clean run: rm -vrf target/thumbv6m-none-eabi/*/examples/* | sed -e "s/removed '\(.*\)'/\1/" | xargs -l basename | grep -Ev '(-|\.d)' - name: Test run: cargo test --tests --target x86_64-unknown-linux-gnu ${{ matrix.features }} - name: Test docs run: cargo test --doc --target x86_64-unknown-linux-gnu ${{ matrix.features }} - name: Clean run: cargo clean udeps: name: Check rp2040-hal for unused dependencies runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@master with: toolchain: nightly-2024-01-30 target: thumbv6m-none-eabi - name: Install cargo-udeps uses: baptiste0928/cargo-install@v2 with: crate: cargo-udeps version: "=0.1.41" - name: Check unused deps run: cargo udeps ${{ matrix.mode }} --workspace ${{ matrix.features }} ================================================ FILE: .github/workflows/clippy.yml ================================================ on: [push, pull_request] name: Clippy check jobs: clippy_check: runs-on: ubuntu-24.04 env: RUSTFLAGS: "-D warnings" steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@stable with: target: thumbv6m-none-eabi components: clippy - run: cargo clippy --workspace --examples --features rp2040-hal/rtic-monotonic -- -Dwarnings ================================================ FILE: .github/workflows/rustfmt.yml ================================================ on: [push, pull_request] name: Code formatting check jobs: fmt: name: Rustfmt runs-on: ubuntu-24.04 env: RUSTFLAGS: "-D warnings" steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@stable with: target: thumbv6m-none-eabi components: rustfmt - run: cargo fmt -- --check ================================================ FILE: .gitignore ================================================ .idea/ target Cargo.lock .vscode *.orig *.raw ================================================ FILE: APACHE2.0 ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2021 rp-rs organization Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # The Rust Code of Conduct ## Conduct **Contact**: [rp-rs team][team] * We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. * On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. * Please be kind and courteous. There's no need to be mean or rude. * Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. * Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. * We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. * Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [rp-rs team][team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. * Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome. ## Moderation These are the policies for upholding our community's standards of conduct. 1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) 2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed. 3. Moderators will first respond to such remarks with a warning. 4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off. 5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded. 6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology. 7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed. 8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others. In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. The enforcement policies listed above apply to all official embedded rp-rs venues; including official Matrix channels (##rp-rs) and GitHub repositories under rp-rs. *Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).* *Text kindly borrowed from the Rust Embedded Working Group* [team]: https://github.com/orgs/rp-rs/teams/rp-rs ================================================ FILE: Cargo.toml ================================================ [workspace] resolver = "2" members = [ "boards/adafruit-feather-rp2040", "boards/adafruit-itsy-bitsy-rp2040", "boards/adafruit-kb2040", "boards/adafruit-macropad", "boards/adafruit-metro-rp2040", "boards/adafruit-qt-py-rp2040", "boards/adafruit-trinkey-qt2040", "boards/arduino_nano_connect", "boards/boardsource-blok", "boards/framework-ledmatrix", "boards/framework16-keyboard", "boards/pimoroni_badger2040", "boards/pimoroni-pico-explorer", "boards/pimoroni-pico-lipo-16mb", "boards/pimoroni-plasma-2040", "boards/pimoroni-servo2040", "boards/pimoroni-tiny2040", "boards/pimoroni-tufty2040", "boards/rp-pico", "boards/seeeduino-xiao-rp2040", "boards/solderparty-rp2040-stamp", "boards/sparkfun-micromod-rp2040", "boards/sparkfun-pro-micro-rp2040", "boards/sparkfun-thing-plus-rp2040", "boards/vcc-gnd-yd-rp2040", "boards/waveshare-rp2040-zero", "boards/waveshare-rp2040-lcd-0-96", "boards/waveshare-rp2040-lcd-1-28", ] [workspace.dependencies] arrayvec = { version = "0.7.4", default-features = false } cortex-m = "0.7.7" cortex-m-rt = "0.7.3" cortex-m-rtic = "1.1.4" critical-section = "1.1.2" defmt = "0.3.5" defmt-rtt = "0.4.0" display-interface = "0.4.1" display-interface-spi = "0.4.1" embedded-graphics = "0.7.1" embedded-hal = "1.0.0" embedded-hal-nb = "1.0.0" embedded-sdmmc = "0.5.0" embedded_hal_0_2 = { package = "embedded-hal", version = "0.2.5", features = ["unproven", ] } fugit = "0.3.7" hd44780-driver = "0.4.0" heapless = "0.7.16" i2c-pio = "0.8.0" nb = "1.1" panic-halt= "0.2.0" panic-probe = "0.3.1" pio = "0.2.1" pio-proc = "0.2.2" rp2040-boot2 = "0.3.0" rp2040-hal = "0.10.0" st7789 = "0.6.1" st7735-lcd = "0.8.1" smart-leds = "0.3.0" ssd1306 = "0.7.1" usb-device = "0.3.1" usbd-hid = "0.7.0" usbd-serial = "0.2.1" ws2812-pio = "0.8.0" gc9a01a_driver = "0.1.3" ================================================ FILE: MIT ================================================ MIT License Copyright (c) 2021 rp-rs organization Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================

Logo

rp-hal-boards

Rust support for boards based on the "Raspberry Silicon" family of microcontrollers

rp2040-hal · Report a Bug · Chat on Matrix

Table of Contents

  1. Getting Started
  2. Programming
  3. Roadmap
  4. Contributing
  5. License
  6. Contact
  7. Acknowledgements
## Getting Started So, you want to program your new Raspberry Silicon microcontroller, using the Rust programming language. You've come to the right place! These board support packages are based on [`rp-hal`](https://github.com/rp-rs/rp-hal) - a collection of high-level drivers for the Raspberry Silicon RP2040 microcontroller and various associated boards, like the Raspberry Pi Pico and the Adafruit Feather RP2040. If you want to write an application for Raspberry Silicon, check out our [RP2040 Project Template](https://github.com/rp-rs/rp2040-project-template). If you want to try out some examples on one of our supported boards, check out the list of *Board Support Packages* below, and click through to see the various examples for each board. Before trying any of the examples, please ensure you have the latest stable version of Rust installed, along with the right target support: ```sh rustup self update rustup update stable rustup target add thumbv6m-none-eabi ``` You may also want to install these helpful tools: ```sh # Useful to creating UF2 images for the RP2040 USB Bootloader cargo install --locked elf2uf2-rs # Useful for flashing over the SWD pins using a supported JTAG probe cargo install --locked probe-rs-tools ``` ## Packages This git repository is organised as a [Cargo Workspace]. If you are writing code that should work on any RP2040 device, use the [HAL crate]. If you are running code on a specific board, use the appropriate _BSP_ crate (which will include the _HAL_ crate for you). Please note, you cannot depend on multiple _BSP_ crates; you have to pick one, or use [Cargo Features] to select one at build time. Each BSP includes some examples to show off the features of that particular board. [HAL crate]: https://github.com/rp-rs/rp-hal [Cargo Workspace]: https://doc.rust-lang.org/cargo/reference/workspaces.html [Embedded HAL]: https://github.com/rust-embedded/embedded-hal [Cargo Features]: https://doc.rust-lang.org/cargo/reference/features.html [rp2040-hal]: https://crates.io/crates/rp2040-hal ### [rp-pico] - Board Support for the [Raspberry Pi Pico] You should include this crate if you are writing code that you want to run on a [Raspberry Pi Pico] - the original launch PCB for the RP2040 chip. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Pico. [Raspberry Pi Pico]: https://www.raspberrypi.org/products/raspberry-pi-pico/ [rp-pico]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/rp-pico ### [adafruit-feather-rp2040] - Board Support for the [Adafruit Feather RP2040] You should include this crate if you are writing code that you want to run on an [Adafruit Feather RP2040] - a Feather form-factor RP2040 board from Adafruit. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Feather RP2040. [Adafruit Feather RP2040]: https://www.adafruit.com/product/4884 [adafruit-feather-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-feather-rp2040 ### [adafruit-itsy-bitsy-rp2040] - Board Support for the [Adafruit ItsyBitsy RP2040] You should include this crate if you are writing code that you want to run on an [Adafruit ItsyBitsy RP2040] - an RP2040 board in the ItsyBitsy family. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the ItsyBitsy RP2040. [Adafruit ItsyBitsy RP2040]: https://www.adafruit.com/product/4888 [adafruit-itsy-bitsy-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-itsy-bitsy-rp2040 ### [adafruit-kb2040] - Board Support for the [Adafruit KB2040] You should include this crate if you are writing code that you want to run on an [Adafruit KB2040] - an Arduino Pro Micro-shaped board for keyboards. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the KB2040. [Adafruit KB2040]: https://www.adafruit.com/product/5302 [adafruit-kb2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-kb2040 ### [adafruit-macropad] - Board Support for the [Adafruit Macropad] You should include this crate if you are writing code that you want to run on an [Adafruit Macropad] - a 3x4 keyboard and OLED combo board from Adafruit. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Macropad. [adafruit-macropad]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-macropad [Adafruit Macropad]: https://www.adafruit.com/product/5128 ### [adafruit-metro-rp2040] - Board Support for the [Adafruit Metro RP2040] You should include this crate if you are writing code that you want to run on an [Adafruit Metro RP2040] - an RP2040 board in the Metro family. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Metro RP2040. [Adafruit Metro RP2040]: https://www.adafruit.com/product/5786 [adafruit-metro-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-metro-rp2040 ### [adafruit-qt-py-rp2040] - Board Support for the [Adafruit QT Py RP2040] You should include this crate if you are writing code that you want to run on an [Adafruit QT Py RP2040] - an extremely small form-factor RP2040 board from Adafruit. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Feather RP2040. [Adafruit QT Py RP2040]: https://www.adafruit.com/product/4900 [adafruit-qt-py-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-qt-py-rp2040 ### [adafruit-trinkey-qt2040] - Board Support for the [Adafruit Trinkey QT2040] You should include this crate if you are writing code that you want to run on an [Adafruit Trinkey QT2040] - a 3x4 keyboard and OLED combo board from Adafruit. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Trinkey. [Adafruit-Trinkey-QT2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-trinkey-qt2040 [adafruit trinkey qt2040]: https://www.adafruit.com/product/5056 ### [boardsource-blok] - Board Support for the [Blok] You should include this crate if you are writing code that you want to run on a [Blok] - an RP2040 based controller, made by [Boardsource], built for the keyboard community. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Blok. [Blok]: https://boardsource.xyz/store/628b95b494dfa308a6581622 [boardsource-blok]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/boardsource-blok [Boardsource]: https://boardsource.xyz/ ### [pimoroni_badger2040] - Board Support for the [Pimoroni Badger2040] You should include this crate if you are writing code that you want to run on a [Pimoroni Badger2040] - a conference-style badge built around an e-paper display and an rp2040 This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Badger2040. [Pimoroni Badger2040]: https://shop.pimoroni.com/products/badger-2040 [pimoroni_badger2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni_badger2040 ### [pimoroni-pico-explorer] - Board Support for the [Pimoroni Pico Explorer] You should include this crate if you are writing code that you want to run on a [Pimoroni Pico Explorer] - a breakout board for the [Raspberry Pi Pico] featuring a small LCD screen, a breadboard and some breakout headers. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Pico Explorer. [Pimoroni Pico Explorer]: https://shop.pimoroni.com/products/pimoroni-pico-explorer-base [pimoroni-pico-explorer]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-pico-explorer ### [pimoroni-pico-lipo-16mb] - Board Support for the [Pimoroni Pico Lipo 16MB] You should include this crate if you are writing code that you want to run on a [Pimoroni Pico Lipo 16MB] - a board with USB-C, STEMMA QT/Qwiic connectors, plus a Li-Po battery charging circuit. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Pico Lipo. Note that if you use this crate the compiler will expect the full 16MB flash space, and so it may not work if you only have the 4MB variant. [Pimoroni Pico Lipo 16MB]: https://shop.pimoroni.com/products/pimoroni-pico-lipo?variant=39335427080275 [pimoroni-pico-lipo-16mb]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-pico-lipo-16mb ### [pimoroni-plasma-2040] - Board Support for the [Pimoroni Plasma 2040] You should include this crate if you are writing code that you want to run on a [Pimoroni Plasma 2040] - Swathe everything in rainbows with this all-in-one, USB-C powered controller for WS2812/Neopixel and APA102/Dotstar addressable LED strip. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Pimoroni Plasma 2040. [Pimoroni Plasma 2040]: https://shop.pimoroni.com/products/plasma-2040 [pimoroni-plasma-2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-plasma-2040 ### [pimoroni-servo2040] - Board Support for the [Pimoroni Servo2040] You should include this crate if you are writing code that you want to run on a [Pimoroni Servo2040] - a standalone servo motor controller for up to 18 servos and 6 sensors. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Servo2040. [Pimoroni Servo2040]: https://shop.pimoroni.com/products/servo-2040 [pimoroni-servo2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-servo2040 ### [pimoroni-tiny2040] - Board Support for the [Pimoroni Tiny2040] You should include this crate if you are writing code that you want to run on a [Pimoroni Tiny2040] - one of the first third party RP2040 boards available, with 8MB flash and a 3 colour LED. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Tiny2040. [Pimoroni Tiny2040]: https://shop.pimoroni.com/products/tiny-2040 [pimoroni-tiny2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-tiny2040 ### [solderparty-rp2040-stamp] - Board Support for the [SolderParty RP2040 Stamp] You should include this crate if you are writing code that you want to run on a [SolderParty RP2040 Stamp] - a square RP2040 board with castellated edges. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Stamp. [SolderParty RP2040 Stamp]: https://www.solder.party/docs/rp2040-stamp/ [solderparty-rp2040-stamp]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/solderparty-rp2040-stamp ### [sparkfun-micromod-rp2040] - Board Support for the [SparkFun MicroMod RP2040] You should include this crate if you are writing code that you want to run on a [SparkFun MicroMod RP2040] - the RP2040 processor board for the [SparkFun MicroMod] ecosystem. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the MicroMod RP2040. [SparkFun MicroMod RP2040]: https://www.sparkfun.com/products/17720 [SparkFun MicroMod]: https://www.sparkfun.com/micromod [sparkfun-micromod-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/sparkfun-micromod-rp2040 ### [sparkfun-pro-micro-rp2040] - Board Support for the [Sparkfun Pro Micro RP2040] You should include this crate if you are writing code that you want to run on a [Sparkfun Pro Micro RP2040] - a smaller RP2040 board with USB-C and a WS2812B addressable LED. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Pro Micro RP2040. [Sparkfun Pro Micro RP2040]: https://www.sparkfun.com/products/18288 [sparkfun-pro-micro-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/sparkfun-pro-micro-rp2040 ### [sparkfun-thing-plus-rp2040] - Board Support for the [Sparkfun Thing Plus RP2040] You should include this crate if you are writing code that you want to run on a [Sparkfun Thing Plus RP2040] - an RP2040 board with a Feather form factor, USB-C, and a WS2812B addressable LED. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Thing Plus RP2040. [Sparkfun Thing Plus RP2040]: https://www.sparkfun.com/products/17745 [sparkfun-thing-plus-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/sparkfun-thing-plus-rp2040 ### [arduino_nano_connect] - Board Support for the [Arduino Nano RP2040 Connect] You should include this crate if you are writing code that you want to run on an [Arduino Nano RP2040 Connect] - a development pcb with shortwave communication, IMU, and BLE package. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the nano connect. [Arduino Nano RP2040 Connect]: https://store-usa.arduino.cc/collections/boards/products/arduino-nano-rp2040-connect [arduino_nano_connect]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/arduino_nano_connect ### [seeeduino-xiao-rp2040] - Board Support for the [Seeeduino XIAO RP2040] You should include this crate if you are writing code that you want to run on a [Seeeduino XIAO RP2040] - a tiny board for wearable devices and small projects. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the XIAO RP2040. [Seeeduino XIAO RP2040]: https://www.seeedstudio.com/XIAO-RP2040-v1-0-p-5026.html [seeeduino-xiao-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/seeeduino-xiao-rp2040 ### [vcc-gnd-yd-rp2040] - Board Support for the [VCC-GND Studio YD-RP2040] You should include this crate if you are writing code that you want to run on a [VCC-GND Studio YD-RP2040] - a PCB for the RP2040 chip with USB-C port, WS2812 RGB LED on GPIO23, user key on GPIO24 and built-in blue LED. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the YD-RP2040. [VCC-GND Studio YD-RP2040]: http://152.32.187.208:8080/yd-data/YD-RP2040/ [vcc-gnd-yd-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/vcc-gnd-yd-rp2040 ### [waveshare-rp2040-zero] - Board Support for the [Waveshare RP2040 Zero] You should include this crate if you are writing code that you want to run on an [Waveshare RP2040 Zero] - a very small RP2040 breakout board with USB-C and a RGB led from Waveshare. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the board. [Waveshare RP2040 Zero]: https://www.waveshare.com/wiki/RP2040-Zero [waveshare-rp2040-zero]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/waveshare-rp2040-zero ### [waveshare-rp2040-lcd-0_96] - Board Support for the [Waveshare RP2040 LCD 0.96"] You should include this crate if you are writing code that you want to run on an [Waveshare RP2040 LCD 0.96"] - a very small RP2040 breakout board with USB-C, a 65K IPS LCD 160x80, 16MBit Flash and 1A battery charger from Waveshare. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the board. [Waveshare RP2040 LCD 0.96"]: https://www.waveshare.com/wiki/RP2040-LCD-0.96 [waveshare-rp2040-lcd-0_96]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/waveshare-rp2040-lcd-0-96 ## Programming Rust generates standard Arm ELF files, which you can load onto your Raspberry Pi Silicon device with your favourite Arm flashing/debugging tool. In addition, the RP2040 contains a ROM bootloader which appears as a Mass Storage Device over USB that accepts UF2 format images. You can use the `elf2uf2-rs` package to convert the Arm ELF file to a UF2 format image. For boards with USB Device support like the Raspberry Pi Pico, we recommend you use the UF2 process. The RP2040 contains two Cortex-M0+ processors, which execute Thumb-2 encoded ARMv6-M instructions. There are no operating-specific features in the binaries produced - they are for 'bare-metal' systems. For compatibilty with other Arm code (e.g. as produced by GCC), Rust uses the *Arm Embedded-Application Binary Interface* standard or EABI. Therefore, any Rust code for the RP2040 should be compiled with the target *`thumbv6m-none-eabi`*. More details can be found in the [Project Template](https://github.com/rp-rs/rp2040-project-template). ### Loading a UF2 over USB *Step 1* - Install [`elf2uf2-rs`](https://github.com/JoNil/elf2uf2-rs): ```console $ cargo install elf2uf2-rs --locked ``` *Step 2* - Make sure your .cargo/config.toml contains the following (it should by default if you are working in this repository): ```toml [target.thumbv6m-none-eabi] runner = "elf2uf2-rs -d" ``` The `thumbv6m-none-eabi` target may be replaced by the all-Arm wildcard `'cfg(all(target_arch = "arm", target_os = "none"))'`. *Step 3* - Boot your RP2040 into "USB Bootloader mode", typically by rebooting whilst holding some kind of "Boot Select" button. On Linux, you will also need to 'mount' the device, like you would a USB Thumb Drive. *Step 4* - Use `cargo run`, which will compile the code and started the specified 'runner'. As the 'runner' is the elf2uf2-rs tool, it will build a UF2 file and copy it to your RP2040. ```console $ cargo run --release --example pico_pwm_blink ``` ### Loading with probe-rs [probe-rs](https://github.com/probe-rs/probe-rs) is a library and a command-line tool which can flash a wide variety of microcontrollers using a wide variety of debug/JTAG probes. Unlike using, say, OpenOCD, probe-rs can autodetect your debug probe, which can make it easier to use. *Step 1* - Install `probe-rs`: ```console $ cargo install --locked probe-rs-tools ``` Alternatively, follow the installation instructions on https://probe.rs/. *Step 2* - Make sure your .cargo/config.toml contains the following: ```toml [target.thumbv6m-none-eabi] runner = "probe-rs run --chip RP2040" ``` *Step 3* - Connect your USB JTAG/debug probe (such as a Raspberry Pi Pico running [this firmware](https://github.com/majbthrd/DapperMime)) to the SWD programming pins on your RP2040 board. Check the probe has been found by running: ```console $ probe-rs list The following debug probes were found: [0]: J-Link (J-Link) (VID: 1366, PID: 0101, Serial: 000099999999, JLink) ``` There is a SEGGER J-Link connected in the example above - the mesage you see will reflect the probe you have connected. *Step 4* - Use `cargo run`, which will compile the code and start the specified 'runner'. As the 'runner' is the `probe-rs` tool, it will connect to the RP2040 via the first probe it finds, and install your firmware into the Flash connected to the RP2040. ```console $ cargo run --release --example pico_pwm_blink ``` ### Loading with picotool As ELF files produced by compiling Rust code are completely compatible with ELF files produced by compiling C or C++ code, you can also use the Raspberry Pi tool [picotool](https://github.com/raspberrypi/picotool). The only thing to be aware of is that picotool expects your ELF files to have a `.elf` extension, and by default Rust does not give the ELF files any extension. You can fix this by simply renaming the file. Also of note is that the special [pico-sdk](https://github.com/raspberrypi/pico-sdk) macros which hide information in the ELF file in a way that `picotool info` can read it out, are not supported in Rust. An alternative is TBC. ## Roadmap NOTE These packages are under active development. As such, it is likely to remain volatile until a 1.0.0 release. See the [open issues](https://github.com/rp-rs/rp-hal/issues) for a list of proposed features (and known issues). ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ## Contact Raise an issue: [https://github.com/rp-rs/rp-hal-boards/issues](https://github.com/rp-rs/rp-hal-boards/issues) Chat to us on Matrix: [#rp-rs:matrix.org](https://matrix.to/#/#rp-rs:matrix.org) ## Acknowledgements * [Othneil Drew's README template](https://github.com/othneildrew) * [Rust Embedded Working Group](https://github.com/rust-embedded) * [Raspberry Pi](https://raspberrypi.org) and the [Pico SDK](https://github.com/raspberrypi/pico-sdk) ================================================ FILE: boards/adafruit-feather-rp2040/CHANGELOG.md ================================================ # 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.8.0 - 2024-04-07 ### Changed - Update to embedded-hal 1.0.0 - Update to rp2040-hal 0.10.0 ## 0.7.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.6.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.6.0 ## 0.5.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 ## 0.4.0 - 2022-08-26 ### Changed - Migrate from `embedded-time` to `fugit` - Bump `ws2812-pio` to 0.4.0 - Update to rp2040-hal 0.6.0 ## 0.3.0 - 2022-06-13 ### Changed - Update to rp2040-hal 0.5.0 ## 0.2.0 - 2022-03-11 ### Changed - Update to rp2040-hal 0.4.0 ## 0.1.0 - 2021-12-20 - Initial release ================================================ FILE: boards/adafruit-feather-rp2040/Cargo.toml ================================================ [package] name = "adafruit-feather-rp2040" version = "0.8.0" authors = ["Andrea Nall ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-feather-rp2040" description = "Board Support Package for the Adafruit Feather RP2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true panic-halt.workspace = true embedded-hal.workspace = true fugit.workspace = true nb.workspace = true smart-leds.workspace = true ws2812-pio.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it doesn't hurt to enable it rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/adafruit-feather-rp2040/README.md ================================================ # [adafruit-feather-rp2040] - Board Support for the [Adafruit Feather RP2040] You should include this crate if you are writing code that you want to run on an [Adafruit Feather RP2040] - a Feather form-factor RP2040 board from Adafruit. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Feather. [Adafruit Feather RP2040]: https://www.adafruit.com/product/4884 [adafruit-feather-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-feather-rp2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml adafruit-feather-rp2040 = "0.8.0" ``` In your program, you will need to call `adafruit_feather_rp2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/adafruit-feather-rp2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/adafruit-feather-rp2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [adafruit_feather_blinky](./examples/adafruit_feather_blinky.rs) Flashes the Feather's onboard LED on and off. ### [adafruit_feather_neopixel_rainbow](./examples/adafruit_feather_neopixel_rainbow.rs) Flows smoothly through various colors on the Feather's onboard NeoPixel LED. ## Contributing Contributions are what make the open source community such an amazing place to be, learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/adafruit-feather-rp2040/examples/adafruit_feather_blinky.rs ================================================ //! Blinks the LED on a Adafruit Feather RP2040 board //! //! This will blink on-board LED. #![no_std] #![no_main] use adafruit_feather_rp2040::entry; use adafruit_feather_rp2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; use embedded_hal::digital::OutputPin; use panic_halt as _; #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let mut led_pin = pins.d13.into_push_pull_output(); loop { led_pin.set_high().unwrap(); delay.delay_ms(1500); led_pin.set_low().unwrap(); delay.delay_ms(1500); } } ================================================ FILE: boards/adafruit-feather-rp2040/examples/adafruit_feather_neopixel_rainbow.rs ================================================ //! Rainbow effect color wheel using the onboard NeoPixel on an Adafruit Feather RP2040 board //! //! This flows smoothly through various colors on the onboard NeoPixel. //! Uses the `ws2812_pio` driver to control the NeoPixel, which in turns uses the //! RP2040's PIO block. #![no_std] #![no_main] use adafruit_feather_rp2040::entry; use adafruit_feather_rp2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, pio::PIOExt, timer::Timer, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use ws2812_pio::Ws2812; #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Configure the addressable LED let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( // The onboard NeoPixel is attached to GPIO pin #16 on the Feather RP2040. pins.neopixel.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); // Infinite colour wheel loop let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/adafruit-feather-rp2040/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_GD25Q64CS; pub use hal::pac; hal::bsp_pins!( Gpio0 { name: tx, aliases: { FunctionUart, PullNone: UartTx } }, Gpio1 { name: rx, aliases: { FunctionUart, PullNone: UartRx } }, Gpio2 { name: sda, aliases: { FunctionI2C, PullUp: Sda } }, Gpio3 { name: scl, aliases: { FunctionI2C, PullUp: Scl } }, Gpio6 { name: d4 }, Gpio7 { name: d5 }, Gpio8 { name: d6 }, Gpio9 { name: d9 }, Gpio10 { name: d10 }, Gpio11 { name: d11 }, Gpio12 { name: d12 }, Gpio13 { name: d13 }, Gpio16 { name: neopixel }, Gpio18 { name: sclk, aliases: { FunctionSpi, PullNone: Sclk } }, Gpio19 { name: mosi, aliases: { FunctionSpi, PullNone: Mosi } }, Gpio20 { name: miso, aliases: { FunctionSpi, PullNone: Miso } }, Gpio24 { name: d24 }, Gpio25 { name: d25 }, Gpio26 { name: a0 }, Gpio27 { name: a1 }, Gpio28 { name: a2 }, Gpio29 { name: a3 }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/adafruit-itsy-bitsy-rp2040/CHANGELOG.md ================================================ # 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.8.0 - 2024-04-07 ### Changed - Update to embedded-hal 1.0.0 - Update to rp2040-hal 0.10.0 ## 0.7.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.6.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 - Update to ws2812-pio 0.6.0 ## 0.5.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 ## 0.4.0 - 2022-08-26 ### Changed - Migrate from `embedded-time` to `fugit` - Bump `ws2812-pio` to 0.4.0 - Update to rp2040-hal 0.6.0 ## 0.3.0 - 2022-06-13 ### Changed - Update to rp2040-hal 0.5.0 ## 0.2.0 - 2022-03-11 ### Changed - Update to rp2040-hal 0.4.0 ## 0.1.0 - 2021-12-20 - Initial release ================================================ FILE: boards/adafruit-itsy-bitsy-rp2040/Cargo.toml ================================================ [package] name = "adafruit-itsy-bitsy-rp2040" version = "0.8.0" authors = ["Andrew Christiansen ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit_itsy_bitsy_rp2040" description = "Board Support Package for the Adafruit ItsyBitsy RP2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true panic-halt.workspace = true embedded-hal.workspace = true smart-leds.workspace = true nb.workspace = true ws2812-pio.workspace = true fugit.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it doesn't hurt to enable it rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/adafruit-itsy-bitsy-rp2040/README.md ================================================ # [adafruit-itsy-bitsy-rp2040] - Board Support for the [Adafruit ItsyBitsy RP2040] You should include this crate if you are writing code that you want to run on an [Adafruit ItsyBitsy RP2040] - an RP2040 board in the Itsy family from Adafruit. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the ItsyBitsy RP2040. [Adafruit ItsyBitsy RP2040]: https://www.adafruit.com/product/4888 [adafruit-itsy-bitsy-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-itsy-bitsy-rp2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml adafruit-itsy-bitsy-rp2040 = "0.8.0" ``` In your program, you will need to call `adafruit_itsy_bitsy_rp2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/adafruit-itsy-bitsy-rp2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/adafruit-itsy-bitsy-rp2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [adafruit_itsy_bitsy_blinky](./examples/adafruit_itsy_bitsy_blinky.rs) Blink an LED on and off. ### [adafruit_itsy_bitsy_rainbow](./examples/adafruit_itsy_bitsy_rainbow.rs) Continuously changes the color of the ItsyBitsy's onboard Neopixel. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/adafruit-itsy-bitsy-rp2040/examples/adafruit_itsy_bitsy_blinky.rs ================================================ //! # GPIO 'Blinky' Example //! //! Blinks the LED on a Adafruit itsy-bitsy RP2040 board //! //! It may need to be adapted to your particular board layout and/or pin assignment. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use adafruit_itsy_bitsy_rp2040::entry; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Some traits we need use embedded_hal::digital::OutputPin; use adafruit_itsy_bitsy_rp2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, sio::Sio, watchdog::Watchdog, }, Pins, XOSC_CRYSTAL_FREQ, }; use cortex_m::delay::Delay; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then toggles a GPIO pin in /// an infinite loop. If there is an LED connected to that pin, it will blink. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = Watchdog::new(pac.WATCHDOG); // Configure the clocks let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let mut delay = Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // The single-cycle I/O block controls our GPIO pins let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let mut led_pin = pins.d13.into_push_pull_output(); loop { led_pin.set_high().unwrap(); delay.delay_ms(500); led_pin.set_low().unwrap(); delay.delay_ms(500); } } // End of file ================================================ FILE: boards/adafruit-itsy-bitsy-rp2040/examples/adafruit_itsy_bitsy_rainbow.rs ================================================ //! Continuously changes the color of the Neopixel on a Adafruit ItsyBitsy RP2040 board #![no_std] #![no_main] use adafruit_itsy_bitsy_rp2040::entry; use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use ws2812_pio::Ws2812; use adafruit_itsy_bitsy_rp2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, gpio::PinState, pac, pio::PIOExt, watchdog::Watchdog, Sio, Timer, }, Pins, XOSC_CRYSTAL_FREQ, }; #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let led = pins.neopixel_data.into_function(); pins.neopixel_power .into_push_pull_output_in_state(PinState::High); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( led, &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/adafruit-itsy-bitsy-rp2040/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( Gpio0 { name: tx, aliases: { FunctionUart, PullNone: UartTx } }, Gpio1 { name: rx, aliases: { FunctionUart, PullNone: UartRx } }, Gpio2 { name: sda, aliases: { FunctionI2C, PullUp: Sda } }, Gpio3 { name: scl, aliases: { FunctionI2C, PullUp: Scl } }, Gpio4 { name: d4 }, Gpio5 { name: d3 }, Gpio6 { name: d7 }, Gpio7 { name: d9 }, Gpio8 { name: d10 }, Gpio9 { name: d11 }, Gpio10 { name: d12 }, Gpio11 { name: d13 }, Gpio12 { name: d2 }, Gpio14 { name: d5 }, Gpio16 { name: neopixel_power }, Gpio17 { name: neopixel_data }, Gpio18 { name: sclk, aliases: { FunctionSpi, PullNone: Sclk } }, Gpio19 { name: mosi, aliases: { FunctionSpi, PullNone: Mosi } }, Gpio20 { name: miso aliases: { FunctionSpi, PullNone: Miso } }, Gpio24 { name: d24 }, Gpio25 { name: d25 }, Gpio26 { name: a0 }, Gpio27 { name: a1 }, Gpio28 { name: a2 }, Gpio29 { name: a3 }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/adafruit-kb2040/CHANGELOG.md ================================================ # 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.8.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.7.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.6.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 - Update to ws2812-pio 0.6.0 ## 0.5.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 ## 0.4.0 - 2022-08-26 ### Changed - Migrate from `embedded-time` to `fugit` - Bump `ws2812-pio` to 0.4.0 - Update to rp2040-hal 0.6.0 ## 0.3.0 - 2022-06-13 ### Changed - Update to rp2040-hal 0.5.0 ## 0.2.0 - 2022-03-11 ### Changed - Update to rp2040-hal 0.4.0 ## 0.1.0 - 2021-12-20 - Initial release ================================================ FILE: boards/adafruit-kb2040/Cargo.toml ================================================ [package] name = "adafruit-kb2040" version = "0.8.0" authors = ["Andrew Christiansen ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-kb2040" description = "Board Support Package for the Adafruit KB2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } embedded-hal = { workspace = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] embedded-hal.workspace = true heapless.workspace = true fugit.workspace = true nb.workspace = true panic-halt.workspace = true smart-leds.workspace = true ws2812-pio.workspace = true usb-device.workspace = true usbd-serial.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it doesn't hurt to enable it rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/adafruit-kb2040/README.md ================================================ # [adafruit-kb2040] - Board Support for the [Adafruit KB2040] You should include this crate if you are writing code that you want to run on a [Adafruit KB2040] - an Arduino Pro Micro-shaped board for keyboards. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the KB2040. [Adafruit KB2040]: https://www.adafruit.com/product/5302 [adafruit-kb2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-kb2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml adafruit-kb2040 = "0.8.0" ``` In your program, you will need to call `adafruit-kb2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/adafruit-kb2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/adafruit-kb2040$ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [Rainbow](./examples/adafruit_kb2040_rainbow.rs) This example will display a colour-wheel rainbow effect on the on-board LED. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/adafruit-kb2040/examples/adafruit_kb2040_rainbow.rs ================================================ //! # Rainbow Example for the Adafruit KB2040 //! //! Runs a rainbow-effect colour wheel on the on-board LED. //! //! Uses the `ws2812_pio` driver to control the LED, which in turns uses the //! RP2040's PIO block. #![no_std] #![no_main] use adafruit_kb2040::entry; use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use adafruit_kb2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, pio::PIOExt, timer::Timer, watchdog::Watchdog, Sio, }, XOSC_CRYSTAL_FREQ, }; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use ws2812_pio::Ws2812; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this /// function as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then the LED, then runs /// the colour wheel in an infinite loop. #[entry] fn main() -> ! { // Configure the RP2040 peripherals let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = adafruit_kb2040::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Configure the addressable LED let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( pins.neopixel.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); // Infinite colour wheel loop let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/adafruit-kb2040/examples/adafruit_kb2040_usb_serial.rs ================================================ //! # Pico USB Serial Example //! //! Creates a USB Serial device on a Pico board, with the USB driver running in //! the main thread. //! //! This will create a USB Serial device echoing anything it receives. Incoming //! ASCII characters are converted to upercase, so you can tell it is working //! and not just local-echo! //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] use adafruit_kb2040 as bsp; // The macro for our start-up function use bsp::entry; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use bsp::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use bsp::hal; // USB Device support use usb_device::{class_prelude::*, prelude::*}; // USB Communications Class Device support use usbd_serial::SerialPort; // Used to demonstrate writing formatted strings use core::fmt::Write; use heapless::String; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then echoes any characters /// received over USB Serial. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( bsp::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); #[cfg(feature = "rp2040-e5")] { let sio = hal::Sio::new(pac.SIO); let _pins = bsp::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); } // Set up the USB driver let usb_bus = UsbBusAllocator::new(hal::usb::UsbBus::new( pac.USBCTRL_REGS, pac.USBCTRL_DPRAM, clocks.usb_clock, true, &mut pac.RESETS, )); // Set up the USB Communications Class Device driver let mut serial = SerialPort::new(&usb_bus); // Create a USB device with a fake VID and PID let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) .strings(&[StringDescriptors::default() .manufacturer("Fake company") .product("Serial port") .serial_number("TEST")]) .unwrap() .device_class(2) // from: https://www.usb.org/defined-class-codes .build(); let mut said_hello = false; loop { // A welcome message at the beginning if !said_hello && timer.get_counter().ticks() >= 2_000_000 { said_hello = true; let _ = serial.write(b"Hello, World!\r\n"); let time = timer.get_counter().ticks(); let mut text: String<64> = String::new(); writeln!(&mut text, "Current timer ticks: {}", time).unwrap(); // This only works reliably because the number of bytes written to // the serial port is smaller than the buffers available to the USB // peripheral. In general, the return value should be handled, so that // bytes not transferred yet don't get lost. let _ = serial.write(text.as_bytes()); } // Check for new data if usb_dev.poll(&mut [&mut serial]) { let mut buf = [0u8; 64]; match serial.read(&mut buf) { Err(_e) => { // Do nothing } Ok(0) => { // Do nothing } Ok(count) => { // Convert to upper case buf.iter_mut().take(count).for_each(|b| { b.make_ascii_uppercase(); }); // Send back to the host let mut wr_ptr = &buf[..count]; while !wr_ptr.is_empty() { match serial.write(wr_ptr) { Ok(len) => wr_ptr = &wr_ptr[len..], // On error, just drop unwritten data. // One possible error is Err(WouldBlock), meaning the USB // write buffer is full. Err(_) => break, }; } } } } } } // End of file ================================================ FILE: boards/adafruit-kb2040/src/lib.rs ================================================ #![no_std] pub use rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( Gpio0 { name: tx, aliases: { FunctionUart, PullNone: UartTx } }, Gpio1 { name: rx, aliases: { FunctionUart, PullNone: UartRx } }, Gpio2 { name: d2 }, Gpio3 { name: d3 }, Gpio4 { name: d4 }, Gpio5 { name: d5 }, Gpio6 { name: d6 }, Gpio7 { name: d7 }, Gpio8 { name: d8 }, Gpio9 { name: d9 }, Gpio10 { name: d10 }, Gpio11 { name: d11 }, Gpio12 { name: sda, aliases: { FunctionI2C, PullNone: Sda } }, Gpio13 { name: scl, aliases: { FunctionI2C, PullNone: Scl } }, Gpio17 { name: neopixel }, Gpio18 { name: sclk, aliases: { FunctionSpi, PullNone: Sclk } }, Gpio19 { name: mosi, aliases: { FunctionSpi, PullNone: Mosi } }, Gpio20 { name: miso, aliases: { FunctionSpi, PullNone: Miso } }, Gpio26 { name: a0 }, Gpio27 { name: a1 }, Gpio28 { name: a2 }, Gpio29 { name: a3 }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/adafruit-macropad/CHANGELOG.md ================================================ # 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.8.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.7.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 ## 0.6.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 ## 0.5.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 ## 0.4.0 - 2022-08-26 ### Changed - Use `rp2040-hal`'s entry function. - Migrate from `embedded-time` to `fugit` - Update to rp2040-hal 0.6.0 ## 0.3.0 - 2022-06-13 ### Changed - Update to rp2040-hal 0.5.0 ## 0.2.0 - 2022-03-11 ### Changed - Update to rp2040-hal 0.4.0 ## 0.1.0 - 2021-12-20 - Initial release ================================================ FILE: boards/adafruit-macropad/Cargo.toml ================================================ [package] name = "adafruit-macropad" version = "0.8.0" authors = ["Andrea Nall ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit_macropad" description = "Board Support Package for the Adafruit Macropad" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true embedded-hal.workspace = true panic-halt.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it doesn't hurt to enable it rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/adafruit-macropad/README.md ================================================ # [adafruit-macropad] - Board Support for the [Adafruit Macropad] You should include this crate if you are writing code that you want to run on an [Adafruit Macropad] - a 3x4 keyboard and OLED combo board from Adafruit. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Feather. [adafruit-macropad]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-macropad [Adafruit Macropad]: https://www.adafruit.com/product/5128 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml adafruit-macropad = "0.8.0" ``` In your program, you will need to call `adafruit_macropad::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/adafruit-macropad $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/adafruit-macropad $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/adafruit-macropad/examples/adafruit-macropad_blinky.rs ================================================ //! Blinks the LED on a Adafruit MacroPad board //! //! This will blink on-board LED. #![no_std] #![no_main] use adafruit_macropad::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; use embedded_hal::digital::OutputPin; use panic_halt as _; /// Entry point to our bare-metal application. /// /// The `#[rp2040_hal::entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables and the spinlock are initialised. #[rp2040_hal::entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let mut led_pin = pins.led.into_push_pull_output(); loop { led_pin.set_high().unwrap(); delay.delay_ms(1500); led_pin.set_low().unwrap(); delay.delay_ms(1500); } } ================================================ FILE: boards/adafruit-macropad/src/lib.rs ================================================ #![no_std] pub use rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; // Adafruit macropad uses W25Q64JVxQ flash chip. Should work with BOOT_LOADER_W25Q080 (untested) /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( Gpio0 { name: button }, Gpio1 { name: key1 }, Gpio2 { name: key2 }, Gpio3 { name: key3 }, Gpio4 { name: key4 }, Gpio5 { name: key5 }, Gpio6 { name: key6 }, Gpio7 { name: key7 }, Gpio8 { name: key8 }, Gpio9 { name: key9 }, Gpio10 { name: key10 }, Gpio11 { name: key11 }, Gpio12 { name: key12 }, Gpio13 { name: led }, Gpio14 { name: speaker_shutdown }, Gpio16 { name: speaker }, Gpio17 { name: encoder_rota, aliases: { FunctionSioInput, PullUp: RotaryA } }, Gpio18 { name: encoder_rotb, aliases: { FunctionSioInput, PullUp: RotaryB } }, Gpio19 { name: neopixel }, Gpio20 { name: sda, aliases: { FunctionI2C, PullUp: Sda } }, Gpio21 { name: scl, aliases: { FunctionI2C, PullUp: Scl } }, // This CS is on the wrong SPI channel so cannot be controlled by the peripheral Gpio22 { name: oled_cs }, Gpio23 { name: oled_reset }, Gpio24 { name: oled_dc }, Gpio26 { name: sclk, aliases: { FunctionSpi, PullNone: Sclk } }, Gpio27 { name: mosi, aliases: { FunctionSpi, PullNone: Mosi } }, Gpio28 { name: miso, aliases: { FunctionSpi, PullNone: Miso } }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/adafruit-metro-rp2040/CHANGELOG.md ================================================ # 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.1.0 - 2024-04-07 - Initial release ================================================ FILE: boards/adafruit-metro-rp2040/Cargo.toml ================================================ [package] name = "adafruit-metro-rp2040" version = "0.1.0" authors = ["Thad House ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-metro-rp2040" description = "Board Support Package for the Adafruit Metro RP2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true panic-halt.workspace = true embedded-hal.workspace = true smart-leds.workspace = true nb.workspace = true ws2812-pio.workspace = true fugit.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it doesn't hurt to enable it rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/adafruit-metro-rp2040/README.md ================================================ # [adafruit-metro-rp2040] - Board Support for the [Adafruit Metro RP2040] You should include this crate if you are writing code that you want to run on an [Adafruit Metro RP2040] - an RP2040 board in the Metro family from Adafruit. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Metro RP2040. [Adafruit Metro RP2040]: https://www.adafruit.com/product/5786 [adafruit-metro-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-metro-rp2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml adafruit-metro-rp2040 = "0.1.0" ``` In your program, you will need to call `adafruit_metro_rp2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/adafruit-metro-rp2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/adafruit-metro-rp2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [adafruit_metro_blinky](./examples/adafruit_metro_blinky.rs) Blink an LED on and off. ### [adafruit_metro_rainbow](./examples/adafruit_metro_rainbow.rs) Continuously changes the color of the Metro's onboard Neopixel. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/adafruit-metro-rp2040/examples/adafruit_metro_blinky.rs ================================================ //! # GPIO 'Blinky' Example //! //! Blinks the LED on a Adafruit Metro RP2040 board //! //! It may need to be adapted to your particular board layout and/or pin assignment. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use adafruit_metro_rp2040::entry; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Some traits we need use embedded_hal::digital::OutputPin; use adafruit_metro_rp2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, sio::Sio, watchdog::Watchdog, }, Pins, XOSC_CRYSTAL_FREQ, }; use cortex_m::delay::Delay; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then toggles a GPIO pin in /// an infinite loop. If there is an LED connected to that pin, it will blink. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = Watchdog::new(pac.WATCHDOG); // Configure the clocks let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let mut delay = Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // The single-cycle I/O block controls our GPIO pins let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let mut led_pin = pins.d13.into_push_pull_output(); loop { led_pin.set_high().unwrap(); delay.delay_ms(500); led_pin.set_low().unwrap(); delay.delay_ms(500); } } // End of file ================================================ FILE: boards/adafruit-metro-rp2040/examples/adafruit_metro_rainbow.rs ================================================ //! Continuously changes the color of the Neopixel on a Adafruit Metro RP2040 board #![no_std] #![no_main] use adafruit_metro_rp2040::entry; use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use ws2812_pio::Ws2812; use adafruit_metro_rp2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, pio::PIOExt, watchdog::Watchdog, Sio, Timer, }, Pins, XOSC_CRYSTAL_FREQ, }; #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let led = pins.neopixel_data.into_function(); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( led, &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/adafruit-metro-rp2040/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( Gpio0 { name: tx, aliases: { FunctionUart, PullNone: UartTx } }, Gpio1 { name: rx, aliases: { FunctionUart, PullNone: UartRx } }, Gpio2 { name: d2 }, Gpio3 { name: d3 }, Gpio4 { name: d4 }, Gpio5 { name: d5 }, Gpio6 { name: d6 }, Gpio7 { name: d7 }, Gpio8 { name: d8 }, Gpio9 { name: d9 }, Gpio10 { name: d10 }, Gpio11 { name: d11 }, Gpio12 { name: d12 }, Gpio13 { name: d13 }, Gpio14 { name: neopixel_data }, Gpio15 { name: sd_cd, }, Gpio16 { name: sda, aliases: { FunctionI2C, PullUp: Sda } }, Gpio17 { name: scl, aliases: { FunctionI2C, PullUp: Scl } }, Gpio18 { name: sclk, aliases: { FunctionSpi, PullNone: Sclk } }, Gpio19 { name: mosi, aliases: { FunctionSpi, PullNone: Mosi } }, Gpio20 { name: miso aliases: { FunctionSpi, PullNone: Miso } }, Gpio21 { name: sdio_data1 }, Gpio22 { name: sdio_data2 }, Gpio23 { name: sd_cs }, Gpio24 { name: d24 }, Gpio25 { name: d25 }, Gpio26 { name: a0 }, Gpio27 { name: a1 }, Gpio28 { name: a2 }, Gpio29 { name: a3 }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/adafruit-qt-py-rp2040/CHANGELOG.md ================================================ # 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.8.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to ws2812-pio 0.8.0 - Update to embedded-hal 1.0.0 ## 0.7.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.6.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 - Update to ws2812-pio 0.6.0 ## 0.5.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 ## 0.4.0 - 2022-08-26 ### Changed - Migrate from `embedded-time` to `fugit` - Bump `ws2812-pio` to 0.4.0 - Update to rp2040-hal 0.6.0 ## 0.3.0 - 2022-06-13 ### Changed - Update to rp2040-hal 0.5.0 ## 0.2.0 - 2022-03-11 ### Changed - Update to rp2040-hal 0.4.0 ## 0.1.0 - 2021-12-20 - Initial release ================================================ FILE: boards/adafruit-qt-py-rp2040/Cargo.toml ================================================ [package] name = "adafruit-qt-py-rp2040" version = "0.8.0" authors = ["Stephen Onnen ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-qt-py-rp2040" description = "Board Support Package for the Adafruit QT Py RP2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] panic-halt.workspace = true embedded-hal.workspace = true smart-leds.workspace = true nb.workspace = true ws2812-pio.workspace = true fugit.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/adafruit-qt-py-rp2040/README.md ================================================ # [adafruit-qt-py-rp2040] - Board Support for the [Adafruit QT Py RP2040] You should include this crate if you are writing code that you want to run on an [Adafruit QT Py RP2040] - an extremely small form-factor RP2040 board from Adafruit. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the QT Py. [Adafruit QT Py RP2040]: https://www.adafruit.com/product/4900 [adafruit-qt-py-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-qt-py-rp2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml adafruit-qt-py-rp2040 = "0.8.0" ``` In your program, you will need to call `adafruit_qt_py_rp2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/adafruit-qt-py-rp2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/adafruit-qt-py-rp2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [adafruit_qt_py_rp2040_rainbow](./examples/adafruit_qt_py_rp2040_rainbow.rs) Continuously changes the color of the QT Py's onboard Neopixel. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/adafruit-qt-py-rp2040/examples/adafruit_qt_py_rp2040_rainbow.rs ================================================ //! Continuously changes the color of the Neopixel on a Adafruit QT Py RP2040 board #![no_std] #![no_main] use adafruit_qt_py_rp2040::entry; use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use ws2812_pio::Ws2812; use adafruit_qt_py_rp2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, gpio::PinState, pac, pio::PIOExt, watchdog::Watchdog, Sio, Timer, }, Pins, XOSC_CRYSTAL_FREQ, }; #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let led = pins.neopixel_data.into_function(); pins.neopixel_power .into_push_pull_output_in_state(PinState::High); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( led, &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/adafruit-qt-py-rp2040/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_GD25Q64CS; pub use hal::pac; hal::bsp_pins!( Gpio3 { name: mosi, aliases: { FunctionSpi, PullNone: Mosi } }, Gpio4 { name: miso aliases: { FunctionSpi, PullNone: Miso } }, Gpio5 { name: rx, aliases: { FunctionUart, PullNone: UartRx } }, Gpio6 { name: sclk, aliases: { FunctionSpi, PullNone: Sclk } }, Gpio11 { name: neopixel_power }, Gpio12 { name: neopixel_data }, Gpio20 { name: tx, aliases: { FunctionUart, PullNone: UartTx } }, Gpio21 { name: button }, Gpio22 { name: sda1, aliases: { FunctionI2C, PullUp: Sda1 } }, Gpio23 { name: scl1, aliases: { FunctionI2C, PullUp: Scl1 } }, Gpio24 { name: sda, aliases: { FunctionI2C, PullUp: Sda } }, Gpio25 { name: scl, aliases: { FunctionI2C, PullUp: Scl } }, Gpio26 { name: a3 }, Gpio27 { name: a2 }, Gpio28 { name: a1 }, Gpio29 { name: a0 }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/adafruit-trinkey-qt2040/CHANGELOG.md ================================================ # 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.7.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.6.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.5.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 - Update to ws2812-pio 0.6.0 ## 0.4.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 ## 0.3.0 - 2022-08-26 ### Changed - Migrate from `embedded-time` to `fugit` - Bump `ws2812-pio` to 0.4.0 - Update to rp2040-hal 0.6.0 ================================================ FILE: boards/adafruit-trinkey-qt2040/Cargo.toml ================================================ [package] name = "adafruit-trinkey-qt2040" version = "0.7.0" authors = ["The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-trinkey-qt2040" description = "Board Support Package for the Adafruit Trinkey QT2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] panic-halt.workspace = true embedded-hal.workspace = true smart-leds.workspace = true nb.workspace = true ws2812-pio.workspace = true fugit.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/adafruit-trinkey-qt2040/README.md ================================================ # [adafruit-trinkey-qt2040] - Board Support for the [Adafruit Trinkey QT2040] You should include this crate if you are writing code that you want to run on an [Adafruit Trinkey QT2040] - a 3x4 keyboard and OLED combo board from Adafruit. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Trinkey. [adafruit-trinkey-qt2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/adafruit-trinkey-qt2040 [adafruit trinkey qt2040]: https://www.adafruit.com/product/5056 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal ## Using To use this crate, your `Cargo.toml` file should contain: ```toml adafruit-trinkey-qt2040 = "0.7.0" ``` In your program, you will need to call `adafruit-trinkey-qt2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/adafruit-trinkey-qt2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/adafruit-trinkey-qt2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [Rainbow](./examples/adafruit_trinkey_qt2040_rainbow.rs) This example will display a colour-wheel rainbow effect on the on-board LED. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][coc], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [coc]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/adafruit-trinkey-qt2040/examples/adafruit_trinkey_qt2040_rainbow.rs ================================================ //! # Rainbow Example for the Adafruit Trinkey QT2040 //! //! Runs a rainbow-effect colour wheel on the on-board LED. //! //! Uses the `ws2812_pio` driver to control the LED, which in turns uses the //! RP2040's PIO block. #![no_std] #![no_main] use adafruit_trinkey_qt2040::entry; use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use adafruit_trinkey_qt2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, pio::PIOExt, timer::Timer, watchdog::Watchdog, Sio, }, XOSC_CRYSTAL_FREQ, }; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use ws2812_pio::Ws2812; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this /// function as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then the LED, then runs /// the colour wheel in an infinite loop. #[entry] fn main() -> ! { // Configure the RP2040 peripherals let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = adafruit_trinkey_qt2040::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Configure the addressable LED let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( pins.neopixel.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); // Infinite colour wheel loop let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/adafruit-trinkey-qt2040/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( Gpio12 { name: button }, Gpio16 { name: sda, aliases: { FunctionI2C, PullUp: Sda } }, Gpio17 { name: scl, aliases: { FunctionI2C, PullUp: Scl } }, Gpio27 { name: neopixel }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/arduino_nano_connect/.gitignore ================================================ # Generated by Cargo # will have compiled files and executables debug/ target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk ================================================ FILE: boards/arduino_nano_connect/CHANGELOG.md ================================================ # 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.7.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.6.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 ## 0.5.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 ## 0.4.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 ## 0.3.0 - 2022-08-26 ### Changed - Use `rp2040-hal`'s entry function. - Migrate from `embedded-time` to `fugit` - Update to rp2040-hal 0.6.0 ### Removed - Unused dependencies ================================================ FILE: boards/arduino_nano_connect/Cargo.toml ================================================ [package] name = "arduino_nano_connect" version = "0.7.0" authors = ["splicedbread ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/arduino_nano_connect" description = "Board Support Package for the Arduino Nano RP2040 Connect" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } embedded-hal = { workspace = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true panic-halt.workspace = true embedded-hal.workspace = true nb.workspace = true fugit.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/arduino_nano_connect/README.md ================================================ # [arduino_nano_connect] - Board Support for the [Arduino Nano RP2040 Connect] You should include this crate if you are writing code that you want to run on an [Arduino Nano RP2040 Connect] - a development pcb with shortwave communication, IMU, and BLE package. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the nano connect. [Arduino Nano RP2040 Connect]: https://store-usa.arduino.cc/collections/boards/products/arduino-nano-rp2040-connect [arduino_nano_connect]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/arduino_nano_connect [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml arduino_nano_connect = "0.7.0" ``` # TODO - down and out In your program, you will need to call `arduino_nano_connect::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples [nano_blinky](./examples/nano_blinky.rs) ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/arduino_nano_connect $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/arduino_nano_connect $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` then try repeating the `cargo run` command above. ### [nano_blinky](./examples/nano_blinky.rs) Flashes the Arduino Nano Connect's on-board LED on and off. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can chose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/arduino_nano_connect/examples/nano_blinky.rs ================================================ //! # Nano Blinky Example //! //! Blinks the LED on a Arduino Nano Connect board. //! //! This will blink an LED attached to GP25, which is the pin the Nano uses for //! the on-board LED. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] use embedded_hal::digital::OutputPin; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; use arduino_nano_connect as bsp; // Pull in any important traits use bsp::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use bsp::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use bsp::hal; /// Entry point to our bare-metal application. /// /// The `#[arduino_nano_connect::entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables and the spinlock are initialised. /// /// The function configures the RP2040 peripherals, then blinks the LED in an /// infinite loop. #[arduino_nano_connect::entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( bsp::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = bsp::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Set the LED to be an output let mut led_pin = pins.sck0.into_push_pull_output(); // Blink the LED at 1 Hz loop { led_pin.set_high().unwrap(); delay.delay_ms(500); led_pin.set_low().unwrap(); delay.delay_ms(500); } } // End of file ================================================ FILE: boards/arduino_nano_connect/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] pub use rp2040_hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. /// /// According to [the Arduino store] /// the board should contain a AT25SF128A flash chip. But /// there are [reports] of board with different flash chips, /// where the boot loader BOOT_LOADER_AT25SF128A does not /// work. /// /// Therefore, the generic boot loader is used by default. For a specific /// board, the flash performance can be increased by switching to the /// matching boot loader. /// /// [the Arduino store]: https://store.arduino.cc/products/arduino-nano-rp2040-connect /// [reports]: https://github.com/rp-rs/rp-hal/issues/503 /// #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_GENERIC_03H; // pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_AT25SF128A; pub use hal::pac; // borrowed some pin defs from rp-pico from a dicussion on the bsp_pins! macro // stripped out functions from connected lines that are no available through // any of the header pins hal::bsp_pins!( /// GPIO 0 supports following functions: /// | Default | UART0 TX (arduino nano connect) /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp0Spi0Rx] | /// | `UART0 TX` | [crate::Gp0Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp0I2C0Sda] | /// | `PWM0 A` | [crate::Gp0Pwm0A] | /// | `PIO0` | [crate::Gp0Pio0] | /// | `PIO1` | [crate::Gp0Pio1] | Gpio0 { name: tx, aliases: { /// UART Function alias for pin [crate::Pins::gpio0]. FunctionUart, PullNone: Gp0Uart0Tx } }, /// GPIO 1 supports following functions: /// | Default | UART0 RX (arduino nano connect) /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp1Spi0Csn] | /// | `UART0 RX` | [crate::Gp1Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp1I2C0Scl] | /// | `PWM0 B` | [crate::Gp1Pwm0B] | /// | `PIO0` | [crate::Gp1Pio0] | /// | `PIO1` | [crate::Gp1Pio1] | Gpio1 { name: rx, aliases: { /// UART Function alias for pin [crate::Pins::gpio1]. FunctionUart, PullNone: Gp1Uart0Rx } }, /// GPIO 2 supports following functions: /// | Default | GPIO0 on nina, relates to BLE CTS /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp2Spi0Sck] | /// | `UART0 CTS` | [crate::Gp2Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp2I2C1Sda] | /// | `PWM1 A` | [crate::Gp2Pwm1A] | /// | `PIO0` | [crate::Gp2Pio0] | /// | `PIO1` | [crate::Gp2Pio1] | Gpio2 { // name indicates BLE CTS on nina module, so outgoing line is bleRts using UART name: ble_rts, aliases: { /// UART Function alias for pin [crate::Pins::gpio2]. FunctionUart, PullNone: Gp2Uart0Cts } }, /// GPIO 3 supports following functions: /// | Default | Line for reset of Nina Wifi Module /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp3Spi0Tx] | /// | `UART0 RTS` | [crate::Gp3Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp3I2C1Scl] | /// | `PWM1 B` | [crate::Gp3Pwm1B] | /// | `PIO0` | [crate::Gp3Pio0] | /// | `PIO1` | [crate::Gp3Pio1] | Gpio3 { name: nina_reset_n }, /// GPIO 4 supports following functions: /// | Default | SpiRx /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp4Spi0Rx] | /// | `UART1 TX` | [crate::Gp4Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp4I2C0Sda] | /// | `PWM2 A` | [crate::Gp4Pwm2A] | /// | `PIO0` | [crate::Gp4Pio0] | /// | `PIO1` | [crate::Gp4Pio1] | Gpio4 { // Conflicting information between schematic and 'latest' pinnout diagram. // MISO in schematic, CIPO in 'latest' arduino pinnout diagram. same thing really // SPIRX in schematic line label. name: cipo, aliases: { /// UART Function alias for pin [crate::Pins::gpio4]. FunctionUart, PullNone: Gp4Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio4]. FunctionSpi, PullNone: Gp4Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio4]. FunctionI2C, PullUp: Gp4I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio4]. FunctionPwm, PullNone: Gp4Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio4]. FunctionPio0, PullNone: Gp4Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio4]. FunctionPio1, PullNone: Gp4Pio1 } }, /// GPIO 5 supports following functions: /// | Default | Generic Digital pin D10 /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp5Spi0Csn] | /// | `UART1 RX` | [crate::Gp5Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp5I2C0Scl] | /// | `PWM2 B` | [crate::Gp5Pwm2B] | /// | `PIO0` | [crate::Gp5Pio0] | /// | `PIO1` | [crate::Gp5Pio1] | Gpio5 { name: d10, aliases: { /// UART Function alias for pin [crate::Pins::gpio5]. FunctionUart, PullNone: Gp5Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio5]. FunctionSpi, PullNone: Gp5Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio5]. FunctionI2C, PullUp: Gp5I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio5]. FunctionPwm, PullNone: Gp5Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio5]. FunctionPio0, PullNone: Gp5Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio5]. FunctionPio1, PullNone: Gp5Pio1 } }, /// GPIO 6 supports following functions: /// | Default | SPI0 SCK (tied to on board led) /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp6Spi0Sck] | /// | `UART1 CTS` | [crate::Gp6Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp6I2C1Sda] | /// | `PWM3 A` | [crate::Gp6Pwm3A] | /// | `PIO0` | [crate::Gp6Pio0] | /// | `PIO1` | [crate::Gp6Pio1] | Gpio6 { // also tied to on board led, on pin 13 name: sck0, aliases: { /// UART Function alias for pin [crate::Pins::gpio6]. FunctionUart, PullNone: Gp6Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio6]. FunctionSpi, PullNone: Gp6Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio6]. FunctionI2C, PullUp: Gp6I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio6]. FunctionPwm, PullNone: Gp6Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio6]. FunctionPio0, PullNone: Gp6Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio6]. FunctionPio1, PullNone: Gp6Pio1 } }, /// GPIO 7 supports following functions: /// | Default | SPI0 TX /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp7Spi0Tx] | /// | `UART1 RTS` | [crate::Gp7Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp7I2C1Scl] | /// | `PWM3 B` | [crate::Gp7Pwm3B] | /// | `PIO0` | [crate::Gp7Pio0] | /// | `PIO1` | [crate::Gp7Pio1] | Gpio7 { // Conflicting information between schematic and 'latest' pinnout diagram. // MOSI in schematic, COPI in 'latest' arduino pinnout diagram. // SPITX in schematic line label. name: copi, aliases: { /// UART Function alias for pin [crate::Pins::gpio7]. FunctionUart, PullNone: Gp7Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio7]. FunctionSpi, PullNone: Gp7Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio7]. FunctionI2C, PullUp: Gp7I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio7]. FunctionPwm, PullNone: Gp7Pwm3B, /// PIO0 Function alias for pin [crate::Pins::gpio7]. FunctionPio0, PullNone: Gp7Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio7]. FunctionPio1, PullNone: Gp7Pio1 } }, /// GPIO 8 supports following functions: /// | Default | SPI1 CIPO / UART1 TX connection to Nina Module /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp8Spi1Rx] | /// | `UART1 TX` | [crate::Gp8Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp8I2C0Sda] | /// | `PWM4 A` | [crate::Gp8Pwm4A] | /// | `PIO0` | [crate::Gp8Pio0] | /// | `PIO1` | [crate::Gp8Pio1] | Gpio8 { // name indicates port to BLE RX on nina module and SPI CIPO for wifi name: ble_tx_cipo, aliases: { /// UART Function alias for pin [crate::Pins::gpio8]. FunctionUart, PullNone: Gp8Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio8]. FunctionSpi, PullNone: Gp8Spi1Rx } }, /// GPIO 9 supports following functions: /// | Default | SPI1 CS / UART1 RX /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp9Spi1Csn] | /// | `UART1 RX` | [crate::Gp9Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp9I2C0Scl] | /// | `PWM4 B` | [crate::Gp9Pwm4B] | /// | `PIO0` | [crate::Gp9Pio0] | /// | `PIO1` | [crate::Gp9Pio1] | Gpio9 { // name indicates BLE TX on nina module and spi1 cs signal to wifi name: ble_rx_cs, aliases: { /// UART Function alias for pin [crate::Pins::gpio9]. FunctionUart, PullNone: Gp9Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio9]. FunctionSpi, PullNone: Gp9Spi1Csn } }, /// GPIO 10 supports following functions: /// | Default | SPI1 ACK / UART1 CTS /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp10Spi1Sck] | /// | `UART1 CTS` | [crate::Gp10Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp10I2C1Sda] | /// | `PWM5 A` | [crate::Gp10Pwm5A] | /// | `PIO0` | [crate::Gp10Pio0] | /// | `PIO1` | [crate::Gp10Pio1] | Gpio10 { // name indicates BLE RTS on nina module and spi1 ack name: ble_cts_ack, aliases: { /// UART Function alias for pin [crate::Pins::gpio10]. FunctionUart, PullNone: Gp10Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio10]. FunctionSpi, PullNone: Gp10Spi1Sck } }, /// GPIO 11 supports following functions: /// | Default | SPI1 COPI / UART1 RTS /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp11Spi1Tx] | /// | `UART1 RTS` | [crate::Gp11Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp11I2C1Scl] | /// | `PWM5 B` | [crate::Gp11Pwm5B] | /// | `PIO0` | [crate::Gp11Pio0] | /// | `PIO1` | [crate::Gp11Pio1] | Gpio11 { // ninaCOPI is name: nina_copi, aliases: { /// UART Function alias for pin [crate::Pins::gpio11]. FunctionUart, PullNone: Gp11Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio11]. FunctionSpi, PullNone: Gp11Spi1Tx } }, /// GPIO 12 supports following functions: /// | Default | I2C0 SDA / A4 ~ goes to pullups and auth /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp12Spi1Rx] | /// | `UART0 TX` | [crate::Gp12Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp12I2C0Sda] | /// | `PWM6 A` | [crate::Gp12Pwm6A] | /// | `PIO0` | [crate::Gp12Pio0] | /// | `PIO1` | [crate::Gp12Pio1] | Gpio12 { // Also SDA Crypto name: a4, aliases: { /// UART Function alias for pin [crate::Pins::gpio12]. FunctionUart, PullNone: Gp12Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio12]. FunctionSpi, PullNone: Gp12Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio12]. FunctionI2C, PullUp: Gp12I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio12]. FunctionPwm, PullNone: Gp12Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio12]. FunctionPio0, PullNone: Gp12Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio12]. FunctionPio1, PullNone: Gp12Pio1 } }, /// GPIO 13 supports following functions: /// | Default | I2C0 SCL / A5 ~ goes to pullups /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp13Spi1Csn] | /// | `UART0 RX` | [crate::Gp13Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp13I2C0Scl] | /// | `PWM6 B` | [crate::Gp13Pwm6B] | /// | `PIO0` | [crate::Gp13Pio0] | /// | `PIO1` | [crate::Gp13Pio1] | Gpio13 { // Also SCL Crypto name: a5, aliases: { /// UART Function alias for pin [crate::Pins::gpio13]. FunctionUart, PullNone: Gp13Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio13]. FunctionSpi, PullNone: Gp13Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio13]. FunctionI2C, PullUp: Gp13I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio13]. FunctionPwm, PullNone: Gp13Pwm6B, /// PIO0 Function alias for pin [crate::Pins::gpio13]. FunctionPio0, PullNone: Gp13Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio13]. FunctionPio1, PullNone: Gp13Pio1 } }, /// GPIO 14 supports following functions: /// | Default | SPI1 SCK ~ nina SCK /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp14Spi1Sck] | /// | `UART0 CTS` | [crate::Gp14Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp14I2C1Sda] | /// | `PWM7 A` | [crate::Gp14Pwm7A] | /// | `PIO0` | [crate::Gp14Pio0] | /// | `PIO1` | [crate::Gp14Pio1] | Gpio14 { name: nina_sck, aliases: { /// SPI Function alias for pin [crate::Pins::gpio14]. FunctionSpi, PullNone: Gp14Spi1Sck } }, /// GPIO 15 supports following functions: /// | Default | General Digital pin D3 /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp15Spi1Tx] | /// | `UART0 RTS` | [crate::Gp15Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp15I2C1Scl] | /// | `PWM7 B` | [crate::Gp15Pwm7B] | /// | `PIO0` | [crate::Gp15Pio0] | /// | `PIO1` | [crate::Gp15Pio1] | Gpio15 { name: d3, aliases: { /// UART Function alias for pin [crate::Pins::gpio15]. FunctionUart, PullNone: Gp15Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio15]. FunctionSpi, PullNone: Gp15Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio15]. FunctionI2C, PullUp: Gp15I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio15]. FunctionPwm, PullNone: Gp15Pwm7B, /// PIO0 Function alias for pin [crate::Pins::gpio15]. FunctionPio0, PullNone: Gp15Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio15]. FunctionPio1, PullNone: Gp15Pio1 } }, /// GPIO 16 supports following functions: /// | Default | General Digital pin D4 /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp16Spi0Rx] | /// | `UART0 TX` | [crate::Gp16Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp16I2C0Sda] | /// | `PWM0 A` | [crate::Gp16Pwm0A] | /// | `PIO0` | [crate::Gp16Pio0] | /// | `PIO1` | [crate::Gp16Pio1] | Gpio16 { name: d4, aliases: { /// UART Function alias for pin [crate::Pins::gpio16]. FunctionUart, PullNone: Gp16Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio16]. FunctionSpi, PullNone: Gp16Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio16]. FunctionI2C, PullUp: Gp16I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio16]. FunctionPwm, PullNone: Gp16Pwm0A, /// PIO0 Function alias for pin [crate::Pins::gpio16]. FunctionPio0, PullNone: Gp16Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio16]. FunctionPio1, PullNone: Gp16Pio1 } }, /// GPIO 17 supports following functions: /// | Default | General Digital pin D5 /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp17Spi0Csn] | /// | `UART0 RX` | [crate::Gp17Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp17I2C0Scl] | /// | `PWM0 B` | [crate::Gp17Pwm0B] | /// | `PIO0` | [crate::Gp17Pio0] | /// | `PIO1` | [crate::Gp17Pio1] | Gpio17 { name: d5, aliases: { /// UART Function alias for pin [crate::Pins::gpio17]. FunctionUart, PullNone: Gp17Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio17]. FunctionSpi, PullNone: Gp17Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio17]. FunctionI2C, PullUp: Gp17I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio17]. FunctionPwm, PullNone: Gp17Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio17]. FunctionPio0, PullNone: Gp17Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio17]. FunctionPio1, PullNone: Gp17Pio1 } }, /// GPIO 18 supports following functions: /// | Default | General Digital pin D6 /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp18Spi0Sck] | /// | `UART0 CTS` | [crate::Gp18Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp18I2C1Sda] | /// | `PWM1 A` | [crate::Gp18Pwm1A] | /// | `PIO0` | [crate::Gp18Pio0] | /// | `PIO1` | [crate::Gp18Pio1] | Gpio18 { name: d6, aliases: { /// UART Function alias for pin [crate::Pins::gpio18]. FunctionUart, PullNone: Gp18Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio18]. FunctionSpi, PullNone: Gp18Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio18]. FunctionI2C, PullUp: Gp18I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio18]. FunctionPwm, PullNone: Gp18Pwm1A, /// PIO0 Function alias for pin [crate::Pins::gpio18]. FunctionPio0, PullNone: Gp18Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio18]. FunctionPio1, PullNone: Gp18Pio1 } }, /// GPIO 19 supports following functions: /// | Default | General Digital Pin D7 /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp19Spi0Tx] | /// | `UART0 RTS` | [crate::Gp19Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp19I2C1Scl] | /// | `PWM1 B` | [crate::Gp19Pwm1B] | /// | `PIO0` | [crate::Gp19Pio0] | /// | `PIO1` | [crate::Gp19Pio1] | Gpio19 { name: d7, aliases: { /// UART Function alias for pin [crate::Pins::gpio19]. FunctionUart, PullNone: Gp19Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio19]. FunctionSpi, PullNone: Gp19Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio19]. FunctionI2C, PullUp: Gp19I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio19]. FunctionPwm, PullNone: Gp19Pwm1B, /// PIO0 Function alias for pin [crate::Pins::gpio19]. FunctionPio0, PullNone: Gp19Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio19]. FunctionPio1, PullNone: Gp19Pio1 } }, /// GPIO 20 supports following functions: /// | Default | General Digital pin D8 /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp20Spi0Rx] | /// | `UART1 TX` | [crate::Gp20Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp20I2C0Sda] | /// | `PWM2 A` | [crate::Gp20Pwm2A] | /// | `PIO0` | [crate::Gp20Pio0] | /// | `PIO1` | [crate::Gp20Pio1] | Gpio20 { name: d8, aliases: { /// UART Function alias for pin [crate::Pins::gpio20]. FunctionUart, PullNone: Gp20Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio20]. FunctionSpi, PullNone: Gp20Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio20]. FunctionI2C, PullUp: Gp20I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio20]. FunctionPwm, PullNone: Gp20Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio20]. FunctionPio0, PullNone: Gp20Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio20]. FunctionPio1, PullNone: Gp20Pio1 } }, /// GPIO 21 supports following functions: /// | Default | General Digital pin D9 /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp21Spi0Csn] | /// | `UART1 RX` | [crate::Gp21Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp21I2C0Scl] | /// | `PWM2 B` | [crate::Gp21Pwm2B] | /// | `PIO0` | [crate::Gp21Pio0] | /// | `PIO1` | [crate::Gp21Pio1] | Gpio21 { name: d9, aliases: { /// UART Function alias for pin [crate::Pins::gpio21]. FunctionUart, PullNone: Gp21Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio21]. FunctionSpi, PullNone: Gp21Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio21]. FunctionI2C, PullUp: Gp21I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio21]. FunctionPwm, PullNone: Gp21Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio21]. FunctionPio0, PullNone: Gp21Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio21]. FunctionPio1, PullNone: Gp21Pio1 } }, /// GPIO 22 supports following functions: /// | Default | PDMDIN /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp22Spi0Sck] | /// | `UART1 CTS` | [crate::Gp22Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp22I2C1Sda] | /// | `PWM3 A` | [crate::Gp22Pwm3A] | /// | `PIO0` | [crate::Gp22Pio0] | /// | `PIO1` | [crate::Gp22Pio1] | Gpio22 { // this connects to the microphone module name: pdmdin }, /// GPIO 23 supports following functions: /// | Default | PDMCLK /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp23Spi0Tx] | /// | `UART1 RTS` | [crate::Gp23Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp23I2C1Scl] | /// | `PWM3 B` | [crate::Gp23Pwm3B] | /// | `PIO0` | [crate::Gp23Pio0] | /// | `PIO1` | [crate::Gp23Pio1] | Gpio23 { name: pdmclk }, /// GPIO 24 supports following functions: /// | Default | INT1 ~ connected to INT1 on the IMU /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp24Spi1Rx] | /// | `UART1 TX` | [crate::Gp24Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp24I2C0Sda] | /// | `PWM4 A` | [crate::Gp24Pwm4A] | /// | `PIO0` | [crate::Gp24Pio0] | /// | `PIO1` | [crate::Gp24Pio1] | Gpio24 { name: int1 }, /// GPIO 25 supports following functions: /// | Default | /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp25Spi1Csn] | /// | `UART1 RX` | [crate::Gp25Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp25I2C0Scl] | /// | `PWM4 B` | [crate::Gp25Pwm4B] | /// | `PIO0` | [crate::Gp25Pio0] | /// | `PIO1` | [crate::Gp25Pio1] | Gpio25 { name: d2, aliases: { /// UART Function alias for pin [crate::Pins::gpio25]. FunctionUart, PullNone: Gp25Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio25]. FunctionSpi, PullNone: Gp25Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio25]. FunctionI2C, PullUp: Gp25I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio25]. FunctionPwm, PullNone: Gp25Pwm4B, /// PIO0 Function alias for pin [crate::Pins::gpio25]. FunctionPio0, PullNone: Gp25Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio25]. FunctionPio1, PullNone: Gp25Pio1 } }, /// GPIO 26 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp26Spi1Sck] | /// | `UART1 CTS` | [crate::Gp26Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp26I2C1Sda] | /// | `PWM5 A` | [crate::Gp26Pwm5A] | /// | `PIO0` | [crate::Gp26Pio0] | /// | `PIO1` | [crate::Gp26Pio1] | Gpio26 { name: a0, aliases: { /// UART Function alias for pin [crate::Pins::gpio26]. FunctionUart, PullNone: Gp26Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio26]. FunctionSpi, PullNone: Gp26Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio26]. FunctionI2C, PullUp: Gp26I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio26]. FunctionPwm, PullNone: Gp26Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio26]. FunctionPio0, PullNone: Gp26Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio26]. FunctionPio1, PullNone: Gp26Pio1 } }, /// GPIO 27 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp27Spi1Tx] | /// | `UART1 RTS` | [crate::Gp27Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp27I2C1Scl] | /// | `PWM5 B` | [crate::Gp27Pwm5B] | /// | `PIO0` | [crate::Gp27Pio0] | /// | `PIO1` | [crate::Gp27Pio1] | Gpio27 { name: a1, aliases: { /// UART Function alias for pin [crate::Pins::gpio27]. FunctionUart, PullNone: Gp27Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio27]. FunctionSpi, PullNone: Gp27Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio27]. FunctionI2C, PullUp: Gp27I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio27]. FunctionPwm, PullNone: Gp27Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio27]. FunctionPio0, PullNone: Gp27Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio27]. FunctionPio1, PullNone: Gp27Pio1 } }, /// GPIO 28 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp28Spi1Rx] | /// | `UART0 TX` | [crate::Gp28Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp28I2C0Sda] | /// | `PWM6 A` | [crate::Gp28Pwm6A] | /// | `PIO0` | [crate::Gp28Pio0] | /// | `PIO1` | [crate::Gp28Pio1] | Gpio28 { name: a2, aliases: { /// UART Function alias for pin [crate::Pins::gpio28]. FunctionUart, PullNone: Gp28Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio28]. FunctionSpi, PullNone: Gp28Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio28]. FunctionI2C, PullUp: Gp28I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio28]. FunctionPwm, PullNone: Gp28Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio28]. FunctionPio0, PullNone: Gp28Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio28]. FunctionPio1, PullNone: Gp28Pio1 } }, /// GPIO 29 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CS` | [crate::Gp29Spi1CSn] | /// | `UART0 RX` | [crate::Gp29Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp29I2C0Scl] | /// | `PWM6 B` | [crate::Gp29Pwm6B] | /// | `PIO0` | [crate::Gp29Pio0] | /// | `PIO1` | [crate::Gp29Pio1] | Gpio29 { name: a3, aliases: { /// UART Function alias for pin [crate::Pins::gpio28]. FunctionUart, PullNone: Gp29Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio28]. FunctionSpi, PullNone: Gp29Spi1CSn, /// I2C Function alias for pin [crate::Pins::gpio28]. FunctionI2C, PullUp: Gp29I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio28]. FunctionPwm, PullNone: Gp29Pwm6B, /// PIO0 Function alias for pin [crate::Pins::gpio28]. FunctionPio0, PullNone: Gp29Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio28]. FunctionPio1, PullNone: Gp29Pio1 } }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/boardsource-blok/.gitignore ================================================ # Generated by Cargo # will have compiled files and executables debug/ target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk ================================================ FILE: boards/boardsource-blok/CHANGELOG.md ================================================ # 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.3.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.2.1 - 2023-10-25 ### Changed - Updated pinout ## 0.2.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.1.0 - 2023-6-8 - Initial release ================================================ FILE: boards/boardsource-blok/Cargo.toml ================================================ [package] name = "boardsource-blok" version = "0.3.0" edition = "2021" authors = ["Agent59 ", "The rp-rs Developers"] homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/boardsource-blok" description = "Board Support Package for the rp2040 based Blok" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m.workspace = true rp2040-boot2 = { workspace = true, optional = true} rp2040-hal.workspace = true cortex-m-rt = { workspace = true, optional = true} fugit.workspace = true [dev-dependencies] panic-halt.workspace = true embedded-hal.workspace = true nb.workspace = true smart-leds.workspace = true ws2812-pio.workspace = true usb-device.workspace = true usbd-hid.workspace = true critical-section.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/boardsource-blok/README.md ================================================ # [boardsource-blok] - Board Support for the [Blok] You should include this crate if you are writing code that you want to run on a [Blok] - an RP2040 based controller, made by [Boardsource], built for the keyboard community. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Blok. More Information about the pin layout at [Peg]. [Blok]: https://boardsource.xyz/store/628b95b494dfa308a6581622 [boardsource-blok]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/boardsource-blok [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Boardsource]: https://boardsource.xyz/ [Peg]: https://peg.software/docs/blok ## Using To use this crate, your `Cargo.toml` file should contain: ```toml boardsource-blok = "0.3.0" ``` In your program, you will need to call `blok::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/boardsource-blok $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/boardsource-blok $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` then try repeating the `cargo run` command above. ### From Scratch To start a basic project from scratch, create a project using `cargo new project-name`. Within the project directory, run `cargo add blok`, `cargo add cortex-m-rt`, and `cargo add panic-halt`. The first command will add this HAL (Hardware Abstraction Layer), the second is required for the `#[entry]` macro, and _panic-halt_ creates a simple panic function, which just halts. You'll also need to copy the cargo config file from the [repo](https://github.com/rp-rs/rp-hal-boards/blob/main/.cargo/config.toml). It specifies the target and optimizing flags to the linker. You'll also need to copy [_memory.x_](https://github.com/rp-rs/rp-hal-boards/blob/main/memory.x) to your project root. This file tells the linker the flash and RAM layout, so it won't clobber the bootloader or write to an out of bounds memory address. The simplest working example, which does nothing except loop forever, is: ```ignore #![no_std] #![no_main] use blok::entry; use panic_halt as _; #[entry] fn see_doesnt_have_to_be_called_main() -> ! { loop {} } ``` It can be placed in _/src/main.rs_. You can use `cargo run` to compile and install it. **Note**: You won't see any activity since this program does nothing. You can use the examples provided to add more functionality. ### [blok_rainbow](./examples/blok_rainbow.rs) Runs a rainbow-effect color wheel on the on-board neopixel. ### [blok_reset_to_usb_boot](./examples/blok_reset_to_usb_boot.rs) Resets the Blok after 10 seconds to usb boot mode. ### [blok_usb_keyboard_input](./examples/blok_usb_keyboard_input.rs) Demonstrates emulating a USB Human Input Device (HID) Keyboard. The keyboard will type "HELLO" five times. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/boardsource-blok/examples/blok_rainbow.rs ================================================ //! # Rainbow Example for the Blok //! //! Runs a rainbow-effect colour wheel on the on-board neopixel. //! Uses the `ws2821_pio` driver to control the NeoPixel, which in turn uses the //! RP2040's PIO block //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] use boardsource_blok::entry; use boardsource_blok::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, pio::PIOExt, timer::Timer, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use ws2812_pio::Ws2812; #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Configure the addressable LED let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( // The onboard neopixel is attached to GPIO pin 25 pins.neopixel.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); // Infinite colour wheel loop let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/boardsource-blok/examples/blok_reset_to_usb_boot.rs ================================================ //! # Reset To Usb Boot Example for the Blok //! //! Resets the Blok after 10 seconds to usb boot mode. //! //! Afterwards the microcontroller should be automatically mounted as a drive, //! just like when booted while holding down the boot button. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] use boardsource_blok::{entry, hal}; use boardsource_blok::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, timer::Timer, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; use panic_halt as _; #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let _pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let _timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); let core = pac::CorePeripherals::take().unwrap(); let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); loop { // waits 10 seconds delay.delay_ms(10_000); // resets to usb boot mode hal::rom_data::reset_to_usb_boot(0, 0); } } ================================================ FILE: boards/boardsource-blok/examples/blok_usb_keyboard_input.rs ================================================ //! # Keyboard Input Example for the Blok //! //! Creates a USB HID Class Keyboard device on a Blok, //! with the USB driver running in the main thread. //! //! It generates keyboard reports which all together //! type the word "HELLO" on the computer. //! //! This behaviour will be repeated 5 times //! after which the Blok will reset to usb boot mode. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] #![allow(static_mut_refs)] use boardsource_blok::{entry, hal}; use boardsource_blok::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, pac::interrupt, timer::Timer, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; use panic_halt as _; use usb_device::{ bus::UsbBusAllocator, device::{StringDescriptors, UsbDevice, UsbDeviceBuilder, UsbVidPid}, }; use usbd_hid::{descriptor::KeyboardReport, descriptor::SerializedDescriptor, hid_class::HIDClass}; // shared with the interrupt static mut USB_BUS: Option> = None; static mut USB_HID: Option> = None; static mut USB_DEVICE: Option> = None; #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let _pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let _timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); let usb_bus = UsbBusAllocator::new(hal::usb::UsbBus::new( pac.USBCTRL_REGS, pac.USBCTRL_DPRAM, clocks.usb_clock, true, &mut pac.RESETS, )); unsafe { USB_BUS = Some(usb_bus); } let bus_ref = unsafe { USB_BUS.as_ref().unwrap() }; let usb_hid = HIDClass::new(bus_ref, KeyboardReport::desc(), 10); unsafe { USB_HID = Some(usb_hid); } let usb_device = UsbDeviceBuilder::new(bus_ref, UsbVidPid(0x1209, 0x0001)) .strings(&[StringDescriptors::default().product("keyboard input")]) .unwrap() .build(); unsafe { USB_DEVICE = Some(usb_device); } // enable usb interrupt unsafe { pac::NVIC::unmask(hal::pac::Interrupt::USBCTRL_IRQ); } let core = pac::CorePeripherals::take().unwrap(); let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); let mut i = 0; loop { // wait 5 seconds on the first loop, otherwise the first keyboard reports // might not be processed by the computer if i == 0 { delay.delay_ms(5_000); } delay.delay_ms(100); push_report(KeyboardReport { modifier: 0b0000_0010, // LeftShift reserved: 0x00, leds: 0x00, keycodes: [0x0b, 0x00, 0x00, 0x00, 0x00, 0x00], // H }); delay.delay_ms(100); push_report(KeyboardReport { modifier: 0b0000_0010, // LeftShift reserved: 0x00, leds: 0x00, keycodes: [0x08, 0x00, 0x00, 0x00, 0x00, 0x00], // E }); delay.delay_ms(100); push_report(KeyboardReport { modifier: 0b0000_0010, // LeftShift reserved: 0x00, leds: 0x00, keycodes: [0x0f, 0x00, 0x00, 0x00, 0x00, 0x00], // L }); delay.delay_ms(100); push_report(KeyboardReport { modifier: 0x00, reserved: 0x00, leds: 0x00, keycodes: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // no keys pressed }); delay.delay_ms(100); push_report(KeyboardReport { modifier: 0b0000_0010, // LeftShift reserved: 0x00, leds: 0x00, keycodes: [0x0f, 0x00, 0x00, 0x00, 0x00, 0x00], // L }); delay.delay_ms(100); push_report(KeyboardReport { modifier: 0b0000_0010, // LeftShift reserved: 0x00, leds: 0x00, keycodes: [0x12, 0x00, 0x00, 0x00, 0x00, 0x00], // O }); delay.delay_ms(100); push_report(KeyboardReport { modifier: 0x00, reserved: 0x00, leds: 0x00, keycodes: [0x2c, 0x00, 0x00, 0x00, 0x00, 0x00], // space }); i += 1; if i >= 5 { hal::rom_data::reset_to_usb_boot(0, 0); } } } /// Submit a new Keyboard Report to the USB stack. /// /// We do this with interrupts disabled, to avoid a race hazard with the USB IRQ. fn push_report(report: KeyboardReport) { let _ = critical_section::with(|_| unsafe { // Now interrupts are disabled USB_HID.as_mut().map(|hid| hid.push_input(&report)) }) .unwrap(); } /// This function is called whenever the USB Hardware generates /// an Interrupt Request #[allow(non_snake_case)] #[interrupt] unsafe fn USBCTRL_IRQ() { let usb_device = USB_DEVICE.as_mut().unwrap(); let usb_hid = USB_HID.as_mut().unwrap(); usb_device.poll(&mut [usb_hid]); } ================================================ FILE: boards/boardsource-blok/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( /// GPIO 0 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp0Spi0Rx] | /// | `UART0 TX` | [crate::Gp0Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp0I2C0Sda] | /// | `PWM0 A` | [crate::Gp0Pwm0A] | /// | `PIO0` | [crate::Gp0Pio0] | /// | `PIO1` | [crate::Gp0Pio1] | Gpio0 { name: gpio0, aliases: { /// UART Function alias for pin [crate::Pins::gpio0]. FunctionUart, PullNone: Gp0Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio0]. FunctionSpi, PullNone: Gp0Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio0]. FunctionI2C, PullUp: Gp0I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio0]. FunctionPwm, PullNone: Gp0Pwm0A, /// PIO0 Function alias for pin [crate::Pins::gpio0]. FunctionPio0, PullNone: Gp0Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio0]. FunctionPio1, PullNone: Gp0Pio1 } }, /// GPIO 1 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp1Spi0Csn] | /// | `UART0 RX` | [crate::Gp1Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp1I2C0Scl] | /// | `PWM0 B` | [crate::Gp1Pwm0B] | /// | `PIO0` | [crate::Gp1Pio0] | /// | `PIO1` | [crate::Gp1Pio1] | Gpio1 { name: gpio1, aliases: { /// UART Function alias for pin [crate::Pins::gpio1]. FunctionUart, PullNone: Gp1Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio1]. FunctionSpi, PullNone: Gp1Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio1]. FunctionI2C, PullUp: Gp1I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio1]. FunctionPwm, PullNone: Gp1Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio1]. FunctionPio0, PullNone: Gp1Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio1]. FunctionPio1, PullNone: Gp1Pio1 } }, /// GPIO 16 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp16Spi0Rx] | /// | `UART0 TX` | [crate::Gp16Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp16I2C0Sda] | /// | `PWM0 A` | [crate::Gp16Pwm0A] | /// | `PIO0` | [crate::Gp16Pio0] | /// | `PIO1` | [crate::Gp16Pio1] | Gpio16 { name: gpio16, aliases: { /// UART Function alias for pin [crate::Pins::gpio16]. FunctionUart, PullNone: Gp16Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio16]. FunctionSpi, PullNone: Gp16Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio16]. FunctionI2C, PullUp: Gp16I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio16]. FunctionPwm, PullNone: Gp16Pwm0A, /// PIO0 Function alias for pin [crate::Pins::gpio16]. FunctionPio0, PullNone: Gp16Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio16]. FunctionPio1, PullNone: Gp16Pio1 } }, /// GPIO 17 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp17Spi0Csn] | /// | `UART0 RX` | [crate::Gp17Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp17I2C0Scl] | /// | `PWM0 B` | [crate::Gp17Pwm0B] | /// | `PIO0` | [crate::Gp17Pio0] | /// | `PIO1` | [crate::Gp17Pio1] | Gpio17 { name: gpio17, aliases: { /// UART Function alias for pin [crate::Pins::gpio17]. FunctionUart, PullNone: Gp17Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio17]. FunctionSpi, PullNone: Gp17Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio17]. FunctionI2C, PullUp: Gp17I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio17]. FunctionPwm, PullNone: Gp17Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio17]. FunctionPio0, PullNone: Gp17Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio17]. FunctionPio1, PullNone: Gp17Pio1 } }, /// GPIO 4 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp4Spi0Rx] | /// | `UART1 TX` | [crate::Gp4Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp4I2C0Sda] | /// | `PWM2 A` | [crate::Gp4Pwm2A] | /// | `PIO0` | [crate::Gp4Pio0] | /// | `PIO1` | [crate::Gp4Pio1] | Gpio4 { name: gpio4, aliases: { /// UART Function alias for pin [crate::Pins::gpio4]. FunctionUart, PullNone: Gp4Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio4]. FunctionSpi, PullNone: Gp4Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio4]. FunctionI2C, PullUp: Gp4I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio4]. FunctionPwm, PullNone: Gp4Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio4]. FunctionPio0, PullNone: Gp4Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio4]. FunctionPio1, PullNone: Gp4Pio1 } }, /// GPIO 5 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp5Spi0Csn] | /// | `UART1 RX` | [crate::Gp5Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp5I2C0Scl] | /// | `PWM2 B` | [crate::Gp5Pwm2B] | /// | `PIO0` | [crate::Gp5Pio0] | /// | `PIO1` | [crate::Gp5Pio1] | Gpio5 { name: gpio5, aliases: { /// UART Function alias for pin [crate::Pins::gpio5]. FunctionUart, PullNone: Gp5Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio5]. FunctionSpi, PullNone: Gp5Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio5]. FunctionI2C, PullUp: Gp5I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio5]. FunctionPwm, PullNone: Gp5Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio5]. FunctionPio0, PullNone: Gp5Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio5]. FunctionPio1, PullNone: Gp5Pio1 } }, /// GPIO 6 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp6Spi0Sck] | /// | `UART1 CTS` | [crate::Gp6Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp6I2C1Sda] | /// | `PWM3 A` | [crate::Gp6Pwm3A] | /// | `PIO0` | [crate::Gp6Pio0] | /// | `PIO1` | [crate::Gp6Pio1] | Gpio6 { name: gpio6, aliases: { /// UART Function alias for pin [crate::Pins::gpio6]. FunctionUart, PullNone: Gp6Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio6]. FunctionSpi, PullNone: Gp6Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio6]. FunctionI2C, PullUp: Gp6I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio6]. FunctionPwm, PullNone: Gp6Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio6]. FunctionPio0, PullNone: Gp6Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio6]. FunctionPio1, PullNone: Gp6Pio1 } }, /// GPIO 7 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp7Spi0Tx] | /// | `UART1 RTS` | [crate::Gp7Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp7I2C1Scl] | /// | `PWM3 B` | [crate::Gp7Pwm3B] | /// | `PIO0` | [crate::Gp7Pio0] | /// | `PIO1` | [crate::Gp7Pio1] | Gpio7 { name: gpio7, aliases: { /// UART Function alias for pin [crate::Pins::gpio7]. FunctionUart, PullNone: Gp7Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio7]. FunctionSpi, PullNone: Gp7Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio7]. FunctionI2C, PullUp: Gp7I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio7]. FunctionPwm, PullNone: Gp7Pwm3B, /// PIO0 Function alias for pin [crate::Pins::gpio7]. FunctionPio0, PullNone: Gp7Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio7]. FunctionPio1, PullNone: Gp7Pio1 } }, /// GPIO 8 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp8Spi1Rx] | /// | `UART1 TX` | [crate::Gp8Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp8I2C0Sda] | /// | `PWM4 A` | [crate::Gp8Pwm4A] | /// | `PIO0` | [crate::Gp8Pio0] | /// | `PIO1` | [crate::Gp8Pio1] | Gpio8 { name: gpio8, aliases: { /// UART Function alias for pin [crate::Pins::gpio8]. FunctionUart, PullNone: Gp8Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio8]. FunctionSpi, PullNone: Gp8Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio8]. FunctionI2C, PullUp: Gp8I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio8]. FunctionPwm, PullNone: Gp8Pwm4A, /// PIO0 Function alias for pin [crate::Pins::gpio8]. FunctionPio0, PullNone: Gp8Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio8]. FunctionPio1, PullNone: Gp8Pio1 } }, /// GPIO 9 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp9Spi1Csn] | /// | `UART1 RX` | [crate::Gp9Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp9I2C0Scl] | /// | `PWM4 B` | [crate::Gp9Pwm4B] | /// | `PIO0` | [crate::Gp9Pio0] | /// | `PIO1` | [crate::Gp9Pio1] | Gpio9 { name: gpio9, aliases: { /// UART Function alias for pin [crate::Pins::gpio9]. FunctionUart, PullNone: Gp9Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio9]. FunctionSpi, PullNone: Gp9Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio9]. FunctionI2C, PullUp: Gp9I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio9]. FunctionPwm, PullNone: Gp9Pwm4B, /// PIO0 Function alias for pin [crate::Pins::gpio9]. FunctionPio0, PullNone: Gp9Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio9]. FunctionPio1, PullNone: Gp9Pio1 } }, /// GPIO 29 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp29Spi1Csn] | /// | `UART0 RX` | [crate::Gp29Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp29I2C0Scl] | /// | `PWM4 B` | [crate::Gp29Pwm6B] | /// | `PIO0` | [crate::Gp29Pio0] | /// | `PIO1` | [crate::Gp29Pio1] | Gpio29 { name: gpio29, aliases: { /// UART Function alias for pin [crate::Pins::gpio29]. FunctionUart, PullNone: Gp29Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio29]. FunctionSpi, PullNone: Gp29Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio29]. FunctionI2C, PullUp: Gp29I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio29]. FunctionPwm, PullNone: Gp29Pwm6B, /// PIO0 Function alias for pin [crate::Pins::gpio29]. FunctionPio0, PullNone: Gp29Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio29]. FunctionPio1, PullNone: Gp29Pio1 } }, /// GPIO 28 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp28Spi1Rx] | /// | `UART0 TX` | [crate::Gp28Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp28I2C0Sda] | /// | `PWM6 A` | [crate::Gp28Pwm6A] | /// | `PIO0` | [crate::Gp28Pio0] | /// | `PIO1` | [crate::Gp28Pio1] | Gpio28 { name: gpio28, aliases: { /// UART Function alias for pin [crate::Pins::gpio28]. FunctionUart, PullNone: Gp28Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio28]. FunctionSpi, PullNone: Gp28Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio28]. FunctionI2C, PullUp: Gp28I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio28]. FunctionPwm, PullNone: Gp28Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio28]. FunctionPio0, PullNone: Gp28Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio28]. FunctionPio1, PullNone: Gp28Pio1 } }, /// GPIO 27 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp27Spi1Tx] | /// | `UART1 RTS` | [crate::Gp27Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp27I2C1Scl] | /// | `PWM5 B` | [crate::Gp27Pwm5B] | /// | `PIO0` | [crate::Gp27Pio0] | /// | `PIO1` | [crate::Gp27Pio1] | Gpio27 { name: gpio27, aliases: { /// UART Function alias for pin [crate::Pins::gpio27]. FunctionUart, PullNone: Gp27Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio27]. FunctionSpi, PullNone: Gp27Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio27]. FunctionI2C, PullUp: Gp27I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio27]. FunctionPwm, PullNone: Gp27Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio27]. FunctionPio0, PullNone: Gp27Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio27]. FunctionPio1, PullNone: Gp27Pio1 } }, /// GPIO 26 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp26Spi1Sck] | /// | `UART1 CTS` | [crate::Gp26Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp26I2C1Sda] | /// | `PWM5 A` | [crate::Gp26Pwm5A] | /// | `PIO0` | [crate::Gp26Pio0] | /// | `PIO1` | [crate::Gp26Pio1] | Gpio26 { name: gpio26, aliases: { /// UART Function alias for pin [crate::Pins::gpio26]. FunctionUart, PullNone: Gp26Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio26]. FunctionSpi, PullNone: Gp26Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio26]. FunctionI2C, PullUp: Gp26I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio26]. FunctionPwm, PullNone: Gp26Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio26]. FunctionPio0, PullNone: Gp26Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio26]. FunctionPio1, PullNone: Gp26Pio1 } }, /// GPIO 22 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp22Spi0Sck] | /// | `UART1 CTS` | [crate::Gp22Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp22I2C1Sda] | /// | `PWM3 A` | [crate::Gp22Pwm3A] | /// | `PIO0` | [crate::Gp22Pio0] | /// | `PIO1` | [crate::Gp22Pio1] | Gpio22 { name: gpio22, aliases: { /// UART Function alias for pin [crate::Pins::gpio22]. FunctionUart, PullNone: Gp22Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio22]. FunctionSpi, PullNone: Gp22Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio22]. FunctionI2C, PullUp: Gp22I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio22]. FunctionPwm, PullNone: Gp22Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio22]. FunctionPio0, PullNone: Gp22Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio22]. FunctionPio1, PullNone: Gp22Pio1 } }, /// GPIO 20 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp20Spi0Rx] | /// | `UART1 TX` | [crate::Gp20Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp20I2C0Sda] | /// | `PWM2 A` | [crate::Gp20Pwm2A] | /// | `PIO0` | [crate::Gp20Pio0] | /// | `PIO1` | [crate::Gp20Pio1] | Gpio20 { name: gpio20, aliases: { /// UART Function alias for pin [crate::Pins::gpio20]. FunctionUart, PullNone: Gp20Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio20]. FunctionSpi, PullNone: Gp20Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio20]. FunctionI2C, PullUp: Gp20I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio20]. FunctionPwm, PullNone: Gp20Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio20]. FunctionPio0, PullNone: Gp20Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio20]. FunctionPio1, PullNone: Gp20Pio1 } }, /// GPIO 23 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp23Spi0Tx] | /// | `UART1 RTS` | [crate::Gp23Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp23I2C1Scl] | /// | `PWM3 B` | [crate::Gp23Pwm3B] | /// | `PIO0` | [crate::Gp23Pio0] | /// | `PIO1` | [crate::Gp23Pio1] | Gpio23 { name: gpio23, aliases: { /// UART Function alias for pin [crate::Pins::gpio21]. FunctionUart, PullNone: Gp23Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio21]. FunctionSpi, PullNone: Gp23Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio21]. FunctionI2C, PullUp: Gp23I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio21]. FunctionPwm, PullNone: Gp23Pwm3B, /// PIO0 Function alias for pin [crate::Pins::gpio21]. FunctionPio0, PullNone: Gp23Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio21]. FunctionPio1, PullNone: Gp23Pio1 } }, /// GPIO 21 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp21Spi0Csn] | /// | `UART1 RX` | [crate::Gp21Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp21I2C0Scl] | /// | `PWM2 B` | [crate::Gp21Pwm2B] | /// | `PIO0` | [crate::Gp21Pio0] | /// | `PIO1` | [crate::Gp21Pio1] | Gpio21 { name: gpio21, aliases: { /// UART Function alias for pin [crate::Pins::gpio21]. FunctionUart, PullNone: Gp21Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio21]. FunctionSpi, PullNone: Gp21Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio21]. FunctionI2C, PullUp: Gp21I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio21]. FunctionPwm, PullNone: Gp21Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio21]. FunctionPio0, PullNone: Gp21Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio21]. FunctionPio1, PullNone: Gp21Pio1 } }, /// GPIO 25 is connected to a neopixel on the top right of the board Gpio25 { name: neopixel, }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/framework-ledmatrix/.gitignore ================================================ # Generated by Cargo # will have compiled files and executables debug/ target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk ================================================ FILE: boards/framework-ledmatrix/CHANGELOG.md ================================================ # 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.1.0 - 2024-10-21 ### Added - Initial release of Framework LED Matrix HAL ================================================ FILE: boards/framework-ledmatrix/Cargo.toml ================================================ [package] name = "framework-ledmatrix" version = "0.1.0" authors = ["Daniel Schaefer ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/framework-ledmatrix" description = "Board Support Package for the Framework LED Matrix" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } fugit.workspace = true rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true critical-section.workspace = true embedded-graphics.workspace = true embedded-hal.workspace = true heapless.workspace = true nb.workspace = true panic-halt.workspace = true rp2040-hal = { workspace = true, features = [ "defmt" ] } is31fl3741 = { version = "0.4.0", features = [ "framework_ledmatrix" ] } defmt.workspace = true defmt-rtt.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/framework-ledmatrix/README.md ================================================ # [framework-ledmatrix] - Board Support for the [Framework LED Matrix] You should include this crate if you are writing code that you want to run on a [Frameworkg LED Matrix]. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the module. [Framework LED Matrix]: https://frame.work/tw/en/products/16-led-matrix [framework-ledmatrix]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/framework-ledmatrix [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml framework-ledmatrix = "0.1.0" ``` In your program, you will need to call `framework_ledmatrix::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/framework-ledmatrix $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/framework-ledmatrix $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` then try repeating the `cargo run` command above. ### From Scratch To start a basic project from scratch, create a project using `cargo new project-name`. Within the project directory, run `cargo add framework-ledmatrix`, `cargo add cortex-m-rt`, and `cargo add panic-halt`. The first command will add this HAL (Hardware Abstraction Layer), the second is required for the `#[entry]` macro, and _panic-halt_ creates a simple panic function, which just halts. You'll also need to copy the cargo config file from the [repo](https://github.com/rp-rs/rp-hal-boards/blob/main/.cargo/config.toml). It specifies the target and optimizing flags to the linker. You'll also need to copy [_memory.x_](https://github.com/rp-rs/rp-hal-boards/blob/main/memory.x) to your project root. This file tells the linker the flash and RAM layout, so it won't clobber the bootloader or write to an out of bounds memory address. The simplest working example, which does nothing except loop forever, is: ```ignore #![no_std] #![no_main] use framework_ledmatrix::entry; use panic_halt as _; #[entry] fn see_doesnt_have_to_be_called_main() -> ! { loop {} } ``` It can be placed in _/src/main.rs_. You can use `cargo run` to compile and install it. **Note**: You won't see any activity since this program does nothing. You can use the examples provided to add more functionality. ### [ledtest](./examples/ledtest.rs) Lights up every single LED one after another. It goes back into bootloader mode when the system goes to sleep. This makes it easy for you to reflash it to other firmware. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/framework-ledmatrix/build.rs ================================================ //! This build script makes sure the linker flag -Tdefmt.x is added //! for the examples. fn main() { println!("cargo:rustc-link-arg-examples=-Tdefmt.x"); } ================================================ FILE: boards/framework-ledmatrix/examples/ledtest.rs ================================================ //! # Framework LED Matrix Module LED Test Example //! //! Lights up every single LED one after another. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] #![allow(clippy::needless_range_loop)] // The macro for our start-up function use framework_ledmatrix::entry; use framework_ledmatrix::{Pins, XOSC_CRYSTAL_FREQ}; use embedded_hal::digital::{InputPin, OutputPin}; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use framework_ledmatrix::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use framework_ledmatrix::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use framework_ledmatrix::hal; use fugit::RateExtU32; /// Maximum brightness out of 255 /// /// 100/255 results in 250mA current draw and is plenty bright. /// 50/255 results in 160mA current draw and is plenty bright. const MAX_BRIGHTNESS: u8 = 50; use is31fl3741::devices::{LedMatrix, CALC_PIXEL}; #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // Enable LED controller // SDB - Gpio29 let mut led_enable = pins.sdb.into_push_pull_output(); led_enable.set_high().unwrap(); // INTB. Currently ignoring pins.intb.into_floating_input(); let sda_pin: hal::gpio::Pin<_, hal::gpio::FunctionI2C, _> = pins.gpio26.reconfigure(); let scl_pin: hal::gpio::Pin<_, hal::gpio::FunctionI2C, _> = pins.gpio27.reconfigure(); let i2c = hal::I2C::i2c1( pac.I2C1, sda_pin, scl_pin, 1000.kHz(), &mut pac.RESETS, &clocks.peripheral_clock, ); let mut dip1 = pins.dip1.into_pull_up_input(); let _ = dip1.is_high().unwrap(); // Detect whether the sleep pin is connected // Early revisions of the hardware didn't have it wired up, if that is the // case we have to ignore its state. let mut sleep_present = false; let mut sleep = pins.sleep.into_pull_up_input(); if sleep.is_low().unwrap() { sleep_present = true; } let mut sleep = sleep.into_pull_down_input(); if sleep.is_high().unwrap() { sleep_present = true; } let mut matrix = LedMatrix::new(i2c, CALC_PIXEL); matrix .setup(&mut delay) .expect("failed to setup RGB controller"); // Enable only the SW pins that we're using. // Otherwise driving the unused pins might result in audible noise. matrix .device .sw_enablement(is31fl3741::SwSetting::Sw1Sw8) .unwrap(); matrix .set_scaling(MAX_BRIGHTNESS) .expect("failed to set scaling"); loop { // Light up each LED, one by one for y in 0..matrix.device.height { for x in 0..matrix.device.width { matrix.device.pixel(x, y, 0xFF).expect("couldn't turn on"); delay.delay_ms(100); matrix.device.pixel(x, y, 0).expect("couldn't turn off"); // Reset into bootloader if system asleep if sleep_present && sleep.is_low().unwrap() { hal::rom_data::reset_to_usb_boot(0, 0); } } } } } ================================================ FILE: boards/framework-ledmatrix/src/lib.rs ================================================ #![no_std] //! A Hardware Abstraction Layer for the Framework LED Matrix //! //! This crate serves as a HAL (Hardware Abstraction Layer) for the Framework LED Matrix. Since it //! is based on the RP2040 chip, it re-exports the [rp2040_hal] crate which contains the tooling to work with the //! rp2040 chip. pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( /// GPIO 0 is connected to the SLEEP# pin of the EC Gpio0 { name: sleep }, /// GPIO 25 is connected to the DIP Switch #1 Gpio25 { name: dip1 }, /// GPIO 26 is connected to I2C SDA of the LED controller Gpio26 { name: gpio26, aliases: { /// I2C Function alias for pin [crate::Pins::gpio26]. FunctionI2C, PullUp: Gp26I2C1Sda } }, /// GPIO 27 is connected to I2C SCL of the LED controller Gpio27 { name: gpio27, aliases: { /// I2C Function alias for pin [crate::Pins::gpio27]. FunctionI2C, PullUp: Gp27I2C1Scl } }, /// GPIO 29 is connected to the INTB pin of the LED controller Gpio28 { name: intb }, /// GPIO 29 is connected to the SDB pin of the LED controller Gpio29 { name: sdb }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/framework16-keyboard/.gitignore ================================================ # Generated by Cargo # will have compiled files and executables debug/ target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk ================================================ FILE: boards/framework16-keyboard/CHANGELOG.md ================================================ # 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.1.0 - 2024-10-21 ### Added - Initial release of Frameworkt 16 Keyboard HAL ================================================ FILE: boards/framework16-keyboard/Cargo.toml ================================================ [package] name = "framework16-keyboard" version = "0.1.0" authors = ["Daniel Schaefer ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/framework16-keyboard" description = "Board Support Package for the Framework 16 Keyboards" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true critical-section.workspace = true embedded-hal.workspace = true heapless.workspace = true nb.workspace = true panic-halt.workspace = true rp2040-hal = { workspace = true, features = [ "defmt" ] } defmt.workspace = true defmt-rtt.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/framework16-keyboard/README.md ================================================ # [framework16-keyboard] - Board Support for the [Framework 16 Keyboard] You should include this crate if you are writing code that you want to run on a [Framework 16 Keyboard]. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the module. [Framework 16 Keyboard]: https://frame.work/tw/en/products/keyboard-module [framework16-keyboard]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/framework16-keyboard [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml framework16-keyboard = "0.1.0" ``` In your program, you will need to call `framewogk16_keyboard::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/framework16-keyboard $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/framework16-keyboard $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` then try repeating the `cargo run` command above. ### From Scratch To start a basic project from scratch, create a project using `cargo new project-name`. Within the project directory, run `cargo add framework16-keyboard`, `cargo add cortex-m-rt`, and `cargo add panic-halt`. The first command will add this HAL (Hardware Abstraction Layer), the second is required for the `#[entry]` macro, and _panic-halt_ creates a simple panic function, which just halts. You'll also need to copy the cargo config file from the [repo](https://github.com/rp-rs/rp-hal-boards/blob/main/.cargo/config.toml). It specifies the target and optimizing flags to the linker. You'll also need to copy [_memory.x_](https://github.com/rp-rs/rp-hal-boards/blob/main/memory.x) to your project root. This file tells the linker the flash and RAM layout, so it won't clobber the bootloader or write to an out of bounds memory address. The simplest working example, which does nothing except loop forever, is: ```ignore #![no_std] #![no_main] use framework16_keyboard::entry; use panic_halt as _; #[entry] fn see_doesnt_have_to_be_called_main() -> ! { loop {} } ``` It can be placed in _/src/main.rs_. You can use `cargo run` to compile and install it. **Note**: You won't see any activity since this program does nothing. You can use the examples provided to add more functionality. ### [capslock](./examples/capslock.rs) Flashes the keyboard's capslock LED on and off. Only works on keyboards, not the numpad or macropad. ### [white_backlight](./examples/white_backlight.rs) Pulses the backlight on and off. Only works on white backlight keyboard or numpad. Not on RGB keyboards or the macropad. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/framework16-keyboard/build.rs ================================================ //! This build script makes sure the linker flag -Tdefmt.x is added //! for the examples. fn main() { println!("cargo:rustc-link-arg-examples=-Tdefmt.x"); } ================================================ FILE: boards/framework16-keyboard/examples/capslock.rs ================================================ //! # Framework 16 Keyboard Capslock Example //! //! Blink the capslock LED on Framework 16 keyboards //! //! Note: This won't work on the numpad or macropad, as they don't have capslock //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use framework16_keyboard::entry; use framework16_keyboard::{Pins, XOSC_CRYSTAL_FREQ}; use embedded_hal::digital::{InputPin, OutputPin}; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use framework16_keyboard::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use framework16_keyboard::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use framework16_keyboard::hal; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then fades the LED in an /// infinite loop. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); let mut caps_led = pins.caps_led.into_push_pull_output(); let mut sleep = pins.sleep.into_floating_input(); loop { // Turn off LED in sleep if sleep.is_low().unwrap() { caps_led.set_low().unwrap(); delay.delay_ms(100); continue; } // Blink LED otherwise caps_led.set_high().unwrap(); delay.delay_ms(500); caps_led.set_low().unwrap(); delay.delay_ms(500); } } ================================================ FILE: boards/framework16-keyboard/examples/white_backlight.rs ================================================ //! # Framework 16 Keyboard/Numpad Backlight Example //! //! Blink the white backlight on Framework 16 keyboards or numpads //! //! Note this won't work on RGB keyboards or the macropad. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use framework16_keyboard::entry; use framework16_keyboard::{Pins, XOSC_CRYSTAL_FREQ}; // GPIO traits use embedded_hal::digital::InputPin; use embedded_hal::pwm::SetDutyCycle; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use framework16_keyboard::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use framework16_keyboard::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use framework16_keyboard::hal; // The minimum PWM value (i.e. LED brightness) we want const LOW: u16 = 0; // The maximum PWM value (i.e. LED brightness) we want const HIGH: u16 = 25000; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then fades the LED in an /// infinite loop. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); let mut sleep = pins.sleep.into_floating_input(); // Init PWMs let mut pwm_slices = hal::pwm::Slices::new(pac.PWM, &mut pac.RESETS); // Configure PWM4 let pwm = &mut pwm_slices.pwm4; pwm.set_ph_correct(); pwm.enable(); // Output channel B on PWM4 to the LED pin let channel = &mut pwm.channel_b; channel.output_to(pins.backlight); // Infinite loop, fading backlight up and down loop { // Turn off backlight in sleep if sleep.is_low().unwrap() { let _ = channel.set_duty_cycle(LOW); delay.delay_ms(100); continue; } // Ramp brightness up for i in (LOW..=HIGH).skip(100) { delay.delay_us(8); let _ = channel.set_duty_cycle(i); } // Ramp brightness down for i in (LOW..=HIGH).rev().skip(100) { delay.delay_us(8); let _ = channel.set_duty_cycle(i); } delay.delay_ms(500); } } ================================================ FILE: boards/framework16-keyboard/src/lib.rs ================================================ #![no_std] //! A Hardware Abstraction Layer for the Framework 16 Keyboards //! //! This crate serves as a HAL (Hardware Abstraction Layer) for the Framework 16 Keyboards. Since they //! is based on the RP2040 chip, it re-exports the [rp2040_hal] crate which contains the tooling to work with the //! rp2040 chip. //! //! # Examples: //! //! The following example turns on the onboard LED. Note that most of the logic works through the [rp2040_hal] crate. //! ```ignore //! #![no_main] //! use framework16_keyboard::entry; //! use panic_halt as _; //! use embedded_hal::digital::v2::OutputPin; //! use framework16_keyboard::hal::pac; //! use framework16_keyboard::hal; //! #[entry] //! fn does_not_have_to_be_main() -> ! { //! let mut pac = pac::Peripherals::take().unwrap(); //! let sio = hal::Sio::new(pac.SIO); //! let pins = framework16_keyboard::Pins::new( //! pac.IO_BANK0, //! pac.PADS_BANK0, //! sio.gpio_bank0, //! &mut pac.RESETS, //! ); //! let mut led_pin = pins.caps_led.into_push_pull_output(); //! led_pin.set_high().unwrap(); //! loop { //! } //! } //! ``` pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( /// GPIO 0 is connected to the SLEEP# pin of the EC Gpio0 { name: sleep }, /// Mux selector A Gpio1 { name: mux_a }, /// Mux selector B Gpio2 { name: mux_b }, /// Mux selector C Gpio3 { name: mux_c }, /// Mux enable Gpio4 { name: mux_enable }, /// Pull low when firmware has started to turn off bootloader logic Gpio5 { name: boot_done }, /// Connected to KSI5 but unused, should use high-Z Gpio6 { name: ksi5_reserved }, /// Connected to KSI5 but unused, should use high-Z Gpio7 { name: ksi6_reserved }, /// Keyboard column drive Gpio8 { name: kso0 }, /// Keyboard column drive Gpio9 { name: kso1 }, /// Keyboard column drive Gpio10 { name: kso2 }, /// Keyboard column drive Gpio11 { name: kso3 }, /// Keyboard column drive Gpio12 { name: kso4 }, /// Keyboard column drive Gpio13 { name: kso5 }, /// Keyboard column drive Gpio14 { name: kso6 }, /// Keyboard column drive Gpio15 { name: kso7 }, /// Keyboard column drive Gpio16 { name: kso13 }, /// Keyboard column drive Gpio17 { name: kso12 }, /// Keyboard column drive Gpio18 { name: kso11 }, /// Keyboard column drive Gpio19 { name: kso10 }, /// Keyboard column drive Gpio20 { name: kso9 }, /// Keyboard column drive Gpio21 { name: kso8 }, /// Keyboard column drive Gpio22 { name: kso15 }, /// Keyboard column drive Gpio23 { name: kso14 }, /// Capslock LED Gpio24 { name: caps_led }, /// Single zone backlight (unused on RGB keyboard) Gpio25 { name: backlight, aliases: { /// PWM Function alias for pin [crate::Pins::gpio25]. FunctionPwm, PullNone: Gp25Pwm4B } }, /// GPIO 26 is connected to I2C SDA of the LED controller Gpio26 { name: gpio26, aliases: { /// I2C Function alias for pin [crate::Pins::gpio26]. FunctionI2C, PullUp: Gp26I2C1Sda } }, /// GPIO 27 is connected to I2C SCL of the LED controller Gpio27 { name: gpio27, aliases: { /// I2C Function alias for pin [crate::Pins::gpio27]. FunctionI2C, PullUp: Gp27I2C1Scl } }, /// Analog IN from mux Gpio28 { name: analog_in }, /// GPIO 29 is connected to the SDB pin of the LED controller Gpio29 { name: sdb }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/pimoroni-pico-explorer/CHANGELOG.md ================================================ # 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.8.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.7.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 ## 0.6.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 ## 0.5.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 ## 0.4.0 - 2022-08-26 ### Changed - Migrate from `embedded-time` to `fugit` - Update to rp2040-hal 0.6.0 ## 0.3.0 - 2022-06-13 ### Changed - Update to rp2040-hal 0.5.0 ## 0.2.0 - 2022-03-11 ### Changed - Update to rp2040-hal 0.4.0 ## 0.1.0 - 2021-12-20 - Initial release ================================================ FILE: boards/pimoroni-pico-explorer/Cargo.toml ================================================ [package] name = "pimoroni-pico-explorer" version = "0.8.0" authors = ["Hmvp ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-pico-explorer" description = "Board Support Package for the Pico Explorer" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } display-interface-spi.workspace = true embedded-graphics.workspace = true embedded-hal = { workspace = true } embedded_hal_0_2.workspace = true fugit.workspace = true rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true st7789.workspace = true [dev-dependencies] arrayvec.workspace = true cortex-m.workspace = true display-interface.workspace = true nb.workspace = true panic-halt.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt", "rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/pimoroni-pico-explorer/README.md ================================================ # [pimoroni-pico-explorer] - Board Support for the [Pimoroni Pico Explorer] You should include this crate if you are writing code that you want to run on a [Pimoroni Pico Explorer] - a board featuring a small LCD screen, a breadboard and some breakout headers. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Pico Explorer. [Pimoroni Pico Explorer]: https://shop.pimoroni.com/products/pimoroni-pico-explorer-base [pimoroni-pico-explorer]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-pico-explorer [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml pimoroni-pico-explorer = "0.8.0" ``` In your program, you will need to call `pimoroni_pico_explorer::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/pimoroni-pico-explorer $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/pimoroni-pico-explorer $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [pimoroni_pico_explorer_showcase](./examples/pimoroni_pico_explorer_showcase.rs) Displays the current temperature on the Pico Explorer's on-board LCD screen. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/pimoroni-pico-explorer/examples/pimoroni_pico_explorer_showcase.rs ================================================ #![no_std] #![no_main] use arrayvec::ArrayString; use core::fmt::Write; use embedded_graphics::{ mono_font::{ascii::FONT_10X20, MonoTextStyleBuilder}, pixelcolor::Rgb565, prelude::*, text::{Alignment, Text}, }; use embedded_hal::digital::OutputPin; use hal::{adc::Adc, clocks::*, watchdog::Watchdog, Sio}; use panic_halt as _; use pimoroni_pico_explorer::entry; use pimoroni_pico_explorer::{hal, pac, Button, PicoExplorer, XOSC_CRYSTAL_FREQ}; // See 4.9.5 from RP2040 datasheet fn calc_temp(adc_value: f32, refv: f64) -> f64 { let vbe: f64 = f64::from(adc_value) * refv; 27f64 - (vbe - 0.706) / 0.001721 } #[entry] fn main() -> ! { let mut p = pac::Peripherals::take().unwrap(); let cp = pac::CorePeripherals::take().unwrap(); // Enable watchdog and clocks let mut watchdog = Watchdog::new(p.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, p.XOSC, p.CLOCKS, p.PLL_SYS, p.PLL_USB, &mut p.RESETS, &mut watchdog, ) .ok() .unwrap(); let mut delay = cortex_m::delay::Delay::new(cp.SYST, clocks.system_clock.get_freq().to_Hz()); // Enable adc let mut adc = Adc::new(p.ADC, &mut p.RESETS); let mut temp_sense = adc.take_temp_sensor().unwrap(); let sio = Sio::new(p.SIO); let (mut explorer, pins) = PicoExplorer::new( p.IO_BANK0, p.PADS_BANK0, sio.gpio_bank0, p.SPI0, adc, &mut p.RESETS, &mut delay, ); let mut led = pins.led.into_push_pull_output(); let mut even = true; loop { delay.delay_ms(500); // Set GPIO25 to be low led.set_low().unwrap(); delay.delay_ms(500); // Set GPIO25 to be high led.set_high().unwrap(); let adc_value = explorer.get_adc(&mut temp_sense); let temp: f64 = calc_temp(adc_value, 3.3); // Create a fixed buffer to store screen contents let mut buf = ArrayString::<100>::new(); // Write to buffer writeln!(&mut buf, "Hello World {}", if even { '|' } else { '-' }).unwrap(); writeln!(&mut buf, "Temp: {:.1}", temp).unwrap(); writeln!( &mut buf, "A:{:.1} B:{:.1}\nX:{:.1} Y:{:.1}", explorer.is_pressed(Button::A), explorer.is_pressed(Button::B), explorer.is_pressed(Button::X), explorer.is_pressed(Button::Y) ) .unwrap(); // Draw buffer on screen let style = MonoTextStyleBuilder::new() .font(&FONT_10X20) .text_color(Rgb565::GREEN) .background_color(Rgb565::BLACK) .build(); Text::with_alignment(&buf, Point::new(20, 30), style, Alignment::Left) .draw(&mut explorer.screen) .unwrap(); even = !even; } } ================================================ FILE: boards/pimoroni-pico-explorer/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. /// /// This currently assumes an rp-pico or pimoroni-pico-lipo is used as the brains. /// Currently those are the only boards that have the right pin out to be able to be used #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; use display_interface_spi::SPIInterface; use embedded_graphics::{ draw_target::DrawTarget, pixelcolor::{Rgb565, RgbColor}, }; use embedded_hal_0_2::{ adc::{Channel, OneShot}, blocking::delay::DelayUs, digital::v2::{InputPin, OutputPin}, spi::MODE_0, }; use fugit::RateExtU32; pub use hal::pac; use hal::{ adc::Adc, gpio::{ bank0::{ Gpio0, Gpio1, Gpio12, Gpio13, Gpio14, Gpio15, Gpio16, Gpio17, Gpio2, Gpio22, Gpio23, Gpio24, Gpio25, Gpio26, Gpio27, Gpio28, Gpio29, Gpio3, Gpio4, Gpio5, Gpio6, Gpio7, }, FunctionNull, FunctionPwm, FunctionSioInput, FunctionSioOutput, Pin, PullNone, PullUp, }, pac::{RESETS, SPI0}, sio::SioGpioBank0, spi::{Enabled, Spi}, }; use st7789::ST7789; pub mod all_pins { hal::bsp_pins!( Gpio0 { name: gpio0 }, Gpio1 { name: gpio1 }, Gpio2 { name: gpio2 }, Gpio3 { name: gpio3 }, Gpio4 { name: gpio4 }, Gpio5 { name: gpio5 }, Gpio6 { name: gpio6 }, Gpio7 { name: gpio7 }, Gpio8 { name: motor1_neg, aliases: { FunctionPwm, PullNone: Motor1Neg } }, Gpio9 { name: motor1_pos, aliases: { FunctionPwm, PullNone: Motor1Pos } }, Gpio10 { name: motor2_neg, aliases: { FunctionPwm, PullNone: Motor2Neg } }, Gpio11 { name: motor2_pos, aliases: { FunctionPwm, PullNone: Motor2Pos } }, Gpio12 { name: switch_a }, Gpio13 { name: switch_b }, Gpio14 { name: switch_x }, Gpio15 { name: switch_y }, Gpio16 { name: spi_miso, aliases: { FunctionSpi, PullNone: Miso } }, Gpio17 { name: lcd_cs, aliases: { FunctionSpi, PullNone: LcdCs } }, Gpio18 { name: spi_sclk, aliases: { FunctionSpi, PullNone: Sclk } }, Gpio19 { name: spi_mosi, aliases: { FunctionSpi, PullNone: Mosi } }, Gpio20 { name: i2c_sda, aliases: { FunctionI2C, PullUp: Sda } }, Gpio21 { name: i2c_scl, aliases: { FunctionI2C, PullUp: Scl } }, Gpio22 { name: i2c_int }, Gpio23 { name: b_power_save }, Gpio24 { name: vbus_detect }, Gpio25 { name: led }, Gpio26 { name: adc0 }, Gpio27 { name: adc1 }, Gpio28 { name: adc2 }, Gpio29 { name: voltage_monitor }, ); } // Can't use `hal::bsp_pins!` here because some pins are not set to their reset state pub struct Pins { pub gpio0: Pin, pub gpio1: Pin, pub gpio2: Pin, pub gpio3: Pin, pub gpio4: Pin, pub gpio5: Pin, pub gpio6: Pin, pub gpio7: Pin, pub i2c_sda: all_pins::Sda, pub i2c_scl: all_pins::Scl, pub i2c_int: Pin, pub b_power_save: Pin, pub vbus_detect: Pin, pub led: Pin, pub adc0: Pin, pub adc1: Pin, pub adc2: Pin, pub voltage_monitor: Pin, } pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; pub enum Button { A, B, X, Y, } pub enum Motor { _1, _2, } pub enum MotorAction { Forward(f32), Reverse(f32), Stop, } pub type Screen = ST7789< SPIInterface< Spi, Pin, Pin, >, DummyPin, >; pub struct PicoExplorer { pub a: Pin, pub b: Pin, pub x: Pin, pub y: Pin, adc: Adc, pub screen: Screen, } pub struct DummyPin; impl OutputPin for DummyPin { type Error = (); fn set_high(&mut self) -> Result<(), Self::Error> { Ok(()) } fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) } } impl PicoExplorer { pub fn new( io: pac::IO_BANK0, pads: pac::PADS_BANK0, sio: SioGpioBank0, spi0: SPI0, adc: Adc, resets: &mut RESETS, delay: &mut impl DelayUs, ) -> (Self, Pins) { let internal_pins = all_pins::Pins::new(io, pads, sio, resets); let a = internal_pins.switch_a.into_pull_up_input(); let b = internal_pins.switch_b.into_pull_up_input(); let x = internal_pins.switch_x.into_pull_up_input(); let y = internal_pins.switch_y.into_pull_up_input(); internal_pins.motor1_pos.into_function::(); internal_pins.motor1_neg.into_function::(); internal_pins.motor2_pos.into_function::(); internal_pins.motor2_neg.into_function::(); let dc = internal_pins.spi_miso.reconfigure(); let cs = internal_pins.lcd_cs.reconfigure(); let spi_sclk = internal_pins.spi_sclk.reconfigure(); let spi_mosi = internal_pins.spi_mosi.reconfigure(); let spi_screen = Spi::new(spi0, (spi_mosi, spi_sclk)).init(resets, 125u32.MHz(), 16u32.MHz(), MODE_0); let spii_screen = SPIInterface::new(spi_screen, dc, cs); let mut screen = ST7789::new(spii_screen, DummyPin, 240, 240); screen.init(delay).unwrap(); screen .set_orientation(st7789::Orientation::Portrait) .unwrap(); screen.clear(Rgb565::BLACK).unwrap(); ( PicoExplorer { a, b, x, y, adc, screen, }, Pins { gpio0: internal_pins.gpio0.reconfigure(), gpio1: internal_pins.gpio1.reconfigure(), gpio2: internal_pins.gpio2.reconfigure(), gpio3: internal_pins.gpio3.reconfigure(), gpio4: internal_pins.gpio4.reconfigure(), gpio5: internal_pins.gpio5.reconfigure(), gpio6: internal_pins.gpio6.reconfigure(), gpio7: internal_pins.gpio7.reconfigure(), i2c_sda: internal_pins.i2c_sda.reconfigure(), i2c_scl: internal_pins.i2c_scl.reconfigure(), i2c_int: internal_pins.i2c_int.reconfigure(), b_power_save: internal_pins.b_power_save.reconfigure(), vbus_detect: internal_pins.vbus_detect.reconfigure(), led: internal_pins.led.reconfigure(), adc0: internal_pins.adc0.reconfigure(), adc1: internal_pins.adc1.reconfigure(), adc2: internal_pins.adc2.reconfigure(), voltage_monitor: internal_pins.voltage_monitor.reconfigure(), }, ) } pub fn is_pressed(&self, button: Button) -> bool { use Button::*; match button { A => self.a.is_low().unwrap(), B => self.b.is_low().unwrap(), X => self.x.is_low().unwrap(), Y => self.y.is_low().unwrap(), } } pub fn get_adc>(&mut self, channel: &mut Pin) -> f32 { // scale raw 12-bit adc value to 0 .. 1 float let adc_value: u16 = self.adc.read(channel).unwrap(); let result: f32 = f32::from(adc_value) / f32::from(1u16 << 12); result.clamp(0.0, 1.0) } } ================================================ FILE: boards/pimoroni-pico-lipo-16mb/CHANGELOG.md ================================================ # 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.8.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.7.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 ## 0.6.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 ## 0.5.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 ## 0.4.0 - 2022-08-26 ### Changed - Migrate from `embedded-time` to `fugit` - Update to rp2040-hal 0.6.0 ## 0.3.0 - 2022-06-13 ### Changed - Update to rp2040-hal 0.5.0 ## 0.2.0 - 2022-03-11 ### Changed - Update to rp2040-hal 0.4.0 ## 0.1.0 - 2021-12-20 - Initial release ================================================ FILE: boards/pimoroni-pico-lipo-16mb/Cargo.toml ================================================ [package] name = "pimoroni-pico-lipo-16mb" version = "0.8.0" authors = ["Hmvp ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-pico-lipo-16mb" description = "Board Support Package for the Pico LiPo 16MB" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true panic-halt.workspace = true embedded-hal.workspace = true nb.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/pimoroni-pico-lipo-16mb/README.md ================================================ # [pimoroni-pico-lipo-16mb] - Board Support for the [Pimoroni Pico Lipo 16MB] You should include this crate if you are writing code that you want to run on a [Pimoroni Pico Lipo 16MB] - a board with USB-C, STEMMA QT/Qwiic connectors, plus a Li-Po battery charging circuit. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Pico Lipo. Note that if you use this crate the compiler will expect the full 16MB flash space, and so it may not work if you only have the 4MB variant. [Pimoroni Pico Lipo 16MB]: https://shop.pimoroni.com/products/pimoroni-pico-lipo?variant=39335427080275 [pimoroni-pico-lipo-16mb]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-pico-lipo-16mb ## Using To use this crate, your `Cargo.toml` file should contain: ```toml pimoroni-pico-lipo-16mb = "0.8.0" ``` In your program, you will need to call `pimoroni_pico_lipo_16mb::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/pimoroni-pico-lipo-16mb $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/pimoroni-pico-lipo-16mb $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [pimoroni_pico_lipo_16mb_blinky](./examples/pimoroni_pico_lipo_16mb_blinky.rs) Flashes the Pico Lipo's on-board LED on and off. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/pimoroni-pico-lipo-16mb/examples/pimoroni_pico_lipo_16mb_blinky.rs ================================================ //! # Pimoroni Pico Lipo Blinky Example //! //! Blinks the LED on a Pimoroni Pico Lipo 16MB board. //! //! This will blink an LED attached to GPIO25, which is the pin the Pico Lipo uses //! for the on-board LED. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use pimoroni_pico_lipo_16mb::entry; // GPIO traits use embedded_hal::digital::OutputPin; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use pimoroni_pico_lipo_16mb::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use pimoroni_pico_lipo_16mb::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use pimoroni_pico_lipo_16mb::hal; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then blinks the LED in an /// infinite loop. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( pimoroni_pico_lipo_16mb::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = pimoroni_pico_lipo_16mb::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Set the LED to be an output let mut led_pin = pins.led.into_push_pull_output(); // Blink the LED at 1 Hz loop { led_pin.set_high().unwrap(); delay.delay_ms(500); led_pin.set_low().unwrap(); delay.delay_ms(500); } } // End of file ================================================ FILE: boards/pimoroni-pico-lipo-16mb/src/lib.rs ================================================ #![no_std] pub use rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( Gpio0 { name: gpio0 }, Gpio1 { name: gpio1 }, Gpio2 { name: gpio2 }, Gpio3 { name: gpio3 }, Gpio4 { name: gpio4 }, Gpio5 { name: gpio5 }, Gpio6 { name: gpio6 }, Gpio7 { name: gpio7 }, Gpio8 { name: gpio8 }, Gpio9 { name: gpio9 }, Gpio10 { name: gpio10 }, Gpio11 { name: gpio11 }, Gpio12 { name: gpio12 }, Gpio13 { name: gpio13 }, Gpio14 { name: gpio14 }, Gpio15 { name: gpio15 }, Gpio16 { name: gpio16 }, Gpio17 { name: gpio17 }, Gpio18 { name: gpio18 }, Gpio19 { name: gpio19 }, Gpio20 { name: gpio20 }, Gpio21 { name: gpio21 }, Gpio22 { name: gpio22 }, Gpio23 { name: user_sw }, Gpio24 { name: vbus_detect }, Gpio25 { name: led }, Gpio26 { name: gpio26 }, Gpio27 { name: gpio27 }, Gpio28 { name: gpio28 }, Gpio29 { name: batt_sense }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/pimoroni-plasma-2040/.gitignore ================================================ # Generated by Cargo # will have compiled files and executables debug/ target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk ================================================ FILE: boards/pimoroni-plasma-2040/CHANGELOG.md ================================================ # 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.7.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.6.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.5.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 - Update to ws2812-pio 0.6.0 ## 0.4.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 ## 0.3.0 - 2022-08-26 ### Changed - Use `rp2040-hal`'s entry function. - Migrate from `embedded-time` to `fugit` - Bump `ws2812-pio` to 0.4.0 - Update to rp2040-hal 0.6.0 ================================================ FILE: boards/pimoroni-plasma-2040/Cargo.toml ================================================ [package] name = "pimoroni-plasma-2040" version = "0.7.0" authors = ["Jordan Williams ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-plasma-2040" description = "Board Support Package for the Pimoroni Plasma 2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true embedded-hal.workspace = true fugit.workspace = true panic-halt.workspace = true rp2040-hal = { workspace = true, features = [ "defmt" ] } smart-leds.workspace = true ws2812-pio.workspace = true defmt.workspace = true defmt-rtt.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/pimoroni-plasma-2040/README.md ================================================ # [pimoroni-plasma-2040] - Board Support for the [Pimoroni Plasma 2040] You should include this crate if you are writing code that you want to run on a [Pimoroni Plasma 2040] - Swathe everything in rainbows with this all-in-one, USB-C powered controller for WS2812/Neopixel and APA102/Dotstar addressable LED strip. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Pimoroni Plasma 2040. [Pimoroni Plasma 2040]: https://shop.pimoroni.com/products/plasma-2040 [pimoroni-plasma-2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-plasma-2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml pimoroni-plasma-2040 = "0.7.0" ``` In your program, you will need to call `pimoroni_plasma_2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/pimoroni-plasma-2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/pimoroni-plasma-2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` then try repeating the `cargo run` command above. ### [pimoroni_plasma_2040_blinky](./examples/pimoroni_plasma_2040_blinky.rs) Flashes the Plasma 2040's three on-board LEDs in sequence. ### [pimoroni_plasma_2040_ws2812_led](./examples/pimoroni_plasma_2040_ws2812_led.rs) Drives 3 WS2812 LEDs connected directly to the Pimoroni Plasma 2040 via its onboard terminal block. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/pimoroni-plasma-2040/build.rs ================================================ //! This build script makes sure the linker flag -Tdefmt.x is added //! for the examples. fn main() { println!("cargo:rustc-link-arg-examples=-Tdefmt.x"); } ================================================ FILE: boards/pimoroni-plasma-2040/examples/pimoroni_plasma_2040_blinky.rs ================================================ //! Blinks the 3 colour LEDs on a Pimoroni Plasma 2040 in sequence #![no_std] #![no_main] use defmt::*; use defmt_rtt as _; use embedded_hal::digital::OutputPin; use panic_halt as _; use pimoroni_plasma_2040 as bsp; use bsp::hal::{ clocks::{init_clocks_and_plls, Clock}, gpio::PinState, pac, sio::Sio, watchdog::Watchdog, }; /// Entry point to our bare-metal application. /// /// The `#[rp2040_hal::entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables and the spinlock are initialised. #[rp2040_hal::entry] fn main() -> ! { info!("Program start"); let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let sio = Sio::new(pac.SIO); let clocks = init_clocks_and_plls( bsp::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); let pins = bsp::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let mut led_green = pins .led_green .into_push_pull_output_in_state(PinState::High); let mut led_red = pins.led_red.into_push_pull_output_in_state(PinState::High); let mut led_blue = pins.led_blue.into_push_pull_output_in_state(PinState::High); loop { led_green.set_low().unwrap(); delay.delay_ms(500); led_green.set_high().unwrap(); led_blue.set_low().unwrap(); delay.delay_ms(500); led_blue.set_high().unwrap(); led_red.set_low().unwrap(); delay.delay_ms(500); led_red.set_high().unwrap(); } } // End of file ================================================ FILE: boards/pimoroni-plasma-2040/examples/pimoroni_plasma_2040_ws2812_led.rs ================================================ //! # Pimoroni Plasma 2040 WS2812 RGB LED Example //! //! Drives 3 WS2812 LEDs connected directly to the Pimoroni Plasma 2040 via its terminal block. //! Derived from the [pico_ws2812_led](../../rp-pico/examples/pico_ws2812_led.rs) example for the Raspberry Pi Pico. #![no_std] #![no_main] // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use pimoroni_plasma_2040::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use pimoroni_plasma_2040::hal::pac; // Import the Timer for Ws2812: use pimoroni_plasma_2040::hal::timer::Timer; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use pimoroni_plasma_2040::hal; // PIOExt for the split() method that is needed to bring // PIO0 into useable form for Ws2812: use pimoroni_plasma_2040::hal::pio::PIOExt; // Import useful traits to handle the ws2812 LEDs: use smart_leds::{brightness, SmartLedsWrite, RGB8}; // Import the actual crate to handle the Ws2812 protocol: use ws2812_pio::Ws2812; // Currently 3 consecutive LEDs are driven by this example // to keep the power draw compatible with USB: const STRIP_LEN: usize = 3; /// Entry point to our bare-metal application. /// /// The `#[pimoroni_plasma_2040::entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables and the spinlock are initialised. #[pimoroni_plasma_2040::entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( pimoroni_plasma_2040::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = pimoroni_plasma_2040::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Setup a delay for the LED blink signals: let mut frame_delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // Import the `sin` function for a smooth hue animation from the // Pico rp2040 ROM: let sin = hal::rom_data::float_funcs::fsin::ptr(); // Create a count down timer for the Ws2812 instance: let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Split the PIO state machine 0 into individual objects, so that // Ws2812 can use it: let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); // Instantiate a Ws2812 LED strip: let mut ws = Ws2812::new( pins.data.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); let mut leds: [RGB8; STRIP_LEN] = [(0, 0, 0).into(); STRIP_LEN]; let mut t = 0.0; // Bring down the overall brightness of the strip to not blow // the USB power supply: every LED draws ~60mA, RGB means 3 LEDs per // ws2812 LED, for 3 LEDs that would be: 3 * 3 * 60mA, which is // already 540mA for just 3 white LEDs! let strip_brightness = 64u8; // Limit brightness to 64/256 // Slow down timer by this factor (0.1 will result in 10 seconds): let animation_speed = 0.1; loop { for (i, led) in leds.iter_mut().enumerate() { // An offset to give 3 consecutive LEDs a different color: let hue_offs = match i % 3 { 1 => 0.25, 2 => 0.5, _ => 0.0, }; let sin_11 = sin((t + hue_offs) * 2.0 * core::f32::consts::PI); // Bring -1..1 sine range to 0..1 range: let sin_01 = (sin_11 + 1.0) * 0.5; let hue = 360.0 * sin_01; let sat = 1.0; let val = 1.0; let rgb = hsv2rgb_u8(hue, sat, val); *led = rgb.into(); } // Here the magic happens and the `leds` buffer is written to the // ws2812 LEDs: ws.write(brightness(leds.iter().copied(), strip_brightness)) .unwrap(); // Wait a bit until calculating the next frame: frame_delay.delay_ms(16); // ~60 FPS // Increase the time counter variable and make sure it // stays inbetween 0.0 to 1.0 range: t += (16.0 / 1000.0) * animation_speed; while t > 1.0 { t -= 1.0; } } } pub fn hsv2rgb(hue: f32, sat: f32, val: f32) -> (f32, f32, f32) { let c = val * sat; let v = (hue / 60.0) % 2.0 - 1.0; let v = if v < 0.0 { -v } else { v }; let x = c * (1.0 - v); let m = val - c; let (r, g, b) = if hue < 60.0 { (c, x, 0.0) } else if hue < 120.0 { (x, c, 0.0) } else if hue < 180.0 { (0.0, c, x) } else if hue < 240.0 { (0.0, x, c) } else if hue < 300.0 { (x, 0.0, c) } else { (c, 0.0, x) }; (r + m, g + m, b + m) } pub fn hsv2rgb_u8(h: f32, s: f32, v: f32) -> (u8, u8, u8) { let r = hsv2rgb(h, s, v); ( (r.0 * 255.0) as u8, (r.1 * 255.0) as u8, (r.2 * 255.0) as u8, ) } ================================================ FILE: boards/pimoroni-plasma-2040/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] pub use rp2040_hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( /// GPIO 0 is connected to I2C0_SDA Gpio0 { name: i2c0_sda }, /// GPIO 1 is connected to I2C0_SCL Gpio1 { name: i2c0_scl }, /// GPIO 2 is connected to I2C1_SDA Gpio2 { name: i2c1_sda }, /// GPIO 3 is connected to I2C1_SCL Gpio3 { name: i2c1_scl }, Gpio4 { name: gpio4 }, Gpio5 { name: gpio5 }, /// GPIO 12 is connected to button A, active low Gpio12 { name: button_a }, /// GPIO 13 is connected to button B, active low Gpio13 { name: button_b }, /// GPIO 14 is connected to CLK for APA102 only Gpio14 { name: clk }, /// GPIO 15 is connected to DAT for Apa102 and Ws2812 Gpio15 { name: data }, /// GPIO 16 is red LED, active low Gpio16 { name: led_red }, /// GPIO 17 is green LED, active low Gpio17 { name: led_green }, /// GPIO 18 is blue LED, active low Gpio18 { name: led_blue }, /// GPIO 19 is I2C_INT Gpio19 { name: i2c_int }, /// GPIO 20 is I2C_SDA Gpio20 { name: i2c_sda, aliases: { FunctionI2C, PullUp: Sda } }, /// GPIO 21 is I2C_SCL Gpio21 { name: i2c_scl, aliases: { FunctionI2C, PullUp: Scl } }, /// GPIO 23 is connected to the USER_SW, the BOOT button, active low Gpio23 { name: user_sw }, /// GPIO 26 is connected to ADC0 Gpio26 { name: adc0 }, /// GPIO 27 is connected to ADC1 Gpio27 { name: adc1 }, /// GPIO 28 is connected to ADC2 Gpio28 { name: adc2 }, /// GPIO 29 is connected to ADC3 which is used for low side current sensing Gpio29 { name: current_sense, }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; pub const ADC_GAIN: u32 = 50; pub const SHUNT_RESISTOR: f32 = 0.015; ================================================ FILE: boards/pimoroni-servo2040/.gitignore ================================================ # Generated by Cargo # will have compiled files and executables debug/ target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk ================================================ FILE: boards/pimoroni-servo2040/CHANGELOG.md ================================================ # 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.5.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.4.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.3.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 - Update to ws2812-pio 0.6.0 ## 0.2.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 ## 0.1.0 - 2022-09-06 ### Changed ================================================ FILE: boards/pimoroni-servo2040/Cargo.toml ================================================ [package] name = "pimoroni-servo2040" version = "0.5.0" authors = ["Paul Daniel Faria ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-servo2040" description = "Board Support Package for the Pimoroni Servo2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] defmt.workspace = true defmt-rtt.workspace = true embedded-hal.workspace = true fugit.workspace = true nb.workspace = true panic-halt.workspace = true rp2040-hal = { workspace = true, features = [ "defmt" ] } smart-leds.workspace = true ws2812-pio.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/pimoroni-servo2040/README.md ================================================ # [pimoroni-servo2040] - Board Support for the [Pimoroni Servo2040] You should include this crate if you are writing code that you want to run on a [Pimoroni Servo2040] - a standalone servo motor controller for up to 18 servos and 6 sensors. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Servo2040. [Pimoroni Servo2040]: https://shop.pimoroni.com/products/servo-2040 [pimoroni-servo2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-servo2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml pimoroni-servo2040 = "0.5.0" ``` In your program, you will need to call `pimoroni_servo2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/pimoroni-servo2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/pimoroni-servo2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` then try repeating the `cargo run` command above. ### [pimoroni_servo2040_rainbow](./examples/pimoroni_servo2040_rainbow.rs) Animates a rainbow wheel on the Servo2040's six on-board LEDs in sequence. ![Servo 2040 Rainbow LED Animation]( https://user-images.githubusercontent.com/1673130/190923083-4cd9794a-6775-4f9e-92c3-64d6d25c61dd.gif) ### [pimoroni_servo2040_pwm_servo](./examples/pimoroni_servo2040_pwm_servo.rs) Moves a micro servo connected to pin Servo 1 on a Servo2040 board using the PWM peripheral. ![Servo 2040 Servo Animation]( https://user-images.githubusercontent.com/1673130/190923094-1e7dc85d-2742-4d2f-9b9d-f3337b03cda2.gif) ![Servo 2040 Oscilloscope Waveform Animation]( https://user-images.githubusercontent.com/1673130/190923098-f725bf4a-541b-4e4c-9f79-eb435e8d2d27.gif) ![Servo 2040 Oscilloscope Waveform Image with Frequency]( https://user-images.githubusercontent.com/1673130/190923130-43bab8aa-8773-42f8-90cb-9bc684368027.jpg) ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/pimoroni-servo2040/build.rs ================================================ //! This build script makes sure the linker flag -Tdefmt.x is added //! for the examples. fn main() { println!("cargo:rustc-link-arg-examples=-Tdefmt.x"); } ================================================ FILE: boards/pimoroni-servo2040/examples/pimoroni_servo2040_pwm_servo.rs ================================================ //! # Pimoroni Servo2040 PWM Micro Servo Example //! //! Moves the micro servo on a Servo2040 board using the PWM peripheral. //! //! This will move in different positions the motor attached to GP0. #![no_std] #![no_main] // GPIO traits use embedded_hal::delay::DelayNs; use embedded_hal::pwm::SetDutyCycle; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use pimoroni_servo2040::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use pimoroni_servo2040::hal; /// Number of microseconds for the pwm signal period. const PERIOD_US: u32 = 20_000; /// Max resolution for the pwm signal. const TOP: u16 = u16::MAX; #[pimoroni_servo2040::entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); let sio = hal::Sio::new(pac.SIO); let clocks = hal::clocks::init_clocks_and_plls( pimoroni_servo2040::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // Configure the Timer peripheral in count-down mode let mut timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); let pins = pimoroni_servo2040::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let pwm_slices = hal::pwm::Slices::new(pac.PWM, &mut pac.RESETS); const MIN_PULSE: u16 = 1000; const MID_PULSE: u16 = 1500; const MAX_PULSE: u16 = 2000; let mut pwm: hal::pwm::Slice<_, _> = pwm_slices.pwm0; // 50Hz desired frequency // Rp2040 clock = 125MHz // Top = 65_535, resolution for counter (maximum possible u16 value) // Wrap = Top+1 (number of possible values) // Phase correction multiplier = 2 if phase correction enabled, else 1 // Divider = rp2040_clock / (Wrap * phase_correction_multiplier * desired_frequency) // Divider = 125,000,000/(65_536 * 1 * 50) // Divider = 38.14639 // Divider int = 38 // Divider frac = 3 (3/16 = 0.1875, smallest frac greater than desired clock divider). pwm.set_div_int(38); pwm.set_div_frac(3); // If phase correction enabled, then values would be: // Divider = rp2040_clock / (Wrap * phase_correction_multiplier * desired_frequency) // Divider = 125,000,000/(65_536 * 2 * 50) // Divider = 19.073195 // Divider int = 19 // Divider frac = 2 (2/16 = .1250, smallest frac greater than desired clock divider). // pwm.set_ph_correct(); // pwm.set_div_int(19); // pwm.set_div_frac(2); pwm.set_top(TOP); pwm.enable(); // Output channel A on PWM0 to the GPIO0/servo1 pin let mut channel_a = pwm.channel_a; let _channel_a_pin = channel_a.output_to(pins.servo1); let movement_delay_ms = 400; // Infinite loop, moving micro servo from one position to another. // You may need to adjust the pulse width since several servos from // different manufacturers respond differently. loop { // move to 0° let _ = channel_a.set_duty_cycle(us_to_duty(MID_PULSE)); timer.delay_ms(movement_delay_ms); // 0° to 90° let _ = channel_a.set_duty_cycle(us_to_duty(MAX_PULSE)); timer.delay_ms(movement_delay_ms); // 90° to 0° let _ = channel_a.set_duty_cycle(us_to_duty(MID_PULSE)); timer.delay_ms(movement_delay_ms); // 0° to -90° let _ = channel_a.set_duty_cycle(us_to_duty(MIN_PULSE)); timer.delay_ms(movement_delay_ms); } } /// Convert microseconds to duty value. /// /// This function uses the constants TOP and PERIOD_US defined at the top of the file. fn us_to_duty(us: u16) -> u16 { // Do math in u32 so we maintain higher precision. If we do math in u16, we need to divide first // and lose some precision when truncating the remainder. (TOP as u32 * us as u32 / PERIOD_US) as u16 } ================================================ FILE: boards/pimoroni-servo2040/examples/pimoroni_servo2040_rainbow.rs ================================================ //! Animates a rainbow wheel on the 6 color LEDs on a Servo2040 in sequence #![no_std] #![no_main] use bsp::entry; use bsp::hal::{ clocks::{init_clocks_and_plls, Clock}, pac, sio::Sio, watchdog::Watchdog, }; use defmt::*; use defmt_rtt as _; use embedded_hal::delay::DelayNs; use panic_halt as _; use pimoroni_servo2040 as bsp; use rp2040_hal::pio::PIOExt; use rp2040_hal::Timer; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use ws2812_pio::Ws2812; #[entry] fn main() -> ! { info!("Program start"); let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let sio = Sio::new(pac.SIO); let clocks = init_clocks_and_plls( bsp::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let pins = bsp::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Configure the addressable LED let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( pins.led_data.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); // Infinite color wheel loop let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer let offset = (256u16 / bsp::NUM_LEDS as u16) as u8; loop { ws.write(brightness( IntoIterator::into_iter([ wheel(n), wheel(n.wrapping_add(offset)), wheel(n.wrapping_add(offset * 2)), wheel(n.wrapping_add(offset * 3)), wheel(n.wrapping_add(offset * 4)), wheel(n.wrapping_add(offset * 5)), ]), 32, )) .unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } // End of file ================================================ FILE: boards/pimoroni-servo2040/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub const NUM_SERVOS: u8 = 18; pub const NUM_SENSORS: u8 = 6; pub const NUM_LEDS: u8 = 6; pub const SENSOR_1_ADDR: u8 = 0b_0000; pub const SENSOR_2_ADDR: u8 = 0b_0001; pub const SENSOR_3_ADDR: u8 = 0b_0010; pub const SENSOR_4_ADDR: u8 = 0b_0011; pub const SENSOR_5_ADDR: u8 = 0b_0100; pub const SENSOR_6_ADDR: u8 = 0b_0101; pub const VOLTAGE_SENSE_ADDR: u8 = 0b_0110; pub const CURRENT_SENSE_ADDR: u8 = 0b_0111; pub const VOLTAGE_GAIN: f32 = 0.28058; pub const SHUNT_RESISTOR: f32 = 0.003; pub const CURRENT_GAIN: u8 = 69; pub const CURRENT_OFFSET: f32 = -0.02; pub use hal::pac; hal::bsp_pins!( /// GPIO 0 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM0 A` | [crate::Servo1Pwm0A] | /// | `PIO0` | [crate::Servo1Pio0] | /// | `PIO1` | [crate::Servo1Pio1] | Gpio0 { name: servo1, aliases: { /// PWM Function alias for pin [crate::Pins::servo1]. FunctionPwm, PullNone: Servo1Pwm0A, /// PIO0 Function alias for pin [crate::Pins::servo1]. FunctionPio0, PullNone: Servo1Pio0, /// PIO1 Function alias for pin [crate::Pins::servo1]. FunctionPio1, PullNone: Servo1Pio1 } }, /// GPIO 1 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM0 B` | [crate::Servo2Pwm0B] | /// | `PIO0` | [crate::Servo2Pio0] | /// | `PIO1` | [crate::Servo2Pio1] | Gpio1 { name: servo2, aliases: { /// PWM Function alias for pin [crate::Pins::servo2]. FunctionPwm, PullNone: Servo2Pwm0B, /// PIO0 Function alias for pin [crate::Pins::servo2]. FunctionPio0, PullNone: Servo2Pio0, /// PIO1 Function alias for pin [crate::Pins::servo2]. FunctionPio1, PullNone: Servo2Pio1 } }, /// GPIO 2 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM1 A` | [crate::Servo3Pwm1A] | /// | `PIO0` | [crate::Servo3Pio0] | /// | `PIO1` | [crate::Servo3Pio1] | Gpio2 { name: servo3, aliases: { /// PWM Function alias for pin [crate::Pins::servo3]. FunctionPwm, PullNone: Servo3Pwm1A, /// PIO0 Function alias for pin [crate::Pins::servo3]. FunctionPio0, PullNone: Servo3Pio0, /// PIO1 Function alias for pin [crate::Pins::servo3]. FunctionPio1, PullNone: Servo3Pio1 } }, /// GPIO 3 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM1 B` | [crate::Servo4Pwm1B] | /// | `PIO0` | [crate::Servo4Pio0] | /// | `PIO1` | [crate::Servo4Pio1] | Gpio3 { name: servo4, aliases: { /// PWM Function alias for pin [crate::Pins::servo4]. FunctionPwm, PullNone: Servo4Pwm1B, /// PIO0 Function alias for pin [crate::Pins::servo4]. FunctionPio0, PullNone: Servo4Pio0, /// PIO1 Function alias for pin [crate::Pins::servo4]. FunctionPio1, PullNone: Servo4Pio1 } }, /// GPIO 4 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM2 A` | [crate::Servo5Pwm2A] | /// | `PIO0` | [crate::Servo5Pio0] | /// | `PIO1` | [crate::Servo5Pio1] | Gpio4 { name: servo5, aliases: { /// PWM Function alias for pin [crate::Pins::servo5]. FunctionPwm, PullNone: Servo5Pwm2A, /// PIO0 Function alias for pin [crate::Pins::servo5]. FunctionPio0, PullNone: Servo5Pio0, /// PIO1 Function alias for pin [crate::Pins::servo5]. FunctionPio1, PullNone: Servo5Pio1 } }, /// GPIO 5 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM2 B` | [crate::Servo6Pwm2B] | /// | `PIO0` | [crate::Servo6Pio0] | /// | `PIO1` | [crate::Servo6Pio1] | Gpio5 { name: servo6, aliases: { /// PWM Function alias for pin [crate::Pins::servo6]. FunctionPwm, PullNone: Servo6Pwm2B, /// PIO0 Function alias for pin [crate::Pins::servo6]. FunctionPio0, PullNone: Servo6Pio0, /// PIO1 Function alias for pin [crate::Pins::servo6]. FunctionPio1, PullNone: Servo6Pio1 } }, /// GPIO 6 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM3 A` | [crate::Servo7Pwm3A] | /// | `PIO0` | [crate::Servo7Pio0] | /// | `PIO1` | [crate::Servo7Pio1] | Gpio6 { name: servo7, aliases: { /// PWM Function alias for pin [crate::Pins::servo7]. FunctionPwm, PullNone: Servo7Pwm3A, /// PIO0 Function alias for pin [crate::Pins::servo7]. FunctionPio0, PullNone: Servo7Pio0, /// PIO1 Function alias for pin [crate::Pins::servo7]. FunctionPio1, PullNone: Servo7Pio1 } }, /// GPIO 7 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM3 B` | [crate::Servo8Pwm3B] | /// | `PIO0` | [crate::Servo8Pio0] | /// | `PIO1` | [crate::Servo8Pio1] | Gpio7 { name: servo8, aliases: { /// PWM Function alias for pin [crate::Pins::servo8]. FunctionPwm, PullNone: Servo8Pwm3B, /// PIO0 Function alias for pin [crate::Pins::servo8]. FunctionPio0, PullNone: Servo8Pio0, /// PIO1 Function alias for pin [crate::Pins::servo8]. FunctionPio1, PullNone: Servo8Pio1 } }, /// GPIO 8 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM4 A` | [crate::Servo9Pwm4A] | /// | `PIO0` | [crate::Servo9Pio0] | /// | `PIO1` | [crate::Servo9Pio1] | Gpio8 { name: servo9, aliases: { /// PWM Function alias for pin [crate::Pins::servo9]. FunctionPwm, PullNone: Servo9Pwm4A, /// PIO0 Function alias for pin [crate::Pins::servo9]. FunctionPio0, PullNone: Servo9Pio0, /// PIO1 Function alias for pin [crate::Pins::servo9]. FunctionPio1, PullNone: Servo9Pio1 } }, /// GPIO 9 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM4 B` | [crate::Servo10Pwm4B] | /// | `PIO0` | [crate::Servo10Pio0] | /// | `PIO1` | [crate::Servo10Pio1] | Gpio9 { name: servo10, aliases: { /// PWM Function alias for pin [crate::Pins::servo10]. FunctionPwm, PullNone: Servo10Pwm4B, /// PIO0 Function alias for pin [crate::Pins::servo10]. FunctionPio0, PullNone: Servo10Pio0, /// PIO1 Function alias for pin [crate::Pins::servo10]. FunctionPio1, PullNone: Servo10Pio1 } }, /// GPIO 10 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM5 A` | [crate::Servo11Pwm5A] | /// | `PIO0` | [crate::Servo11Pio0] | /// | `PIO1` | [crate::Servo11Pio1] | Gpio10 { name: servo11, aliases: { /// PWM Function alias for pin [crate::Pins::servo11]. FunctionPwm, PullNone: Servo11Pwm5A, /// PIO0 Function alias for pin [crate::Pins::servo11]. FunctionPio0, PullNone: Servo11Pio0, /// PIO1 Function alias for pin [crate::Pins::servo11]. FunctionPio1, PullNone: Servo11Pio1 } }, /// GPIO 11 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM5 B` | [crate::Servo12Pwm5B] | /// | `PIO0` | [crate::Servo12Pio0] | /// | `PIO1` | [crate::Servo12Pio1] | Gpio11 { name: servo12, aliases: { /// PWM Function alias for pin [crate::Pins::servo12]. FunctionPwm, PullNone: Servo12Pwm5B, /// PIO0 Function alias for pin [crate::Pins::servo12]. FunctionPio0, PullNone: Servo12Pio0, /// PIO1 Function alias for pin [crate::Pins::servo12]. FunctionPio1, PullNone: Servo12Pio1 } }, /// GPIO 12 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM6 A` | [crate::Servo13Pwm6A] | /// | `PIO0` | [crate::Servo13Pio0] | /// | `PIO1` | [crate::Servo13Pio1] | Gpio12 { name: servo13, aliases: { /// PWM Function alias for pin [crate::Pins::servo13]. FunctionPwm, PullNone: Servo13Pwm6A, /// PIO0 Function alias for pin [crate::Pins::servo13]. FunctionPio0, PullNone: Servo13Pio0, /// PIO1 Function alias for pin [crate::Pins::servo13]. FunctionPio1, PullNone: Servo13Pio1 } }, /// GPIO 13 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM6 B` | [crate::Servo14Pwm6B] | /// | `PIO0` | [crate::Servo14Pio0] | /// | `PIO1` | [crate::Servo14Pio1] | Gpio13 { name: servo14, aliases: { /// PWM Function alias for pin [crate::Pins::servo14]. FunctionPwm, PullNone: Servo14Pwm6B, /// PIO0 Function alias for pin [crate::Pins::servo14]. FunctionPio0, PullNone: Servo14Pio0, /// PIO1 Function alias for pin [crate::Pins::servo14]. FunctionPio1, PullNone: Servo14Pio1 } }, /// GPIO 14 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM7 A` | [crate::Servo15Pwm7A] | /// | `PIO0` | [crate::Servo15Pio0] | /// | `PIO1` | [crate::Servo15Pio1] | Gpio14 { name: servo15, aliases: { /// PWM Function alias for pin [crate::Pins::servo15]. FunctionPwm, PullNone: Servo15Pwm7A, /// PIO0 Function alias for pin [crate::Pins::servo15]. FunctionPio0, PullNone: Servo15Pio0, /// PIO1 Function alias for pin [crate::Pins::servo15]. FunctionPio1, PullNone: Servo15Pio1 } }, /// GPIO 15 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM7 B` | [crate::Servo16Pwm7B] | /// | `PIO0` | [crate::Servo16Pio0] | /// | `PIO1` | [crate::Servo16Pio1] | Gpio15 { name: servo16, aliases: { /// PWM Function alias for pin [crate::Pins::servo16]. FunctionPwm, PullNone: Servo16Pwm7B, /// PIO0 Function alias for pin [crate::Pins::servo16]. FunctionPio0, PullNone: Servo16Pio0, /// PIO1 Function alias for pin [crate::Pins::servo16]. FunctionPio1, PullNone: Servo16Pio1 } }, /// GPIO 16 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM0 A` | [crate::Servo17Pwm0A] | /// | `PIO0` | [crate::Servo17Pio0] | /// | `PIO1` | [crate::Servo17Pio1] | Gpio16 { name: servo17, aliases: { /// PWM Function alias for pin [crate::Pins::servo17]. FunctionPwm, PullNone: Servo17Pwm0A, /// PIO0 Function alias for pin [crate::Pins::servo17]. FunctionPio0, PullNone: Servo17Pio0, /// PIO1 Function alias for pin [crate::Pins::servo17]. FunctionPio1, PullNone: Servo17Pio1 } }, /// GPIO 17 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `PWM0 B` | [crate::Servo18Pwm0B] | /// | `PIO0` | [crate::Servo18Pio0] | /// | `PIO1` | [crate::Servo18Pio1] | Gpio17 { name: servo18, aliases: { /// PWM Function alias for pin [crate::Pins::servo18]. FunctionPwm, PullNone: Servo18Pwm0B, /// PIO0 Function alias for pin [crate::Pins::servo18]. FunctionPio0, PullNone: Servo18Pio0, /// PIO1 Function alias for pin [crate::Pins::servo18]. FunctionPio1, PullNone: Servo18Pio1 } }, /// GPIO 18 is connected to the leds of the Servo 2040 board. Gpio18 { name: led_data }, /// GPIO 19 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp19Spi0Tx] | /// | `UART0 RTS` | [crate::Gp19Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp19I2C1Scl] | /// | `PWM1 B` | [crate::Gp19Pwm1B] | /// | `PIO0` | [crate::Gp19Pio0] | /// | `PIO1` | [crate::Gp19Pio1] | Gpio19 { name: int_, aliases: { /// UART Function alias for pin [crate::Pins::int_]. FunctionUart, PullNone: Gp19Uart0Rts, /// SPI Function alias for pin [crate::Pins::int_]. FunctionSpi, PullNone: Gp19Spi0Tx, /// I2C Function alias for pin [crate::Pins::int_]. FunctionI2C, PullUp: Gp19I2C1Scl, /// PWM Function alias for pin [crate::Pins::int_]. FunctionPwm, PullNone: Gp19Pwm1B, /// PIO0 Function alias for pin [crate::Pins::int_]. FunctionPio0, PullNone: Gp19Pio0, /// PIO1 Function alias for pin [crate::Pins::int_]. FunctionPio1, PullNone: Gp19Pio1 } }, /// GPIO 20 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp20Spi0Rx] | /// | `UART1 TX` | [crate::Gp20Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp20I2C0Sda] | /// | `PWM2 A` | [crate::Gp20Pwm2A] | /// | `PIO0` | [crate::Gp20Pio0] | /// | `PIO1` | [crate::Gp20Pio1] | Gpio20 { name: sda, aliases: { /// UART Function alias for pin [crate::Pins::sda]. FunctionUart, PullNone: Gp20Uart1Tx, /// SPI Function alias for pin [crate::Pins::sda]. FunctionSpi, PullNone: Gp20Spi0Rx, /// I2C Function alias for pin [crate::Pins::sda]. FunctionI2C, PullUp: Gp20I2C0Sda, /// PWM Function alias for pin [crate::Pins::sda]. FunctionPwm, PullNone: Gp20Pwm2A, /// PIO0 Function alias for pin [crate::Pins::sda]. FunctionPio0, PullNone: Gp20Pio0, /// PIO1 Function alias for pin [crate::Pins::sda]. FunctionPio1, PullNone: Gp20Pio1 } }, /// GPIO 21 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp21Spi0Csn] | /// | `UART1 RX` | [crate::Gp21Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp21I2C0Scl] | /// | `PWM2 B` | [crate::Gp21Pwm2B] | /// | `PIO0` | [crate::Gp21Pio0] | /// | `PIO1` | [crate::Gp21Pio1] | Gpio21 { name: scl, aliases: { /// UART Function alias for pin [crate::Pins::scl]. FunctionUart, PullNone: Gp21Uart1Rx, /// SPI Function alias for pin [crate::Pins::scl]. FunctionSpi, PullNone: Gp21Spi0Csn, /// I2C Function alias for pin [crate::Pins::scl]. FunctionI2C, PullUp: Gp21I2C0Scl, /// PWM Function alias for pin [crate::Pins::scl]. FunctionPwm, PullNone: Gp21Pwm2B, /// PIO0 Function alias for pin [crate::Pins::scl]. FunctionPio0, PullNone: Gp21Pio0, /// PIO1 Function alias for pin [crate::Pins::scl]. FunctionPio1, PullNone: Gp21Pio1 } }, /// GPIO 22 is connected to adc_addr_0 of the Servo 2040 board. Gpio22 { name: adc_addr_0, }, /// GPIO 23 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp23Spi0Tx] | /// | `UART1 RTS` | [crate::Gp23Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp23I2C1Scl] | /// | `PWM3 B` | [crate::Gp23Pwm3B] | /// | `PIO0` | [crate::Gp23Pio0] | /// | `PIO1` | [crate::Gp23Pio1] | Gpio23 { name: user_sw, aliases: { /// UART Function alias for pin [crate::Pins::user_sw]. FunctionUart, PullNone: Gp23Uart1Rts, /// SPI Function alias for pin [crate::Pins::user_sw]. FunctionSpi, PullNone: Gp23Spi0Tx, /// I2C Function alias for pin [crate::Pins::user_sw]. FunctionI2C, PullUp: Gp23I2C1Scl, /// PWM Function alias for pin [crate::Pins::user_sw]. FunctionPwm, PullNone: Gp23Pwm3B, /// PIO0 Function alias for pin [crate::Pins::user_sw]. FunctionPio0, PullNone: Gp23Pio0, /// PIO1 Function alias for pin [crate::Pins::user_sw]. FunctionPio1, PullNone: Gp23Pio1 } }, /// GPIO 24 is connected to adc_addr_1 of the Servo 2040 board. Gpio24 { name: adc_addr_1, }, /// GPIO 25 is connected to adc_addr_2 of the Servo 2040 board. Gpio25 { name: adc_addr_2, }, /// GPIO 26 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp26Spi1Sck] | /// | `UART1 CTS` | [crate::Gp26Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp26I2C1Sda] | /// | `PWM5 A` | [crate::Gp26Pwm5A] | /// | `PIO0` | [crate::Gp26Pio0] | /// | `PIO1` | [crate::Gp26Pio1] | Gpio26 { name: adc0, aliases: { /// UART Function alias for pin [crate::Pins::gpio26]. FunctionUart, PullNone: Gp26Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio26]. FunctionSpi, PullNone: Gp26Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio26]. FunctionI2C, PullUp: Gp26I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio26]. FunctionPwm, PullNone: Gp26Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio26]. FunctionPio0, PullNone: Gp26Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio26]. FunctionPio1, PullNone: Gp26Pio1 } }, /// GPIO 27 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp27Spi1Tx] | /// | `UART1 RTS` | [crate::Gp27Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp27I2C1Scl] | /// | `PWM5 B` | [crate::Gp27Pwm5B] | /// | `PIO0` | [crate::Gp27Pio0] | /// | `PIO1` | [crate::Gp27Pio1] | Gpio27 { name: adc1, aliases: { /// UART Function alias for pin [crate::Pins::gpio27]. FunctionUart, PullNone: Gp27Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio27]. FunctionSpi, PullNone: Gp27Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio27]. FunctionI2C, PullUp: Gp27I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio27]. FunctionPwm, PullNone: Gp27Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio27]. FunctionPio0, PullNone: Gp27Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio27]. FunctionPio1, PullNone: Gp27Pio1 } }, /// GPIO 28 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp28Spi1Rx] | /// | `UART0 TX` | [crate::Gp28Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp28I2C0Sda] | /// | `PWM6 A` | [crate::Gp28Pwm6A] | /// | `PIO0` | [crate::Gp28Pio0] | /// | `PIO1` | [crate::Gp28Pio1] | Gpio28 { name: adc2, aliases: { /// UART Function alias for pin [crate::Pins::gpio28]. FunctionUart, PullNone: Gp28Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio28]. FunctionSpi, PullNone: Gp28Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio28]. FunctionI2C, PullUp: Gp28I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio28]. FunctionPwm, PullNone: Gp28Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio28]. FunctionPio0, PullNone: Gp28Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio28]. FunctionPio1, PullNone: Gp28Pio1 } }, /// GPIO 29 is connected to shared adc of the Servo2040 board. Gpio29 { name: shared_adc, }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/pimoroni-tiny2040/.gitignore ================================================ # Generated by Cargo # will have compiled files and executables debug/ target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk ================================================ FILE: boards/pimoroni-tiny2040/CHANGELOG.md ================================================ # 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.7.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.6.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 ## 0.5.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 ## 0.4.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 ## 0.3.0 - 2022-08-26 ### Changed - Migrate from `embedded-time` to `fugit` - Update to rp2040-hal 0.6.0 ================================================ FILE: boards/pimoroni-tiny2040/Cargo.toml ================================================ [package] name = "pimoroni-tiny2040" version = "0.7.0" authors = ["Mike Bell ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-tiny2040" description = "Board Support Package for the Pimoroni Tiny2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m.workspace = true cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] embedded-hal.workspace = true fugit.workspace = true panic-halt.workspace = true rp2040-hal = { workspace = true, features = [ "defmt" ] } defmt = "0.3.5" defmt-rtt = "0.4.0" [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/pimoroni-tiny2040/README.md ================================================ # [pimoroni-tiny2040] - Board Support for the [Pimoroni Tiny2040] You should include this crate if you are writing code that you want to run on a [Pimoroni Tiny2040] - one of the first third party RP2040 boards available, with 8MB flash and a 3 colour LED. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Tiny2040. [Pimoroni Tiny2040]: https://shop.pimoroni.com/products/tiny-2040 [pimoroni-tiny2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-tiny2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml pimoroni-tiny2040 = "0.7.0" ``` In your program, you will need to call `pimoroni_tiny2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/pimoroni-tiny2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/pimoroni-tiny2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` then try repeating the `cargo run` command above. ### [tiny2040_blinky](./examples/tiny2040_blinky.rs) Flashes the Tiny2040's three on-board LEDs in sequence. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/pimoroni-tiny2040/build.rs ================================================ //! This build script makes sure the linker flag -Tdefmt.x is added //! for the examples. fn main() { println!("cargo:rustc-link-arg-examples=-Tdefmt.x"); } ================================================ FILE: boards/pimoroni-tiny2040/examples/tiny2040_blinky.rs ================================================ //! Blinks the 3 colour LEDs on a Tiny2040 in sequence #![no_std] #![no_main] use bsp::entry; use defmt::*; use defmt_rtt as _; use embedded_hal::digital::OutputPin; use panic_halt as _; use pimoroni_tiny2040 as bsp; use bsp::hal::{ clocks::{init_clocks_and_plls, Clock}, pac, sio::Sio, watchdog::Watchdog, }; #[entry] fn main() -> ! { info!("Program start"); let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let sio = Sio::new(pac.SIO); let clocks = init_clocks_and_plls( bsp::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); let pins = bsp::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let mut led_green = pins.led_green.into_push_pull_output(); let mut led_red = pins.led_red.into_push_pull_output(); let mut led_blue = pins.led_blue.into_push_pull_output(); led_green.set_high().unwrap(); led_red.set_high().unwrap(); led_blue.set_high().unwrap(); loop { led_green.set_low().unwrap(); delay.delay_ms(500); led_green.set_high().unwrap(); led_blue.set_low().unwrap(); delay.delay_ms(500); led_blue.set_high().unwrap(); led_red.set_low().unwrap(); delay.delay_ms(500); led_red.set_high().unwrap(); } } // End of file ================================================ FILE: boards/pimoroni-tiny2040/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( /// GPIO 0 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp0Spi0Rx] | /// | `UART0 TX` | [crate::Gp0Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp0I2C0Sda] | /// | `PWM0 A` | [crate::Gp0Pwm0A] | /// | `PIO0` | [crate::Gp0Pio0] | /// | `PIO1` | [crate::Gp0Pio1] | Gpio0 { name: gpio0, aliases: { /// UART Function alias for pin [crate::Pins::gpio0]. FunctionUart, PullNone: Gp0Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio0]. FunctionSpi, PullNone: Gp0Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio0]. FunctionI2C, PullUp: Gp0I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio0]. FunctionPwm, PullNone: Gp0Pwm0A, /// PIO0 Function alias for pin [crate::Pins::gpio0]. FunctionPio0, PullNone: Gp0Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio0]. FunctionPio1, PullNone: Gp0Pio1 } }, /// GPIO 1 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp1Spi0Csn] | /// | `UART0 RX` | [crate::Gp1Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp1I2C0Scl] | /// | `PWM0 B` | [crate::Gp1Pwm0B] | /// | `PIO0` | [crate::Gp1Pio0] | /// | `PIO1` | [crate::Gp1Pio1] | Gpio1 { name: gpio1, aliases: { /// UART Function alias for pin [crate::Pins::gpio1]. FunctionUart, PullNone: Gp1Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio1]. FunctionSpi, PullNone: Gp1Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio1]. FunctionI2C, PullUp: Gp1I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio1]. FunctionPwm, PullNone: Gp1Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio1]. FunctionPio0, PullNone: Gp1Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio1]. FunctionPio1, PullNone: Gp1Pio1 } }, /// GPIO 2 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp2Spi0Sck] | /// | `UART0 CTS` | [crate::Gp2Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp2I2C1Sda] | /// | `PWM1 A` | [crate::Gp2Pwm1A] | /// | `PIO0` | [crate::Gp2Pio0] | /// | `PIO1` | [crate::Gp2Pio1] | Gpio2 { name: gpio2, aliases: { /// UART Function alias for pin [crate::Pins::gpio2]. FunctionUart, PullNone: Gp2Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio2]. FunctionSpi, PullNone: Gp2Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio2]. FunctionI2C, PullUp: Gp2I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio2]. FunctionPwm, PullNone: Gp2Pwm1A, /// PIO0 Function alias for pin [crate::Pins::gpio2]. FunctionPio0, PullNone: Gp2Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio2]. FunctionPio1, PullNone: Gp2Pio1 } }, /// GPIO 3 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp3Spi0Tx] | /// | `UART0 RTS` | [crate::Gp3Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp3I2C1Scl] | /// | `PWM1 B` | [crate::Gp3Pwm1B] | /// | `PIO0` | [crate::Gp3Pio0] | /// | `PIO1` | [crate::Gp3Pio1] | Gpio3 { name: gpio3, aliases: { /// UART Function alias for pin [crate::Pins::gpio3]. FunctionUart, PullNone: Gp3Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio3]. FunctionSpi, PullNone: Gp3Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio3]. FunctionI2C, PullUp: Gp3I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio3]. FunctionPwm, PullNone: Gp3Pwm1B, /// PIO0 Function alias for pin [crate::Pins::gpio3]. FunctionPio0, PullNone: Gp3Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio3]. FunctionPio1, PullNone: Gp3Pio1 } }, /// GPIO 4 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp4Spi0Rx] | /// | `UART1 TX` | [crate::Gp4Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp4I2C0Sda] | /// | `PWM2 A` | [crate::Gp4Pwm2A] | /// | `PIO0` | [crate::Gp4Pio0] | /// | `PIO1` | [crate::Gp4Pio1] | Gpio4 { name: gpio4, aliases: { /// UART Function alias for pin [crate::Pins::gpio4]. FunctionUart, PullNone: Gp4Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio4]. FunctionSpi, PullNone: Gp4Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio4]. FunctionI2C, PullUp: Gp4I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio4]. FunctionPwm, PullNone: Gp4Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio4]. FunctionPio0, PullNone: Gp4Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio4]. FunctionPio1, PullNone: Gp4Pio1 } }, /// GPIO 5 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp5Spi0Csn] | /// | `UART1 RX` | [crate::Gp5Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp5I2C0Scl] | /// | `PWM2 B` | [crate::Gp5Pwm2B] | /// | `PIO0` | [crate::Gp5Pio0] | /// | `PIO1` | [crate::Gp5Pio1] | Gpio5 { name: gpio5, aliases: { /// UART Function alias for pin [crate::Pins::gpio5]. FunctionUart, PullNone: Gp5Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio5]. FunctionSpi, PullNone: Gp5Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio5]. FunctionI2C, PullUp: Gp5I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio5]. FunctionPwm, PullNone: Gp5Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio5]. FunctionPio0, PullNone: Gp5Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio5]. FunctionPio1, PullNone: Gp5Pio1 } }, /// GPIO 6 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp6Spi0Sck] | /// | `UART1 CTS` | [crate::Gp6Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp6I2C1Sda] | /// | `PWM3 A` | [crate::Gp6Pwm3A] | /// | `PIO0` | [crate::Gp6Pio0] | /// | `PIO1` | [crate::Gp6Pio1] | Gpio6 { name: gpio6, aliases: { /// UART Function alias for pin [crate::Pins::gpio6]. FunctionUart, PullNone: Gp6Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio6]. FunctionSpi, PullNone: Gp6Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio6]. FunctionI2C, PullUp: Gp6I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio6]. FunctionPwm, PullNone: Gp6Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio6]. FunctionPio0, PullNone: Gp6Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio6]. FunctionPio1, PullNone: Gp6Pio1 } }, /// GPIO 7 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp7Spi0Tx] | /// | `UART1 RTS` | [crate::Gp7Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp7I2C1Scl] | /// | `PWM3 B` | [crate::Gp7Pwm3B] | /// | `PIO0` | [crate::Gp7Pio0] | /// | `PIO1` | [crate::Gp7Pio1] | Gpio7 { name: gpio7, aliases: { /// UART Function alias for pin [crate::Pins::gpio7]. FunctionUart, PullNone: Gp7Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio7]. FunctionSpi, PullNone: Gp7Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio7]. FunctionI2C, PullUp: Gp7I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio7]. FunctionPwm, PullNone: Gp7Pwm3B, /// PIO0 Function alias for pin [crate::Pins::gpio7]. FunctionPio0, PullNone: Gp7Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio7]. FunctionPio1, PullNone: Gp7Pio1 } }, /// GPIO 18 is red LED, active low Gpio18 { name: led_red }, /// GPIO 19 is green LED, active low Gpio19 { name: led_green }, /// GPIO 20 is blue LED, active low Gpio20 { name: led_blue }, /// GPIO 23 is connected to bootsel button, active low Gpio23 { name: bootsel }, /// GPIO 26 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp26Spi1Sck] | /// | `UART1 CTS` | [crate::Gp26Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp26I2C1Sda] | /// | `PWM5 A` | [crate::Gp26Pwm5A] | /// | `PIO0` | [crate::Gp26Pio0] | /// | `PIO1` | [crate::Gp26Pio1] | Gpio26 { name: gpio26, aliases: { /// UART Function alias for pin [crate::Pins::gpio26]. FunctionUart, PullNone: Gp26Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio26]. FunctionSpi, PullNone: Gp26Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio26]. FunctionI2C, PullUp: Gp26I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio26]. FunctionPwm, PullNone: Gp26Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio26]. FunctionPio0, PullNone: Gp26Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio26]. FunctionPio1, PullNone: Gp26Pio1 } }, /// GPIO 27 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp27Spi1Tx] | /// | `UART1 RTS` | [crate::Gp27Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp27I2C1Scl] | /// | `PWM5 B` | [crate::Gp27Pwm5B] | /// | `PIO0` | [crate::Gp27Pio0] | /// | `PIO1` | [crate::Gp27Pio1] | Gpio27 { name: gpio27, aliases: { /// UART Function alias for pin [crate::Pins::gpio27]. FunctionUart, PullNone: Gp27Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio27]. FunctionSpi, PullNone: Gp27Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio27]. FunctionI2C, PullUp: Gp27I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio27]. FunctionPwm, PullNone: Gp27Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio27]. FunctionPio0, PullNone: Gp27Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio27]. FunctionPio1, PullNone: Gp27Pio1 } }, /// GPIO 28 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp28Spi1Rx] | /// | `UART0 TX` | [crate::Gp28Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp28I2C0Sda] | /// | `PWM6 A` | [crate::Gp28Pwm6A] | /// | `PIO0` | [crate::Gp28Pio0] | /// | `PIO1` | [crate::Gp28Pio1] | Gpio28 { name: gpio28, aliases: { /// UART Function alias for pin [crate::Pins::gpio28]. FunctionUart, PullNone: Gp28Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio28]. FunctionSpi, PullNone: Gp28Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio28]. FunctionI2C, PullUp: Gp28I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio28]. FunctionPwm, PullNone: Gp28Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio28]. FunctionPio0, PullNone: Gp28Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio28]. FunctionPio1, PullNone: Gp28Pio1 } }, /// GPIO 29 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp29Spi1Csn] | /// | `UART0 RX` | [crate::Gp29Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp29I2C0Scl] | /// | `PWM6 B` | [crate::Gp29Pwm6B] | /// | `PIO0` | [crate::Gp29Pio0] | /// | `PIO1` | [crate::Gp29Pio1] | Gpio29 { name: gpio29, aliases: { /// UART Function alias for pin [crate::Pins::gpio28]. FunctionUart, PullNone: Gp29Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio28]. FunctionSpi, PullNone: Gp29Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio28]. FunctionI2C, PullUp: Gp29I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio28]. FunctionPwm, PullNone: Gp29Pwm6B, /// PIO0 Function alias for pin [crate::Pins::gpio28]. FunctionPio0, PullNone: Gp29Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio28]. FunctionPio1, PullNone: Gp29Pio1 } }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/pimoroni-tufty2040/CHANGELOG.md ================================================ # 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.1.0 - 2024-04-07 Initial release ================================================ FILE: boards/pimoroni-tufty2040/Cargo.toml ================================================ [package] name = "pimoroni-tufty2040" version = "0.1.0" authors = ["The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-tufty2040" description = "Board Support Package for the Pimoroni Tufty2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m.workspace = true cortex-m-rt = { workspace = true, optional = true } embedded-hal.workspace = true embedded_hal_0_2.workspace = true fugit.workspace = true rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true display-interface.workspace = true pio.workspace = true pio-proc.workspace = true [dev-dependencies] embedded-graphics.workspace = true nb.workspace = true panic-halt.workspace = true st7789.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache", "rom-v2-intrinsics"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt", "rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/pimoroni-tufty2040/README.md ================================================ # [pimoroni-tufty2040] - Board Support for the [Pimoroni Tufty2040] You should include this crate if you are writing code that you want to run on a [Pimoroni Tufty2040] - a hackable, programmable badge with a LCD colour display, powered by a Raspberry Pi RP2040. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Tufty2040. [Pimoroni Tufty2040]: https://shop.pimoroni.com/products/tufty-2040/ [pimoroni-tufty2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni-tufty2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml pimoroni_tufty2040 = "0.1.0" ``` In your program, you will need to call `pimoroni_tufty2040::Board::take().unwrap()` to create a new `Boards` structure. This will set up all the GPIOs for any on-board devices and configure common clocks. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/pimoroni-tufty2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/pimoroni-tufty2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` then try repeating the `cargo run` command above. ### [tufty_demo](./examples/tufty_demo) Flashes the Tufty2040's LED and draws a circle on the screen. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can chose either the MIT licence or the Apache-2.0 licence when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific licence. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/pimoroni-tufty2040/examples/tufty_demo.rs ================================================ //! # Tufty2040 Demo Example //! //! Draws a circle on the LCD screen and then blinks the user LED on the Tufty 2040. //! //! See the `Cargo.toml` file for Copyright and licence details. #![no_std] #![no_main] use pimoroni_tufty2040 as tufty; // The macro for our start-up function use tufty::entry; // GPIO traits use embedded_hal::digital::{OutputPin, PinState}; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use tufty::hal; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use hal::pac; use hal::clocks::ClockSource; use hal::gpio::{FunctionPio0, PullNone}; use hal::Clock; use hal::Timer; use tufty::DummyPin; use embedded_graphics::draw_target::DrawTarget; use embedded_graphics::geometry::Point; use embedded_graphics::pixelcolor::{Rgb565, RgbColor}; use embedded_graphics::primitives::{Circle, Primitive, PrimitiveStyleBuilder}; use embedded_graphics::Drawable; use embedded_hal::delay::DelayNs; use st7789::ST7789; #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let cp = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( tufty::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = tufty::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Configure the timer peripheral for our blinky delay let mut timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); let mut delay = cortex_m::delay::Delay::new(cp.SYST, clocks.system_clock.get_freq().to_Hz()); // Set the LED to be an output let mut led_pin = pins.led.into_push_pull_output(); pins.lcd_backlight .into_push_pull_output_in_state(PinState::High); pins.lcd_rd.into_push_pull_output_in_state(PinState::High); let display_data = { use hal::dma::DMAExt; use hal::pio::PIOExt; let dma = pac.DMA.split(&mut pac.RESETS); let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let wr = pins.lcd_wr.reconfigure::(); let d0 = pins.lcd_db0.reconfigure::(); pins.lcd_db1.reconfigure::(); pins.lcd_db2.reconfigure::(); pins.lcd_db3.reconfigure::(); pins.lcd_db4.reconfigure::(); pins.lcd_db5.reconfigure::(); pins.lcd_db6.reconfigure::(); pins.lcd_db7.reconfigure::(); tufty::PioDataLines::new( &mut pio, clocks.system_clock.freq(), wr.id(), d0.id(), sm0, dma.ch0, ) }; let display_interface = tufty::ParallelDisplayInterface::new( pins.lcd_cs.into_push_pull_output_in_state(PinState::High), pins.lcd_dc.into_push_pull_output_in_state(PinState::High), display_data, ); let mut display = ST7789::new(display_interface, DummyPin, 240, 320); display.init(&mut delay).unwrap(); display.clear(Rgb565::BLUE).unwrap(); let style = PrimitiveStyleBuilder::default() .fill_color(Rgb565::RED) .build(); Circle::new(Point::new(50, 50), 10) .into_styled(style) .draw(&mut display) .unwrap(); // Blink the LED at 1 Hz loop { // LED on, and wait for 500ms led_pin.set_high().unwrap(); timer.delay_ms(500); // LED off, and wait for 500ms led_pin.set_low().unwrap(); timer.delay_ms(500); } } ================================================ FILE: boards/pimoroni-tufty2040/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; pub use hal::pac; use display_interface::{DataFormat, DisplayError, WriteOnlyDataCommand}; use embedded_hal_0_2::digital::v2::OutputPin; use fugit::HertzU32; use hal::dma::{single_buffer, Channel, ChannelIndex, WriteTarget}; use hal::gpio::PinId; use hal::pio::{ Buffers, PIOBuilder, PIOExt, PinDir, PinState, StateMachineIndex, Tx, UninitStateMachine, }; use pio_proc::pio_file; #[cfg(feature = "rt")] pub use rp2040_hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; hal::bsp_pins!( Gpio0 { name: gpio0, aliases: { /// UART Function alias for pin [Pins::gpio0]. FunctionUart, PullNone: UartTx } }, Gpio1 { name: gpio1, aliases: { /// UART Function alias for pin [Pins::gpio1]. FunctionUart, PullNone: UartRx } }, Gpio2 { name: lcd_backlight }, Gpio3 { name: i2c_int }, Gpio4 { name: gpio4, aliases: { /// I2C Function alias for pin [Pins::gpio4]. FunctionI2C, PullUp: I2cSda } }, Gpio5 { name: gpio5, aliases: { /// I2C Function alias for pin [Pins::gpio5]. FunctionI2C, PullUp: I2cScl } }, Gpio6 { name: sw_down }, Gpio7 { name: sw_a }, Gpio8 { name: sw_b }, Gpio9 { name: sw_c }, Gpio10 { name: lcd_cs }, Gpio11 { name: lcd_dc }, Gpio12 { name: lcd_wr }, Gpio13 { name: lcd_rd }, Gpio14 { name: lcd_db0 }, Gpio15 { name: lcd_db1 }, Gpio16 { name: lcd_db2 }, Gpio17 { name: lcd_db3 }, Gpio18 { name: lcd_db4 }, Gpio19 { name: lcd_db5 }, Gpio20 { name: lcd_db6 }, Gpio21 { name: lcd_db7 }, Gpio22 { name: sw_up }, Gpio23 { name: user_sw }, Gpio24 { name: vbus_detect }, Gpio25 { name: led }, Gpio26 { name: light_sense }, Gpio27 { name: sensor_power }, Gpio28 { name: vref_1v24 }, Gpio29 { name: vbat_sense }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; #[inline] fn set_pin_bit(pin: &mut P, bit: u8, value: u8) -> Result<(), DisplayError> { pin.set_state(((bit & value) != 0).into()) .map_err(|_| DisplayError::BusWriteError) } struct WriteBytes(T); // Allow DMA to do byte-size writes to an existing target, // SAFETY: This is only used with the PIO as a target, which is valid to write // byte-width. unsafe impl WriteTarget for WriteBytes { type TransmittedWord = u8; #[inline] fn tx_treq() -> Option { T::tx_treq() } #[inline] fn tx_address_count(&mut self) -> (u32, u32) { self.0.tx_address_count() } #[inline] fn tx_increment(&self) -> bool { self.0.tx_increment() } } pub trait DisplayDataLines { fn flush(&mut self) {} fn write_u8(&mut self, value: u8) -> Result<(), DisplayError>; fn write_slice(&mut self, data: &[u8]) -> Result<(), DisplayError> { for b in data.iter().copied() { self.write_u8(b)?; } Ok(()) } fn write_format(&mut self, data: DataFormat<'_>) -> Result<(), DisplayError> { match data { DataFormat::U8(bytes) => self.write_slice(bytes)?, DataFormat::U16(items) => { for value in items.iter().copied() { self.write_u8(value as u8)?; self.write_u8((value >> 8) as u8)?; } } DataFormat::U16BE(items) => { for value in items.iter().copied() { self.write_u8((value >> 8) as u8)?; self.write_u8(value as u8)?; } } DataFormat::U16LE(items) => { for value in items.iter().copied() { self.write_u8(value as u8)?; self.write_u8((value >> 8) as u8)?; } } DataFormat::U8Iter(iter) => { for value in iter { self.write_u8(value)?; } } DataFormat::U16BEIter(iter) => { for value in iter { self.write_u8((value >> 8) as u8)?; self.write_u8(value as u8)?; } } DataFormat::U16LEIter(iter) => { for value in iter { self.write_u8(value as u8)?; self.write_u8((value >> 8) as u8)?; } } _ => unimplemented!(), } Ok(()) } } pub struct GpioDataLines { pub wr: WR, pub d0: D0, pub d1: D1, pub d2: D2, pub d3: D3, pub d4: D4, pub d5: D5, pub d6: D6, pub d7: D7, } impl< WR: OutputPin, D0: OutputPin, D1: OutputPin, D2: OutputPin, D3: OutputPin, D4: OutputPin, D5: OutputPin, D6: OutputPin, D7: OutputPin, > GpioDataLines { #[inline] fn write_u8_inner(&mut self, value: u8) -> Result<(), DisplayError> { set_pin_bit(&mut self.d0, value, 1 << 0)?; set_pin_bit(&mut self.d1, value, 1 << 1)?; set_pin_bit(&mut self.d2, value, 1 << 2)?; set_pin_bit(&mut self.d3, value, 1 << 3)?; set_pin_bit(&mut self.d4, value, 1 << 4)?; set_pin_bit(&mut self.d5, value, 1 << 5)?; set_pin_bit(&mut self.d6, value, 1 << 6)?; set_pin_bit(&mut self.d7, value, 1 << 7)?; Ok(()) } } impl< WR: OutputPin, D0: OutputPin, D1: OutputPin, D2: OutputPin, D3: OutputPin, D4: OutputPin, D5: OutputPin, D6: OutputPin, D7: OutputPin, > DisplayDataLines for GpioDataLines { fn write_u8(&mut self, value: u8) -> Result<(), DisplayError> { self.wr.set_low().map_err(|_| DisplayError::BusWriteError)?; let err = self.write_u8_inner(value); self.wr.set_high().ok(); err } } type PioTx = (Tx<(P, SM)>, Channel); pub struct PioDataLines { tx: Option>, } impl PioDataLines { pub fn new( pio: &mut hal::pio::PIO

, sys_freq: HertzU32, wr: impl PinId, d0: impl PinId, sm: UninitStateMachine<(P, SM)>, ch: Channel, ) -> PioDataLines { let d0 = d0.as_dyn().num; let wr = wr.as_dyn().num; let max_pio_clk = HertzU32::MHz(32); let divider = (sys_freq + max_pio_clk - HertzU32::Hz(1)) / max_pio_clk; let program = pio_file!("./src/st7789_parallel.pio"); let program = pio.install(&program.program).unwrap(); let (mut sm, _rx, tx) = PIOBuilder::from_installed_program(program) .out_pins(d0, 8) .side_set_pin_base(wr) .buffers(Buffers::OnlyTx) .pull_threshold(8) .autopull(true) .clock_divisor_fixed_point(divider as u16, 0) .build(sm); sm.set_pindirs([ (d0, PinDir::Output), (d0 + 1, PinDir::Output), (d0 + 2, PinDir::Output), (d0 + 3, PinDir::Output), (d0 + 4, PinDir::Output), (d0 + 5, PinDir::Output), (d0 + 6, PinDir::Output), (d0 + 7, PinDir::Output), (wr, PinDir::Output), ]); sm.set_pins([(wr, PinState::High)]); sm.start(); PioDataLines { tx: Some((tx, ch)) } } } impl DisplayDataLines for PioDataLines { fn flush(&mut self) { if let Some((tx, _)) = self.tx.as_mut() { while !tx.is_empty() {} } } fn write_u8(&mut self, value: u8) -> Result<(), DisplayError> { if let Some((tx, _)) = self.tx.as_mut() { while !tx.write(value as u32) {} Ok(()) } else { Err(DisplayError::BusWriteError) } } fn write_slice(&mut self, data: &[u8]) -> Result<(), DisplayError> { // SAFETY: transmute away lifetime, since we will always wait for DMA completion here. let data: &'static [u8] = unsafe { core::mem::transmute(data) }; let (tx, ch) = self.tx.take().expect("DMA already in use"); let xfer = single_buffer::Config::new(ch, data, WriteBytes(tx)).start(); let (ch, _, WriteBytes(tx)) = xfer.wait(); self.tx = Some((tx, ch)); Ok(()) } } pub struct ParallelDisplayInterface { cs: CS, dc: DC, data_lines: D, } impl ParallelDisplayInterface { pub fn new(cs: CS, dc: DC, data_lines: D) -> ParallelDisplayInterface { ParallelDisplayInterface { cs, dc, data_lines } } } impl WriteOnlyDataCommand for ParallelDisplayInterface { fn send_commands(&mut self, cmds: DataFormat<'_>) -> Result<(), DisplayError> { self.cs.set_low().map_err(|_| DisplayError::CSError)?; self.dc.set_low().map_err(|_| DisplayError::DCError)?; let err = self.data_lines.write_format(cmds); self.data_lines.flush(); err } fn send_data(&mut self, buf: DataFormat<'_>) -> Result<(), DisplayError> { self.dc.set_high().map_err(|_| DisplayError::DCError)?; let err = self.data_lines.write_format(buf); self.data_lines.flush(); err } } pub struct DummyPin; impl OutputPin for DummyPin { type Error = (); fn set_high(&mut self) -> Result<(), Self::Error> { Ok(()) } fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) } } ================================================ FILE: boards/pimoroni-tufty2040/src/st7789_parallel.pio ================================================ .program st7789_parallel .side_set 1 out pins, 32 side 0 nop side 1 ================================================ FILE: boards/pimoroni_badger2040/.gitignore ================================================ # Generated by Cargo # will have compiled files and executables debug/ target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk ================================================ FILE: boards/pimoroni_badger2040/CHANGELOG.md ================================================ # 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.6.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.5.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 ## 0.4.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 ## 0.3.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 ## 0.2.0 - 2022-08-26 ### Changed - Use `rp2040-hal`'s entry function. - Migrate from `embedded-time` to `fugit` - Update to rp2040-hal 0.6.0 ### Removed - Unused dependencies ================================================ FILE: boards/pimoroni_badger2040/Cargo.toml ================================================ [package] name = "pimoroni_badger2040" version = "0.6.0" authors = ["9names", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni_badger2040" description = "Board Support Package for the Pimoroni Badger2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } embedded-hal.workspace = true fugit.workspace = true rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] panic-halt.workspace = true nb.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt", "rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/pimoroni_badger2040/README.md ================================================ # [pimoroni_badger2040] - Board Support for the [Pimoroni Badger2040] You should include this crate if you are writing code that you want to run on a [Pimoroni Badger2040] - a conference-style badge built around an e-paper display and an rp2040 This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Badger2040. [Pimoroni Badger2040]: https://shop.pimoroni.com/products/badger-2040/ [pimoroni_badger2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/pimoroni_badger2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml pimoroni_badger2040 = "0.6.0" ``` In your program, you will need to call `pimoroni_badger2040::Board::take().unwrap()` to create a new `Boards` structure. This will set up all the GPIOs for any on-board devices and configure common clocks. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/pimoroni_badger2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/pimoroni_badger2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` then try repeating the `cargo run` command above. ### [badger_blinky](./examples/badger_blinky.rs) Flashes the Badger2040's activity LED on and off. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can chose either the MIT licence or the Apache-2.0 licence when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific licence. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/pimoroni_badger2040/examples/badger_blinky.rs ================================================ //! # Badger2040 Blinky Example //! //! Blinks the activity LED on a badger2040 board, using an RP2040 Timer in Count-down mode. //! //! See the `Cargo.toml` file for Copyright and licence details. #![no_std] #![no_main] // The macro for our start-up function use pimoroni_badger2040::entry; // GPIO traits use embedded_hal::digital::OutputPin; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use pimoroni_badger2040::hal::pac; use pimoroni_badger2040::hal::Timer; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use pimoroni_badger2040::hal; // A few traits required for using the delay with timer use embedded_hal::delay::DelayNs; #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( pimoroni_badger2040::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = pimoroni_badger2040::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Configure the timer peripheral for our blinky delay let mut timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Set the LED to be an output let mut led_pin = pins.led.into_push_pull_output(); // Blink the LED at 1 Hz loop { // LED on, and wait for 500ms led_pin.set_high().unwrap(); timer.delay_ms(500); // LED off, and wait for 500ms led_pin.set_low().unwrap(); timer.delay_ms(500); } } ================================================ FILE: boards/pimoroni_badger2040/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; pub use hal::pac; #[cfg(feature = "rt")] pub use rp2040_hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; hal::bsp_pins!( Gpio0 { name: gpio0, aliases: { /// UART Function alias for pin [crate::Pins::gpio0]. FunctionUart, PullNone: UartTx } }, Gpio1 { name: gpio1, aliases: { /// UART Function alias for pin [crate::Pins::gpio1]. FunctionUart, PullNone: UartRx } }, Gpio3 { name: i2c_int }, Gpio4 { name: gpio4, aliases: { /// I2C Function alias for pin [crate::Pins::gpio4]. FunctionI2C, PullUp: I2cSda } }, Gpio5 { name: gpio5, aliases: { /// I2C Function alias for pin [crate::Pins::gpio5]. FunctionI2C, PullUp: I2cScl } }, Gpio10 { name: p3v3_en }, Gpio11 { name: sw_down }, Gpio12 { name: sw_a }, Gpio13 { name: sw_b }, Gpio14 { name: sw_c }, Gpio15 { name: sw_up }, Gpio16 { name: miso, aliases: { /// SPI Function alias for pin [crate::Pins::gpio16]. FunctionSpi, PullNone: Miso } }, Gpio17 { name: inky_cs_gpio, aliases: { /// SPI Function alias for pin [crate::Pins::gpio17]. FunctionSpi, PullNone: InkyCs } }, Gpio18 { name: sclk, aliases: { /// SPI Function alias for pin [crate::Pins::gpio18]. FunctionSpi, PullNone: Sclk } }, Gpio19 { name: mosi, aliases: { /// SPI Function alias for pin [crate::Pins::gpio19]. FunctionSpi, PullNone: Mosi } }, Gpio20 { name: inky_dc }, Gpio21 { name: inky_res }, Gpio23 { name: user_sw }, /// GPIO 24 is connected to vbus_detect of the badger2040. Gpio24 { name: vbus_detect }, /// GPIO 25 is connected to activity LED of the badger2040. Gpio25 { name: led }, Gpio26 { name: inky_busy }, Gpio27 { name: vref_power }, Gpio28 { name: vref_1v24 }, /// GPIO 29 is connected to battery monitor of the badger2040 Gpio29 { name: vbat_sense }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/rp-pico/.gitignore ================================================ # Generated by Cargo # will have compiled files and executables debug/ target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk ================================================ FILE: boards/rp-pico/CHANGELOG.md ================================================ # 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.9.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to ws2812-pio 0.8.0 - Update to i2c-pio 0.8.0 - Update to embedded-sdmmc 0.5.0 - Update to embedded-hal 1.0.0 - Update to usbd-hid 0.7.0 - Update to usbd-serial 0.2.1 ## 0.8.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 - Update to i2c-pio 0.7.0 ## 0.7.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 - Update to ws2812-pio 0.6.0 - Update to i2c-pio 0.6.0 - Update to embedded-sdmmc 0.4.0 ## 0.6.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 - Update to i2c-pio 0.5.0 ## 0.5.0 - 2022-08-26 ### Added - `rp2040-e5` feature enabling the workaround for errata 5 on the USB device peripheral. - Support for critical-section 1.0.0 in the examples. - Example for the interpolator ### Changed - Use `rp2040-hal`'s entry function. - Migrate from `embedded-time` to `fugit` - Bump `ws2812-pio` to 0.4.0 - Bump `i2c-pio` to 0.4.0 - Update to rp2040-hal 0.6.0 ### Removed - Unused dependencies ## 0.4.0 - 2022-06-13 ### Changed - Update to rp2040-hal 0.5.0 ## 0.3.0 - 2022-03-11 ### Changed - Update to rp-hal 0.4.0 ## 0.2.0 - 2021-12-23 ### Added - Lots of things! ### Changed - Basically re-written. ## 0.1.3 - 2021-02-03 - Last release outside the [rp-rs] organisation by [@jannic]. [@jannic]: https://github.com/jannic [rp-rs]: https://github.com/rp-rs ================================================ FILE: boards/rp-pico/Cargo.toml ================================================ [package] name = "rp-pico" version = "0.9.0" authors = ["evan ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/rp-pico" description = "Board Support Package for the Raspberry Pi Pico" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } fugit.workspace = true rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true usb-device.workspace = true [dev-dependencies] cortex-m.workspace = true cortex-m-rtic.workspace = true critical-section.workspace = true embedded-graphics.workspace = true embedded-hal.workspace = true embedded-hal-nb.workspace = true embedded-sdmmc.workspace = true hd44780-driver.workspace = true heapless.workspace = true i2c-pio.workspace = true nb.workspace = true panic-halt.workspace = true pio.workspace = true pio-proc.workspace = true rp2040-hal = { workspace = true, features = [ "defmt" ] } smart-leds.workspace = true ssd1306.workspace = true usbd-hid.workspace = true usbd-serial.workspace = true ws2812-pio.workspace = true defmt.workspace = true defmt-rtt.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] [[example]] name = "pico_rtic_monotonic" required-features = ["rp2040-hal/rtic-monotonic"] ================================================ FILE: boards/rp-pico/README.md ================================================ # [rp-pico] - Board Support for the [Raspberry Pi Pico] You should include this crate if you are writing code that you want to run on a [Raspberry Pi Pico] - the original launch PCB for the RP2040 chip. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Pico. [Raspberry Pi Pico]: https://www.raspberrypi.org/products/raspberry-pi-pico/ [rp-pico]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/rp-pico [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml rp-pico = "0.9.0" ``` In your program, you will need to call `rp_pico::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/rp-pico $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/rp-pico $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` then try repeating the `cargo run` command above. ### From Scratch To start a basic project from scratch, create a project using `cargo new project-name`. Within the project directory, run `cargo add rp-pico`, `cargo add cortex-m-rt`, and `cargo add panic-halt`. The first command will add this HAL (Hardware Abstraction Layer), the second is required for the `#[entry]` macro, and _panic-halt_ creates a simple panic function, which just halts. You'll also need to copy the cargo config file from the [repo](https://github.com/rp-rs/rp-hal-boards/blob/main/.cargo/config.toml). It specifies the target and optimizing flags to the linker. You'll also need to copy [_memory.x_](https://github.com/rp-rs/rp-hal-boards/blob/main/memory.x) to your project root. This file tells the linker the flash and RAM layout, so it won't clobber the bootloader or write to an out of bounds memory address. The simplest working example, which does nothing except loop forever, is: ```ignore #![no_std] #![no_main] use rp_pico::entry; use panic_halt as _; #[entry] fn see_doesnt_have_to_be_called_main() -> ! { loop {} } ``` It can be placed in _/src/main.rs_. You can use `cargo run` to compile and install it. **Note**: You won't see any activity since this program does nothing. You can use the examples provided to add more functionality. ### [pico_blinky](./examples/pico_blinky.rs) Flashes the Pico's on-board LED on and off. ### [pico_gpio_in_out](./examples/pico_gpio_in_out.rs) Reads a push button attached to GPIO 15 and drives the on-board LED to match it (i.e. on when pressed, off when not pressed). ### [pico_rtic](./examples/pico_rtic.rs) Demonstrates the use of the [Real-Time Interrupt-driven Concurrency Framework] on the Raspberry Pi Pico. [Real-Time Interrupt-driven Concurrency Framework]: https://rtic.rs ### [pico_countdown_blinky](./examples/pico_countdown_blinky.rs) Another LED blinking example, but using a Timer in count-down mode. ### [pico_pwm_blink](./examples/pico_pwm_blink.rs) Puts out an analog 'triangle wave' on GPIO 25, using the PWM hardware. ### [pico_pwm_servo](./examples/pico_pwm_servo.rs) Demonstrates handling a micro servo, using the PWM hardware. ### [pico_usb_serial](./examples/pico_usb_serial.rs) Creates a USB Serial device on a Pico board. The USB Serial device will print `HelloWorld` on start-up, and then echo any incoming characters - except that any lower-case ASCII characters are converted to the upper-case equivalent. ### [pico_usb_serial_interrupt](./examples/pico_usb_serial_interrupt.rs) Creates a USB Serial device on a Pico board, but demonstrating handling interrupts when USB data arrives. ### [pico_usb_twitchy_mouse](./examples/pico_usb_twitchy_mouse.rs) Demonstrates emulating a USB Human Input Device (HID) Mouse. The mouse cursor will jiggle up and down. ### [pico_spi_sd_card](./examples/pico_spi_sd_card.rs) Example that shows how to use the [embedded_sdmmc crate](https://github.com/rust-embedded-community/embedded-sdmmc-rs) with the Raspberry Pi Pico. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/rp-pico/build.rs ================================================ //! This build script makes sure the linker flag -Tdefmt.x is added //! for the examples. fn main() { println!("cargo:rustc-link-arg-examples=-Tdefmt.x"); } ================================================ FILE: boards/rp-pico/examples/pico_blinky.rs ================================================ //! # Pico Blinky Example //! //! Blinks the LED on a Pico board. //! //! This will blink an LED attached to GP25, which is the pin the Pico uses for //! the on-board LED. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use rp_pico::entry; // GPIO traits use embedded_hal::digital::OutputPin; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use rp_pico::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then blinks the LED in an /// infinite loop. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Set the LED to be an output let mut led_pin = pins.led.into_push_pull_output(); // Blink the LED at 1 Hz loop { led_pin.set_high().unwrap(); delay.delay_ms(500); led_pin.set_low().unwrap(); delay.delay_ms(500); } } // End of file ================================================ FILE: boards/rp-pico/examples/pico_countdown_blinky.rs ================================================ //! # Pico Countdown Blinky Example //! //! Blinks the LED on a Pico board, using an RP2040 Timer in Count-down mode. //! //! This will blink an LED attached to GP25, which is the pin the Pico uses for //! the on-board LED. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use rp_pico::entry; use cortex_m::prelude::*; // GPIO traits use embedded_hal::digital::OutputPin; // Traits for converting integers to amounts of time use fugit::ExtU32; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // Configure the Timer peripheral in count-down mode let timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); let mut count_down = timer.count_down(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let mut led_pin = pins.led.into_push_pull_output(); // Blink the LED at 1 Hz loop { // LED on, and wait for 500ms led_pin.set_high().unwrap(); count_down.start(500.millis()); let _ = nb::block!(count_down.wait()); // LED off, and wait for 500ms led_pin.set_low().unwrap(); count_down.start(500.millis()); let _ = nb::block!(count_down.wait()); } } ================================================ FILE: boards/rp-pico/examples/pico_gpio_in_out.rs ================================================ //! # Pico GPIO In/Out Example //! //! Toggles the LED based on GPIO input. //! //! This will control an LED on GP25 based on a button hooked up to GP15. The //! button should cause the line to be grounded, as the input pin is pulled high //! internally by this example. When the button is pressed, the LED will turn //! off. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use rp_pico::entry; // GPIO traits use embedded_hal::digital::{InputPin, OutputPin}; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then just reads the button /// and sets the LED appropriately. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); // Note - we don't do any clock set-up in this example. The RP2040 will run // at it's default clock speed. // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Our LED output let mut led_pin = pins.led.into_push_pull_output(); // Our button input let mut button_pin = pins.gpio15.into_pull_up_input(); // Run forever, setting the LED according to the button loop { if button_pin.is_low().unwrap() { led_pin.set_high().unwrap(); } else { led_pin.set_low().unwrap(); } } } // End of file ================================================ FILE: boards/rp-pico/examples/pico_hd44780_display.rs ================================================ //! # LCD Display Example //! //! In this example, the RP2040 is configured to drive a small two-line //! alphanumeric LCD using the //! [HD44780](https://crates.io/crates/hd44780-driver) driver. //! //! This example drives the LCD by pushing data out of six GPIO pins, writing //! the data four bits at a time. A faster alternative can be created using //! HD44780::new_8bit() but requiring an additional four GPIO pins. //! //! See the `Cargo.toml` file for Copyright and license details. //! //! ```text //! /--------------------------------------\ //! ____________ | /-------------------------\ | //! | 1 GND|-------+---\ | _|USB|_ | | //! | 2 VDD|-------+---+----/ |1 R 40|-VBUS-o v //! | 3 VS|-------/ | |2 P 39| ||POT|| //! | 4 RS|--\ o-----------GND-|3 38|-GND----------o //! | 5 RW|--+--------/ /------GP2-|4 P 37| //! | 6 EN|--+-\ /--+------GP3-|5 I 36| //! | 7 | | | /--+--+------GP4-|6 C | //! | 8 | | | /--+--+--+------GP5-|7 O | //! | 9 | | \--+--+--+--+---\ |8 | //! | 10 | \----+--+--+--+-\ \-GP6-|9 | //! | 11 D4|-------/ | | | \---GP7-|10 | //! | 12 D5|----------/ | | ......... //! | 13 D6|-------------/ | |20 21| //! | 14 D7|----------------/ """"""" //! .............. //! Symbols: //! - (+) crossing lines, not connected //! - (o) connected lines //! ``` //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use rp_pico::hal::prelude::*; // GPIO traits use embedded_hal::digital::OutputPin; // For LCD display use hd44780_driver::HD44780; /// Entry point to our bare-metal application. /// /// The `#[rp_pico::entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables and the spinlock are initialised. #[rp_pico::entry] fn main() -> ! { // Grab our singleton objects let mut pac = rp_pico::hal::pac::Peripherals::take().unwrap(); let core = rp_pico::hal::pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = rp_pico::hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // The default is to generate a 125 MHz system clock let clocks = rp_pico::hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = rp_pico::hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let mut led_pin = pins.led.into_push_pull_output(); // The delay object lets us wait for specified amounts of time let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // Init pins let rs = pins.gpio7.into_push_pull_output(); let en = pins.gpio6.into_push_pull_output(); let d4 = pins.gpio5.into_push_pull_output(); let d5 = pins.gpio4.into_push_pull_output(); let d6 = pins.gpio3.into_push_pull_output(); let d7 = pins.gpio2.into_push_pull_output(); // LCD Init let mut lcd = HD44780::new_4bit(rs, en, d4, d5, d6, d7, &mut delay).unwrap(); loop { // Clear the screen lcd.reset(&mut delay).unwrap(); lcd.clear(&mut delay).unwrap(); // Write to the top line lcd.write_str("rp-hal on", &mut delay).unwrap(); // Move the cursor lcd.set_cursor_pos(40, &mut delay).unwrap(); // Write more more text lcd.write_str("HD44780! ", &mut delay).unwrap(); let mut char_count = 9; for ch in "move along!.. ".chars() { if char_count > 15 { // Switch autoscroll on lcd.set_autoscroll(true, &mut delay).unwrap(); } led_pin.set_high().unwrap(); lcd.write_char(ch, &mut delay).unwrap(); char_count += 1; delay.delay_us(400_000); //0.4s led_pin.set_low().unwrap(); delay.delay_us(100_000); //0.1s } lcd.set_autoscroll(false, &mut delay).unwrap(); } } ================================================ FILE: boards/rp-pico/examples/pico_i2c_oled_display_ssd1306.rs ================================================ //! # Raspberry Pi Pico (monochome) 128x64 OLED Display with SSD1306 Driver Example //! //! This example assumes you got an 128x64 OLED Display with an SSD1306 driver //! connected to your Raspberry Pi Pico. The +3.3V voltage source of the //! Raspberry Pi Pico will be used, and the output pins 21 and 22 of the board //! (on the lower right). //! //! It will demonstrate how to get an I2C device and use it with the ssd1306 crate. //! Additionally you can also see how to format a number into a string using //! [core::fmt]. //! //! The following diagram will show how things should be connected. //! These displays usually can take 3.3V up to 5V. //! //! ```text //! VCC SCL //! /------------\ /----------\ //! | GND \ / SDA | //! _|USB|_ | /-----\ | | /--------+--\ //! |1 R 40| | / __|__|__|__|___ | | //! |2 P 39| | / | ____________ | | | //! |3 38|- GND --+-/ | |Hello worl| | | | //! |4 P 37| | | |Hello Rust| | | | //! |5 I 36|-+3.3V -/ | |counter: 1| | | | //! |6 C | | | | | | | //! |7 O | | """""""""""" | | | //! | | """"""""""""""" | | //! | | (SSD1306 128x64 OLED Display) | | //! ......... / / //! | | / / //! | 22|-GP17 I2C0 SCL---------------------/ / //! |20 21|-GP16 I2C0 SDA-----------------------/ //! """"""" //! Symbols: //! - (+) crossing lines, not connected //! - (o) connected lines //! ``` //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // For string formatting. use core::fmt::Write; // The macro for our start-up function use rp_pico::entry; // Time handling traits: use fugit::RateExtU32; // Timer for the delay on the display: use embedded_hal::delay::DelayNs; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; // For in the graphics drawing utilities like the font // and the drawing routines: use embedded_graphics::{ mono_font::{ascii::FONT_9X18_BOLD, MonoTextStyleBuilder}, pixelcolor::BinaryColor, prelude::*, text::{Baseline, Text}, }; // The display driver: use ssd1306::{prelude::*, Ssd1306}; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, /// gets a handle on the I2C peripheral, /// initializes the SSD1306 driver, initializes the text builder /// and then draws some text on the display. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Configure two pins as being I²C, not GPIO let sda_pin: hal::gpio::Pin<_, hal::gpio::FunctionI2C, _> = pins.gpio16.reconfigure(); let scl_pin: hal::gpio::Pin<_, hal::gpio::FunctionI2C, _> = pins.gpio17.reconfigure(); // Create the I²C driver, using the two pre-configured pins. This will fail // at compile time if the pins are in the wrong mode, or if this I²C // peripheral isn't available on these pins! let i2c = hal::I2C::i2c0( pac.I2C0, sda_pin, scl_pin, 400.kHz(), &mut pac.RESETS, &clocks.peripheral_clock, ); // Create the I²C display interface: let interface = ssd1306::I2CDisplayInterface::new(i2c); // Create a driver instance and initialize: let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0) .into_buffered_graphics_mode(); display.init().unwrap(); // Create a text style for drawing the font: let text_style = MonoTextStyleBuilder::new() .font(&FONT_9X18_BOLD) .text_color(BinaryColor::On) .build(); let mut timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); let mut count = 0; let mut buf = FmtBuf::new(); loop { buf.reset(); // Format some text into a static buffer: write!(&mut buf, "counter: {}", count).unwrap(); count += 1; // Empty the display: display.clear(); // Draw 3 lines of text: Text::with_baseline("Hello world!", Point::zero(), text_style, Baseline::Top) .draw(&mut display) .unwrap(); Text::with_baseline("Hello Rust!", Point::new(0, 16), text_style, Baseline::Top) .draw(&mut display) .unwrap(); Text::with_baseline(buf.as_str(), Point::new(0, 32), text_style, Baseline::Top) .draw(&mut display) .unwrap(); display.flush().unwrap(); // Wait a bit: timer.delay_ms(500); } } /// This is a very simple buffer to pre format a short line of text /// limited arbitrarily to 64 bytes. struct FmtBuf { buf: [u8; 64], ptr: usize, } impl FmtBuf { fn new() -> Self { Self { buf: [0; 64], ptr: 0, } } fn reset(&mut self) { self.ptr = 0; } fn as_str(&self) -> &str { core::str::from_utf8(&self.buf[0..self.ptr]).unwrap() } } impl core::fmt::Write for FmtBuf { fn write_str(&mut self, s: &str) -> core::fmt::Result { let rest_len = self.buf.len() - self.ptr; let len = if rest_len < s.len() { rest_len } else { s.len() }; self.buf[self.ptr..(self.ptr + len)].copy_from_slice(&s.as_bytes()[0..len]); self.ptr += len; Ok(()) } } // End of file ================================================ FILE: boards/rp-pico/examples/pico_i2c_pio.rs ================================================ //! # Pico I2C PIO Example //! //! Reads the temperature from an LM75B //! //! This read over I2C the temerature from an LM75B temperature sensor wired on pins 20 and 21 //! using the PIO peripheral as an I2C bus controller. //! The pins used for the I2C can be remapped to any other pin available to the PIO0 peripheral. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The trait used by formatting macros like write! and writeln! use core::fmt::Write as FmtWrite; // The macro for our start-up function use rp_pico::entry; // I2C HAL traits & Types. use embedded_hal::i2c::{I2c, Operation}; // Time handling traits use fugit::RateExtU32; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use rp_pico::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; // UART related types use hal::uart::{DataBits, StopBits, UartConfig}; /// Prints the temperature received from the sensor fn print_temperature(serial: &mut impl FmtWrite, temp: [u8; 2]) { let temp_i16 = i16::from_be_bytes(temp) >> 5; let temp_f32 = f32::from(temp_i16) * 0.125; // Write formatted output but ignore any error. let _ = writeln!(serial, "Temperature: {:0.2}°C", temp_f32); } /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, reads the temperature from /// the attached LM75B using PIO0. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let uart_pins = ( // UART TX (characters sent from RP2040) on pin 1 (GPIO0) pins.gpio0.into_function::(), // UART RX (characters received by RP2040) on pin 2 (GPIO1) pins.gpio1.into_function::(), ); let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS) .enable( UartConfig::new(115_200.Hz(), DataBits::Eight, None, StopBits::One), clocks.peripheral_clock.freq(), ) .unwrap(); let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut i2c_pio = i2c_pio::I2C::new( &mut pio, pins.gpio20, pins.gpio21, sm0, 100.kHz(), clocks.system_clock.freq(), ); let mut temp = [0; 2]; i2c_pio .read(0x48u8, &mut temp) .expect("Failed to read from the peripheral"); print_temperature(&mut uart, temp); i2c_pio .write(0x48u8, &[0]) .expect("Failed to write to the peripheral"); let mut temp = [0; 2]; i2c_pio .read(0x48u8, &mut temp) .expect("Failed to read from the peripheral"); print_temperature(&mut uart, temp); let mut config = [0]; let mut thyst = [0; 2]; let mut tos = [0; 2]; let mut temp = [0; 2]; let mut operations = [ Operation::Write(&[1]), Operation::Read(&mut config), Operation::Write(&[2]), Operation::Read(&mut thyst), Operation::Write(&[3]), Operation::Read(&mut tos), Operation::Write(&[0]), Operation::Read(&mut temp), ]; i2c_pio .transaction(0x48u8, &mut operations) .expect("Failed to run all operations"); print_temperature(&mut uart, temp); loop { cortex_m::asm::wfi(); } } // End of file ================================================ FILE: boards/rp-pico/examples/pico_interpolator.rs ================================================ //! # Pico Interpolator Example //! //! Example demonstrating the usage of the hardware interpolator. //! //! Runs several test programs, outputs the result on LEDs. //! Green led for successful test connects to GPIO3. //! Red led for unsuccessful test connects to GPIO4. //! In case of failure, the system LED blinks the number of the test. //! In case of success, the system LED stays lit. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use rp_pico::entry; // GPIO traits use embedded_hal::digital::OutputPin; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; // Pull in any important traits use rp_pico::hal::prelude::*; use rp_pico::hal::sio::{Interp, Interp0, Interp1, Lane, LaneCtrl}; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then just reads the button /// and sets the LED appropriately. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // The single-cycle I/O block controls our GPIO pins let mut sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Our LED outputs let mut system_led_pin = pins.led.into_push_pull_output(); let mut green_led_pin = pins.gpio3.into_push_pull_output(); let mut red_led_pin = pins.gpio4.into_push_pull_output(); system_led_pin.set_low().unwrap(); green_led_pin.set_low().unwrap(); red_led_pin.set_low().unwrap(); let mut choose_led = |index: u32, result: bool| { if result { // blink the green led once to indicate success green_led_pin.set_high().unwrap(); delay.delay_ms(500); green_led_pin.set_low().unwrap(); delay.delay_ms(500); } else { // turn the red led on to indicate failure // and blink the on board led to indicate which test failed, looping forever red_led_pin.set_high().unwrap(); loop { for _ in 0..index { system_led_pin.set_high().unwrap(); delay.delay_ms(200); system_led_pin.set_low().unwrap(); delay.delay_ms(200); } delay.delay_ms(1000); } } }; // Run forever, setting the LED according to the button choose_led(1, multiplication_table(&mut sio.interp0)); choose_led(2, moving_mask(&mut sio.interp0)); choose_led(3, cross_lanes(&mut sio.interp0)); choose_led(4, simple_blend1(&mut sio.interp0)); choose_led(5, simple_blend2(&mut sio.interp0)); choose_led(6, clamp(&mut sio.interp1)); choose_led(7, texture_mapping(&mut sio.interp0)); // turn the on board led on to indicate testing is done system_led_pin.set_high().unwrap(); loop { delay.delay_ms(1000); } } fn multiplication_table(interp: &mut Interp0) -> bool { //get the default configuration that just keep adding base into accum let config = LaneCtrl::new(); //write the configuration to the hardware. interp.get_lane0().set_ctrl(config.encode()); //set the accumulator to 0 and the base to 9 interp.get_lane0().set_accum(0); interp.get_lane0().set_base(9); //the expected output for comparison let expected = [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]; for i in expected { //returns the value of accum + base and sets accum to the same value let value = interp.get_lane0().pop(); if value != i { return false; //inform that the interpolator did not return the expected value } } true } fn moving_mask(interp: &mut Interp0) -> bool { //get the default configuration that just keep adding base into accum let mut config = LaneCtrl::new(); interp.get_lane0().set_accum(0x1234ABCD); let expected = [ 0x0000_000D, 0x0000_00C0, 0x0000_0B00, 0x0000_A000, 0x0004_0000, 0x0030_0000, 0x0200_0000, 0x1000_0000, ]; for i in 0..8 { // LSB, then MSB. These are inclusive, so 0,31 means "the entire 32 bit register" config.mask_lsb = i * 4; config.mask_msb = i * 4 + 3; interp.get_lane0().set_ctrl(config.encode()); // Reading read_raw() returns the lane data // after shifting, masking and sign extending, without adding base if interp.get_lane0().read_raw() != expected[i as usize] { return false; } } let signed_expected = [ 0xFFFF_FFFD, 0xFFFF_FFC0, 0xFFFF_FB00, 0xFFFF_A000, 0x0004_0000, 0x0030_0000, 0x0200_0000, 0x1000_0000, ]; config.signed = true; for i in 0..8 { config.mask_lsb = i * 4; config.mask_msb = i * 4 + 3; interp.get_lane0().set_ctrl(config.encode()); if interp.get_lane0().read_raw() != signed_expected[i as usize] { return false; } } true } fn cross_lanes(interp: &mut Interp0) -> bool { // this configuration will at the time of pop() // when applied to lane0 : set lane0 accumulator to the result from lane1 // when applied to lane1 : set lane1 accumulator to the result from lane0 let config = LaneCtrl { cross_result: true, ..LaneCtrl::new() }; let encoded_config = config.encode(); // each lane is used through an accessor, // as lanes mutate each other, they can not be borrowed at the same time interp.get_lane0().set_ctrl(encoded_config); interp.get_lane1().set_ctrl(encoded_config); interp.get_lane0().set_accum(123); interp.get_lane1().set_accum(456); // lane0 will add 1 to its result, lane1 will add nothing interp.get_lane0().set_base(1); interp.get_lane1().set_base(0); let expected = [ (124, 456), (457, 124), (125, 457), (458, 125), (126, 458), (459, 126), (127, 459), (460, 127), (128, 460), (461, 128), ]; for i in expected { if i != (interp.get_lane0().peek(), interp.get_lane1().pop()) { return false; } } true } fn simple_blend1(interp: &mut Interp0) -> bool { let config = LaneCtrl { blend: true, ..LaneCtrl::new() }; //enable blend mode interp.get_lane0().set_ctrl(config.encode()); //make sure the default configuration is in lane1 as the value may be shifted and masked. interp.get_lane1().set_ctrl(LaneCtrl::new().encode()); //set the minimum value for interp.get_lane0().set_accum(0) 0/256 interp.get_lane0().set_base(500); //set the maximum value which is inaccessible // as the blend is done between 0/256 and 255/256 interp.get_lane1().set_base(1000); let expected = [500, 582, 666, 748, 832, 914, 998]; for i in 0..=6 { interp.get_lane1().set_accum(255 * i / 6); if expected[i as usize] != interp.get_lane1().peek() { return false; } } true } fn simple_blend2(interp: &mut Interp0) -> bool { let config = LaneCtrl { blend: true, ..LaneCtrl::new() }; //enable blend mode interp.get_lane0().set_ctrl(config.encode()); interp.get_lane0().set_base((-1000i32) as u32); interp.get_lane1().set_base(1000); let mut config1 = LaneCtrl { signed: true, ..LaneCtrl::new() }; interp.get_lane1().set_ctrl(config1.encode()); let expected_signed = [-1000, -672, -336, -8, 328, 656, 992]; for i in 0..=6 { // write a value between 0 and 256 (exclusive) interp.get_lane1().set_accum(255 * i / 6); // reads it as a value between -1000 and 1000 (exclusive) if interp.get_lane1().peek() as i32 != expected_signed[i as usize] { return false; } } config1.signed = false; interp.get_lane1().set_ctrl(config1.encode()); let expected_unsigned = [ 0xfffffc18, 0xd5fffd60, 0xaafffeb0, 0x80fffff8, 0x56000148, 0x2c000290, 0x010003e0, ]; for i in 0..=6 { interp.get_lane1().set_accum(255 * i / 6); // reads a value between 4294966296 and 1000 if interp.get_lane1().peek() != expected_unsigned[i as usize] { return false; } } true } ///Divides by 4 and clamp the value between 0 and 255 inclusive fn clamp(interp: &mut Interp1) -> bool { // Enables Clamp ONLY AVAILABLE ON Interp1 // shift two bits to the right and mask the two most significant bits // because sign extension is made after the mask let config = LaneCtrl { clamp: true, shift: 2, mask_lsb: 0, mask_msb: 29, signed: true, ..LaneCtrl::new() }; interp.get_lane0().set_ctrl(config.encode()); //set minimum value of result interp.get_lane0().set_base(0); //set maximum value of result interp.get_lane1().set_base(255); let values: [(i32, i32); 9] = [ (-1024, 0), (-768, 0), (-512, 0), (-256, 0), (0, 0), (256, 64), (512, 128), (768, 192), (1024, 255), ]; for (arg, result) in values { interp.get_lane0().set_accum(arg as u32); if result != interp.get_lane0().peek() as i32 { return false; } } true } fn texture_mapping(interp: &mut Interp0) -> bool { #[rustfmt::skip] let texture: [u8;16] = [ 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, 0x20, 0x21, 0x22, 0x23, 0x30, 0x31, 0x32, 0x33, ]; // the position will be given in fixed point with 16 bits // fractional part let uv_fractional_bits = 16; let texture_width_bits = 2; let texture_height_bits = 2; // bits // 3322222222221111 1111110000000000 // 1098765432109876 5432109876543210 // accum0 u axis coordinate xx xxxxxxxxxxxxxxxx 18 bits // after shift and mask xx // accum1 v axis xx xxxxxxxxxxxxxxxx 18 bits // after shift and mask xx // add_raw make the interpolator increment the accumulator // with the base value without masking or shifting let config0 = LaneCtrl { add_raw: true, shift: uv_fractional_bits, mask_lsb: 0, mask_msb: texture_width_bits - 1, ..LaneCtrl::new() }; interp.get_lane0().set_ctrl(config0.encode()); let config1 = LaneCtrl { add_raw: true, shift: uv_fractional_bits - texture_width_bits, mask_lsb: texture_width_bits, mask_msb: texture_width_bits + texture_height_bits - 1, ..LaneCtrl::new() }; interp.get_lane1().set_ctrl(config1.encode()); interp.set_base(0); // set starting position to 0x0 // will move 1/2 a pixel horizontally // and 1/3 a pixel vertically per call to pop() interp.get_lane0().set_accum(0); interp.get_lane0().set_base(65536 / 2); interp.get_lane1().set_accum(0); interp.get_lane1().set_base(65536 / 3); let expected = [ 0x00, 0x00, 0x01, 0x01, 0x12, 0x12, 0x13, 0x23, 0x20, 0x20, 0x31, 0x31, ]; for i in expected { if i != texture[interp.pop() as usize] { return false; } } // reset the starting position interp.get_lane0().set_accum(0); interp.get_lane1().set_accum(0); interp.set_base(texture.as_ptr() as u32); for i in expected { // This is unsafe and should be done extremely carefully // remember to follow memory alignment, // reading or writing an unaligned address will crash if i != unsafe { *(interp.pop() as *const u8) } { return false; } } true } // End of file ================================================ FILE: boards/rp-pico/examples/pico_pio_pwm.rs ================================================ //! # Pico PIO PWM Blink Example //! //! Fades the LED on a Pico board using the PIO peripheral with an pwm program. //! //! This will fade in the LED attached to GP25, which is the pin the Pico //! uses for the on-board LED. //! //! This example uses a few advance pio tricks such as side setting pins and instruction injection. //! //! See the `Cargo.toml` file for Copyright and license details. Except for the pio program which is subject to a different license. #![no_std] #![no_main] use defmt::info; use defmt_rtt as _; // The macro for our start-up function use rp_pico::entry; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use rp_pico::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; // Import pio crates use hal::pio::{PIOBuilder, Running, StateMachine, Tx, ValidStateMachine, SM0}; use pio::{Instruction, InstructionOperands, OutDestination}; use pio_proc::pio_file; /// Set pio pwm period /// /// This uses a sneaky trick to set a second value besides the duty cycle. /// We first write a value to the tx fifo. But instead of the normal instructions we /// have stopped the state machine and inject our own instructions that move the written value to the ISR. fn pio_pwm_set_period( sm: StateMachine<(hal::pac::PIO0, SM0), Running>, tx: &mut Tx, period: u32, ) -> StateMachine<(hal::pac::PIO0, SM0), Running> { // To make sure the inserted instructions actually use our newly written value // We first busy loop to empty the queue. (Which typically should be the case) while !tx.is_empty() {} let mut sm = sm.stop(); tx.write(period); sm.exec_instruction(Instruction { operands: InstructionOperands::PULL { if_empty: false, block: false, }, delay: 0, side_set: None, }); sm.exec_instruction(Instruction { operands: InstructionOperands::OUT { destination: OutDestination::ISR, bit_count: 32, }, delay: 0, side_set: None, }); sm.start() } /// Set pio pwm duty cycle /// /// The value written to the TX FIFO is used directly by the normal pio program fn pio_pwm_set_level(tx: &mut Tx, level: u32) { // Write duty cycle to TX Fifo tx.write(level); } /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then fades the LED in an /// infinite loop. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); let (mut pio0, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); // Create a pio program let program = pio_file!("./examples/pwm.pio", select_program("pwm"),); let installed = pio0.install(&program.program).unwrap(); // Set gpio25 to pio let _led: hal::gpio::Pin<_, hal::gpio::FunctionPio0, hal::gpio::PullNone> = pins.led.reconfigure(); let led_pin_id = 25; // Build the pio program and set pin both for set and side set! // We are running with the default divider which is 1 (max speed) let (mut sm, _, mut tx) = PIOBuilder::from_installed_program(installed) .set_pins(led_pin_id, 1) .side_set_pin_base(led_pin_id) .build(sm0); // Set pio pindir for gpio25 sm.set_pindirs([(led_pin_id, hal::pio::PinDir::Output)]); // Start state machine let sm = sm.start(); // Set period pio_pwm_set_period(sm, &mut tx, u16::MAX as u32 - 1); // Loop forever and adjust duty cycle to make te led brighter let mut level = 0; loop { info!("Level = {}", level); pio_pwm_set_level(&mut tx, level * level); level = (level + 1) % 256; delay.delay_ms(10); } } // End of file ================================================ FILE: boards/rp-pico/examples/pico_pwm_blink.rs ================================================ //! # Pico PWM Blink Example //! //! Fades the LED on a Pico board using the PWM peripheral. //! //! This will fade in/out the LED attached to GP25, which is the pin the Pico //! uses for the on-board LED. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use rp_pico::entry; // GPIO traits use embedded_hal::pwm::SetDutyCycle; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use rp_pico::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; // The minimum PWM value (i.e. LED brightness) we want const LOW: u16 = 0; // The maximum PWM value (i.e. LED brightness) we want const HIGH: u16 = 25000; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then fades the LED in an /// infinite loop. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // Init PWMs let mut pwm_slices = hal::pwm::Slices::new(pac.PWM, &mut pac.RESETS); // Configure PWM4 let pwm = &mut pwm_slices.pwm4; pwm.set_ph_correct(); pwm.enable(); // Output channel B on PWM4 to the LED pin let channel = &mut pwm.channel_b; channel.output_to(pins.led); // Infinite loop, fading LED up and down loop { // Ramp brightness up for i in (LOW..=HIGH).skip(100) { delay.delay_us(8); let _ = channel.set_duty_cycle(i); } // Ramp brightness down for i in (LOW..=HIGH).rev().skip(100) { delay.delay_us(8); let _ = channel.set_duty_cycle(i); } delay.delay_ms(500); } } // End of file ================================================ FILE: boards/rp-pico/examples/pico_pwm_servo.rs ================================================ //! # Pico PWM Micro Servo Example //! //! Moves the micro servo on a Pico board using the PWM peripheral. //! //! This will move in different positions the motor attached to GP1. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] use cortex_m::prelude::*; // GPIO traits use embedded_hal::pwm::SetDutyCycle; // Traits for converting integers to amounts of time use fugit::ExtU32; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; /// Entry point to our bare-metal application. /// /// The `#[rp2040_hal::entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables and the spinlock are initialised. /// /// The function configures the RP2040 peripherals, then fades the LED in an /// infinite loop. #[rp2040_hal::entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // Configure the Timer peripheral in count-down mode let timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); let mut count_down = timer.count_down(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Init PWMs let mut pwm_slices = hal::pwm::Slices::new(pac.PWM, &mut pac.RESETS); // Configure PWM0 let pwm = &mut pwm_slices.pwm0; pwm.set_ph_correct(); pwm.set_div_int(20u8); // 50 hz pwm.enable(); // Output channel B on PWM0 to the GPIO1 pin let channel = &mut pwm.channel_b; channel.output_to(pins.gpio1); // Infinite loop, moving micro servo from one position to another. // You may need to adjust the pulse width since several servos from // different manufacturers respond differently. loop { // move to 0° let _ = channel.set_duty_cycle(2500); count_down.start(400.millis()); let _ = nb::block!(count_down.wait()); // 0° to 90° let _ = channel.set_duty_cycle(3930); count_down.start(400.millis()); let _ = nb::block!(count_down.wait()); // 90° to 180° let _ = channel.set_duty_cycle(7860); count_down.start(400.millis()); let _ = nb::block!(count_down.wait()); // 180° to 90° let _ = channel.set_duty_cycle(3930); count_down.start(400.millis()); let _ = nb::block!(count_down.wait()); } } // End of file ================================================ FILE: boards/rp-pico/examples/pico_rtic.rs ================================================ #![no_std] #![no_main] use panic_halt as _; #[rtic::app(device = rp_pico::hal::pac, peripherals = true)] mod app { use embedded_hal::digital::OutputPin; use fugit::MicrosDurationU32; use rp_pico::{ hal::{self, clocks::init_clocks_and_plls, timer::Alarm, watchdog::Watchdog, Sio}, XOSC_CRYSTAL_FREQ, }; const SCAN_TIME_US: MicrosDurationU32 = MicrosDurationU32::secs(1); #[shared] struct Shared { timer: hal::Timer, alarm: hal::timer::Alarm0, led: hal::gpio::Pin< hal::gpio::bank0::Gpio25, hal::gpio::FunctionSioOutput, hal::gpio::PullNone, >, } #[local] struct Local {} #[init] fn init(c: init::Context) -> (Shared, Local, init::Monotonics) { // Soft-reset does not release the hardware spinlocks // Release them now to avoid a deadlock after debug or watchdog reset unsafe { hal::sio::spinlock_reset(); } let mut resets = c.device.RESETS; let mut watchdog = Watchdog::new(c.device.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, c.device.XOSC, c.device.CLOCKS, c.device.PLL_SYS, c.device.PLL_USB, &mut resets, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(c.device.SIO); let pins = rp_pico::Pins::new( c.device.IO_BANK0, c.device.PADS_BANK0, sio.gpio_bank0, &mut resets, ); let mut led = pins.led.reconfigure(); led.set_low().unwrap(); let mut timer = hal::Timer::new(c.device.TIMER, &mut resets, &clocks); let mut alarm = timer.alarm_0().unwrap(); let _ = alarm.schedule(SCAN_TIME_US); alarm.enable_interrupt(); (Shared { timer, alarm, led }, Local {}, init::Monotonics()) } #[task( binds = TIMER_IRQ_0, priority = 1, shared = [timer, alarm, led], local = [tog: bool = true], )] fn timer_irq(mut c: timer_irq::Context) { if *c.local.tog { c.shared.led.lock(|l| l.set_high().unwrap()); } else { c.shared.led.lock(|l| l.set_low().unwrap()); } *c.local.tog = !*c.local.tog; let mut alarm = c.shared.alarm; (alarm).lock(|a| { a.clear_interrupt(); let _ = a.schedule(SCAN_TIME_US); }); } } ================================================ FILE: boards/rp-pico/examples/pico_rtic_monotonic.rs ================================================ #![no_std] #![no_main] use panic_halt as _; #[rtic::app(device = rp_pico::hal::pac, peripherals = true, dispatchers = [I2C0_IRQ])] mod app { use embedded_hal::digital::OutputPin; use fugit::ExtU64; use rp_pico::{ hal::{ self, clocks::init_clocks_and_plls, timer::{monotonic::Monotonic, Alarm0}, watchdog::Watchdog, Sio, }, XOSC_CRYSTAL_FREQ, }; #[shared] struct Shared { led: hal::gpio::Pin< hal::gpio::bank0::Gpio25, hal::gpio::FunctionSioOutput, hal::gpio::PullNone, >, } #[monotonic(binds = TIMER_IRQ_0, default = true)] type MyMono = Monotonic; #[local] struct Local {} #[init] fn init(c: init::Context) -> (Shared, Local, init::Monotonics) { // Soft-reset does not release the hardware spinlocks // Release them now to avoid a deadlock after debug or watchdog reset unsafe { hal::sio::spinlock_reset(); } let mut resets = c.device.RESETS; let mut watchdog = Watchdog::new(c.device.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, c.device.XOSC, c.device.CLOCKS, c.device.PLL_SYS, c.device.PLL_USB, &mut resets, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(c.device.SIO); let pins = rp_pico::Pins::new( c.device.IO_BANK0, c.device.PADS_BANK0, sio.gpio_bank0, &mut resets, ); let mut led = pins.led.reconfigure(); led.set_low().unwrap(); let mut timer = hal::Timer::new(c.device.TIMER, &mut resets, &clocks); let alarm = timer.alarm_0().unwrap(); blink_led::spawn_after(500.millis()).unwrap(); ( Shared { led }, Local {}, init::Monotonics(Monotonic::new(timer, alarm)), ) } #[task( shared = [led], local = [tog: bool = true], )] fn blink_led(mut c: blink_led::Context) { if *c.local.tog { c.shared.led.lock(|l| l.set_high().unwrap()); } else { c.shared.led.lock(|l| l.set_low().unwrap()); } *c.local.tog = !*c.local.tog; blink_led::spawn_after(500.millis()).unwrap(); } } ================================================ FILE: boards/rp-pico/examples/pico_spi_sd_card.rs ================================================ //! # Pico SD Card Example //! //! Reads and writes a file from/to the SD Card that is formatted in FAT32. //! This example uses the SPI0 device of the Raspberry Pi Pico on the //! pins 4,5,6 and 7. If you don't use an external 3.3V power source, //! you can connect the +3.3V output on pin 36 to the SD card. //! //! SD Cards up to 2TB are supported by the `embedded_sdmmc` crate. //! I've tested this with a 64GB micro SD card. //! //! You need to format the card with an regular old FAT32 filesystem //! and also make sure the first partition has the right type. This is how your //! `fdisk` output should look like: //! //! ```text //! fdisk /dev/sdj //! //! Welcome to fdisk (util-linux 2.34). //! Changes will remain in memory only, until you decide to write them. //! Be careful before using the write command. //! //! Command (m for help): Disk /dev/sdj: //! 59,49 GiB, 63864569856 bytes, 124735488 sectors //! Disk model: SD/MMC/MS/MSPRO //! Units: sectors of 1 * 512 = 512 bytes //! Sector size (logical/physical): 512 bytes / 512 bytes //! I/O size (minimum/optimal): 512 bytes / 512 bytes //! Disklabel type: dos //! Disk identifier: 0x00000000 //! //! Device Boot Start End Sectors Size Id Type //! /dev/sdj1 2048 124735487 124733440 59,5G c W95 FAT32 (LBA) //! ``` //! //! The important bit here is the _Type_ with `W95 FAT32 (LBA)`, other types //! are rejected by the `embedded_sdmmc` filesystem implementation. //! //! Formatting the partition can be done using `mkfs.fat`: //! //! $ mkfs.fat /dev/sdj1 //! //! The example can either be used with a probe to receive debug output //! and also the LED is used as status output. There are different blinking //! patterns. //! //! For every successful stage in the example the LED will blink long once. //! If everything is successful (9 long blink signals), the example will go //! into a loop and either blink in a _"short long"_ or _"short short long"_ pattern. //! //! If there are 4 different error patterns, all with short blinking pulses: //! //! - **3 short blink (in a loop)**: Card size could not be retrieved. //! - **4 short blink (in a loop)**: Error getting volume/partition 0. //! - **5 short blink (in a loop)**: Error opening root directory. //! - **6 short blink (in a loop)**: Could not open file 'O.TST'. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use rp_pico::entry; // info!() and error!() macros for printing information to the debug output use defmt::*; use defmt_rtt as _; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use rp_pico::hal::prelude::*; // Embed the `Hz` function/trait: use fugit::RateExtU32; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // Import the SPI abstraction: use rp_pico::hal::spi; // Import the GPIO abstraction: use rp_pico::hal::gpio; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; // Link in the embedded_sdmmc crate. // The `SdMmcSpi` is used for block level access to the card. // And the `VolumeManager` gives access to the FAT filesystem functions. use embedded_sdmmc::{SdCard, TimeSource, Timestamp, VolumeIdx, VolumeManager}; // Get the file open mode enum: use embedded_sdmmc::filesystem::Mode; use embedded_hal::delay::DelayNs; use rp2040_hal::Timer; /// A dummy timesource, which is mostly important for creating files. #[derive(Default)] pub struct DummyTimesource(); impl TimeSource for DummyTimesource { // In theory you could use the RTC of the rp2040 here, if you had // any external time synchronizing device. fn get_timestamp(&self) -> Timestamp { Timestamp { year_since_1970: 0, zero_indexed_month: 0, zero_indexed_day: 0, hours: 0, minutes: 0, seconds: 0, } } } // Setup some blinking codes: const BLINK_OK_LONG: [u8; 1] = [8u8]; const BLINK_OK_SHORT_LONG: [u8; 4] = [1u8, 0u8, 6u8, 0u8]; const BLINK_OK_SHORT_SHORT_LONG: [u8; 6] = [1u8, 0u8, 1u8, 0u8, 6u8, 0u8]; const BLINK_ERR_3_SHORT: [u8; 6] = [1u8, 0u8, 1u8, 0u8, 1u8, 0u8]; const BLINK_ERR_4_SHORT: [u8; 8] = [1u8, 0u8, 1u8, 0u8, 1u8, 0u8, 1u8, 0u8]; const BLINK_ERR_5_SHORT: [u8; 10] = [1u8, 0u8, 1u8, 0u8, 1u8, 0u8, 1u8, 0u8, 1u8, 0u8]; const BLINK_ERR_6_SHORT: [u8; 12] = [1u8, 0u8, 1u8, 0u8, 1u8, 0u8, 1u8, 0u8, 1u8, 0u8, 1u8, 0u8]; fn blink_signals( pin: &mut dyn embedded_hal::digital::OutputPin, delay: &mut dyn DelayNs, sig: &[u8], ) { for bit in sig { if *bit != 0 { pin.set_high().unwrap(); } else { pin.set_low().unwrap(); } let length = if *bit > 0 { *bit } else { 1 }; for _ in 0..length { delay.delay_ms(100); } } pin.set_low().unwrap(); delay.delay_ms(500); } fn blink_signals_loop( pin: &mut dyn embedded_hal::digital::OutputPin, delay: &mut dyn DelayNs, sig: &[u8], ) -> ! { loop { blink_signals(pin, delay, sig); delay.delay_ms(1000); } } #[entry] fn main() -> ! { info!("Program start"); // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let _core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Set the LED to be an output let mut led_pin = pins.led.into_push_pull_output(); // Set up our SPI pins into the correct mode let spi_sclk: gpio::Pin<_, gpio::FunctionSpi, gpio::PullNone> = pins.gpio2.reconfigure(); let spi_mosi: gpio::Pin<_, gpio::FunctionSpi, gpio::PullNone> = pins.gpio3.reconfigure(); let spi_miso: gpio::Pin<_, gpio::FunctionSpi, gpio::PullUp> = pins.gpio4.reconfigure(); let spi_cs = pins.gpio5.into_push_pull_output(); // Create the SPI driver instance for the SPI0 device let spi = spi::Spi::<_, _, _, 8>::new(pac.SPI0, (spi_mosi, spi_miso, spi_sclk)); // Exchange the uninitialised SPI driver for an initialised one let spi = spi.init( &mut pac.RESETS, clocks.peripheral_clock.freq(), 400.kHz(), // card initialization happens at low baud rate embedded_hal::spi::MODE_0, ); let mut delay = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); info!("Initialize SPI SD/MMC data structures..."); let sdcard = SdCard::new(spi, spi_cs, delay); let mut volume_mgr = VolumeManager::new(sdcard, DummyTimesource::default()); blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); info!("Init SD card controller and retrieve card size..."); match volume_mgr.device().num_bytes() { Ok(size) => info!("card size is {} bytes", size), Err(e) => { error!("Error retrieving card size: {}", defmt::Debug2Format(&e)); blink_signals_loop(&mut led_pin, &mut delay, &BLINK_ERR_3_SHORT); } } blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); // Now that the card is initialized, clock can go faster volume_mgr .device() .spi(|spi| spi.set_baudrate(clocks.peripheral_clock.freq(), 16.MHz())); info!("Getting Volume 0..."); let mut volume = match volume_mgr.get_volume(VolumeIdx(0)) { Ok(v) => v, Err(e) => { error!("Error getting volume 0: {}", defmt::Debug2Format(&e)); blink_signals_loop(&mut led_pin, &mut delay, &BLINK_ERR_4_SHORT); } }; blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); // After we have the volume (partition) of the drive we got to open the // root directory: let dir = match volume_mgr.open_root_dir(&volume) { Ok(dir) => dir, Err(e) => { error!("Error opening root dir: {}", defmt::Debug2Format(&e)); blink_signals_loop(&mut led_pin, &mut delay, &BLINK_ERR_5_SHORT); } }; info!("Root directory opened!"); blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); // This shows how to iterate through the directory and how // to get the file names (and print them in hope they are UTF-8 compatible): volume_mgr .iterate_dir(&volume, &dir, |ent| { info!( "/{}.{}", core::str::from_utf8(ent.name.base_name()).unwrap(), core::str::from_utf8(ent.name.extension()).unwrap() ); }) .unwrap(); blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); let mut successful_read = false; // Next we going to read a file from the SD card: if let Ok(mut file) = volume_mgr.open_file_in_dir(&mut volume, &dir, "O.TST", Mode::ReadOnly) { let mut buf = [0u8; 32]; let read_count = volume_mgr.read(&volume, &mut file, &mut buf).unwrap(); volume_mgr.close_file(&volume, file).unwrap(); if read_count >= 2 { info!("READ {} bytes: {}", read_count, buf); // If we read what we wrote before the last reset, // we set a flag so that the success blinking at the end // changes it's pattern. if buf[0] == 0x42 && buf[1] == 0x1E { successful_read = true; } } } blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); match volume_mgr.open_file_in_dir(&mut volume, &dir, "O.TST", Mode::ReadWriteCreateOrTruncate) { Ok(mut file) => { volume_mgr .write(&mut volume, &mut file, b"\x42\x1E") .unwrap(); volume_mgr.close_file(&volume, file).unwrap(); } Err(e) => { error!("Error opening file 'O.TST': {}", defmt::Debug2Format(&e)); blink_signals_loop(&mut led_pin, &mut delay, &BLINK_ERR_6_SHORT); } } volume_mgr.free(); blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); if successful_read { info!("Successfully read previously written file 'O.TST'"); } else { info!("Could not read file, which is ok for the first run."); info!("Reboot the pico!"); } loop { if successful_read { blink_signals(&mut led_pin, &mut delay, &BLINK_OK_SHORT_SHORT_LONG); } else { blink_signals(&mut led_pin, &mut delay, &BLINK_OK_SHORT_LONG); } delay.delay_ms(1000); } } ================================================ FILE: boards/rp-pico/examples/pico_uart_irq_buffer.rs ================================================ //! # UART IRQ TX Buffer Example //! //! This application demonstrates how to use the UART Driver to talk to a //! serial connection. In this example, the IRQ owns the UART and you cannot //! do any UART access from the main thread. You can, however, write to a //! static queue, and have the queue contents transferred to the UART under //! interrupt. //! //! The pinouts are: //! //! * GPIO 0 - UART TX (out of the RP2040) //! * GPIO 1 - UART RX (in to the RP2040) //! * GPIO 25 - An LED we can blink (active high) //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] #![allow(static_mut_refs)] // These are the traits we need from Embedded HAL to treat our hardware // objects as generic embedded devices. use embedded_hal::digital::OutputPin; use embedded_hal_nb::serial::Write as UartWrite; // The writeln! trait. use core::fmt::Write; // We also need this for the 'Delay' object to work. use rp2040_hal::Clock; // The macro for our start-up function use rp_pico::entry; // Time handling traits use fugit::RateExtU32; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Alias for our HAL crate use rp2040_hal as hal; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use hal::pac; // Our interrupt macro use pac::interrupt; // Some short-cuts to useful types use core::cell::RefCell; use critical_section::Mutex; use heapless::spsc::Queue; /// Import the GPIO pins we use use hal::gpio::bank0::{Gpio0, Gpio1}; // UART related types use hal::uart::{DataBits, StopBits, UartConfig}; /// Alias the type for our UART pins to make things clearer. type UartPins = ( hal::gpio::Pin, hal::gpio::Pin, ); /// Alias the type for our UART to make things clearer. type Uart = hal::uart::UartPeripheral; /// This describes the queue we use for outbound UART data struct UartQueue { mutex_cell_queue: Mutex>>, interrupt: pac::Interrupt, } /// This how we transfer the UART into the Interrupt Handler static GLOBAL_UART: Mutex>> = Mutex::new(RefCell::new(None)); /// This is our outbound UART queue. We write to it from the main thread, and /// read from it in the UART IRQ. static UART_TX_QUEUE: UartQueue = UartQueue { mutex_cell_queue: Mutex::new(RefCell::new(Queue::new())), interrupt: hal::pac::Interrupt::UART0_IRQ, }; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then writes to the UART in /// an infinite loop. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // Lets us wait for fixed periods of time let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins to their default state let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let uart_pins = ( // UART TX (characters sent from RP2040) on pin 1 (GPIO0) pins.gpio0.reconfigure(), // UART RX (characters received by RP2040) on pin 2 (GPIO1) pins.gpio1.reconfigure(), ); // Make a UART on the given pins let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS) .enable( UartConfig::new(9600.Hz(), DataBits::Eight, None, StopBits::One), clocks.peripheral_clock.freq(), ) .unwrap(); // Tell the UART to raise its interrupt line on the NVIC when the TX FIFO // has space in it. uart.enable_tx_interrupt(); // Now we give away the entire UART peripheral, via the variable // `GLOBAL_UART`. We can no longer access the UART from this main thread. critical_section::with(|cs| { GLOBAL_UART.borrow(cs).replace(Some(uart)); }); // But we can blink an LED. let mut led_pin = pins.led.into_push_pull_output(); loop { // Light the LED whilst the main thread is in the transmit routine. It // shouldn't be on very long, but it will be on until we get enough // data /out/ of the queue and over the UART for this remainder of // this string to fit. led_pin.set_high().unwrap(); // Note we can only write to &UART_TX_QUEUE, because it's not mutable and // `core::fmt::Write` takes mutable references. writeln!( &UART_TX_QUEUE, "Hello, this was sent under interrupt! It's quite a \ long message, designed not to fit in either the \ hardware FIFO or the software queue." ) .unwrap(); led_pin.set_low().unwrap(); // Wait for a second - the UART TX IRQ will transmit the remainder of // our queue contents in the background. delay.delay_ms(1000); } } impl UartQueue { /// Try and get some data out of the UART Queue. Returns None if queue empty. fn read_byte(&self) -> Option { critical_section::with(|cs| { let cell_queue = self.mutex_cell_queue.borrow(cs); let mut queue = cell_queue.borrow_mut(); queue.dequeue() }) } /// Peek at the next byte in the queue without removing it. fn peek_byte(&self) -> Option { critical_section::with(|cs| { let cell_queue = self.mutex_cell_queue.borrow(cs); let queue = cell_queue.borrow_mut(); queue.peek().cloned() }) } /// Write some data to the queue, spinning until it all fits. fn write_bytes_blocking(&self, data: &[u8]) { // Go through all the bytes we need to write. for byte in data.iter() { // Keep trying until there is space in the queue. But release the // mutex between each attempt, otherwise the IRQ will never run // and we will never have space! let mut written = false; while !written { // Grab the mutex, by turning interrupts off. NOTE: This // doesn't work if you are using Core 1 as we only turn // interrupts off on one core. critical_section::with(|cs| { // Grab the mutex contents. let cell_queue = self.mutex_cell_queue.borrow(cs); // Grab mutable access to the queue. This can't fail // because there are no interrupts running. let mut queue = cell_queue.borrow_mut(); // Try and put the byte in the queue. if queue.enqueue(*byte).is_ok() { // It worked! We must have had space. if !pac::NVIC::is_enabled(self.interrupt) { unsafe { // Now enable the UART interrupt in the *Nested // Vectored Interrupt Controller*, which is part // of the Cortex-M0+ core. If the FIFO has space, // the interrupt will run as soon as we're out of // the closure. pac::NVIC::unmask(self.interrupt); // We also have to kick the IRQ in case the FIFO // was already below the threshold level. pac::NVIC::pend(self.interrupt); } } written = true; } }); } } } } impl core::fmt::Write for &UartQueue { /// This function allows us to `writeln!` on our global static UART queue. /// Note we have an impl for &UartQueue, because our global static queue /// is not mutable and `core::fmt::Write` takes mutable references. fn write_str(&mut self, data: &str) -> core::fmt::Result { self.write_bytes_blocking(data.as_bytes()); Ok(()) } } #[interrupt] fn UART0_IRQ() { // This variable is special. It gets mangled by the `#[interrupt]` macro // into something that we can access without the `unsafe` keyword. It can // do this because this function cannot be called re-entrantly. We know // this because the function's 'real' name is unknown, and hence it cannot // be called from the main thread. We also know that the NVIC will not // re-entrantly call an interrupt. static mut UART: Option> = None; // This is one-time lazy initialisation. We steal the variable given to us // via `GLOBAL_UART`. if UART.is_none() { critical_section::with(|cs| { *UART = GLOBAL_UART.borrow(cs).take(); }); } // Check if we have a UART to work with if let Some(uart) = UART { // Check if we have data to transmit while let Some(byte) = UART_TX_QUEUE.peek_byte() { if uart.write(byte).is_ok() { // The UART took it, so pop it off the queue. let _ = UART_TX_QUEUE.read_byte(); } else { break; } } if UART_TX_QUEUE.peek_byte().is_none() { pac::NVIC::mask(UART_TX_QUEUE.interrupt); } } // Set an event to ensure the main thread always wakes up, even if it's in // the process of going to sleep. cortex_m::asm::sev(); } // End of file ================================================ FILE: boards/rp-pico/examples/pico_uart_irq_echo.rs ================================================ //! # UART IRQ Echo Example //! //! This application demonstrates how to use the UART Driver to talk to a serial //! connection. In this example, the IRQ owns the UART and you cannot do any UART //! access from the main thread. //! //! The pinouts are: //! //! * GPIO 0 - UART TX (out of the RP2040) //! * GPIO 1 - UART RX (in to the RP2040) //! * GPIO 25 - An LED we can blink (active high) //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] #![allow(static_mut_refs)] // These are the traits we need from Embedded HAL to treat our hardware // objects as generic embedded devices. use embedded_hal::digital::OutputPin; use embedded_hal_nb::serial::{Read, Write}; // We also need this for the 'Delay' object to work. use rp2040_hal::Clock; // The macro for our start-up function use rp_pico::entry; // Time handling traits use fugit::RateExtU32; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Alias for our HAL crate use rp2040_hal as hal; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use hal::pac; // Our interrupt macro use hal::pac::interrupt; // Some short-cuts to useful types use core::cell::RefCell; use critical_section::Mutex; /// Import the GPIO pins we use use hal::gpio::bank0::{Gpio0, Gpio1}; // UART related types use hal::uart::{DataBits, StopBits, UartConfig}; /// Alias the type for our UART pins to make things clearer. type UartPins = ( hal::gpio::Pin, hal::gpio::Pin, ); /// Alias the type for our UART to make things clearer. type Uart = hal::uart::UartPeripheral; /// This how we transfer the UART into the Interrupt Handler static GLOBAL_UART: Mutex>> = Mutex::new(RefCell::new(None)); /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then writes to the UART in /// an infinite loop. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // Lets us wait for fixed periods of time let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins to their default state let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let uart_pins = ( // UART TX (characters sent from RP2040) on pin 1 (GPIO0) pins.gpio0.reconfigure(), // UART RX (characters received by RP2040) on pin 2 (GPIO1) pins.gpio1.reconfigure(), ); // Make a UART on the given pins let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS) .enable( UartConfig::new(9600.Hz(), DataBits::Eight, None, StopBits::One), clocks.peripheral_clock.freq(), ) .unwrap(); unsafe { // Enable the UART interrupt in the *Nested Vectored Interrupt // Controller*, which is part of the Cortex-M0+ core. pac::NVIC::unmask(hal::pac::Interrupt::UART0_IRQ); } // Tell the UART to raise its interrupt line on the NVIC when the RX FIFO // has data in it. uart.enable_rx_interrupt(); // Write something to the UART on start-up so we can check the output pin // is wired correctly. uart.write_full_blocking(b"uart_interrupt example started...\n"); // Now we give away the entire UART peripheral, via the variable // `GLOBAL_UART`. We can no longer access the UART from this main thread. critical_section::with(|cs| { GLOBAL_UART.borrow(cs).replace(Some(uart)); }); // But we can blink an LED. let mut led_pin = pins.led.into_push_pull_output(); loop { // The normal *Wait For Interrupts* (WFI) has a race-hazard - the // interrupt could occur between the CPU checking for interrupts and // the CPU going to sleep. We wait for events (and interrupts), and // then we set an event in every interrupt handler. This ensures we // always wake up correctly. cortex_m::asm::wfe(); // Light the LED to indicate we saw an interrupt. led_pin.set_high().unwrap(); delay.delay_ms(100); led_pin.set_low().unwrap(); } } #[interrupt] fn UART0_IRQ() { // This variable is special. It gets mangled by the `#[interrupt]` macro // into something that we can access without the `unsafe` keyword. It can // do this because this function cannot be called re-entrantly. We know // this because the function's 'real' name is unknown, and hence it cannot // be called from the main thread. We also know that the NVIC will not // re-entrantly call an interrupt. static mut UART: Option> = None; // This is one-time lazy initialisation. We steal the variable given to us // via `GLOBAL_UART`. if UART.is_none() { critical_section::with(|cs| { *UART = GLOBAL_UART.borrow(cs).take(); }); } // Check if we have a UART to work with if let Some(uart) = UART { // Echo the input back to the output until the FIFO is empty. Reading // from the UART should also clear the UART interrupt flag. while let Ok(byte) = uart.read() { let _ = uart.write(byte); } } // Set an event to ensure the main thread always wakes up, even if it's in // the process of going to sleep. cortex_m::asm::sev(); } // End of file ================================================ FILE: boards/rp-pico/examples/pico_usb_serial.rs ================================================ //! # Pico USB Serial Example //! //! Creates a USB Serial device on a Pico board, with the USB driver running in //! the main thread. //! //! This will create a USB Serial device echoing anything it receives. Incoming //! ASCII characters are converted to upercase, so you can tell it is working //! and not just local-echo! //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use rp_pico::entry; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; // USB Device support use usb_device::{class_prelude::*, prelude::*}; // USB Communications Class Device support use usbd_serial::SerialPort; // Used to demonstrate writing formatted strings use core::fmt::Write; use heapless::String; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then echoes any characters /// received over USB Serial. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); #[cfg(feature = "rp2040-e5")] { let sio = hal::Sio::new(pac.SIO); let _pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); } // Set up the USB driver let usb_bus = UsbBusAllocator::new(hal::usb::UsbBus::new( pac.USBCTRL_REGS, pac.USBCTRL_DPRAM, clocks.usb_clock, true, &mut pac.RESETS, )); // Set up the USB Communications Class Device driver let mut serial = SerialPort::new(&usb_bus); // Create a USB device with a fake VID and PID let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) .strings(&[StringDescriptors::default() .manufacturer("Fake company") .product("Serial port") .serial_number("TEST")]) .unwrap() .device_class(2) // from: https://www.usb.org/defined-class-codes .build(); let mut said_hello = false; loop { // A welcome message at the beginning if !said_hello && timer.get_counter().ticks() >= 2_000_000 { said_hello = true; let _ = serial.write(b"Hello, World!\r\n"); let time = timer.get_counter().ticks(); let mut text: String<64> = String::new(); writeln!(&mut text, "Current timer ticks: {}", time).unwrap(); // This only works reliably because the number of bytes written to // the serial port is smaller than the buffers available to the USB // peripheral. In general, the return value should be handled, so that // bytes not transferred yet don't get lost. let _ = serial.write(text.as_bytes()); } // Check for new data if usb_dev.poll(&mut [&mut serial]) { let mut buf = [0u8; 64]; match serial.read(&mut buf) { Err(_e) => { // Do nothing } Ok(0) => { // Do nothing } Ok(count) => { // Convert to upper case buf.iter_mut().take(count).for_each(|b| { b.make_ascii_uppercase(); }); // Send back to the host let mut wr_ptr = &buf[..count]; while !wr_ptr.is_empty() { match serial.write(wr_ptr) { Ok(len) => wr_ptr = &wr_ptr[len..], // On error, just drop unwritten data. // One possible error is Err(WouldBlock), meaning the USB // write buffer is full. Err(_) => break, }; } } } } } } // End of file ================================================ FILE: boards/rp-pico/examples/pico_usb_serial_interrupt.rs ================================================ //! # Pico USB Serial (with Interrupts) Example //! //! Creates a USB Serial device on a Pico board, with the USB driver running in //! the USB interrupt. //! //! This will create a USB Serial device echoing anything it receives. Incoming //! ASCII characters are converted to upercase, so you can tell it is working //! and not just local-echo! //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] #![allow(static_mut_refs)] // The macro for our start-up function use rp_pico::entry; // The macro for marking our interrupt functions use rp_pico::hal::pac::interrupt; // GPIO traits use embedded_hal::digital::OutputPin; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use rp_pico::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; // USB Device support use usb_device::{class_prelude::*, prelude::*}; // USB Communications Class Device support use usbd_serial::SerialPort; /// The USB Device Driver (shared with the interrupt). static mut USB_DEVICE: Option> = None; /// The USB Bus Driver (shared with the interrupt). static mut USB_BUS: Option> = None; /// The USB Serial Device Driver (shared with the interrupt). static mut USB_SERIAL: Option> = None; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then blinks the LED in an /// infinite loop. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // Set up the USB driver let usb_bus = UsbBusAllocator::new(hal::usb::UsbBus::new( pac.USBCTRL_REGS, pac.USBCTRL_DPRAM, clocks.usb_clock, true, &mut pac.RESETS, )); unsafe { // Note (safety): This is safe as interrupts haven't been started yet USB_BUS = Some(usb_bus); } // Grab a reference to the USB Bus allocator. We are promising to the // compiler not to take mutable access to this global variable whilst this // reference exists! let bus_ref = unsafe { USB_BUS.as_ref().unwrap() }; // Set up the USB Communications Class Device driver let serial = SerialPort::new(bus_ref); unsafe { USB_SERIAL = Some(serial); } // Create a USB device with a fake VID and PID let usb_dev = UsbDeviceBuilder::new(bus_ref, UsbVidPid(0x16c0, 0x27dd)) .strings(&[StringDescriptors::default() .manufacturer("Fake company") .product("Serial port") .serial_number("TEST")]) .unwrap() .device_class(2) // from: https://www.usb.org/defined-class-codes .build(); unsafe { // Note (safety): This is safe as interrupts haven't been started yet USB_DEVICE = Some(usb_dev); } // Enable the USB interrupt unsafe { pac::NVIC::unmask(hal::pac::Interrupt::USBCTRL_IRQ); }; // No more USB code after this point in main! We can do anything we want in // here since USB is handled in the interrupt - let's blink an LED! // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Set the LED to be an output let mut led_pin = pins.led.into_push_pull_output(); // Blink the LED at 1 Hz loop { led_pin.set_high().unwrap(); delay.delay_ms(500); led_pin.set_low().unwrap(); delay.delay_ms(500); } } /// This function is called whenever the USB Hardware generates an Interrupt /// Request. /// /// We do all our USB work under interrupt, so the main thread can continue on /// knowing nothing about USB. #[allow(non_snake_case)] #[interrupt] unsafe fn USBCTRL_IRQ() { use core::sync::atomic::{AtomicBool, Ordering}; /// Note whether we've already printed the "hello" message. static SAID_HELLO: AtomicBool = AtomicBool::new(false); // Grab the global objects. This is OK as we only access them under interrupt. let usb_dev = USB_DEVICE.as_mut().unwrap(); let serial = USB_SERIAL.as_mut().unwrap(); // Say hello exactly once on start-up if !SAID_HELLO.load(Ordering::Relaxed) { SAID_HELLO.store(true, Ordering::Relaxed); let _ = serial.write(b"Hello, World!\r\n"); } // Poll the USB driver with all of our supported USB Classes if usb_dev.poll(&mut [serial]) { let mut buf = [0u8; 64]; match serial.read(&mut buf) { Err(_e) => { // Do nothing } Ok(0) => { // Do nothing } Ok(count) => { // Convert to upper case buf.iter_mut().take(count).for_each(|b| { b.make_ascii_uppercase(); }); // Send back to the host let mut wr_ptr = &buf[..count]; while !wr_ptr.is_empty() { let _ = serial.write(wr_ptr).map(|len| { wr_ptr = &wr_ptr[len..]; }); } } } } } // End of file ================================================ FILE: boards/rp-pico/examples/pico_usb_twitchy_mouse.rs ================================================ //! # Pico USB 'Twitchy' Mouse Example //! //! Creates a USB HID Class Pointing device (i.e. a virtual mouse) on a Pico //! board, with the USB driver running in the main thread. //! //! It generates movement reports which will twitch the cursor up and down by a //! few pixels, several times a second. //! //! See the `Cargo.toml` file for Copyright and license details. //! //! This is a port of //! https://github.com/atsamd-rs/atsamd/blob/master/boards/itsybitsy_m0/examples/twitching_usb_mouse.rs #![no_std] #![no_main] #![allow(static_mut_refs)] // The macro for our start-up function use rp_pico::entry; // The macro for marking our interrupt functions use rp_pico::hal::pac::interrupt; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use rp_pico::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; // USB Device support use usb_device::{class_prelude::*, prelude::*}; // USB Human Interface Device (HID) Class support use usbd_hid::descriptor::generator_prelude::*; use usbd_hid::descriptor::MouseReport; use usbd_hid::hid_class::HIDClass; /// The USB Device Driver (shared with the interrupt). static mut USB_DEVICE: Option> = None; /// The USB Bus Driver (shared with the interrupt). static mut USB_BUS: Option> = None; /// The USB Human Interface Device Driver (shared with the interrupt). static mut USB_HID: Option> = None; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then submits cursor movement /// updates periodically. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); #[cfg(feature = "rp2040-e5")] { let sio = hal::Sio::new(pac.SIO); let _pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); } // Set up the USB driver let usb_bus = UsbBusAllocator::new(hal::usb::UsbBus::new( pac.USBCTRL_REGS, pac.USBCTRL_DPRAM, clocks.usb_clock, true, &mut pac.RESETS, )); unsafe { // Note (safety): This is safe as interrupts haven't been started yet USB_BUS = Some(usb_bus); } // Grab a reference to the USB Bus allocator. We are promising to the // compiler not to take mutable access to this global variable whilst this // reference exists! let bus_ref = unsafe { USB_BUS.as_ref().unwrap() }; // Set up the USB HID Class Device driver, providing Mouse Reports let usb_hid = HIDClass::new(bus_ref, MouseReport::desc(), 60); unsafe { // Note (safety): This is safe as interrupts haven't been started yet. USB_HID = Some(usb_hid); } // Create a USB device with a fake VID and PID let usb_dev = UsbDeviceBuilder::new(bus_ref, UsbVidPid(0x16c0, 0x27da)) .strings(&[StringDescriptors::default() .manufacturer("Fake company") .product("Twitchy Mousey") .serial_number("TEST")]) .unwrap() .device_class(0) .build(); unsafe { // Note (safety): This is safe as interrupts haven't been started yet USB_DEVICE = Some(usb_dev); } unsafe { // Enable the USB interrupt pac::NVIC::unmask(hal::pac::Interrupt::USBCTRL_IRQ); }; let core = pac::CorePeripherals::take().unwrap(); let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // Move the cursor up and down every 200ms loop { delay.delay_ms(100); let rep_up = MouseReport { x: 0, y: 4, buttons: 0, wheel: 0, pan: 0, }; push_mouse_movement(rep_up).ok().unwrap_or(0); delay.delay_ms(100); let rep_down = MouseReport { x: 0, y: -4, buttons: 0, wheel: 0, pan: 0, }; push_mouse_movement(rep_down).ok().unwrap_or(0); } } /// Submit a new mouse movement report to the USB stack. /// /// We do this with interrupts disabled, to avoid a race hazard with the USB IRQ. fn push_mouse_movement(report: MouseReport) -> Result { critical_section::with(|_| unsafe { // Now interrupts are disabled, grab the global variable and, if // available, send it a HID report USB_HID.as_mut().map(|hid| hid.push_input(&report)) }) .unwrap() } /// This function is called whenever the USB Hardware generates an Interrupt /// Request. #[allow(non_snake_case)] #[interrupt] unsafe fn USBCTRL_IRQ() { // Handle USB request let usb_dev = USB_DEVICE.as_mut().unwrap(); let usb_hid = USB_HID.as_mut().unwrap(); usb_dev.poll(&mut [usb_hid]); } // End of file ================================================ FILE: boards/rp-pico/examples/pico_ws2812_led.rs ================================================ //! # Pico WS2812 RGB LED Example //! //! Drives 3 WS2812 LEDs connected directly to the Raspberry Pi Pico. //! This assumes you drive the Raspberry Pi Pico via USB power, so that VBUS //! delivers the 5V and at least enough amperes to drive the LEDs. //! //! For a more large scale and longer strips you should use an extra power //! supply for the LED strip (or know what you are doing ;-) ). //! //! The example also comes with an utility function to calculate the colors //! from HSV color space. It also limits the brightness a bit to save a //! few milliamperes - be careful if you increase the strip length you will //! quickly get into power consumption of multiple amperes. //! //! The example assumes you connected the data input to pin 6 of the //! Raspberry Pi Pico, which is GPIO4 of the rp2040. Here is a circuit //! diagram that shows the assumed setup: //! //! ```text //! _______________ /----------------------\ //! |+5V /---\ +5V|----/ _|USB|_ | //! |DO <-|LED|<- DI|-\ |1 R 40|-VBUS-/ //! |GND \---/ GND|--+---\ |2 P 39| //! """"""""""""""" | \-GND-|3 38| //! | |4 P 37| //! | |5 I 36| //! \------GP4-|6 C | //! |7 O | //! | | //! ......... //! |20 21| //! """"""" //! Symbols: //! - (+) crossing lines, not connected //! - (o) connected lines //! ``` //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use rp_pico::entry; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use rp_pico::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use rp_pico::hal::pac; // Import the Timer for Ws2812: use rp_pico::hal::timer::Timer; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use rp_pico::hal; // PIOExt for the split() method that is needed to bring // PIO0 into useable form for Ws2812: use rp_pico::hal::pio::PIOExt; // Import useful traits to handle the ws2812 LEDs: use smart_leds::{brightness, SmartLedsWrite, RGB8}; // Import the actual crate to handle the Ws2812 protocol: use ws2812_pio::Ws2812; // Currently 3 consecutive LEDs are driven by this example // to keep the power draw compatible with USB: const STRIP_LEN: usize = 3; #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( rp_pico::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = rp_pico::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Setup a delay for the LED blink signals: let mut frame_delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // Import the `sin` function for a smooth hue animation from the // Pico rp2040 ROM: let sin = hal::rom_data::float_funcs::fsin::ptr(); // Create a count down timer for the Ws2812 instance: let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Split the PIO state machine 0 into individual objects, so that // Ws2812 can use it: let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); // Instanciate a Ws2812 LED strip: let mut ws = Ws2812::new( // Use pin 6 on the Raspberry Pi Pico (which is GPIO4 of the rp2040 chip) // for the LED data output: pins.gpio4.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); let mut leds: [RGB8; STRIP_LEN] = [(0, 0, 0).into(); STRIP_LEN]; let mut t = 0.0; // Bring down the overall brightness of the strip to not blow // the USB power supply: every LED draws ~60mA, RGB means 3 LEDs per // ws2812 LED, for 3 LEDs that would be: 3 * 3 * 60mA, which is // already 540mA for just 3 white LEDs! let strip_brightness = 64u8; // Limit brightness to 64/256 // Slow down timer by this factor (0.1 will result in 10 seconds): let animation_speed = 0.1; loop { for (i, led) in leds.iter_mut().enumerate() { // An offset to give 3 consecutive LEDs a different color: let hue_offs = match i % 3 { 1 => 0.25, 2 => 0.5, _ => 0.0, }; let sin_11 = sin((t + hue_offs) * 2.0 * core::f32::consts::PI); // Bring -1..1 sine range to 0..1 range: let sin_01 = (sin_11 + 1.0) * 0.5; let hue = 360.0 * sin_01; let sat = 1.0; let val = 1.0; let rgb = hsv2rgb_u8(hue, sat, val); *led = rgb.into(); } // Here the magic happens and the `leds` buffer is written to the // ws2812 LEDs: ws.write(brightness(leds.iter().copied(), strip_brightness)) .unwrap(); // Wait a bit until calculating the next frame: frame_delay.delay_ms(16); // ~60 FPS // Increase the time counter variable and make sure it // stays inbetween 0.0 to 1.0 range: t += (16.0 / 1000.0) * animation_speed; while t > 1.0 { t -= 1.0; } } } pub fn hsv2rgb(hue: f32, sat: f32, val: f32) -> (f32, f32, f32) { let c = val * sat; let v = (hue / 60.0) % 2.0 - 1.0; let v = if v < 0.0 { -v } else { v }; let x = c * (1.0 - v); let m = val - c; let (r, g, b) = if hue < 60.0 { (c, x, 0.0) } else if hue < 120.0 { (x, c, 0.0) } else if hue < 180.0 { (0.0, c, x) } else if hue < 240.0 { (0.0, x, c) } else if hue < 300.0 { (x, 0.0, c) } else { (c, 0.0, x) }; (r + m, g + m, b + m) } pub fn hsv2rgb_u8(h: f32, s: f32, v: f32) -> (u8, u8, u8) { let r = hsv2rgb(h, s, v); ( (r.0 * 255.0) as u8, (r.1 * 255.0) as u8, (r.2 * 255.0) as u8, ) } ================================================ FILE: boards/rp-pico/examples/pwm.pio ================================================ ; ; Copyright (c) 2020 Raspberry Pi (Trading) Ltd. ; ; SPDX-License-Identifier: BSD-3-Clause ; ; Side-set pin 0 is used for PWM output .program pwm .side_set 1 opt pull noblock side 0 ; Pull from FIFO to OSR if available, else copy X to OSR. mov x, osr ; Copy most-recently-pulled value back to scratch X mov y, isr ; ISR contains PWM period. Y used as counter. countloop: jmp x!=y noset ; Set pin high if X == Y, keep the two paths length matched jmp skip side 1 noset: nop ; Single dummy cycle to keep the two paths the same length skip: jmp y-- countloop ; Loop until Y hits 0, then pull a fresh PWM value from FIFO % c-sdk { static inline void pwm_program_init(PIO pio, uint sm, uint offset, uint pin) { pio_gpio_init(pio, pin); pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true); pio_sm_config c = pwm_program_get_default_config(offset); sm_config_set_sideset_pins(&c, pin); pio_sm_init(pio, sm, offset, &c); } %} ================================================ FILE: boards/rp-pico/src/lib.rs ================================================ #![no_std] //! A Hardware Abstraction Layer for the Raspberry Pi Pico. //! //! This crate serves as a HAL (Hardware Abstraction Layer) for the Raspberry Pi Pico. Since the Raspberry Pi Pico //! is based on the RP2040 chip, it re-exports the [rp2040_hal] crate which contains the tooling to work with the //! rp2040 chip. //! //! # Examples: //! //! The following example turns on the onboard LED. Note that most of the logic works through the [rp2040_hal] crate. //! ```ignore //! #![no_main] //! use rp_pico::entry; //! use panic_halt as _; //! use embedded_hal::digital::v2::OutputPin; //! use rp_pico::hal::pac; //! use rp_pico::hal; //! #[entry] //! fn does_not_have_to_be_main() -> ! { //! let mut pac = pac::Peripherals::take().unwrap(); //! let sio = hal::Sio::new(pac.SIO); //! let pins = rp_pico::Pins::new( //! pac.IO_BANK0, //! pac.PADS_BANK0, //! sio.gpio_bank0, //! &mut pac.RESETS, //! ); //! let mut led_pin = pins.led.into_push_pull_output(); //! led_pin.set_high().unwrap(); //! loop { //! } //! } //! ``` pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; /// The `entry` macro declares the starting function to the linker. /// This is similar to the `main` function in console applications. /// /// It is based on the [cortex_m_rt](https://docs.rs/cortex-m-rt/latest/cortex_m_rt/attr.entry.html) crate. /// /// # Examples /// ```ignore /// #![no_std] /// #![no_main] /// use rp_pico::entry; /// #[entry] /// fn you_can_use_a_custom_main_name_here() -> ! { /// loop {} /// } /// ``` #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( /// GPIO 0 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp0Spi0Rx] | /// | `UART0 TX` | [crate::Gp0Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp0I2C0Sda] | /// | `PWM0 A` | [crate::Gp0Pwm0A] | /// | `PIO0` | [crate::Gp0Pio0] | /// | `PIO1` | [crate::Gp0Pio1] | Gpio0 { name: gpio0, aliases: { /// UART Function alias for pin [crate::Pins::gpio0]. FunctionUart, PullNone: Gp0Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio0]. FunctionSpi, PullNone: Gp0Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio0]. FunctionI2C, PullUp: Gp0I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio0]. FunctionPwm, PullNone: Gp0Pwm0A, /// PIO0 Function alias for pin [crate::Pins::gpio0]. FunctionPio0, PullNone: Gp0Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio0]. FunctionPio1, PullNone: Gp0Pio1 } }, /// GPIO 1 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp1Spi0Csn] | /// | `UART0 RX` | [crate::Gp1Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp1I2C0Scl] | /// | `PWM0 B` | [crate::Gp1Pwm0B] | /// | `PIO0` | [crate::Gp1Pio0] | /// | `PIO1` | [crate::Gp1Pio1] | Gpio1 { name: gpio1, aliases: { /// UART Function alias for pin [crate::Pins::gpio1]. FunctionUart, PullNone: Gp1Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio1]. FunctionSpi, PullNone: Gp1Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio1]. FunctionI2C, PullUp: Gp1I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio1]. FunctionPwm, PullNone: Gp1Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio1]. FunctionPio0, PullNone: Gp1Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio1]. FunctionPio1, PullNone: Gp1Pio1 } }, /// GPIO 2 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp2Spi0Sck] | /// | `UART0 CTS` | [crate::Gp2Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp2I2C1Sda] | /// | `PWM1 A` | [crate::Gp2Pwm1A] | /// | `PIO0` | [crate::Gp2Pio0] | /// | `PIO1` | [crate::Gp2Pio1] | Gpio2 { name: gpio2, aliases: { /// UART Function alias for pin [crate::Pins::gpio2]. FunctionUart, PullNone: Gp2Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio2]. FunctionSpi, PullNone: Gp2Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio2]. FunctionI2C, PullUp: Gp2I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio2]. FunctionPwm, PullNone: Gp2Pwm1A, /// PIO0 Function alias for pin [crate::Pins::gpio2]. FunctionPio0, PullNone: Gp2Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio2]. FunctionPio1, PullNone: Gp2Pio1 } }, /// GPIO 3 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp3Spi0Tx] | /// | `UART0 RTS` | [crate::Gp3Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp3I2C1Scl] | /// | `PWM1 B` | [crate::Gp3Pwm1B] | /// | `PIO0` | [crate::Gp3Pio0] | /// | `PIO1` | [crate::Gp3Pio1] | Gpio3 { name: gpio3, aliases: { /// UART Function alias for pin [crate::Pins::gpio3]. FunctionUart, PullNone: Gp3Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio3]. FunctionSpi, PullNone: Gp3Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio3]. FunctionI2C, PullUp: Gp3I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio3]. FunctionPwm, PullNone: Gp3Pwm1B, /// PIO0 Function alias for pin [crate::Pins::gpio3]. FunctionPio0, PullNone: Gp3Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio3]. FunctionPio1, PullNone: Gp3Pio1 } }, /// GPIO 4 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp4Spi0Rx] | /// | `UART1 TX` | [crate::Gp4Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp4I2C0Sda] | /// | `PWM2 A` | [crate::Gp4Pwm2A] | /// | `PIO0` | [crate::Gp4Pio0] | /// | `PIO1` | [crate::Gp4Pio1] | Gpio4 { name: gpio4, aliases: { /// UART Function alias for pin [crate::Pins::gpio4]. FunctionUart, PullNone: Gp4Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio4]. FunctionSpi, PullNone: Gp4Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio4]. FunctionI2C, PullUp: Gp4I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio4]. FunctionPwm, PullNone: Gp4Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio4]. FunctionPio0, PullNone: Gp4Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio4]. FunctionPio1, PullNone: Gp4Pio1 } }, /// GPIO 5 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp5Spi0Csn] | /// | `UART1 RX` | [crate::Gp5Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp5I2C0Scl] | /// | `PWM2 B` | [crate::Gp5Pwm2B] | /// | `PIO0` | [crate::Gp5Pio0] | /// | `PIO1` | [crate::Gp5Pio1] | Gpio5 { name: gpio5, aliases: { /// UART Function alias for pin [crate::Pins::gpio5]. FunctionUart, PullNone: Gp5Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio5]. FunctionSpi, PullNone: Gp5Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio5]. FunctionI2C, PullUp: Gp5I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio5]. FunctionPwm, PullNone: Gp5Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio5]. FunctionPio0, PullNone: Gp5Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio5]. FunctionPio1, PullNone: Gp5Pio1 } }, /// GPIO 6 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp6Spi0Sck] | /// | `UART1 CTS` | [crate::Gp6Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp6I2C1Sda] | /// | `PWM3 A` | [crate::Gp6Pwm3A] | /// | `PIO0` | [crate::Gp6Pio0] | /// | `PIO1` | [crate::Gp6Pio1] | Gpio6 { name: gpio6, aliases: { /// UART Function alias for pin [crate::Pins::gpio6]. FunctionUart, PullNone: Gp6Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio6]. FunctionSpi, PullNone: Gp6Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio6]. FunctionI2C, PullUp: Gp6I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio6]. FunctionPwm, PullNone: Gp6Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio6]. FunctionPio0, PullNone: Gp6Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio6]. FunctionPio1, PullNone: Gp6Pio1 } }, /// GPIO 7 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp7Spi0Tx] | /// | `UART1 RTS` | [crate::Gp7Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp7I2C1Scl] | /// | `PWM3 B` | [crate::Gp7Pwm3B] | /// | `PIO0` | [crate::Gp7Pio0] | /// | `PIO1` | [crate::Gp7Pio1] | Gpio7 { name: gpio7, aliases: { /// UART Function alias for pin [crate::Pins::gpio7]. FunctionUart, PullNone: Gp7Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio7]. FunctionSpi, PullNone: Gp7Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio7]. FunctionI2C, PullUp: Gp7I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio7]. FunctionPwm, PullNone: Gp7Pwm3B, /// PIO0 Function alias for pin [crate::Pins::gpio7]. FunctionPio0, PullNone: Gp7Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio7]. FunctionPio1, PullNone: Gp7Pio1 } }, /// GPIO 8 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp8Spi1Rx] | /// | `UART1 TX` | [crate::Gp8Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp8I2C0Sda] | /// | `PWM4 A` | [crate::Gp8Pwm4A] | /// | `PIO0` | [crate::Gp8Pio0] | /// | `PIO1` | [crate::Gp8Pio1] | Gpio8 { name: gpio8, aliases: { /// UART Function alias for pin [crate::Pins::gpio8]. FunctionUart, PullNone: Gp8Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio8]. FunctionSpi, PullNone: Gp8Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio8]. FunctionI2C, PullUp: Gp8I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio8]. FunctionPwm, PullNone: Gp8Pwm4A, /// PIO0 Function alias for pin [crate::Pins::gpio8]. FunctionPio0, PullNone: Gp8Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio8]. FunctionPio1, PullNone: Gp8Pio1 } }, /// GPIO 9 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp9Spi1Csn] | /// | `UART1 RX` | [crate::Gp9Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp9I2C0Scl] | /// | `PWM4 B` | [crate::Gp9Pwm4B] | /// | `PIO0` | [crate::Gp9Pio0] | /// | `PIO1` | [crate::Gp9Pio1] | Gpio9 { name: gpio9, aliases: { /// UART Function alias for pin [crate::Pins::gpio9]. FunctionUart, PullNone: Gp9Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio9]. FunctionSpi, PullNone: Gp9Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio9]. FunctionI2C, PullUp: Gp9I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio9]. FunctionPwm, PullNone: Gp9Pwm4B, /// PIO0 Function alias for pin [crate::Pins::gpio9]. FunctionPio0, PullNone: Gp9Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio9]. FunctionPio1, PullNone: Gp9Pio1 } }, /// GPIO 10 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp10Spi1Sck] | /// | `UART1 CTS` | [crate::Gp10Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp10I2C1Sda] | /// | `PWM5 A` | [crate::Gp10Pwm5A] | /// | `PIO0` | [crate::Gp10Pio0] | /// | `PIO1` | [crate::Gp10Pio1] | Gpio10 { name: gpio10, aliases: { /// UART Function alias for pin [crate::Pins::gpio10]. FunctionUart, PullNone: Gp10Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio10]. FunctionSpi, PullNone: Gp10Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio10]. FunctionI2C, PullUp: Gp10I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio10]. FunctionPwm, PullNone: Gp10Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio10]. FunctionPio0, PullNone: Gp10Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio10]. FunctionPio1, PullNone: Gp10Pio1 } }, /// GPIO 11 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp11Spi1Tx] | /// | `UART1 RTS` | [crate::Gp11Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp11I2C1Scl] | /// | `PWM5 B` | [crate::Gp11Pwm5B] | /// | `PIO0` | [crate::Gp11Pio0] | /// | `PIO1` | [crate::Gp11Pio1] | Gpio11 { name: gpio11, aliases: { /// UART Function alias for pin [crate::Pins::gpio11]. FunctionUart, PullNone: Gp11Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio11]. FunctionSpi, PullNone: Gp11Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio11]. FunctionI2C, PullUp: Gp11I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio11]. FunctionPwm, PullNone: Gp11Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio11]. FunctionPio0, PullNone: Gp11Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio11]. FunctionPio1, PullNone: Gp11Pio1 } }, /// GPIO 12 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp12Spi1Rx] | /// | `UART0 TX` | [crate::Gp12Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp12I2C0Sda] | /// | `PWM6 A` | [crate::Gp12Pwm6A] | /// | `PIO0` | [crate::Gp12Pio0] | /// | `PIO1` | [crate::Gp12Pio1] | Gpio12 { name: gpio12, aliases: { /// UART Function alias for pin [crate::Pins::gpio12]. FunctionUart, PullNone: Gp12Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio12]. FunctionSpi, PullNone: Gp12Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio12]. FunctionI2C, PullUp: Gp12I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio12]. FunctionPwm, PullNone: Gp12Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio12]. FunctionPio0, PullNone: Gp12Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio12]. FunctionPio1, PullNone: Gp12Pio1 } }, /// GPIO 13 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp13Spi1Csn] | /// | `UART0 RX` | [crate::Gp13Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp13I2C0Scl] | /// | `PWM6 B` | [crate::Gp13Pwm6B] | /// | `PIO0` | [crate::Gp13Pio0] | /// | `PIO1` | [crate::Gp13Pio1] | Gpio13 { name: gpio13, aliases: { /// UART Function alias for pin [crate::Pins::gpio13]. FunctionUart, PullNone: Gp13Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio13]. FunctionSpi, PullNone: Gp13Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio13]. FunctionI2C, PullUp: Gp13I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio13]. FunctionPwm, PullNone: Gp13Pwm6B, /// PIO0 Function alias for pin [crate::Pins::gpio13]. FunctionPio0, PullNone: Gp13Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio13]. FunctionPio1, PullNone: Gp13Pio1 } }, /// GPIO 14 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp14Spi1Sck] | /// | `UART0 CTS` | [crate::Gp14Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp14I2C1Sda] | /// | `PWM7 A` | [crate::Gp14Pwm7A] | /// | `PIO0` | [crate::Gp14Pio0] | /// | `PIO1` | [crate::Gp14Pio1] | Gpio14 { name: gpio14, aliases: { /// UART Function alias for pin [crate::Pins::gpio14]. FunctionUart, PullNone: Gp14Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio14]. FunctionSpi, PullNone: Gp14Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio14]. FunctionI2C, PullUp: Gp14I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio14]. FunctionPwm, PullNone: Gp14Pwm7A, /// PIO0 Function alias for pin [crate::Pins::gpio14]. FunctionPio0, PullNone: Gp14Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio14]. FunctionPio1, PullNone: Gp14Pio1 } }, /// GPIO 15 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp15Spi1Tx] | /// | `UART0 RTS` | [crate::Gp15Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp15I2C1Scl] | /// | `PWM7 B` | [crate::Gp15Pwm7B] | /// | `PIO0` | [crate::Gp15Pio0] | /// | `PIO1` | [crate::Gp15Pio1] | Gpio15 { name: gpio15, aliases: { /// UART Function alias for pin [crate::Pins::gpio15]. FunctionUart, PullNone: Gp15Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio15]. FunctionSpi, PullNone: Gp15Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio15]. FunctionI2C, PullUp: Gp15I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio15]. FunctionPwm, PullNone: Gp15Pwm7B, /// PIO0 Function alias for pin [crate::Pins::gpio15]. FunctionPio0, PullNone: Gp15Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio15]. FunctionPio1, PullNone: Gp15Pio1 } }, /// GPIO 16 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp16Spi0Rx] | /// | `UART0 TX` | [crate::Gp16Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp16I2C0Sda] | /// | `PWM0 A` | [crate::Gp16Pwm0A] | /// | `PIO0` | [crate::Gp16Pio0] | /// | `PIO1` | [crate::Gp16Pio1] | Gpio16 { name: gpio16, aliases: { /// UART Function alias for pin [crate::Pins::gpio16]. FunctionUart, PullNone: Gp16Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio16]. FunctionSpi, PullNone: Gp16Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio16]. FunctionI2C, PullUp: Gp16I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio16]. FunctionPwm, PullNone: Gp16Pwm0A, /// PIO0 Function alias for pin [crate::Pins::gpio16]. FunctionPio0, PullNone: Gp16Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio16]. FunctionPio1, PullNone: Gp16Pio1 } }, /// GPIO 17 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp17Spi0Csn] | /// | `UART0 RX` | [crate::Gp17Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp17I2C0Scl] | /// | `PWM0 B` | [crate::Gp17Pwm0B] | /// | `PIO0` | [crate::Gp17Pio0] | /// | `PIO1` | [crate::Gp17Pio1] | Gpio17 { name: gpio17, aliases: { /// UART Function alias for pin [crate::Pins::gpio17]. FunctionUart, PullNone: Gp17Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio17]. FunctionSpi, PullNone: Gp17Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio17]. FunctionI2C, PullUp: Gp17I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio17]. FunctionPwm, PullNone: Gp17Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio17]. FunctionPio0, PullNone: Gp17Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio17]. FunctionPio1, PullNone: Gp17Pio1 } }, /// GPIO 18 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp18Spi0Sck] | /// | `UART0 CTS` | [crate::Gp18Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp18I2C1Sda] | /// | `PWM1 A` | [crate::Gp18Pwm1A] | /// | `PIO0` | [crate::Gp18Pio0] | /// | `PIO1` | [crate::Gp18Pio1] | Gpio18 { name: gpio18, aliases: { /// UART Function alias for pin [crate::Pins::gpio18]. FunctionUart, PullNone: Gp18Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio18]. FunctionSpi, PullNone: Gp18Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio18]. FunctionI2C, PullUp: Gp18I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio18]. FunctionPwm, PullNone: Gp18Pwm1A, /// PIO0 Function alias for pin [crate::Pins::gpio18]. FunctionPio0, PullNone: Gp18Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio18]. FunctionPio1, PullNone: Gp18Pio1 } }, /// GPIO 19 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp19Spi0Tx] | /// | `UART0 RTS` | [crate::Gp19Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp19I2C1Scl] | /// | `PWM1 B` | [crate::Gp19Pwm1B] | /// | `PIO0` | [crate::Gp19Pio0] | /// | `PIO1` | [crate::Gp19Pio1] | Gpio19 { name: gpio19, aliases: { /// UART Function alias for pin [crate::Pins::gpio19]. FunctionUart, PullNone: Gp19Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio19]. FunctionSpi, PullNone: Gp19Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio19]. FunctionI2C, PullUp: Gp19I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio19]. FunctionPwm, PullNone: Gp19Pwm1B, /// PIO0 Function alias for pin [crate::Pins::gpio19]. FunctionPio0, PullNone: Gp19Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio19]. FunctionPio1, PullNone: Gp19Pio1 } }, /// GPIO 20 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp20Spi0Rx] | /// | `UART1 TX` | [crate::Gp20Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp20I2C0Sda] | /// | `PWM2 A` | [crate::Gp20Pwm2A] | /// | `PIO0` | [crate::Gp20Pio0] | /// | `PIO1` | [crate::Gp20Pio1] | Gpio20 { name: gpio20, aliases: { /// UART Function alias for pin [crate::Pins::gpio20]. FunctionUart, PullNone: Gp20Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio20]. FunctionSpi, PullNone: Gp20Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio20]. FunctionI2C, PullUp: Gp20I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio20]. FunctionPwm, PullNone: Gp20Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio20]. FunctionPio0, PullNone: Gp20Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio20]. FunctionPio1, PullNone: Gp20Pio1 } }, /// GPIO 21 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp21Spi0Csn] | /// | `UART1 RX` | [crate::Gp21Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp21I2C0Scl] | /// | `PWM2 B` | [crate::Gp21Pwm2B] | /// | `PIO0` | [crate::Gp21Pio0] | /// | `PIO1` | [crate::Gp21Pio1] | Gpio21 { name: gpio21, aliases: { /// UART Function alias for pin [crate::Pins::gpio21]. FunctionUart, PullNone: Gp21Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio21]. FunctionSpi, PullNone: Gp21Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio21]. FunctionI2C, PullUp: Gp21I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio21]. FunctionPwm, PullNone: Gp21Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio21]. FunctionPio0, PullNone: Gp21Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio21]. FunctionPio1, PullNone: Gp21Pio1 } }, /// GPIO 22 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp22Spi0Sck] | /// | `UART1 CTS` | [crate::Gp22Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp22I2C1Sda] | /// | `PWM3 A` | [crate::Gp22Pwm3A] | /// | `PIO0` | [crate::Gp22Pio0] | /// | `PIO1` | [crate::Gp22Pio1] | Gpio22 { name: gpio22, aliases: { /// UART Function alias for pin [crate::Pins::gpio22]. FunctionUart, PullNone: Gp22Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio22]. FunctionSpi, PullNone: Gp22Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio22]. FunctionI2C, PullUp: Gp22I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio22]. FunctionPwm, PullNone: Gp22Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio22]. FunctionPio0, PullNone: Gp22Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio22]. FunctionPio1, PullNone: Gp22Pio1 } }, /// GPIO 23 is connected to b_power_save of the Raspberry Pi Pico board. Gpio23 { name: b_power_save, }, /// GPIO 24 is connected to vbus_detect of the Raspberry Pi Pico board. Gpio24 { name: vbus_detect, }, /// GPIO 25 is connected to led of the Raspberry Pi Pico board. Gpio25 { name: led, }, /// GPIO 26 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp26Spi1Sck] | /// | `UART1 CTS` | [crate::Gp26Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp26I2C1Sda] | /// | `PWM5 A` | [crate::Gp26Pwm5A] | /// | `PIO0` | [crate::Gp26Pio0] | /// | `PIO1` | [crate::Gp26Pio1] | Gpio26 { name: gpio26, aliases: { /// UART Function alias for pin [crate::Pins::gpio26]. FunctionUart, PullNone: Gp26Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio26]. FunctionSpi, PullNone: Gp26Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio26]. FunctionI2C, PullUp: Gp26I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio26]. FunctionPwm, PullNone: Gp26Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio26]. FunctionPio0, PullNone: Gp26Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio26]. FunctionPio1, PullNone: Gp26Pio1 } }, /// GPIO 27 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp27Spi1Tx] | /// | `UART1 RTS` | [crate::Gp27Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp27I2C1Scl] | /// | `PWM5 B` | [crate::Gp27Pwm5B] | /// | `PIO0` | [crate::Gp27Pio0] | /// | `PIO1` | [crate::Gp27Pio1] | Gpio27 { name: gpio27, aliases: { /// UART Function alias for pin [crate::Pins::gpio27]. FunctionUart, PullNone: Gp27Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio27]. FunctionSpi, PullNone: Gp27Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio27]. FunctionI2C, PullUp: Gp27I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio27]. FunctionPwm, PullNone: Gp27Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio27]. FunctionPio0, PullNone: Gp27Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio27]. FunctionPio1, PullNone: Gp27Pio1 } }, /// GPIO 28 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp28Spi1Rx] | /// | `UART0 TX` | [crate::Gp28Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp28I2C0Sda] | /// | `PWM6 A` | [crate::Gp28Pwm6A] | /// | `PIO0` | [crate::Gp28Pio0] | /// | `PIO1` | [crate::Gp28Pio1] | Gpio28 { name: gpio28, aliases: { /// UART Function alias for pin [crate::Pins::gpio28]. FunctionUart, PullNone: Gp28Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio28]. FunctionSpi, PullNone: Gp28Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio28]. FunctionI2C, PullUp: Gp28I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio28]. FunctionPwm, PullNone: Gp28Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio28]. FunctionPio0, PullNone: Gp28Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio28]. FunctionPio1, PullNone: Gp28Pio1 } }, /// GPIO 29 is connected to voltage_monitor of the Raspberry Pi Pico board. Gpio29 { name: voltage_monitor, }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/seeeduino-xiao-rp2040/CHANGELOG.md ================================================ # 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.6.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.5.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 ## 0.4.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 ## 0.3.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 ## 0.2.0 - 2022-08-26 ### Changed - Migrate from `embedded-time` to `fugit` - Update to rp2040-hal 0.6.0 ## 0.1.0 - 2022-06-26 - Initial release ================================================ FILE: boards/seeeduino-xiao-rp2040/Cargo.toml ================================================ [package] name = "seeeduino-xiao-rp2040" version = "0.6.0" authors = ["Philip L. McMahon ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/seeeduino-xiao-rp02040" description = "Board Support Package for the Seeediuno XIAO RP2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true embedded-hal.workspace = true fugit.workspace = true nb.workspace = true panic-halt.workspace = true smart-leds.workspace = true ws2812-pio.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/seeeduino-xiao-rp2040/README.md ================================================ # [seeeduino-xiao-rp2040] - Board Support for the [Seeeduino XIAO RP2040] You should include this crate if you are writing code that you want to run on a [Seeeduino XIAO RP2040] - a tiny board for wearable devices and small projects. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the XIAO RP2040. [Seeeduino XIAO RP2040]: https://www.seeedstudio.com/XIAO-RP2040-v1-0-p-5026.html [seeeduino-xiao-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/seeeduino-xiao-rp2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal ## Using To use this crate, your `Cargo.toml` file should contain: ```toml seeeduino-xiao-rp2040 = "0.6.0" ``` In your program, you will need to call `seeeduino-xiao-rp2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/seeeduino-xiao-rp2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/seeeduino-xiao-rp2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` After installing `elf2uf2-rs`, retry the `cargo run` command above. ### [seeeduino_xiao_rp2040_blinky](./examples/seeeduino_xiao_rp2040_blinky.rs) Flashes the XIAO RP2040's on-board LED on and off. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/seeeduino-xiao-rp2040/examples/seeeduino_xiao_rp2040_blinky.rs ================================================ //! # Seeeduino XIAO RP2040 Blinky Example //! //! Blinks the LED on a Seeeduino XIAO RP2040 16MB board. //! //! This will blink an LED attached to GPIO25, which is the pin the XIAO RP2040 //! uses for the on-board LED. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use seeeduino_xiao_rp2040::entry; // GPIO traits use embedded_hal::digital::OutputPin; use embedded_hal::pwm::SetDutyCycle; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use seeeduino_xiao_rp2040::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use seeeduino_xiao_rp2040::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use seeeduino_xiao_rp2040::hal; use hal::gpio::PinState; // The minimum PWM value (i.e. LED brightness) we want const LOW: u16 = 0; // The maximum PWM value (i.e. LED brightness) we want const HIGH: u16 = 60000; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then blinks the LED in an /// infinite loop. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( seeeduino_xiao_rp2040::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = seeeduino_xiao_rp2040::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // Init PWMs let mut pwm_slices = hal::pwm::Slices::new(pac.PWM, &mut pac.RESETS); // Configure PWM4 let pwm = &mut pwm_slices.pwm0; pwm.set_ph_correct(); pwm.enable(); // Output channel B on PWM0 to the red LED pin, initially off let channel = &mut pwm.channel_b; channel.output_to(pins.led_red); let _ = channel.set_duty_cycle(u16::MAX); // Set the blue LED to be an output, initially off let mut led_blue_pin = pins.led_blue.into_push_pull_output_in_state(PinState::High); // Turn off the green LED let mut _led_green_pin = pins .led_green .into_push_pull_output_in_state(PinState::High); loop { // Blink blue LED at 1 Hz for _ in 0..5 { led_blue_pin.set_low().unwrap(); delay.delay_ms(500); led_blue_pin.set_high().unwrap(); delay.delay_ms(500); } // Ramp red LED brightness up for i in (LOW..=HIGH).skip(30) { delay.delay_us(100); let _ = channel.set_duty_cycle(u16::MAX - i); } // Ramp red LED brightness down for i in (LOW..=HIGH).rev().skip(30) { delay.delay_us(100); let _ = channel.set_duty_cycle(u16::MAX - i); } } } // End of file ================================================ FILE: boards/seeeduino-xiao-rp2040/examples/seeeduino_xiao_rp2040_neopixel_rainbow.rs ================================================ //! Rainbow effect color wheel using the onboard NeoPixel on a Seeed XIAO RP2040 board //! //! This flows smoothly through various colours on the onboard NeoPixel. //! Uses the `ws2812_pio` driver to control the NeoPixel, which in turns uses the //! RP2040's PIO block. #![no_std] #![no_main] use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use seeeduino_xiao_rp2040::{ entry, hal::{ clocks::{init_clocks_and_plls, Clock}, gpio::PinState, pac, pio::PIOExt, timer::Timer, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; use ws2812_pio::Ws2812; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then infinitely cycles the built-in LED colour from red, to green, /// to blue and back to red. #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Turn on neopixel power pins.neopixel_power .into_push_pull_output_in_state(PinState::High); // Configure the addressable LED let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( // The onboard NeoPixel is attached to GPIO pin #16 on the Waveshare RP2040-Zero. pins.neopixel_data.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); // Infinite colour wheel loop let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/seeeduino-xiao-rp2040/src/lib.rs ================================================ #![no_std] pub use rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( Gpio0 { name: tx, aliases: { FunctionUart, PullNone: UartTx } }, Gpio1 { name: rx aliases: { FunctionUart, PullNone: UartRx, FunctionSpi, PullNone: Csn } }, Gpio2 { name: sck, aliases: { FunctionSpi, PullNone: Sck } }, Gpio3 { name: mosi, aliases: { FunctionSpi, PullNone: Mosi } }, Gpio4 { name: miso, aliases: { FunctionSpi, PullNone: Miso } }, Gpio6 { name: sda, aliases: { FunctionI2C, PullUp: Sda } }, Gpio7 { name: scl, aliases: { FunctionI2C, PullUp: Scl } }, Gpio11 { name: neopixel_power }, Gpio12 { name: neopixel_data }, Gpio16 { name: led_green, aliases: { FunctionPwm, PullNone: LedGreenPwm } }, Gpio17 { name: led_red, aliases: { FunctionPwm, PullNone: LedRedPwm } }, Gpio25 { name: led_blue, aliases: { FunctionPwm, PullNone: LedBluePwm } }, Gpio26 { name: a0 }, Gpio27 { name: a1 }, Gpio28 { name: a2 }, Gpio29 { name: a3 }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/solderparty-rp2040-stamp/CHANGELOG.md ================================================ # 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.7.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.6.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.5.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 - Update to ws2812-pio 0.6.0 ## 0.4.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 ## 0.3.0 - 2022-08-26 ### Changed - Migrate from `embedded-time` to `fugit` - Bump `pio` to 0.2.0 - Bump `ws2812-pio` to 0.4.0 - Update to rp2040-hal 0.6.0 ================================================ FILE: boards/solderparty-rp2040-stamp/Cargo.toml ================================================ [package] name = "solderparty-rp2040-stamp" version = "0.7.0" authors = ["The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/solderparty-rp2040-stamp" description = "Board Support Package for the Solder Party RP2040 Stamp" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] embedded-hal.workspace = true fugit.workspace = true nb.workspace = true panic-halt.workspace = true pio.workspace = true smart-leds.workspace = true ws2812-pio.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/solderparty-rp2040-stamp/README.md ================================================ # [solderparty-rp2040-stamp] - Board Support for the [Solder Party RP2040 Stamp] You should include this crate if you are writing code that you want to run on a [Solder Party RP2040 Stamp] This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Stamp [Solder Party RP2040 Stamp]: https://www.solder.party/docs/rp2040-stamp/ [solderparty-rp2040-stamp]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/solderparty-rp2040-stamp [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml solderparty-rp2040-stamp = "0.7.0" ``` In your program, you will need to call `solderparty_rp2040_stamp::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal_ repository and run: ```console rp-hal-boards/boards/solderparty-rp2040-stamp $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/solderparty-rp2040-stamp $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [solderparty_stamp_neopixel_rainbow](./examples/solderparty_stamp_neopixel_rainbow.rs) Flows smoothly through various colors on the Feather's onboard NeoPixel LED. ## Contributing Contributions are what make the open source community such an amazing place to be, learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/solderparty-rp2040-stamp/examples/solderparty_stamp_neopixel_rainbow.rs ================================================ //! Rainbow effect color wheel using the onboard NeoPixel on an Solder Party Stamp RP2040 board //! //! This flows smoothly through various colors on the onboard NeoPixel. //! Uses the `ws2812_pio` driver to control the NeoPixel, which in turns uses the //! RP2040's PIO block. #![no_std] #![no_main] use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use solderparty_rp2040_stamp::entry; use solderparty_rp2040_stamp::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, pio::PIOExt, timer::Timer, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; use ws2812_pio::Ws2812; #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Configure the addressable LED let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( // The onboard NeoPixel is attached to GPIO pin #21 on the RP2040 Stamp. pins.neopixel.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); // Infinite colour wheel loop let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/solderparty-rp2040-stamp/src/lib.rs ================================================ #![no_std] pub use rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_GD25Q64CS; pub use hal::pac; hal::bsp_pins!( Gpio0 { name: gpio0 }, Gpio1 { name: gpio1 }, Gpio2 { name: gpio2 }, Gpio3 { name: gpio3 }, Gpio4 { name: gpio4 }, Gpio5 { name: gpio5 }, Gpio6 { name: gpio6 }, Gpio7 { name: gpio7 }, Gpio8 { name: gpio8 }, Gpio9 { name: gpio9 }, Gpio10 { name: gpio10 }, Gpio11 { name: gpio11 }, Gpio12 { name: gpio12 }, Gpio13 { name: gpio13 }, Gpio14 { name: gpio14 }, Gpio15 { name: gpio15 }, Gpio16 { name: gpio16 }, Gpio17 { name: gpio17 }, Gpio18 { name: gpio18 }, Gpio19 { name: gpio19 }, Gpio20 { name: gpio20 }, Gpio21 { name: neopixel }, Gpio22 { name: gpio22 }, Gpio23 { name: gpio23 }, Gpio24 { name: gpio24 }, Gpio25 { name: gpio25 }, Gpio26 { name: gpio26 }, Gpio27 { name: gpio27 }, Gpio28 { name: gpio28 }, Gpio29 { name: gpio29 }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/sparkfun-micromod-rp2040/.gitignore ================================================ # Generated by Cargo # will have compiled files and executables debug/ target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk ================================================ FILE: boards/sparkfun-micromod-rp2040/CHANGELOG.md ================================================ # 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.3.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.1.1 - 2023-06-22 - Improve README and Documentation ## 0.1.0 - 2023-05-20 - Initial release ================================================ FILE: boards/sparkfun-micromod-rp2040/Cargo.toml ================================================ [package] name = "sparkfun-micromod-rp2040" version = "0.3.0" authors = ["Finomnis ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/sparkfun-micromod-rp2040" description = "Board Support Package for the SparkFun MicroMod RP2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m.workspace = true rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true cortex-m-rt = { workspace = true, optional = true } embedded-hal.workspace = true embedded_hal_0_2 = { workspace = true } nb.workspace = true [dev-dependencies] panic-probe = { workspace = true, features = ["print-defmt"] } panic-halt.workspace = true rp2040-hal = { workspace = true, features = ["defmt"] } defmt.workspace = true defmt-rtt.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt", "rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/sparkfun-micromod-rp2040/README.md ================================================ # [sparkfun-micromod-rp2040] - Board Support for the [SparkFun MicroMod RP2040] You should include this crate if you are writing code that you want to run on a [SparkFun MicroMod RP2040] - the RP2040 processor board for the [SparkFun MicroMod] ecosystem. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the MicroMod RP2040. [SparkFun MicroMod RP2040]: https://www.sparkfun.com/products/17720 [SparkFun MicroMod]: https://www.sparkfun.com/micromod [sparkfun-micromod-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/sparkfun-micromod-rp2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml sparkfun-micromod-rp2040 = "0.3.0" ``` In your program, you will need to call `sparkfun_micromod_rp2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/sparkfun-micromod-rp2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/sparkfun-micromod-rp2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` Then repeat the `cargo run` command above. ### [Blinky](./examples/sparkfun_micromod_blinky.rs) This example will blink the on-board LED. ### [Battery Voltage](./examples/sparkfun_micromod_battery_voltage.rs) This example will continuously print the current supply voltage. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/sparkfun-micromod-rp2040/build.rs ================================================ //! This build script makes sure the linker flag -Tdefmt.x is added //! for the examples. fn main() { println!("cargo:rustc-link-arg-examples=-Tdefmt.x"); } ================================================ FILE: boards/sparkfun-micromod-rp2040/examples/sparkfun_micromod_battery_voltage.rs ================================================ //! # SparkFun MicroMod Battery Voltage Example //! //! Continuously reads the battery voltage and prints it over defmt-rtt. //! //! Note that for this example to work, you need to change the runner //! to `probe-rs run` (in `.cargo/config.toml` at the root of the repository) //! and connect to the RP2040 via SWD, preferredly via the Raspberry //! Pi Debug Probe. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use sparkfun_micromod_rp2040 as bsp; // Import log macros and register global logger use defmt::*; use defmt_rtt as _; // Register panic handler use panic_probe as _; #[defmt::panic_handler] fn panic() -> ! { // don't print a panic message // this prevents the panic message being printed *twice* when `defmt::panic` is invoked cortex_m::asm::udf() } // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use bsp::hal; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use hal::pac; // Pull in any important traits use hal::prelude::*; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then blinks the LED in an /// infinite loop. #[bsp::entry] fn main() -> ! { info!("Battery Voltage Example!"); // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( bsp::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = bsp::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let mut adc = hal::Adc::new(pac.ADC, &mut pac.RESETS); let mut battery_voltage = bsp::BatteryVoltage::new( hal::adc::AdcPin::new(pins.batt_vin.into_floating_input()).unwrap(), ); // Print battery voltage once per second loop { println!("Battery: {} mV", battery_voltage.read(&mut adc)); delay.delay_ms(1000); } } // End of file ================================================ FILE: boards/sparkfun-micromod-rp2040/examples/sparkfun_micromod_blinky.rs ================================================ //! # SparkFun MicroMod Blinky Example //! //! Blinks the LED on a SparkFun MicroMod RP2040 board. //! //! This will blink an LED attached to GP25, which is the pin the SparkFun MicroMod RP2040 uses for //! the on-board LED. //! //! See the `Cargo.toml` file for Copyright and license details. #![no_std] #![no_main] // The macro for our start-up function use sparkfun_micromod_rp2040::entry; // GPIO traits use embedded_hal::digital::OutputPin; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; // Pull in any important traits use sparkfun_micromod_rp2040::hal::prelude::*; // A shorter alias for the Peripheral Access Crate, which provides low-level // register access use sparkfun_micromod_rp2040::hal::pac; // A shorter alias for the Hardware Abstraction Layer, which provides // higher-level drivers. use sparkfun_micromod_rp2040::hal; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then blinks the LED in an /// infinite loop. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( sparkfun_micromod_rp2040::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = sparkfun_micromod_rp2040::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Set the LED to be an output let mut led_pin = pins.led.into_push_pull_output(); // Blink the LED at 1 Hz loop { led_pin.set_high().unwrap(); delay.delay_ms(500); led_pin.set_low().unwrap(); delay.delay_ms(500); } } // End of file ================================================ FILE: boards/sparkfun-micromod-rp2040/src/lib.rs ================================================ #![no_std] //! Board Support Package for the SparkFun MicroMod RP2040. //! //! This crate serves as a HAL (Hardware Abstraction Layer) for the SparkFun MicroMod RP2040. Since the SparkFun MicroMod RP2040 //! is based on the RP2040 chip, it re-exports the [rp2040_hal] crate which contains the tooling to work with the //! rp2040 chip. //! //! # Examples: //! //! The following example turns on the onboard LED. Note that most of the logic works through the [rp2040_hal] crate. //! ```ignore //! #![no_main] //! use sparkfun_micromod_rp2040::entry; //! use panic_halt as _; //! use embedded_hal::digital::v2::OutputPin; //! use sparkfun_micromod_rp2040::hal::pac; //! use sparkfun_micromod_rp2040::hal; //! #[entry] //! fn does_not_have_to_be_main() -> ! { //! let mut pac = pac::Peripherals::take().unwrap(); //! let sio = hal::Sio::new(pac.SIO); //! let pins = rp_pico::Pins::new( //! pac.IO_BANK0, //! pac.PADS_BANK0, //! sio.gpio_bank0, //! &mut pac.RESETS, //! ); //! let mut led_pin = pins.led.into_push_pull_output(); //! led_pin.set_high().unwrap(); //! loop { //! } //! } //! ``` pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; /// The `entry` macro declares the starting function to the linker. /// This is similar to the `main` function in console applications. /// /// It is based on the [cortex_m_rt](https://docs.rs/cortex-m-rt/latest/cortex_m_rt/attr.entry.html) crate. /// /// # Examples /// ```ignore /// #![no_std] /// #![no_main] /// use sparkfun_micromod_rp2040::entry; /// #[entry] /// fn you_can_use_a_custom_main_name_here() -> ! { /// loop {} /// } /// ``` #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; use hal::gpio::{bank0::Gpio29, FunctionSioInput, PullNone}; pub use hal::pac; hal::bsp_pins!( /// GPIO 0 can serve as: /// - `UART_TX1` Gpio0 { name: gpio0, aliases: { FunctionUart, PullNone: UartTx1 } }, /// GPIO 1 can serve as: /// - `UART_RX1` Gpio1 { name: gpio1, aliases: { FunctionUart, PullNone: UartRx1 } }, /// GPIO 2 can serve as: /// - `UART_CTS1` /// - `AUD_LRCLK` Gpio2 { name: gpio2, aliases: { FunctionUart, PullNone: UartCts1, FunctionPio0, PullNone: AudLrclkPio0, FunctionPio1, PullNone: AudLrclkPio1 } }, /// GPIO 3 can serve as: /// - `UART_RTS1` /// - `AUD_BCLK` Gpio3 { name: gpio3, aliases: { FunctionUart, PullNone: UartRts1, FunctionPio0, PullNone: AudBclkPio0, FunctionPio1, PullNone: AudBclkPio1 } }, /// GPIO 4 can serve as: /// - `I2C_SDA` Gpio4 { name: gpio4, aliases: { FunctionI2C, PullUp: I2CSda } }, /// GPIO 5 can serve as: /// - `I2C_SCL` Gpio5 { name: gpio5, aliases: { FunctionI2C, PullUp: I2CScl } }, /// GPIO 6 can serve as: /// - `D0` Gpio6 { name: gpio6, aliases: { FunctionPwm, PullNone: D0Pwm, FunctionPio0, PullNone: D0Pio0, FunctionPio1, PullNone: D0Pio1 } }, /// GPIO 7 can serve as: /// - `D1` Gpio7 { name: gpio7, aliases: { FunctionPwm, PullNone: D1Pwm, FunctionPio0, PullNone: D1Pio0, FunctionPio1, PullNone: D1Pio1 } }, /// GPIO 8 can serve as: /// - `I2C_INT` /// - `UART_TX2` Gpio8 { name: gpio8, aliases: { FunctionI2C, PullUp: I2CInt, FunctionUart, PullNone: UartTx2 } }, /// GPIO 9 can serve as: /// - `SPI_CS1` /// - `UART_RX2` /// - `SDIO_DATA3` Gpio9 { name: gpio9, aliases: { FunctionUart, PullNone: UartRx2, FunctionSpi, PullNone: SpiCs1, FunctionPio0, PullNone: SdioData3Pio0, FunctionPio1, PullNone: SdioData3Pio1 } }, /// GPIO 10 can serve as: /// - `SDIO_DATA2` /// - `AUD_OUT` Gpio10 { name: gpio10, aliases: { FunctionPio0, PullNone: SdioData2Pio0, FunctionPio1, PullNone: SdioData2Pio1, FunctionPio0, PullNone: AudOutPio0, FunctionPio1, PullNone: AudOutPio1 } }, /// GPIO 11 can serve as: /// - `SDIO_DATA1` /// - `AUD_IN` Gpio11 { name: gpio11, aliases: { FunctionPio0, PullNone: SdioData1Pio0, FunctionPio1, PullNone: SdioData1Pio1, FunctionPio0, PullNone: AudInPio0, FunctionPio1, PullNone: AudInPio1 } }, /// GPIO 12 can serve as: /// - `SPI_COPI1` /// - `SDIO_DATA0` Gpio12 { name: gpio12, aliases: { FunctionSpi, PullNone: SpiCipo1, FunctionPio0, PullNone: SdioData0Pio0, FunctionPio1, PullNone: SdioData0Pio1 } }, /// GPIO 13 can serve as: /// - `PWM0` Gpio13 { name: gpio13, aliases: { FunctionPwm, PullNone: Pwm0 } }, /// GPIO 14 can serve as: /// - `SPI_SCK1` /// - `SDIO_SCK` Gpio14 { name: gpio14, aliases: { FunctionSpi, PullNone: SpiSck1, FunctionPio0, PullNone: SdioSckPio0, FunctionPio1, PullNone: SdioSckPio1 } }, /// GPIO 15 can serve as: /// - `SPI_COPI1` /// - `SDIO_CMD` Gpio15 { name: gpio15, aliases: { FunctionSpi, PullNone: SpiCopi1, FunctionPio0, PullNone: SdioCmdPio0, FunctionPio1, PullNone: SdioCmdPio1 } }, /// GPIO 16 can serve as: /// - `G0` Gpio16 { name: gpio16, aliases: { FunctionPwm, PullNone: G0Pwm, FunctionPio0, PullNone: G0Pio0, FunctionPio1, PullNone: G0Pio1 } }, /// GPIO 17 can serve as: /// - `G1` Gpio17 { name: gpio17, aliases: { FunctionPwm, PullNone: G1Pwm, FunctionPio0, PullNone: G1Pio0, FunctionPio1, PullNone: G1Pio1 } }, /// GPIO 18 can serve as: /// - `G2` Gpio18 { name: gpio18, aliases: { FunctionPwm, PullNone: G2Pwm, FunctionPio0, PullNone: G2Pio0, FunctionPio1, PullNone: G2Pio1 } }, /// GPIO 19 can serve as: /// - `G3` Gpio19 { name: gpio19, aliases: { FunctionPwm, PullNone: G3Pwm, FunctionPio0, PullNone: G3Pio0, FunctionPio1, PullNone: G3Pio1 } }, /// GPIO 20 can serve as: /// - `SPI_CIPO` /// - `G4` Gpio20 { name: gpio20, aliases: { FunctionSpi, PullNone: SpiCipo, FunctionPwm, PullNone: G4Pwm, FunctionPio0, PullNone: G4Pio0, FunctionPio1, PullNone: G4Pio1 } }, /// GPIO 21 can serve as: /// - `SPI_CS` /// - `G5` Gpio21 { name: gpio21, aliases: { FunctionSpi, PullNone: SpiCs, FunctionPwm, PullNone: G5Pwm, FunctionPio0, PullNone: G5Pio0, FunctionPio1, PullNone: G5Pio1 } }, /// GPIO 22 can serve as: /// - `SPI_SCK` /// - `G6` Gpio22 { name: gpio22, aliases: { FunctionSpi, PullNone: SpiSck, FunctionPwm, PullNone: G6Pwm, FunctionPio0, PullNone: G6Pio0, FunctionPio1, PullNone: G6Pio1 } }, /// GPIO 23 can serve as: /// - `SPI_COPI` /// - `G7` Gpio23 { name: gpio23, aliases: { FunctionSpi, PullNone: SpiCopi, FunctionPwm, PullNone: G7Pwm, FunctionPio0, PullNone: G7Pio0, FunctionPio1, PullNone: G7Pio1 } }, /// GPIO 24 can serve as: /// - `PWM1` /// - `AUD_MCLK` Gpio24 { name: gpio24, aliases: { FunctionPwm, PullNone: Pwm1, FunctionPio0, PullNone: AudMclkPio0, FunctionPio1, PullNone: AudMclkPio1 } }, /// GPIO 25 can serve as: /// - Builtin LED /// - `G10` Gpio25 { name: led, aliases: { FunctionPwm, PullNone: G10Pwm, FunctionPio0, PullNone: G10Pio0, FunctionPio1, PullNone: G10Pio1 } }, /// ADC 0 can serve as: /// - `ADC0` Gpio26 { name: adc0, }, /// ADC 1 can serve as: /// - `ADC1` Gpio27 { name: adc1, }, /// GPIO 28 can serve as: /// - `G9` Gpio28 { name: gpio28, aliases: { FunctionPwm, PullNone: G9Pwm, FunctionPio0, PullNone: G9Pio0, FunctionPio1, PullNone: G9Pio1 } }, /// ADC 3 can serve as: /// - `BATT_VIN` Gpio29 { name: batt_vin, }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; /// Alias for a configured pin pub type BattVin = hal::adc::AdcPin>; /// Driver for reading the battery volatage pub struct BatteryVoltage { pin: BattVin, } impl BatteryVoltage { /// Creates a new battery voltage reader pub fn new(pin: BattVin) -> Self { Self { pin } } /// Reads the current battery voltage /// /// # Return /// /// The current voltage in millivolts pub fn read(&mut self, adc: &mut hal::Adc) -> u16 { use embedded_hal_0_2::adc::OneShot; let raw_value: u32 = loop { match adc.read(&mut self.pin) { Ok(val) => break val, Err(nb::Error::WouldBlock) => (), Err(nb::Error::Other(_)) => unreachable!(), } }; // Convert value to millivolts // The raw ADC value is in in the range of 0..4096, // where 0 = 0V and 4096 = 3.3V. // The MicroMod interface defines that the voltage is divided by 3, // so the conversion formula: // value / 4096 * 3300(mV) * 3 let value = (raw_value * 3300 * 3) / 4096; // The maximum possible value is 9900, so it's safe to convert // back to u16. value as u16 } } ================================================ FILE: boards/sparkfun-pro-micro-rp2040/CHANGELOG.md ================================================ # 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.8.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.7.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.6.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 - Update to ws2812-pio 0.6.0 ## 0.5.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 ## 0.4.0 - 2022-08-26 ### Changed - Migrate from `embedded-time` to `fugit` - Bump `pio` to 0.2.0 - Bump `ws2812-pio` to 0.4.0 - Update to rp2040-hal 0.6.0 ## 0.3.0 - 2022-06-13 ### Changed - Update to rp2040-hal 0.5.0 ## 0.2.0 - 2022-03-11 ### Changed - Update to rp-hal 0.4.0 ## 0.1.0 - 2021-12-20 - Initial release ================================================ FILE: boards/sparkfun-pro-micro-rp2040/Cargo.toml ================================================ [package] name = "sparkfun-pro-micro-rp2040" version = "0.8.0" authors = ["Wilfried Chauveau ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/sparkfun-pro-micro-rp2040" description = "Board Support Package for the Sparkfun Pro Micro RP2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } embedded-hal = { workspace = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] fugit.workspace = true nb.workspace = true panic-halt.workspace = true pio.workspace = true smart-leds.workspace = true ws2812-pio.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/sparkfun-pro-micro-rp2040/README.md ================================================ # [sparkfun-pro-micro-rp2040] - Board Support for the [Sparkfun Pro Micro RP2040] You should include this crate if you are writing code that you want to run on a [Sparkfun Pro Micro RP2040] - a smaller [RP2040][Raspberry Silicon RP2040] board with USB-C and a WS2812B addressable LED. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Pro Micro RP2040. [Sparkfun Pro Micro RP2040]: https://www.sparkfun.com/products/18288 [sparkfun-pro-micro-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/sparkfun-pro-micro-rp2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml sparkfun-pro-micro-rp2040 = "0.8.0" ``` In your program, you will need to call `sparkfun_pro_micro_rp2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/sparkfun-pro-micro-rp2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/sparkfun-pro-micro-rp2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [Rainbow](./examples/sparkfun_pro_micro_rainbow.rs) This example will display a colour-wheel rainbow effect on the on-board LED. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/sparkfun-pro-micro-rp2040/examples/sparkfun_pro_micro_rainbow.rs ================================================ //! # Rainbow Example for the Pro Micro RP2040 //! //! Runs a rainbow-effect colour wheel on the on-board LED. //! //! Uses the `ws2812_pio` driver to control the LED, which in turns uses the //! RP2040's PIO block. #![no_std] #![no_main] use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use sparkfun_pro_micro_rp2040::entry; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use sparkfun_pro_micro_rp2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, pio::PIOExt, timer::Timer, watchdog::Watchdog, Sio, }, XOSC_CRYSTAL_FREQ, }; use ws2812_pio::Ws2812; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this /// function as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then the LED, then runs /// the colour wheel in an infinite loop. #[entry] fn main() -> ! { // Configure the RP2040 peripherals let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = sparkfun_pro_micro_rp2040::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Configure the addressable LED let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( pins.led.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); // Infinite colour wheel loop let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/sparkfun-pro-micro-rp2040/src/lib.rs ================================================ #![no_std] pub use rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( Gpio0 { name: tx0 }, Gpio1 { name: rx0 }, Gpio2 { name: gpio2 }, Gpio3 { name: gpio3 }, Gpio4 { name: gpio4 }, Gpio5 { name: gpio5 }, Gpio6 { name: gpio6 }, Gpio7 { name: gpio7 }, Gpio8 { name: tx1 }, Gpio9 { name: rx1 }, Gpio16 { name: sda }, Gpio17 { name: scl }, Gpio20 { name: cipo }, Gpio21 { name: ncs }, Gpio22 { name: sck }, Gpio23 { name: copi }, Gpio25 { name: led }, Gpio26 { name: adc0 }, Gpio27 { name: adc1 }, Gpio28 { name: adc2 }, Gpio29 { name: adc3 }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/sparkfun-thing-plus-rp2040/CHANGELOG.md ================================================ # 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.7.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.6.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.5.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 - Update to ws2812-pio 0.6.0 ## 0.4.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 ## 0.3.0 - 2022-08-26 ### Changed - Use `rp2040-hal`'s entry function. - Migrate from `embedded-time` to `fugit` - Bump `pio` to 0.2.0 - Bump `ws2812-pio` to 0.4.0 - Update to rp2040-hal 0.6.0 ## 0.2.0 - 2022-06-13 ### Changed - Update to rp2040-hal 0.5.0 ## 0.1.0 - 2022-04-28 - Initial release ================================================ FILE: boards/sparkfun-thing-plus-rp2040/Cargo.toml ================================================ [package] name = "sparkfun-thing-plus-rp2040" version = "0.7.0" authors = ["Tyler Pottenger ", "Wilfried Chauveau ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/sparkfun-thing-plus-rp2040" description = "Board Support Package for the Sparkfun Thing Plus RP2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } embedded-hal = { workspace = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] panic-halt.workspace = true smart-leds.workspace = true nb.workspace = true pio.workspace = true ws2812-pio.workspace = true fugit.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/sparkfun-thing-plus-rp2040/README.md ================================================ # [sparkfun-thing-plus-rp2040] - Board Support for the [Sparkfun Thing Plus RP2040] You should include this crate if you are writing code that you want to run on a [Sparkfun Thing Plus RP2040] - a smaller [RP2040][Raspberry Silicon RP2040] board with USB-C and a WS2812B addressable LED. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Thing Plus RP2040. [Sparkfun Thing Plus RP2040]: https://www.sparkfun.com/products/17745 [sparkfun-thing-plus-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/sparkfun-thing-plus-rp2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml sparkfun-thing-plus-rp2040 = "0.7.0" ``` In your program, you will need to call `sparkfun_thing_plus_rp2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/sparkfun-thing-plus-rp2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/sparkfun-thing-plus-rp2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [Rainbow](./examples/sparkfun_thing_plus_rainbow.rs) This example will display a colour-wheel rainbow effect on the on-board LED. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT licence or the Apache-2.0 licence when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific licence. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/sparkfun-thing-plus-rp2040/examples/sparkfun_thing_plus_rainbow.rs ================================================ //! # Rainbow Example for the Thing Plus RP2040 //! //! Runs a rainbow-effect colour wheel on the on-board LED. //! //! Uses the `ws2812_pio` driver to control the LED, which in turns uses the //! RP2040's PIO block. #![no_std] #![no_main] use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use sparkfun_thing_plus_rp2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, pio::PIOExt, timer::Timer, watchdog::Watchdog, Sio, }, XOSC_CRYSTAL_FREQ, }; use ws2812_pio::Ws2812; /// Entry point to our bare-metal application. /// /// The `#[sparkfun_thing_plus_rp2040::entry]` macro ensures the Cortex-M start-up code calls this /// function as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then the LED, then runs /// the colour wheel in an infinite loop. #[sparkfun_thing_plus_rp2040::entry] fn main() -> ! { // Configure the RP2040 peripherals let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = sparkfun_thing_plus_rp2040::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Configure the addressable LED let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( pins.ws2812.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); // Infinite colour wheel loop let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/sparkfun-thing-plus-rp2040/src/lib.rs ================================================ #![no_std] pub use rp2040_hal as hal; #[cfg(feature = "rt")] pub use rp2040_hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( Gpio0 { name: tx }, Gpio1 { name: rx }, Gpio2 { name: sck }, Gpio3 { name: copi }, Gpio4 { name: cipo }, Gpio6 { name: sda }, Gpio7 { name: scl }, Gpio8 { name: ws2812 }, Gpio16 { name: gpio16 }, Gpio17 { name: gpio17 }, Gpio18 { name: gpio18 }, Gpio19 { name: gpio19 }, Gpio20 { name: gpio20 }, Gpio21 { name: gpio21 }, Gpio22 { name: gpio22 }, Gpio25 { name: led }, Gpio26 { name: adc0 }, Gpio27 { name: adc1 }, Gpio28 { name: adc2 }, Gpio29 { name: adc3 }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/vcc-gnd-yd-rp2040/.gitignore ================================================ # Generated by Cargo # will have compiled files and executables debug/ target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk ================================================ FILE: boards/vcc-gnd-yd-rp2040/CHANGELOG.md ================================================ # 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.6.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 - Update to usb-device 0.3 ## 0.5.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.4.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 - Update to ws2812-pio 0.6.0 - Update to i2c-pio 0.6.0 ## 0.3.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 - Update to i2c-pio 0.5.0 ### Changed - Bump `i2c-pio` to 0.5.0 ## 0.2.0 - 2022-08-26 ### Changed - Migrate from `embedded-time` to `fugit` - Bump `ws2812-pio` to 0.4.0 - Bump `i2c-pio` to 0.4.0 - Update to rp2040-hal 0.6.0 ### Removed - Unused dependencies ## 0.1.0 - 2022-07-17 - Initial release ================================================ FILE: boards/vcc-gnd-yd-rp2040/Cargo.toml ================================================ [package] name = "vcc-gnd-yd-rp2040" version = "0.6.0" authors = ["Nicolas ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/vcc-gnd-yd-rp2040" description = "Board Support Package for the VCC-GND Studio YD-RP2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } fugit.workspace = true rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true usb-device.workspace = true [dev-dependencies] cortex-m.workspace = true embedded-hal.workspace = true nb.workspace = true panic-halt.workspace = true pio.workspace = true smart-leds.workspace = true ws2812-pio.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/vcc-gnd-yd-rp2040/README.md ================================================ # [vcc-gnd-yd-rp2040] - Board Support for the [VCC-GND Studio YD-RP2040] You should include this crate if you are writing code that you want to run on a [VCC-GND Studio YD-RP2040] - a PCB for the RP2040 chip with USB-C port, WS2812 RGB LED on GPIO23, user key on GPIO24 and built-in blue LED. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the YD-RP2040. [VCC-GND Studio YD-RP2040]: http://152.32.187.208:8080/yd-data/YD-RP2040/ [vcc-gnd-yd-rp2040]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/vcc-gnd-yd-rp2040 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml vcc-gnd-yd-rp2040 = "0.6.0" ``` In your program, you will need to call `vcc_gnd_studio_yd_rp2040::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/vcc-gnd-yd-rp2040 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/vcc-gnd-yd-rp2040 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs ``` then try repeating the `cargo run` command above. ### [yd_rp2040_blinky](./examples/yd_rp2040_blinky.rs) Flashes the YD-RP2040's onboard LED on and off. ### [yd_rp2040_neopixel_rainbow](./examples/yd_rp2040_neopixel_rainbow.rs) Flows smoothly through various colors on the YD-RP2040's onboard NeoPixel LED. ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/vcc-gnd-yd-rp2040/examples/yd_rp2040_blinky.rs ================================================ //! Blinks the LED on a VCC-GND Studio YD-RP2040 board //! //! This will blink on-board LED. #![no_std] #![no_main] use embedded_hal::digital::OutputPin; use panic_halt as _; use vcc_gnd_yd_rp2040::entry; use vcc_gnd_yd_rp2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let mut led_pin = pins.led.into_push_pull_output(); loop { led_pin.set_high().unwrap(); delay.delay_ms(1500); led_pin.set_low().unwrap(); delay.delay_ms(1500); } } ================================================ FILE: boards/vcc-gnd-yd-rp2040/examples/yd_rp2040_neopixel_rainbow.rs ================================================ //! Rainbow effect color wheel using the onboard NeoPixel on a VCC-GND Studio YD-RP2040 board //! //! This flows smoothly through various colors on the onboard NeoPixel. //! Uses the `ws2812_pio` driver to control the NeoPixel, which in turns uses the //! RP2040's PIO block. #![no_std] #![no_main] use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use vcc_gnd_yd_rp2040::entry; use vcc_gnd_yd_rp2040::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, pio::PIOExt, timer::Timer, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; use ws2812_pio::Ws2812; #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Configure the addressable LED let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( // The onboard NeoPixel is attached to GPIO pin #16 on the Feather RP2040. pins.neopixel.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); // Infinite colour wheel loop let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/vcc-gnd-yd-rp2040/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( /// GPIO 0 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp0Spi0Rx] | /// | `UART0 TX` | [crate::Gp0Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp0I2C0Sda] | /// | `PWM0 A` | [crate::Gp0Pwm0A] | /// | `PIO0` | [crate::Gp0Pio0] | /// | `PIO1` | [crate::Gp0Pio1] | Gpio0 { name: gpio0, aliases: { /// UART Function alias for pin [crate::Pins::gpio0]. FunctionUart, PullNone: Gp0Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio0]. FunctionSpi, PullNone: Gp0Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio0]. FunctionI2C, PullUp: Gp0I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio0]. FunctionPwm, PullNone: Gp0Pwm0A, /// PIO0 Function alias for pin [crate::Pins::gpio0]. FunctionPio0, PullNone: Gp0Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio0]. FunctionPio1, PullNone: Gp0Pio1 } }, /// GPIO 1 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp1Spi0Csn] | /// | `UART0 RX` | [crate::Gp1Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp1I2C0Scl] | /// | `PWM0 B` | [crate::Gp1Pwm0B] | /// | `PIO0` | [crate::Gp1Pio0] | /// | `PIO1` | [crate::Gp1Pio1] | Gpio1 { name: gpio1, aliases: { /// UART Function alias for pin [crate::Pins::gpio1]. FunctionUart, PullNone: Gp1Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio1]. FunctionSpi, PullNone: Gp1Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio1]. FunctionI2C, PullUp: Gp1I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio1]. FunctionPwm, PullNone: Gp1Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio1]. FunctionPio0, PullNone: Gp1Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio1]. FunctionPio1, PullNone: Gp1Pio1 } }, /// GPIO 2 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp2Spi0Sck] | /// | `UART0 CTS` | [crate::Gp2Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp2I2C1Sda] | /// | `PWM1 A` | [crate::Gp2Pwm1A] | /// | `PIO0` | [crate::Gp2Pio0] | /// | `PIO1` | [crate::Gp2Pio1] | Gpio2 { name: gpio2, aliases: { /// UART Function alias for pin [crate::Pins::gpio2]. FunctionUart, PullNone: Gp2Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio2]. FunctionSpi, PullNone: Gp2Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio2]. FunctionI2C, PullUp: Gp2I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio2]. FunctionPwm, PullNone: Gp2Pwm1A, /// PIO0 Function alias for pin [crate::Pins::gpio2]. FunctionPio0, PullNone: Gp2Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio2]. FunctionPio1, PullNone: Gp2Pio1 } }, /// GPIO 3 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp3Spi0Tx] | /// | `UART0 RTS` | [crate::Gp3Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp3I2C1Scl] | /// | `PWM1 B` | [crate::Gp3Pwm1B] | /// | `PIO0` | [crate::Gp3Pio0] | /// | `PIO1` | [crate::Gp3Pio1] | Gpio3 { name: gpio3, aliases: { /// UART Function alias for pin [crate::Pins::gpio3]. FunctionUart, PullNone: Gp3Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio3]. FunctionSpi, PullNone: Gp3Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio3]. FunctionI2C, PullUp: Gp3I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio3]. FunctionPwm, PullNone: Gp3Pwm1B, /// PIO0 Function alias for pin [crate::Pins::gpio3]. FunctionPio0, PullNone: Gp3Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio3]. FunctionPio1, PullNone: Gp3Pio1 } }, /// GPIO 4 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp4Spi0Rx] | /// | `UART1 TX` | [crate::Gp4Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp4I2C0Sda] | /// | `PWM2 A` | [crate::Gp4Pwm2A] | /// | `PIO0` | [crate::Gp4Pio0] | /// | `PIO1` | [crate::Gp4Pio1] | Gpio4 { name: gpio4, aliases: { /// UART Function alias for pin [crate::Pins::gpio4]. FunctionUart, PullNone: Gp4Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio4]. FunctionSpi, PullNone: Gp4Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio4]. FunctionI2C, PullUp: Gp4I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio4]. FunctionPwm, PullNone: Gp4Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio4]. FunctionPio0, PullNone: Gp4Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio4]. FunctionPio1, PullNone: Gp4Pio1 } }, /// GPIO 5 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp5Spi0Csn] | /// | `UART1 RX` | [crate::Gp5Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp5I2C0Scl] | /// | `PWM2 B` | [crate::Gp5Pwm2B] | /// | `PIO0` | [crate::Gp5Pio0] | /// | `PIO1` | [crate::Gp5Pio1] | Gpio5 { name: gpio5, aliases: { /// UART Function alias for pin [crate::Pins::gpio5]. FunctionUart, PullNone: Gp5Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio5]. FunctionSpi, PullNone: Gp5Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio5]. FunctionI2C, PullUp: Gp5I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio5]. FunctionPwm, PullNone: Gp5Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio5]. FunctionPio0, PullNone: Gp5Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio5]. FunctionPio1, PullNone: Gp5Pio1 } }, /// GPIO 6 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp6Spi0Sck] | /// | `UART1 CTS` | [crate::Gp6Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp6I2C1Sda] | /// | `PWM3 A` | [crate::Gp6Pwm3A] | /// | `PIO0` | [crate::Gp6Pio0] | /// | `PIO1` | [crate::Gp6Pio1] | Gpio6 { name: gpio6, aliases: { /// UART Function alias for pin [crate::Pins::gpio6]. FunctionUart, PullNone: Gp6Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio6]. FunctionSpi, PullNone: Gp6Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio6]. FunctionI2C, PullUp: Gp6I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio6]. FunctionPwm, PullNone: Gp6Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio6]. FunctionPio0, PullNone: Gp6Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio6]. FunctionPio1, PullNone: Gp6Pio1 } }, /// GPIO 7 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp7Spi0Tx] | /// | `UART1 RTS` | [crate::Gp7Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp7I2C1Scl] | /// | `PWM3 B` | [crate::Gp7Pwm3B] | /// | `PIO0` | [crate::Gp7Pio0] | /// | `PIO1` | [crate::Gp7Pio1] | Gpio7 { name: gpio7, aliases: { /// UART Function alias for pin [crate::Pins::gpio7]. FunctionUart, PullNone: Gp7Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio7]. FunctionSpi, PullNone: Gp7Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio7]. FunctionI2C, PullUp: Gp7I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio7]. FunctionPwm, PullNone: Gp7Pwm3B, /// PIO0 Function alias for pin [crate::Pins::gpio7]. FunctionPio0, PullNone: Gp7Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio7]. FunctionPio1, PullNone: Gp7Pio1 } }, /// GPIO 8 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp8Spi1Rx] | /// | `UART1 TX` | [crate::Gp8Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp8I2C0Sda] | /// | `PWM4 A` | [crate::Gp8Pwm4A] | /// | `PIO0` | [crate::Gp8Pio0] | /// | `PIO1` | [crate::Gp8Pio1] | Gpio8 { name: gpio8, aliases: { /// UART Function alias for pin [crate::Pins::gpio8]. FunctionUart, PullNone: Gp8Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio8]. FunctionSpi, PullNone: Gp8Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio8]. FunctionI2C, PullUp: Gp8I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio8]. FunctionPwm, PullNone: Gp8Pwm4A, /// PIO0 Function alias for pin [crate::Pins::gpio8]. FunctionPio0, PullNone: Gp8Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio8]. FunctionPio1, PullNone: Gp8Pio1 } }, /// GPIO 9 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp9Spi1Csn] | /// | `UART1 RX` | [crate::Gp9Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp9I2C0Scl] | /// | `PWM4 B` | [crate::Gp9Pwm4B] | /// | `PIO0` | [crate::Gp9Pio0] | /// | `PIO1` | [crate::Gp9Pio1] | Gpio9 { name: gpio9, aliases: { /// UART Function alias for pin [crate::Pins::gpio9]. FunctionUart, PullNone: Gp9Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio9]. FunctionSpi, PullNone: Gp9Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio9]. FunctionI2C, PullUp: Gp9I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio9]. FunctionPwm, PullNone: Gp9Pwm4B, /// PIO0 Function alias for pin [crate::Pins::gpio9]. FunctionPio0, PullNone: Gp9Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio9]. FunctionPio1, PullNone: Gp9Pio1 } }, /// GPIO 10 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp10Spi1Sck] | /// | `UART1 CTS` | [crate::Gp10Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp10I2C1Sda] | /// | `PWM5 A` | [crate::Gp10Pwm5A] | /// | `PIO0` | [crate::Gp10Pio0] | /// | `PIO1` | [crate::Gp10Pio1] | Gpio10 { name: gpio10, aliases: { /// UART Function alias for pin [crate::Pins::gpio10]. FunctionUart, PullNone: Gp10Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio10]. FunctionSpi, PullNone: Gp10Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio10]. FunctionI2C, PullUp: Gp10I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio10]. FunctionPwm, PullNone: Gp10Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio10]. FunctionPio0, PullNone: Gp10Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio10]. FunctionPio1, PullNone: Gp10Pio1 } }, /// GPIO 11 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp11Spi1Tx] | /// | `UART1 RTS` | [crate::Gp11Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp11I2C1Scl] | /// | `PWM5 B` | [crate::Gp11Pwm5B] | /// | `PIO0` | [crate::Gp11Pio0] | /// | `PIO1` | [crate::Gp11Pio1] | Gpio11 { name: gpio11, aliases: { /// UART Function alias for pin [crate::Pins::gpio11]. FunctionUart, PullNone: Gp11Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio11]. FunctionSpi, PullNone: Gp11Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio11]. FunctionI2C, PullUp: Gp11I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio11]. FunctionPwm, PullNone: Gp11Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio11]. FunctionPio0, PullNone: Gp11Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio11]. FunctionPio1, PullNone: Gp11Pio1 } }, /// GPIO 12 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp12Spi1Rx] | /// | `UART0 TX` | [crate::Gp12Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp12I2C0Sda] | /// | `PWM6 A` | [crate::Gp12Pwm6A] | /// | `PIO0` | [crate::Gp12Pio0] | /// | `PIO1` | [crate::Gp12Pio1] | Gpio12 { name: gpio12, aliases: { /// UART Function alias for pin [crate::Pins::gpio12]. FunctionUart, PullNone: Gp12Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio12]. FunctionSpi, PullNone: Gp12Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio12]. FunctionI2C, PullUp: Gp12I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio12]. FunctionPwm, PullNone: Gp12Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio12]. FunctionPio0, PullNone: Gp12Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio12]. FunctionPio1, PullNone: Gp12Pio1 } }, /// GPIO 13 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp13Spi1Csn] | /// | `UART0 RX` | [crate::Gp13Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp13I2C0Scl] | /// | `PWM6 B` | [crate::Gp13Pwm6B] | /// | `PIO0` | [crate::Gp13Pio0] | /// | `PIO1` | [crate::Gp13Pio1] | Gpio13 { name: gpio13, aliases: { /// UART Function alias for pin [crate::Pins::gpio13]. FunctionUart, PullNone: Gp13Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio13]. FunctionSpi, PullNone: Gp13Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio13]. FunctionI2C, PullUp: Gp13I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio13]. FunctionPwm, PullNone: Gp13Pwm6B, /// PIO0 Function alias for pin [crate::Pins::gpio13]. FunctionPio0, PullNone: Gp13Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio13]. FunctionPio1, PullNone: Gp13Pio1 } }, /// GPIO 14 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp14Spi1Sck] | /// | `UART0 CTS` | [crate::Gp14Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp14I2C1Sda] | /// | `PWM7 A` | [crate::Gp14Pwm7A] | /// | `PIO0` | [crate::Gp14Pio0] | /// | `PIO1` | [crate::Gp14Pio1] | Gpio14 { name: gpio14, aliases: { /// UART Function alias for pin [crate::Pins::gpio14]. FunctionUart, PullNone: Gp14Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio14]. FunctionSpi, PullNone: Gp14Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio14]. FunctionI2C, PullUp: Gp14I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio14]. FunctionPwm, PullNone: Gp14Pwm7A, /// PIO0 Function alias for pin [crate::Pins::gpio14]. FunctionPio0, PullNone: Gp14Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio14]. FunctionPio1, PullNone: Gp14Pio1 } }, /// GPIO 15 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp15Spi1Tx] | /// | `UART0 RTS` | [crate::Gp15Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp15I2C1Scl] | /// | `PWM7 B` | [crate::Gp15Pwm7B] | /// | `PIO0` | [crate::Gp15Pio0] | /// | `PIO1` | [crate::Gp15Pio1] | Gpio15 { name: gpio15, aliases: { /// UART Function alias for pin [crate::Pins::gpio15]. FunctionUart, PullNone: Gp15Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio15]. FunctionSpi, PullNone: Gp15Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio15]. FunctionI2C, PullUp: Gp15I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio15]. FunctionPwm, PullNone: Gp15Pwm7B, /// PIO0 Function alias for pin [crate::Pins::gpio15]. FunctionPio0, PullNone: Gp15Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio15]. FunctionPio1, PullNone: Gp15Pio1 } }, /// GPIO 16 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp16Spi0Rx] | /// | `UART0 TX` | [crate::Gp16Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp16I2C0Sda] | /// | `PWM0 A` | [crate::Gp16Pwm0A] | /// | `PIO0` | [crate::Gp16Pio0] | /// | `PIO1` | [crate::Gp16Pio1] | Gpio16 { name: gpio16, aliases: { /// UART Function alias for pin [crate::Pins::gpio16]. FunctionUart, PullNone: Gp16Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio16]. FunctionSpi, PullNone: Gp16Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio16]. FunctionI2C, PullUp: Gp16I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio16]. FunctionPwm, PullNone: Gp16Pwm0A, /// PIO0 Function alias for pin [crate::Pins::gpio16]. FunctionPio0, PullNone: Gp16Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio16]. FunctionPio1, PullNone: Gp16Pio1 } }, /// GPIO 17 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp17Spi0Csn] | /// | `UART0 RX` | [crate::Gp17Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp17I2C0Scl] | /// | `PWM0 B` | [crate::Gp17Pwm0B] | /// | `PIO0` | [crate::Gp17Pio0] | /// | `PIO1` | [crate::Gp17Pio1] | Gpio17 { name: gpio17, aliases: { /// UART Function alias for pin [crate::Pins::gpio17]. FunctionUart, PullNone: Gp17Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio17]. FunctionSpi, PullNone: Gp17Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio17]. FunctionI2C, PullUp: Gp17I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio17]. FunctionPwm, PullNone: Gp17Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio17]. FunctionPio0, PullNone: Gp17Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio17]. FunctionPio1, PullNone: Gp17Pio1 } }, /// GPIO 18 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp18Spi0Sck] | /// | `UART0 CTS` | [crate::Gp18Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp18I2C1Sda] | /// | `PWM1 A` | [crate::Gp18Pwm1A] | /// | `PIO0` | [crate::Gp18Pio0] | /// | `PIO1` | [crate::Gp18Pio1] | Gpio18 { name: gpio18, aliases: { /// UART Function alias for pin [crate::Pins::gpio18]. FunctionUart, PullNone: Gp18Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio18]. FunctionSpi, PullNone: Gp18Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio18]. FunctionI2C, PullUp: Gp18I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio18]. FunctionPwm, PullNone: Gp18Pwm1A, /// PIO0 Function alias for pin [crate::Pins::gpio18]. FunctionPio0, PullNone: Gp18Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio18]. FunctionPio1, PullNone: Gp18Pio1 } }, /// GPIO 19 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp19Spi0Tx] | /// | `UART0 RTS` | [crate::Gp19Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp19I2C1Scl] | /// | `PWM1 B` | [crate::Gp19Pwm1B] | /// | `PIO0` | [crate::Gp19Pio0] | /// | `PIO1` | [crate::Gp19Pio1] | Gpio19 { name: gpio19, aliases: { /// UART Function alias for pin [crate::Pins::gpio19]. FunctionUart, PullNone: Gp19Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio19]. FunctionSpi, PullNone: Gp19Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio19]. FunctionI2C, PullUp: Gp19I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio19]. FunctionPwm, PullNone: Gp19Pwm1B, /// PIO0 Function alias for pin [crate::Pins::gpio19]. FunctionPio0, PullNone: Gp19Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio19]. FunctionPio1, PullNone: Gp19Pio1 } }, /// GPIO 20 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp20Spi0Rx] | /// | `UART1 TX` | [crate::Gp20Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp20I2C0Sda] | /// | `PWM2 A` | [crate::Gp20Pwm2A] | /// | `PIO0` | [crate::Gp20Pio0] | /// | `PIO1` | [crate::Gp20Pio1] | Gpio20 { name: gpio20, aliases: { /// UART Function alias for pin [crate::Pins::gpio20]. FunctionUart, PullNone: Gp20Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio20]. FunctionSpi, PullNone: Gp20Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio20]. FunctionI2C, PullUp: Gp20I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio20]. FunctionPwm, PullNone: Gp20Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio20]. FunctionPio0, PullNone: Gp20Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio20]. FunctionPio1, PullNone: Gp20Pio1 } }, /// GPIO 21 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp21Spi0Csn] | /// | `UART1 RX` | [crate::Gp21Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp21I2C0Scl] | /// | `PWM2 B` | [crate::Gp21Pwm2B] | /// | `PIO0` | [crate::Gp21Pio0] | /// | `PIO1` | [crate::Gp21Pio1] | Gpio21 { name: gpio21, aliases: { /// UART Function alias for pin [crate::Pins::gpio21]. FunctionUart, PullNone: Gp21Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio21]. FunctionSpi, PullNone: Gp21Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio21]. FunctionI2C, PullUp: Gp21I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio21]. FunctionPwm, PullNone: Gp21Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio21]. FunctionPio0, PullNone: Gp21Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio21]. FunctionPio1, PullNone: Gp21Pio1 } }, /// GPIO 22 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp22Spi0Sck] | /// | `UART1 CTS` | [crate::Gp22Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp22I2C1Sda] | /// | `PWM3 A` | [crate::Gp22Pwm3A] | /// | `PIO0` | [crate::Gp22Pio0] | /// | `PIO1` | [crate::Gp22Pio1] | Gpio22 { name: gpio22, aliases: { /// UART Function alias for pin [crate::Pins::gpio22]. FunctionUart, PullNone: Gp22Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio22]. FunctionSpi, PullNone: Gp22Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio22]. FunctionI2C, PullUp: Gp22I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio22]. FunctionPwm, PullNone: Gp22Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio22]. FunctionPio0, PullNone: Gp22Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio22]. FunctionPio1, PullNone: Gp22Pio1 } }, /// GPIO 23 is connected to the WS2812 RGB LED of the YD-RP2040 board. Gpio23 { name: neopixel, }, /// GPIO 24 is connected to the user key of the YD-RP2040 board. Gpio24 { name: user_key, }, /// GPIO 25 is connected to the blue LED of the YD-RP2040 board. Gpio25 { name: led, }, /// GPIO 26 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp26Spi1Sck] | /// | `UART1 CTS` | [crate::Gp26Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp26I2C1Sda] | /// | `PWM5 A` | [crate::Gp26Pwm5A] | /// | `PIO0` | [crate::Gp26Pio0] | /// | `PIO1` | [crate::Gp26Pio1] | Gpio26 { name: gpio26, aliases: { /// UART Function alias for pin [crate::Pins::gpio26]. FunctionUart, PullNone: Gp26Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio26]. FunctionSpi, PullNone: Gp26Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio26]. FunctionI2C, PullUp: Gp26I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio26]. FunctionPwm, PullNone: Gp26Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio26]. FunctionPio0, PullNone: Gp26Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio26]. FunctionPio1, PullNone: Gp26Pio1 } }, /// GPIO 27 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp27Spi1Tx] | /// | `UART1 RTS` | [crate::Gp27Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp27I2C1Scl] | /// | `PWM5 B` | [crate::Gp27Pwm5B] | /// | `PIO0` | [crate::Gp27Pio0] | /// | `PIO1` | [crate::Gp27Pio1] | Gpio27 { name: gpio27, aliases: { /// UART Function alias for pin [crate::Pins::gpio27]. FunctionUart, PullNone: Gp27Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio27]. FunctionSpi, PullNone: Gp27Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio27]. FunctionI2C, PullUp: Gp27I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio27]. FunctionPwm, PullNone: Gp27Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio27]. FunctionPio0, PullNone: Gp27Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio27]. FunctionPio1, PullNone: Gp27Pio1 } }, /// GPIO 28 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp28Spi1Rx] | /// | `UART0 TX` | [crate::Gp28Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp28I2C0Sda] | /// | `PWM6 A` | [crate::Gp28Pwm6A] | /// | `PIO0` | [crate::Gp28Pio0] | /// | `PIO1` | [crate::Gp28Pio1] | Gpio28 { name: gpio28, aliases: { /// UART Function alias for pin [crate::Pins::gpio28]. FunctionUart, PullNone: Gp28Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio28]. FunctionSpi, PullNone: Gp28Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio28]. FunctionI2C, PullUp: Gp28I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio28]. FunctionPwm, PullNone: Gp28Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio28]. FunctionPio0, PullNone: Gp28Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio28]. FunctionPio1, PullNone: Gp28Pio1 } }, /// GPIO 29 is connected to voltage_monitor of the YD-RP2040 board. Gpio29 { name: gpio29, aliases: { /// UART Function alias for pin [crate::Pins::gpio29]. FunctionUart, PullNone: Gp29Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio29]. FunctionSpi, PullNone: Gp29Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio29]. FunctionI2C, PullUp: Gp29I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio29]. FunctionPwm, PullNone: Gp29Pwm6B, /// PIO0 Function alias for pin [crate::Pins::gpio29]. FunctionPio0, PullNone: Gp29Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio29]. FunctionPio1, PullNone: Gp29Pio1 } }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/waveshare-rp2040-lcd-0-96/CHANGELOG.md ================================================ # 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.8.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.7.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 ## 0.6.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 ## 0.5.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 ## 0.4.0 - 2022-11-15 ### Changed - Inital release - Copied from waveshare-rp2040-zero - Update board name ================================================ FILE: boards/waveshare-rp2040-lcd-0-96/Cargo.toml ================================================ [package] name = "waveshare-rp2040-lcd-0-96" version = "0.8.0" authors = ["René van Dorst ", "Andrea Nall ", "TilCreator ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/waveshare-rp2040-lcd-0_96" description = "Board Support Package for the Waveshare RP2040 LCD 0.96 inch" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true panic-halt.workspace = true embedded-hal.workspace = true fugit.workspace = true nb.workspace = true embedded-graphics.workspace = true st7735-lcd = { workspace = true, features = ["graphics"] } [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it doesn't hurt to enable it rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/waveshare-rp2040-lcd-0-96/README.md ================================================ # [waveshare-rp2040-lcd-0-96] - Board Support for the [Waveshare RP2040 LCD 0.96] You should include this crate if you are writing code that you want to run on an [Waveshare RP2040 LCD 0.96] - a very small RP2040 breakout board with USB-C, a 65K IPS LCD 160x80, 16MBit Flash and 1A battery charger from Waveshare. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Feather. [Waveshare RP2040 LCD 0.96]: https://www.waveshare.com/wiki/RP2040-LCD-0.96 [waveshare-rp2040-lcd-0-96]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/waveshare-rp2040-lcd-0-96 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml waveshare-rp2040-lcd-0-96 = "0.8.0" ``` In your program, you will need to call `waveshare_rp2040_lcd_0_96::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/waveshare-rp2040-lcd-0-96 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/waveshare-rp2040-lcd-0-96 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [waveshare_rp2040_lcd_demo](./examples/waveshare_rp2040_lcd_demo.rs) Draws a red and green line with a blue regtangle. After that is fills the screen line for line, that end it starts over with an other colour, RED, GREEN and BLUE. ## Contributing Contributions are what make the open source community such an amazing place to be, learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/waveshare-rp2040-lcd-0-96/examples/waveshare_rp2040_lcd_demo.rs ================================================ //! Example of graphics on the LCD of the Waveshare RP2040-LCD-0.96 //! //! Draws a red and green line with a blue rectangle. //! After that it fills the screen line for line, at the end it starts over with //! another colour, RED, GREEN and BLUE. #![no_std] #![no_main] use cortex_m::delay::Delay; use embedded_graphics::primitives::Line; use fugit::RateExtU32; use panic_halt as _; use waveshare_rp2040_lcd_0_96::entry; use waveshare_rp2040_lcd_0_96::{ hal::{ self, clocks::{init_clocks_and_plls, Clock}, pac, pio::PIOExt, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; use embedded_graphics::{ pixelcolor::Rgb565, prelude::*, primitives::{PrimitiveStyle, PrimitiveStyleBuilder, Rectangle}, }; use st7735_lcd::{Orientation, ST7735}; const LCD_WIDTH: u32 = 160; const LCD_HEIGHT: u32 = 80; #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Set up the delay for the first core. let sys_freq = clocks.system_clock.freq().to_Hz(); let mut delay = Delay::new(core.SYST, sys_freq); let (mut _pio, _sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); // https://www.waveshare.com/wiki/RP2040-LCD-0.96 // ST7735S LCD let lcd_dc = pins.gp8.into_push_pull_output(); let lcd_clk = pins.gp10.into_function::(); let lcd_mosi = pins.gp11.into_function::(); let lcd_rst = pins .gp12 .into_push_pull_output_in_state(hal::gpio::PinState::High); let mut _lcd_bl = pins .gp25 .into_push_pull_output_in_state(hal::gpio::PinState::High); let spi = hal::Spi::<_, _, _, 8>::new(pac.SPI1, (lcd_mosi, lcd_clk)); // Exchange the uninitialised SPI driver for an initialised one let spi = spi.init( &mut pac.RESETS, clocks.peripheral_clock.freq(), 10.MHz(), embedded_hal::spi::MODE_0, ); // LCD is a 65K IPS LCD 160x80, color order is BGR and a offset 1,26 pixel. // LCD controller can correct this by settings the order bit (bit 3) in MADCTL register. // Also the colours are inverted, LCD controller can also correct this by writing to INVON register with no paramters. // All this is handled by the ST7735 crate. let mut display = ST7735::new(spi, lcd_dc, lcd_rst, false, true, LCD_WIDTH, LCD_HEIGHT); display.init(&mut delay).unwrap(); display.set_orientation(&Orientation::Landscape).unwrap(); display.set_offset(1, 26); let lcd_zero = Point::zero(); let lcd_max_corner = Point::new((LCD_WIDTH - 1) as i32, (LCD_HEIGHT - 1) as i32); let style = PrimitiveStyleBuilder::new() .fill_color(Rgb565::BLUE) .build(); Rectangle::with_corners(lcd_zero, lcd_max_corner) .into_styled(style) .draw(&mut display) .unwrap(); let style = PrimitiveStyleBuilder::new() .fill_color(Rgb565::BLACK) .build(); Rectangle::with_corners( Point::new(1, 1), Point::new((LCD_WIDTH - 2) as i32, (LCD_HEIGHT - 2) as i32), ) .into_styled(style) .draw(&mut display) .unwrap(); Line::new(lcd_zero, lcd_max_corner) .into_styled(PrimitiveStyle::with_stroke(Rgb565::RED, 1)) .draw(&mut display) .unwrap(); Line::new( Point::new(0, (LCD_HEIGHT - 1) as i32), Point::new((LCD_WIDTH - 1) as i32, 0), ) .into_styled(PrimitiveStyle::with_stroke(Rgb565::GREEN, 1)) .draw(&mut display) .unwrap(); // Infinite colour wheel loop let mut l: i32 = 0; let mut c = Rgb565::RED; loop { Line::new(Point::new(0, l), Point::new((LCD_WIDTH - 1) as i32, l)) .into_styled(PrimitiveStyle::with_stroke(c, 1)) .draw(&mut display) .unwrap(); delay.delay_ms(10); l += 1; if l == LCD_HEIGHT as i32 { l = 0; c = match c { Rgb565::RED => Rgb565::GREEN, Rgb565::GREEN => Rgb565::BLUE, _ => Rgb565::RED, } } } } ================================================ FILE: boards/waveshare-rp2040-lcd-0-96/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( /// GPIO 0 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp0Spi0Rx] | /// | `UART0 TX` | [crate::Gp0Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp0I2C0Sda] | /// | `PWM0 A` | [crate::Gp0Pwm0A] | /// | `PIO0` | [crate::Gp0Pio0] | /// | `PIO1` | [crate::Gp0Pio1] | Gpio0 { name: gp0, aliases: { /// UART Function alias for pin [crate::Pins::gpio0]. FunctionUart, PullNone: Gp0Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio0]. FunctionSpi, PullNone: Gp0Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio0]. FunctionI2C, PullUp: Gp0I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio0]. FunctionPwm, PullNone: Gp0Pwm0A, /// PIO0 Function alias for pin [crate::Pins::gpio0]. FunctionPio0, PullNone: Gp0Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio0]. FunctionPio1, PullNone: Gp0Pio1 } }, /// GPIO 1 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp1Spi0Csn] | /// | `UART0 RX` | [crate::Gp1Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp1I2C0Scl] | /// | `PWM0 B` | [crate::Gp1Pwm0B] | /// | `PIO0` | [crate::Gp1Pio0] | /// | `PIO1` | [crate::Gp1Pio1] | Gpio1 { name: gp1, aliases: { /// UART Function alias for pin [crate::Pins::gpio1]. FunctionUart, PullNone: Gp1Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio1]. FunctionSpi, PullNone: Gp1Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio1]. FunctionI2C, PullUp: Gp1I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio1]. FunctionPwm, PullNone: Gp1Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio1]. FunctionPio0, PullNone: Gp1Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio1]. FunctionPio1, PullNone: Gp1Pio1 } }, /// GPIO 2 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp2Spi0Sck] | /// | `UART0 CTS` | [crate::Gp2Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp2I2C1Sda] | /// | `PWM1 A` | [crate::Gp2Pwm1A] | /// | `PIO0` | [crate::Gp2Pio0] | /// | `PIO1` | [crate::Gp2Pio1] | Gpio2 { name: gp2, aliases: { /// UART Function alias for pin [crate::Pins::gpio2]. FunctionUart, PullNone: Gp2Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio2]. FunctionSpi, PullNone: Gp2Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio2]. FunctionI2C, PullUp: Gp2I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio2]. FunctionPwm, PullNone: Gp2Pwm1A, /// PIO0 Function alias for pin [crate::Pins::gpio2]. FunctionPio0, PullNone: Gp2Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio2]. FunctionPio1, PullNone: Gp2Pio1 } }, /// GPIO 3 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp3Spi0Tx] | /// | `UART0 RTS` | [crate::Gp3Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp3I2C1Scl] | /// | `PWM1 B` | [crate::Gp3Pwm1B] | /// | `PIO0` | [crate::Gp3Pio0] | /// | `PIO1` | [crate::Gp3Pio1] | Gpio3 { name: gp3, aliases: { /// UART Function alias for pin [crate::Pins::gpio3]. FunctionUart, PullNone: Gp3Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio3]. FunctionSpi, PullNone: Gp3Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio3]. FunctionI2C, PullUp: Gp3I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio3]. FunctionPwm, PullNone: Gp3Pwm1B, /// PIO0 Function alias for pin [crate::Pins::gpio3]. FunctionPio0, PullNone: Gp3Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio3]. FunctionPio1, PullNone: Gp3Pio1 } }, /// GPIO 4 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp4Spi0Rx] | /// | `UART1 TX` | [crate::Gp4Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp4I2C0Sda] | /// | `PWM2 A` | [crate::Gp4Pwm2A] | /// | `PIO0` | [crate::Gp4Pio0] | /// | `PIO1` | [crate::Gp4Pio1] | Gpio4 { name: gp4, aliases: { /// UART Function alias for pin [crate::Pins::gpio4]. FunctionUart, PullNone: Gp4Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio4]. FunctionSpi, PullNone: Gp4Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio4]. FunctionI2C, PullUp: Gp4I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio4]. FunctionPwm, PullNone: Gp4Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio4]. FunctionPio0, PullNone: Gp4Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio4]. FunctionPio1, PullNone: Gp4Pio1 } }, /// GPIO 5 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp5Spi0Csn] | /// | `UART1 RX` | [crate::Gp5Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp5I2C0Scl] | /// | `PWM2 B` | [crate::Gp5Pwm2B] | /// | `PIO0` | [crate::Gp5Pio0] | /// | `PIO1` | [crate::Gp5Pio1] | Gpio5 { name: gp5, aliases: { /// UART Function alias for pin [crate::Pins::gpio5]. FunctionUart, PullNone: Gp5Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio5]. FunctionSpi, PullNone: Gp5Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio5]. FunctionI2C, PullUp: Gp5I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio5]. FunctionPwm, PullNone: Gp5Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio5]. FunctionPio0, PullNone: Gp5Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio5]. FunctionPio1, PullNone: Gp5Pio1 } }, /// GPIO 6 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp6Spi0Sck] | /// | `UART1 CTS` | [crate::Gp6Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp6I2C1Sda] | /// | `PWM3 A` | [crate::Gp6Pwm3A] | /// | `PIO0` | [crate::Gp6Pio0] | /// | `PIO1` | [crate::Gp6Pio1] | Gpio6 { name: gp6, aliases: { /// UART Function alias for pin [crate::Pins::gpio6]. FunctionUart, PullNone: Gp6Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio6]. FunctionSpi, PullNone: Gp6Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio6]. FunctionI2C, PullUp: Gp6I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio6]. FunctionPwm, PullNone: Gp6Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio6]. FunctionPio0, PullNone: Gp6Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio6]. FunctionPio1, PullNone: Gp6Pio1 } }, /// GPIO 7 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp7Spi0Tx] | /// | `UART1 RTS` | [crate::Gp7Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp7I2C1Scl] | /// | `PWM3 B` | [crate::Gp7Pwm3B] | /// | `PIO0` | [crate::Gp7Pio0] | /// | `PIO1` | [crate::Gp7Pio1] | Gpio7 { name: gp7, aliases: { /// UART Function alias for pin [crate::Pins::gpio7]. FunctionUart, PullNone: Gp7Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio7]. FunctionSpi, PullNone: Gp7Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio7]. FunctionI2C, PullUp: Gp7I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio7]. FunctionPwm, PullNone: Gp7Pwm3B, /// PIO0 Function alias for pin [crate::Pins::gpio7]. FunctionPio0, PullNone: Gp7Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio7]. FunctionPio1, PullNone: Gp7Pio1 } }, /// GPIO 8 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp8Spi1Rx] | /// | `UART1 TX` | [crate::Gp8Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp8I2C0Sda] | /// | `PWM4 A` | [crate::Gp8Pwm4A] | /// | `PIO0` | [crate::Gp8Pio0] | /// | `PIO1` | [crate::Gp8Pio1] | Gpio8 { name: gp8, aliases: { /// UART Function alias for pin [crate::Pins::gpio8]. FunctionUart, PullNone: Gp8Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio8]. FunctionSpi, PullNone: Gp8Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio8]. FunctionI2C, PullUp: Gp8I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio8]. FunctionPwm, PullNone: Gp8Pwm4A, /// PIO0 Function alias for pin [crate::Pins::gpio8]. FunctionPio0, PullNone: Gp8Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio8]. FunctionPio1, PullNone: Gp8Pio1 } }, /// GPIO 9 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp9Spi1Csn] | /// | `UART1 RX` | [crate::Gp9Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp9I2C0Scl] | /// | `PWM4 B` | [crate::Gp9Pwm4B] | /// | `PIO0` | [crate::Gp9Pio0] | /// | `PIO1` | [crate::Gp9Pio1] | Gpio9 { name: gp9, aliases: { /// UART Function alias for pin [crate::Pins::gpio9]. FunctionUart, PullNone: Gp9Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio9]. FunctionSpi, PullNone: Gp9Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio9]. FunctionI2C, PullUp: Gp9I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio9]. FunctionPwm, PullNone: Gp9Pwm4B, /// PIO0 Function alias for pin [crate::Pins::gpio9]. FunctionPio0, PullNone: Gp9Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio9]. FunctionPio1, PullNone: Gp9Pio1 } }, /// GPIO 10 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp10Spi1Sck] | /// | `UART1 CTS` | [crate::Gp10Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp10I2C1Sda] | /// | `PWM5 A` | [crate::Gp10Pwm5A] | /// | `PIO0` | [crate::Gp10Pio0] | /// | `PIO1` | [crate::Gp10Pio1] | Gpio10 { name: gp10, aliases: { /// UART Function alias for pin [crate::Pins::gpio10]. FunctionUart, PullNone: Gp10Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio10]. FunctionSpi, PullNone: Gp10Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio10]. FunctionI2C, PullUp: Gp10I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio10]. FunctionPwm, PullNone: Gp10Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio10]. FunctionPio0, PullNone: Gp10Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio10]. FunctionPio1, PullNone: Gp10Pio1 } }, /// GPIO 11 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp11Spi1Tx] | /// | `UART1 RTS` | [crate::Gp11Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp11I2C1Scl] | /// | `PWM5 B` | [crate::Gp11Pwm5B] | /// | `PIO0` | [crate::Gp11Pio0] | /// | `PIO1` | [crate::Gp11Pio1] | Gpio11 { name: gp11, aliases: { /// UART Function alias for pin [crate::Pins::gpio11]. FunctionUart, PullNone: Gp11Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio11]. FunctionSpi, PullNone: Gp11Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio11]. FunctionI2C, PullUp: Gp11I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio11]. FunctionPwm, PullNone: Gp11Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio11]. FunctionPio0, PullNone: Gp11Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio11]. FunctionPio1, PullNone: Gp11Pio1 } }, /// GPIO 12 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp12Spi1Rx] | /// | `UART0 TX` | [crate::Gp12Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp12I2C0Sda] | /// | `PWM6 A` | [crate::Gp12Pwm6A] | /// | `PIO0` | [crate::Gp12Pio0] | /// | `PIO1` | [crate::Gp12Pio1] | Gpio12 { name: gp12, aliases: { /// UART Function alias for pin [crate::Pins::gpio12]. FunctionUart, PullNone: Gp12Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio12]. FunctionSpi, PullNone: Gp12Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio12]. FunctionI2C, PullUp: Gp12I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio12]. FunctionPwm, PullNone: Gp12Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio12]. FunctionPio0, PullNone: Gp12Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio12]. FunctionPio1, PullNone: Gp12Pio1 } }, /// GPIO 13 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp13Spi1Csn] | /// | `UART0 RX` | [crate::Gp13Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp13I2C0Scl] | /// | `PWM6 B` | [crate::Gp13Pwm6B] | /// | `PIO0` | [crate::Gp13Pio0] | /// | `PIO1` | [crate::Gp13Pio1] | Gpio13 { name: gp13, aliases: { /// UART Function alias for pin [crate::Pins::gpio13]. FunctionUart, PullNone: Gp13Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio13]. FunctionSpi, PullNone: Gp13Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio13]. FunctionI2C, PullUp: Gp13I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio13]. FunctionPwm, PullNone: Gp13Pwm6B, /// PIO0 Function alias for pin [crate::Pins::gpio13]. FunctionPio0, PullNone: Gp13Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio13]. FunctionPio1, PullNone: Gp13Pio1 } }, /// GPIO 14 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp14Spi1Sck] | /// | `UART0 CTS` | [crate::Gp14Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp14I2C1Sda] | /// | `PWM7 A` | [crate::Gp14Pwm7A] | /// | `PIO0` | [crate::Gp14Pio0] | /// | `PIO1` | [crate::Gp14Pio1] | Gpio14 { name: gp14, aliases: { /// UART Function alias for pin [crate::Pins::gpio14]. FunctionUart, PullNone: Gp14Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio14]. FunctionSpi, PullNone: Gp14Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio14]. FunctionI2C, PullUp: Gp14I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio14]. FunctionPwm, PullNone: Gp14Pwm7A, /// PIO0 Function alias for pin [crate::Pins::gpio14]. FunctionPio0, PullNone: Gp14Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio14]. FunctionPio1, PullNone: Gp14Pio1 } }, /// GPIO 15 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp15Spi1Tx] | /// | `UART0 RTS` | [crate::Gp15Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp15I2C1Scl] | /// | `PWM7 B` | [crate::Gp15Pwm7B] | /// | `PIO0` | [crate::Gp15Pio0] | /// | `PIO1` | [crate::Gp15Pio1] | Gpio15 { name: gp15, aliases: { /// UART Function alias for pin [crate::Pins::gpio15]. FunctionUart, PullNone: Gp15Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio15]. FunctionSpi, PullNone: Gp15Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio15]. FunctionI2C, PullUp: Gp15I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio15]. FunctionPwm, PullNone: Gp15Pwm7B, /// PIO0 Function alias for pin [crate::Pins::gpio15]. FunctionPio0, PullNone: Gp15Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio15]. FunctionPio1, PullNone: Gp15Pio1 } }, /// GPIO 16 is connected internally to a single Neopixel RGB LED Gpio16 { name: neopixel }, /// GPIO 17 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp17Spi0Csn] | /// | `UART0 RX` | [crate::Gp17Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp17I2C0Scl] | /// | `PWM0 B` | [crate::Gp17Pwm0B] | /// | `PIO0` | [crate::Gp17Pio0] | /// | `PIO1` | [crate::Gp17Pio1] | Gpio17 { name: gpio17, aliases: { /// UART Function alias for pin [crate::Pins::gpio17]. FunctionUart, PullNone: Gp17Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio17]. FunctionSpi, PullNone: Gp17Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio17]. FunctionI2C, PullUp: Gp17I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio17]. FunctionPwm, PullNone: Gp17Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio17]. FunctionPio0, PullNone: Gp17Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio17]. FunctionPio1, PullNone: Gp17Pio1 } }, /// GPIO 18 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp18Spi0Sck] | /// | `UART0 CTS` | [crate::Gp18Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp18I2C1Sda] | /// | `PWM1 A` | [crate::Gp18Pwm1A] | /// | `PIO0` | [crate::Gp18Pio0] | /// | `PIO1` | [crate::Gp18Pio1] | Gpio18 { name: gpio18, aliases: { /// UART Function alias for pin [crate::Pins::gpio18]. FunctionUart, PullNone: Gp18Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio18]. FunctionSpi, PullNone: Gp18Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio18]. FunctionI2C, PullUp: Gp18I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio18]. FunctionPwm, PullNone: Gp18Pwm1A, /// PIO0 Function alias for pin [crate::Pins::gpio18]. FunctionPio0, PullNone: Gp18Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio18]. FunctionPio1, PullNone: Gp18Pio1 } }, /// GPIO 19 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp19Spi0Tx] | /// | `UART0 RTS` | [crate::Gp19Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp19I2C1Scl] | /// | `PWM1 B` | [crate::Gp19Pwm1B] | /// | `PIO0` | [crate::Gp19Pio0] | /// | `PIO1` | [crate::Gp19Pio1] | Gpio19 { name: gpio19, aliases: { /// UART Function alias for pin [crate::Pins::gpio19]. FunctionUart, PullNone: Gp19Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio19]. FunctionSpi, PullNone: Gp19Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio19]. FunctionI2C, PullUp: Gp19I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio19]. FunctionPwm, PullNone: Gp19Pwm1B, /// PIO0 Function alias for pin [crate::Pins::gpio19]. FunctionPio0, PullNone: Gp19Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio19]. FunctionPio1, PullNone: Gp19Pio1 } }, /// GPIO 20 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp20Spi0Rx] | /// | `UART1 TX` | [crate::Gp20Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp20I2C0Sda] | /// | `PWM2 A` | [crate::Gp20Pwm2A] | /// | `PIO0` | [crate::Gp20Pio0] | /// | `PIO1` | [crate::Gp20Pio1] | Gpio20 { name: gpio20, aliases: { /// UART Function alias for pin [crate::Pins::gpio20]. FunctionUart, PullNone: Gp20Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio20]. FunctionSpi, PullNone: Gp20Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio20]. FunctionI2C, PullUp: Gp20I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio20]. FunctionPwm, PullNone: Gp20Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio20]. FunctionPio0, PullNone: Gp20Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio20]. FunctionPio1, PullNone: Gp20Pio1 } }, /// GPIO 21 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp21Spi0Csn] | /// | `UART1 RX` | [crate::Gp21Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp21I2C0Scl] | /// | `PWM2 B` | [crate::Gp21Pwm2B] | /// | `PIO0` | [crate::Gp21Pio0] | /// | `PIO1` | [crate::Gp21Pio1] | Gpio21 { name: gpio21, aliases: { /// UART Function alias for pin [crate::Pins::gpio21]. FunctionUart, PullNone: Gp21Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio21]. FunctionSpi, PullNone: Gp21Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio21]. FunctionI2C, PullUp: Gp21I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio21]. FunctionPwm, PullNone: Gp21Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio21]. FunctionPio0, PullNone: Gp21Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio21]. FunctionPio1, PullNone: Gp21Pio1 } }, /// GPIO 22 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp22Spi0Sck] | /// | `UART1 CTS` | [crate::Gp22Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp22I2C1Sda] | /// | `PWM3 A` | [crate::Gp22Pwm3A] | /// | `PIO0` | [crate::Gp22Pio0] | /// | `PIO1` | [crate::Gp22Pio1] | Gpio22 { name: gpio22, aliases: { /// UART Function alias for pin [crate::Pins::gpio22]. FunctionUart, PullNone: Gp22Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio22]. FunctionSpi, PullNone: Gp22Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio22]. FunctionI2C, PullUp: Gp22I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio22]. FunctionPwm, PullNone: Gp22Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio22]. FunctionPio0, PullNone: Gp22Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio22]. FunctionPio1, PullNone: Gp22Pio1 } }, /// GPIO 23 Gpio23 { name: gp23, aliases: { FunctionUart, PullNone: Gp23Uart1Rts, FunctionSpi, PullNone: Gp23Spi0Tx, FunctionI2C, PullUp: Gp23I2C1Scl, FunctionPwm, PullNone: Gp23Pwm3B, FunctionPio0, PullNone: Gp23Pio0, FunctionPio1, PullNone: Gp23Pio1 } }, /// GPIO 24 Gpio24 { name: gp24, aliases: { FunctionUart, PullNone: Gp24Uart1Tx, FunctionSpi, PullNone: Gp24Spi1Rx, FunctionI2C, PullUp: Gp24I2C0Sda, FunctionPwm, PullNone: Gp24Pwm4A, FunctionPio0, PullNone: Gp24Pio0, FunctionPio1, PullNone: Gp24Pio1 } }, /// GPIO 25 Gpio25 { name: gp25, aliases: { FunctionUart, PullNone: Gp25Uart1Rx, FunctionSpi, PullNone: Gp25Spi1Csn, FunctionI2C, PullUp: Gp25I2C0Scl, FunctionPwm, PullNone: Gp25Pwm4B, FunctionPio0, PullNone: Gp25Pio0, FunctionPio1, PullNone: Gp25Pio1 } }, /// GPIO 26 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp26Spi1Sck] | /// | `UART1 CTS` | [crate::Gp26Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp26I2C1Sda] | /// | `PWM5 A` | [crate::Gp26Pwm5A] | /// | `PIO0` | [crate::Gp26Pio0] | /// | `PIO1` | [crate::Gp26Pio1] | /// /// ADC0 Gpio26 { name: gp26, aliases: { /// UART Function alias for pin [crate::Pins::gpio26]. FunctionUart, PullNone: Gp26Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio26]. FunctionSpi, PullNone: Gp26Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio26]. FunctionI2C, PullUp: Gp26I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio26]. FunctionPwm, PullNone: Gp26Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio26]. FunctionPio0, PullNone: Gp26Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio26]. FunctionPio1, PullNone: Gp26Pio1 } }, /// GPIO 27 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp27Spi1Tx] | /// | `UART1 RTS` | [crate::Gp27Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp27I2C1Scl] | /// | `PWM5 B` | [crate::Gp27Pwm5B] | /// | `PIO0` | [crate::Gp27Pio0] | /// | `PIO1` | [crate::Gp27Pio1] | /// /// ADC1 Gpio27 { name: gp27, aliases: { /// UART Function alias for pin [crate::Pins::gpio27]. FunctionUart, PullNone: Gp27Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio27]. FunctionSpi, PullNone: Gp27Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio27]. FunctionI2C, PullUp: Gp27I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio27]. FunctionPwm, PullNone: Gp27Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio27]. FunctionPio0, PullNone: Gp27Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio27]. FunctionPio1, PullNone: Gp27Pio1 } }, /// GPIO 28 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp28Spi1Rx] | /// | `UART0 TX` | [crate::Gp28Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp28I2C0Sda] | /// | `PWM6 A` | [crate::Gp28Pwm6A] | /// | `PIO0` | [crate::Gp28Pio0] | /// | `PIO1` | [crate::Gp28Pio1] | /// /// ADC2 Gpio28 { name: gp28, aliases: { /// UART Function alias for pin [crate::Pins::gpio28]. FunctionUart, PullNone: Gp28Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio28]. FunctionSpi, PullNone: Gp28Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio28]. FunctionI2C, PullUp: Gp28I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio28]. FunctionPwm, PullNone: Gp28Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio28]. FunctionPio0, PullNone: Gp28Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio28]. FunctionPio1, PullNone: Gp28Pio1 } }, /// GPIO 29 /// /// ADC3 Gpio29 { name: gp29, aliases: { FunctionUart, PullNone: Gp29Uart0Rx, FunctionSpi, PullNone: Gp29Spi1Csn, FunctionI2C, PullUp: Gp29I2C0Scl, FunctionPwm, PullNone: Gp29Pwm6B, FunctionPio0, PullNone: Gp29Pio0, FunctionPio1, PullNone: Gp29Pio1 } }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/waveshare-rp2040-lcd-1-28/CHANGELOG.md ================================================ # 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.1.0 - 2024-07-29 ### Changed - Inital release - Copied from waveshare-rp2040-0.96 - Update board name ================================================ FILE: boards/waveshare-rp2040-lcd-1-28/Cargo.toml ================================================ [package] name = "waveshare-rp2040-lcd-1-28" version = "0.8.0" authors = ["René van Dorst ", "Andrea Nall ", "TilCreator ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/waveshare-rp2040-lcd-0_96" description = "Board Support Package for the Waveshare RP2040 LCD 0.96 inch" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true panic-halt.workspace = true embedded-hal.workspace = true fugit.workspace = true nb.workspace = true embedded-graphics.workspace = true gc9a01a_driver = { workspace = true } [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it doesn't hurt to enable it rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/waveshare-rp2040-lcd-1-28/README.md ================================================ # [waveshare-rp2040-lcd-1-28] - Board Support for the [Waveshare RP2040 LCD 1.28] You should include this crate if you are writing code that you want to run on an [Waveshare RP2040 LCD 1.28] - a very small RP2040 breakout board with USB-C, a 65K IPS LCD 240x240, 16MBit Flash and 1A battery charger from Waveshare. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Feather. [Waveshare RP2040 LCD 1.28]: https://www.waveshare.com/wiki/RP2040-LCD-1.28 [waveshare-rp2040-lcd-1-28]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/waveshare-rp2040-lcd-1-28 [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml waveshare_rp2040_lcd_1_28 = "0.8.0" ``` In your program, you will need to call `waveshare_rp2040_lcd_1_28::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/waveshare-rp2040-lcd-1-28 $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/waveshare-rp2040-lcd-1-28 $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [waveshare_rp2040_lcd_demo](./examples/waveshare_rp2040_lcd_demo.rs) Draws a red and green line with a blue regtangle. After that is fills the screen line for line, that end it starts over with an other colour, RED, GREEN and BLUE. ## Contributing Contributions are what make the open source community such an amazing place to be, learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/waveshare-rp2040-lcd-1-28/examples/waveshare_rp2040_lcd_demo.rs ================================================ //! Example of graphics on the LCD of the Waveshare RP2040-LCD-1.28 //! //! Draws a red and green line with a blue rectangle. //! After that it fills the screen line for line, at the end it starts over with //! another colour, RED, GREEN and BLUE. #![no_std] #![no_main] use cortex_m::delay::Delay; use fugit::RateExtU32; use gc9a01a_driver::{Orientation, GC9A01A}; use panic_halt as _; use waveshare_rp2040_lcd_1_28::entry; use waveshare_rp2040_lcd_1_28::{ hal::{ self, clocks::{init_clocks_and_plls, Clock}, pac, pio::PIOExt, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; use embedded_graphics::{ pixelcolor::Rgb565, prelude::*, primitives::{Line, PrimitiveStyle, PrimitiveStyleBuilder, Rectangle}, }; const LCD_WIDTH: u32 = 240; const LCD_HEIGHT: u32 = 240; // Define static buffers /// Main entry point for the application #[entry] fn main() -> ! { // Take ownership of peripheral instances let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Initialize watchdog let mut watchdog = Watchdog::new(pac.WATCHDOG); // Initialize clocks and PLLs let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // Initialize SIO let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // Set up the delay for the first core let sys_freq = clocks.system_clock.freq().to_Hz(); let mut delay = Delay::new(core.SYST, sys_freq); let (mut _pio, _sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); // Initialize LCD pins let lcd_dc = pins.gp8.into_push_pull_output(); let lcd_cs = pins.gp9.into_push_pull_output(); let lcd_clk = pins.gp10.into_function::(); let lcd_mosi = pins.gp11.into_function::(); let lcd_rst = pins .gp12 .into_push_pull_output_in_state(hal::gpio::PinState::High); let mut _lcd_bl = pins .gp25 .into_push_pull_output_in_state(hal::gpio::PinState::Low); // Initialize SPI let spi = hal::Spi::<_, _, _, 8>::new(pac.SPI1, (lcd_mosi, lcd_clk)); let spi = spi.init( &mut pac.RESETS, clocks.peripheral_clock.freq(), 40.MHz(), embedded_hal::spi::MODE_0, ); // Initialize the display let mut display = GC9A01A::new(spi, lcd_dc, lcd_cs, lcd_rst, false, LCD_WIDTH, LCD_HEIGHT); display.init(&mut delay).unwrap(); display.set_orientation(&Orientation::Landscape).unwrap(); // Clear the screen before turning on the backlight display.clear(Rgb565::BLACK).unwrap(); _lcd_bl.into_push_pull_output_in_state(hal::gpio::PinState::High); delay.delay_ms(1000); let lcd_zero = Point::zero(); let lcd_max_corner = Point::new((LCD_WIDTH - 1) as i32, (LCD_HEIGHT - 1) as i32); let style = PrimitiveStyleBuilder::new() .fill_color(Rgb565::BLUE) .build(); Rectangle::with_corners(lcd_zero, lcd_max_corner) .into_styled(style) .draw(&mut display) .unwrap(); delay.delay_ms(1000); let style = PrimitiveStyleBuilder::new() .fill_color(Rgb565::BLACK) .build(); Rectangle::with_corners( Point::new(1, 1), Point::new((LCD_WIDTH - 2) as i32, (LCD_HEIGHT - 2) as i32), ) .into_styled(style) .draw(&mut display) .unwrap(); Line::new(lcd_zero, lcd_max_corner) .into_styled(PrimitiveStyle::with_stroke(Rgb565::RED, 1)) .draw(&mut display) .unwrap(); Line::new( Point::new(0, (LCD_HEIGHT - 1) as i32), Point::new((LCD_WIDTH - 1) as i32, 0), ) .into_styled(PrimitiveStyle::with_stroke(Rgb565::GREEN, 1)) .draw(&mut display) .unwrap(); // Infinite colour wheel loop let mut l: i32 = 0; let mut c = Rgb565::RED; loop { Line::new(Point::new(0, l), Point::new((LCD_WIDTH - 1) as i32, l)) .into_styled(PrimitiveStyle::with_stroke(c, 1)) .draw(&mut display) .unwrap(); delay.delay_ms(10); l += 1; if l == LCD_HEIGHT as i32 { l = 0; c = match c { Rgb565::RED => Rgb565::GREEN, Rgb565::GREEN => Rgb565::BLUE, _ => Rgb565::RED, } } } } ================================================ FILE: boards/waveshare-rp2040-lcd-1-28/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( /// GPIO 0 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp0Spi0Rx] | /// | `UART0 TX` | [crate::Gp0Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp0I2C0Sda] | /// | `PWM0 A` | [crate::Gp0Pwm0A] | /// | `PIO0` | [crate::Gp0Pio0] | /// | `PIO1` | [crate::Gp0Pio1] | Gpio0 { name: gp0, aliases: { /// UART Function alias for pin [crate::Pins::gpio0]. FunctionUart, PullNone: Gp0Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio0]. FunctionSpi, PullNone: Gp0Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio0]. FunctionI2C, PullUp: Gp0I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio0]. FunctionPwm, PullNone: Gp0Pwm0A, /// PIO0 Function alias for pin [crate::Pins::gpio0]. FunctionPio0, PullNone: Gp0Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio0]. FunctionPio1, PullNone: Gp0Pio1 } }, /// GPIO 1 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp1Spi0Csn] | /// | `UART0 RX` | [crate::Gp1Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp1I2C0Scl] | /// | `PWM0 B` | [crate::Gp1Pwm0B] | /// | `PIO0` | [crate::Gp1Pio0] | /// | `PIO1` | [crate::Gp1Pio1] | Gpio1 { name: gp1, aliases: { /// UART Function alias for pin [crate::Pins::gpio1]. FunctionUart, PullNone: Gp1Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio1]. FunctionSpi, PullNone: Gp1Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio1]. FunctionI2C, PullUp: Gp1I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio1]. FunctionPwm, PullNone: Gp1Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio1]. FunctionPio0, PullNone: Gp1Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio1]. FunctionPio1, PullNone: Gp1Pio1 } }, /// GPIO 2 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp2Spi0Sck] | /// | `UART0 CTS` | [crate::Gp2Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp2I2C1Sda] | /// | `PWM1 A` | [crate::Gp2Pwm1A] | /// | `PIO0` | [crate::Gp2Pio0] | /// | `PIO1` | [crate::Gp2Pio1] | Gpio2 { name: gp2, aliases: { /// UART Function alias for pin [crate::Pins::gpio2]. FunctionUart, PullNone: Gp2Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio2]. FunctionSpi, PullNone: Gp2Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio2]. FunctionI2C, PullUp: Gp2I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio2]. FunctionPwm, PullNone: Gp2Pwm1A, /// PIO0 Function alias for pin [crate::Pins::gpio2]. FunctionPio0, PullNone: Gp2Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio2]. FunctionPio1, PullNone: Gp2Pio1 } }, /// GPIO 3 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp3Spi0Tx] | /// | `UART0 RTS` | [crate::Gp3Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp3I2C1Scl] | /// | `PWM1 B` | [crate::Gp3Pwm1B] | /// | `PIO0` | [crate::Gp3Pio0] | /// | `PIO1` | [crate::Gp3Pio1] | Gpio3 { name: gp3, aliases: { /// UART Function alias for pin [crate::Pins::gpio3]. FunctionUart, PullNone: Gp3Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio3]. FunctionSpi, PullNone: Gp3Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio3]. FunctionI2C, PullUp: Gp3I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio3]. FunctionPwm, PullNone: Gp3Pwm1B, /// PIO0 Function alias for pin [crate::Pins::gpio3]. FunctionPio0, PullNone: Gp3Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio3]. FunctionPio1, PullNone: Gp3Pio1 } }, /// GPIO 4 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp4Spi0Rx] | /// | `UART1 TX` | [crate::Gp4Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp4I2C0Sda] | /// | `PWM2 A` | [crate::Gp4Pwm2A] | /// | `PIO0` | [crate::Gp4Pio0] | /// | `PIO1` | [crate::Gp4Pio1] | Gpio4 { name: gp4, aliases: { /// UART Function alias for pin [crate::Pins::gpio4]. FunctionUart, PullNone: Gp4Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio4]. FunctionSpi, PullNone: Gp4Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio4]. FunctionI2C, PullUp: Gp4I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio4]. FunctionPwm, PullNone: Gp4Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio4]. FunctionPio0, PullNone: Gp4Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio4]. FunctionPio1, PullNone: Gp4Pio1 } }, /// GPIO 5 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp5Spi0Csn] | /// | `UART1 RX` | [crate::Gp5Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp5I2C0Scl] | /// | `PWM2 B` | [crate::Gp5Pwm2B] | /// | `PIO0` | [crate::Gp5Pio0] | /// | `PIO1` | [crate::Gp5Pio1] | Gpio5 { name: gp5, aliases: { /// UART Function alias for pin [crate::Pins::gpio5]. FunctionUart, PullNone: Gp5Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio5]. FunctionSpi, PullNone: Gp5Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio5]. FunctionI2C, PullUp: Gp5I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio5]. FunctionPwm, PullNone: Gp5Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio5]. FunctionPio0, PullNone: Gp5Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio5]. FunctionPio1, PullNone: Gp5Pio1 } }, /// GPIO 6 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp6Spi0Sck] | /// | `UART1 CTS` | [crate::Gp6Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp6I2C1Sda] | /// | `PWM3 A` | [crate::Gp6Pwm3A] | /// | `PIO0` | [crate::Gp6Pio0] | /// | `PIO1` | [crate::Gp6Pio1] | Gpio6 { name: gp6, aliases: { /// UART Function alias for pin [crate::Pins::gpio6]. FunctionUart, PullNone: Gp6Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio6]. FunctionSpi, PullNone: Gp6Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio6]. FunctionI2C, PullUp: Gp6I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio6]. FunctionPwm, PullNone: Gp6Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio6]. FunctionPio0, PullNone: Gp6Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio6]. FunctionPio1, PullNone: Gp6Pio1 } }, /// GPIO 7 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp7Spi0Tx] | /// | `UART1 RTS` | [crate::Gp7Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp7I2C1Scl] | /// | `PWM3 B` | [crate::Gp7Pwm3B] | /// | `PIO0` | [crate::Gp7Pio0] | /// | `PIO1` | [crate::Gp7Pio1] | Gpio7 { name: gp7, aliases: { /// UART Function alias for pin [crate::Pins::gpio7]. FunctionUart, PullNone: Gp7Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio7]. FunctionSpi, PullNone: Gp7Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio7]. FunctionI2C, PullUp: Gp7I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio7]. FunctionPwm, PullNone: Gp7Pwm3B, /// PIO0 Function alias for pin [crate::Pins::gpio7]. FunctionPio0, PullNone: Gp7Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio7]. FunctionPio1, PullNone: Gp7Pio1 } }, /// GPIO 8 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp8Spi1Rx] | /// | `UART1 TX` | [crate::Gp8Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp8I2C0Sda] | /// | `PWM4 A` | [crate::Gp8Pwm4A] | /// | `PIO0` | [crate::Gp8Pio0] | /// | `PIO1` | [crate::Gp8Pio1] | Gpio8 { name: gp8, aliases: { /// UART Function alias for pin [crate::Pins::gpio8]. FunctionUart, PullNone: Gp8Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio8]. FunctionSpi, PullNone: Gp8Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio8]. FunctionI2C, PullUp: Gp8I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio8]. FunctionPwm, PullNone: Gp8Pwm4A, /// PIO0 Function alias for pin [crate::Pins::gpio8]. FunctionPio0, PullNone: Gp8Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio8]. FunctionPio1, PullNone: Gp8Pio1 } }, /// GPIO 9 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp9Spi1Csn] | /// | `UART1 RX` | [crate::Gp9Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp9I2C0Scl] | /// | `PWM4 B` | [crate::Gp9Pwm4B] | /// | `PIO0` | [crate::Gp9Pio0] | /// | `PIO1` | [crate::Gp9Pio1] | Gpio9 { name: gp9, aliases: { /// UART Function alias for pin [crate::Pins::gpio9]. FunctionUart, PullNone: Gp9Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio9]. FunctionSpi, PullNone: Gp9Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio9]. FunctionI2C, PullUp: Gp9I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio9]. FunctionPwm, PullNone: Gp9Pwm4B, /// PIO0 Function alias for pin [crate::Pins::gpio9]. FunctionPio0, PullNone: Gp9Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio9]. FunctionPio1, PullNone: Gp9Pio1 } }, /// GPIO 10 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp10Spi1Sck] | /// | `UART1 CTS` | [crate::Gp10Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp10I2C1Sda] | /// | `PWM5 A` | [crate::Gp10Pwm5A] | /// | `PIO0` | [crate::Gp10Pio0] | /// | `PIO1` | [crate::Gp10Pio1] | Gpio10 { name: gp10, aliases: { /// UART Function alias for pin [crate::Pins::gpio10]. FunctionUart, PullNone: Gp10Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio10]. FunctionSpi, PullNone: Gp10Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio10]. FunctionI2C, PullUp: Gp10I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio10]. FunctionPwm, PullNone: Gp10Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio10]. FunctionPio0, PullNone: Gp10Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio10]. FunctionPio1, PullNone: Gp10Pio1 } }, /// GPIO 11 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp11Spi1Tx] | /// | `UART1 RTS` | [crate::Gp11Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp11I2C1Scl] | /// | `PWM5 B` | [crate::Gp11Pwm5B] | /// | `PIO0` | [crate::Gp11Pio0] | /// | `PIO1` | [crate::Gp11Pio1] | Gpio11 { name: gp11, aliases: { /// UART Function alias for pin [crate::Pins::gpio11]. FunctionUart, PullNone: Gp11Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio11]. FunctionSpi, PullNone: Gp11Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio11]. FunctionI2C, PullUp: Gp11I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio11]. FunctionPwm, PullNone: Gp11Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio11]. FunctionPio0, PullNone: Gp11Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio11]. FunctionPio1, PullNone: Gp11Pio1 } }, /// GPIO 12 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp12Spi1Rx] | /// | `UART0 TX` | [crate::Gp12Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp12I2C0Sda] | /// | `PWM6 A` | [crate::Gp12Pwm6A] | /// | `PIO0` | [crate::Gp12Pio0] | /// | `PIO1` | [crate::Gp12Pio1] | Gpio12 { name: gp12, aliases: { /// UART Function alias for pin [crate::Pins::gpio12]. FunctionUart, PullNone: Gp12Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio12]. FunctionSpi, PullNone: Gp12Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio12]. FunctionI2C, PullUp: Gp12I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio12]. FunctionPwm, PullNone: Gp12Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio12]. FunctionPio0, PullNone: Gp12Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio12]. FunctionPio1, PullNone: Gp12Pio1 } }, /// GPIO 13 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp13Spi1Csn] | /// | `UART0 RX` | [crate::Gp13Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp13I2C0Scl] | /// | `PWM6 B` | [crate::Gp13Pwm6B] | /// | `PIO0` | [crate::Gp13Pio0] | /// | `PIO1` | [crate::Gp13Pio1] | Gpio13 { name: gp13, aliases: { /// UART Function alias for pin [crate::Pins::gpio13]. FunctionUart, PullNone: Gp13Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio13]. FunctionSpi, PullNone: Gp13Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio13]. FunctionI2C, PullUp: Gp13I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio13]. FunctionPwm, PullNone: Gp13Pwm6B, /// PIO0 Function alias for pin [crate::Pins::gpio13]. FunctionPio0, PullNone: Gp13Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio13]. FunctionPio1, PullNone: Gp13Pio1 } }, /// GPIO 14 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp14Spi1Sck] | /// | `UART0 CTS` | [crate::Gp14Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp14I2C1Sda] | /// | `PWM7 A` | [crate::Gp14Pwm7A] | /// | `PIO0` | [crate::Gp14Pio0] | /// | `PIO1` | [crate::Gp14Pio1] | Gpio14 { name: gp14, aliases: { /// UART Function alias for pin [crate::Pins::gpio14]. FunctionUart, PullNone: Gp14Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio14]. FunctionSpi, PullNone: Gp14Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio14]. FunctionI2C, PullUp: Gp14I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio14]. FunctionPwm, PullNone: Gp14Pwm7A, /// PIO0 Function alias for pin [crate::Pins::gpio14]. FunctionPio0, PullNone: Gp14Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio14]. FunctionPio1, PullNone: Gp14Pio1 } }, /// GPIO 15 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp15Spi1Tx] | /// | `UART0 RTS` | [crate::Gp15Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp15I2C1Scl] | /// | `PWM7 B` | [crate::Gp15Pwm7B] | /// | `PIO0` | [crate::Gp15Pio0] | /// | `PIO1` | [crate::Gp15Pio1] | Gpio15 { name: gp15, aliases: { /// UART Function alias for pin [crate::Pins::gpio15]. FunctionUart, PullNone: Gp15Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio15]. FunctionSpi, PullNone: Gp15Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio15]. FunctionI2C, PullUp: Gp15I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio15]. FunctionPwm, PullNone: Gp15Pwm7B, /// PIO0 Function alias for pin [crate::Pins::gpio15]. FunctionPio0, PullNone: Gp15Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio15]. FunctionPio1, PullNone: Gp15Pio1 } }, /// GPIO 16 is connected internally to a single Neopixel RGB LED Gpio16 { name: neopixel }, /// GPIO 17 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp17Spi0Csn] | /// | `UART0 RX` | [crate::Gp17Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp17I2C0Scl] | /// | `PWM0 B` | [crate::Gp17Pwm0B] | /// | `PIO0` | [crate::Gp17Pio0] | /// | `PIO1` | [crate::Gp17Pio1] | Gpio17 { name: gpio17, aliases: { /// UART Function alias for pin [crate::Pins::gpio17]. FunctionUart, PullNone: Gp17Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio17]. FunctionSpi, PullNone: Gp17Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio17]. FunctionI2C, PullUp: Gp17I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio17]. FunctionPwm, PullNone: Gp17Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio17]. FunctionPio0, PullNone: Gp17Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio17]. FunctionPio1, PullNone: Gp17Pio1 } }, /// GPIO 18 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp18Spi0Sck] | /// | `UART0 CTS` | [crate::Gp18Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp18I2C1Sda] | /// | `PWM1 A` | [crate::Gp18Pwm1A] | /// | `PIO0` | [crate::Gp18Pio0] | /// | `PIO1` | [crate::Gp18Pio1] | Gpio18 { name: gpio18, aliases: { /// UART Function alias for pin [crate::Pins::gpio18]. FunctionUart, PullNone: Gp18Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio18]. FunctionSpi, PullNone: Gp18Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio18]. FunctionI2C, PullUp: Gp18I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio18]. FunctionPwm, PullNone: Gp18Pwm1A, /// PIO0 Function alias for pin [crate::Pins::gpio18]. FunctionPio0, PullNone: Gp18Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio18]. FunctionPio1, PullNone: Gp18Pio1 } }, /// GPIO 19 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp19Spi0Tx] | /// | `UART0 RTS` | [crate::Gp19Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp19I2C1Scl] | /// | `PWM1 B` | [crate::Gp19Pwm1B] | /// | `PIO0` | [crate::Gp19Pio0] | /// | `PIO1` | [crate::Gp19Pio1] | Gpio19 { name: gpio19, aliases: { /// UART Function alias for pin [crate::Pins::gpio19]. FunctionUart, PullNone: Gp19Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio19]. FunctionSpi, PullNone: Gp19Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio19]. FunctionI2C, PullUp: Gp19I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio19]. FunctionPwm, PullNone: Gp19Pwm1B, /// PIO0 Function alias for pin [crate::Pins::gpio19]. FunctionPio0, PullNone: Gp19Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio19]. FunctionPio1, PullNone: Gp19Pio1 } }, /// GPIO 20 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp20Spi0Rx] | /// | `UART1 TX` | [crate::Gp20Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp20I2C0Sda] | /// | `PWM2 A` | [crate::Gp20Pwm2A] | /// | `PIO0` | [crate::Gp20Pio0] | /// | `PIO1` | [crate::Gp20Pio1] | Gpio20 { name: gpio20, aliases: { /// UART Function alias for pin [crate::Pins::gpio20]. FunctionUart, PullNone: Gp20Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio20]. FunctionSpi, PullNone: Gp20Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio20]. FunctionI2C, PullUp: Gp20I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio20]. FunctionPwm, PullNone: Gp20Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio20]. FunctionPio0, PullNone: Gp20Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio20]. FunctionPio1, PullNone: Gp20Pio1 } }, /// GPIO 21 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp21Spi0Csn] | /// | `UART1 RX` | [crate::Gp21Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp21I2C0Scl] | /// | `PWM2 B` | [crate::Gp21Pwm2B] | /// | `PIO0` | [crate::Gp21Pio0] | /// | `PIO1` | [crate::Gp21Pio1] | Gpio21 { name: gpio21, aliases: { /// UART Function alias for pin [crate::Pins::gpio21]. FunctionUart, PullNone: Gp21Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio21]. FunctionSpi, PullNone: Gp21Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio21]. FunctionI2C, PullUp: Gp21I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio21]. FunctionPwm, PullNone: Gp21Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio21]. FunctionPio0, PullNone: Gp21Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio21]. FunctionPio1, PullNone: Gp21Pio1 } }, /// GPIO 22 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp22Spi0Sck] | /// | `UART1 CTS` | [crate::Gp22Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp22I2C1Sda] | /// | `PWM3 A` | [crate::Gp22Pwm3A] | /// | `PIO0` | [crate::Gp22Pio0] | /// | `PIO1` | [crate::Gp22Pio1] | Gpio22 { name: gpio22, aliases: { /// UART Function alias for pin [crate::Pins::gpio22]. FunctionUart, PullNone: Gp22Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio22]. FunctionSpi, PullNone: Gp22Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio22]. FunctionI2C, PullUp: Gp22I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio22]. FunctionPwm, PullNone: Gp22Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio22]. FunctionPio0, PullNone: Gp22Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio22]. FunctionPio1, PullNone: Gp22Pio1 } }, /// GPIO 23 Gpio23 { name: gp23, aliases: { FunctionUart, PullNone: Gp23Uart1Rts, FunctionSpi, PullNone: Gp23Spi0Tx, FunctionI2C, PullUp: Gp23I2C1Scl, FunctionPwm, PullNone: Gp23Pwm3B, FunctionPio0, PullNone: Gp23Pio0, FunctionPio1, PullNone: Gp23Pio1 } }, /// GPIO 24 Gpio24 { name: gp24, aliases: { FunctionUart, PullNone: Gp24Uart1Tx, FunctionSpi, PullNone: Gp24Spi1Rx, FunctionI2C, PullUp: Gp24I2C0Sda, FunctionPwm, PullNone: Gp24Pwm4A, FunctionPio0, PullNone: Gp24Pio0, FunctionPio1, PullNone: Gp24Pio1 } }, /// GPIO 25 Gpio25 { name: gp25, aliases: { FunctionUart, PullNone: Gp25Uart1Rx, FunctionSpi, PullNone: Gp25Spi1Csn, FunctionI2C, PullUp: Gp25I2C0Scl, FunctionPwm, PullNone: Gp25Pwm4B, FunctionPio0, PullNone: Gp25Pio0, FunctionPio1, PullNone: Gp25Pio1 } }, /// GPIO 26 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp26Spi1Sck] | /// | `UART1 CTS` | [crate::Gp26Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp26I2C1Sda] | /// | `PWM5 A` | [crate::Gp26Pwm5A] | /// | `PIO0` | [crate::Gp26Pio0] | /// | `PIO1` | [crate::Gp26Pio1] | /// /// ADC0 Gpio26 { name: gp26, aliases: { /// UART Function alias for pin [crate::Pins::gpio26]. FunctionUart, PullNone: Gp26Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio26]. FunctionSpi, PullNone: Gp26Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio26]. FunctionI2C, PullUp: Gp26I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio26]. FunctionPwm, PullNone: Gp26Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio26]. FunctionPio0, PullNone: Gp26Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio26]. FunctionPio1, PullNone: Gp26Pio1 } }, /// GPIO 27 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp27Spi1Tx] | /// | `UART1 RTS` | [crate::Gp27Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp27I2C1Scl] | /// | `PWM5 B` | [crate::Gp27Pwm5B] | /// | `PIO0` | [crate::Gp27Pio0] | /// | `PIO1` | [crate::Gp27Pio1] | /// /// ADC1 Gpio27 { name: gp27, aliases: { /// UART Function alias for pin [crate::Pins::gpio27]. FunctionUart, PullNone: Gp27Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio27]. FunctionSpi, PullNone: Gp27Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio27]. FunctionI2C, PullUp: Gp27I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio27]. FunctionPwm, PullNone: Gp27Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio27]. FunctionPio0, PullNone: Gp27Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio27]. FunctionPio1, PullNone: Gp27Pio1 } }, /// GPIO 28 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp28Spi1Rx] | /// | `UART0 TX` | [crate::Gp28Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp28I2C0Sda] | /// | `PWM6 A` | [crate::Gp28Pwm6A] | /// | `PIO0` | [crate::Gp28Pio0] | /// | `PIO1` | [crate::Gp28Pio1] | /// /// ADC2 Gpio28 { name: gp28, aliases: { /// UART Function alias for pin [crate::Pins::gpio28]. FunctionUart, PullNone: Gp28Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio28]. FunctionSpi, PullNone: Gp28Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio28]. FunctionI2C, PullUp: Gp28I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio28]. FunctionPwm, PullNone: Gp28Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio28]. FunctionPio0, PullNone: Gp28Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio28]. FunctionPio1, PullNone: Gp28Pio1 } }, /// GPIO 29 /// /// ADC3 Gpio29 { name: gp29, aliases: { FunctionUart, PullNone: Gp29Uart0Rx, FunctionSpi, PullNone: Gp29Spi1Csn, FunctionI2C, PullUp: Gp29I2C0Scl, FunctionPwm, PullNone: Gp29Pwm6B, FunctionPio0, PullNone: Gp29Pio0, FunctionPio1, PullNone: Gp29Pio1 } }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: boards/waveshare-rp2040-zero/CHANGELOG.md ================================================ # 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.8.0 - 2024-04-07 ### Changed - Update to rp2040-hal 0.10.0 - Update to embedded-hal 1.0.0 ## 0.7.0 - 2023-09-02 ### Changed - Update to rp2040-hal 0.9.0 - Update to ws2812-pio 0.7.0 ## 0.6.0 - 2023-02-18 ### Changed - Update to rp2040-hal 0.8.0 - Update to ws2812-pio 0.6.0 ## 0.5.0 - 2022-12-11 ### Changed - Update to rp2040-hal 0.7.0 - Update to ws2812-pio 0.5.0 ## 0.4.0 - 2022-11-15 ### Changed - Inital release - Copied from adafruit-feather-rp2040 - Update pin names - Update board name ================================================ FILE: boards/waveshare-rp2040-zero/Cargo.toml ================================================ [package] name = "waveshare-rp2040-zero" version = "0.8.0" authors = ["Andrea Nall ", "TilCreator ", "The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/waveshare-rp2040-zero" description = "Board Support Package for the Adafruit Feather RP2040" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal-boards.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cortex-m-rt = { workspace = true, optional = true } rp2040-boot2 = { workspace = true, optional = true } rp2040-hal.workspace = true [dev-dependencies] cortex-m.workspace = true panic-halt.workspace = true embedded-hal.workspace = true fugit.workspace = true nb.workspace = true smart-leds.workspace = true ws2812-pio.workspace = true [features] # This is the set of features we enable by default default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] # critical section that is safe for multicore use critical-section-impl = ["rp2040-hal/critical-section-impl"] # 2nd stage bootloaders for rp2040 boot2 = ["rp2040-boot2"] # Minimal startup / runtime for Cortex-M microcontrollers rt = ["cortex-m-rt","rp2040-hal/rt"] # This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. # Only required for RP2040 B0 and RP2040 B1, but it doesn't hurt to enable it rp2040-e5 = ["rp2040-hal/rp2040-e5"] # Memoize(cache) ROM function pointers on first use to improve performance rom-func-cache = ["rp2040-hal/rom-func-cache"] # Disable automatic mapping of language features (like floating point math) to ROM functions disable-intrinsics = ["rp2040-hal/disable-intrinsics"] # This enables ROM functions for f64 math that were not present in the earliest RP2040s rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] ================================================ FILE: boards/waveshare-rp2040-zero/README.md ================================================ # [waveshare-rp2040-zero] - Board Support for the [Waveshare RP2040 Zero] You should include this crate if you are writing code that you want to run on an [Waveshare RP2040 Zero] - a very small RP2040 breakout board with USB-C and a RGB led from Waveshare. This crate includes the [rp2040-hal], but also configures each pin of the RP2040 chip according to how it is connected up on the Feather. [Waveshare RP2040 Zero]: https://www.waveshare.com/wiki/RP2040-Zero [waveshare-rp2040-zero]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/waveshare-rp2040-zero [rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal [Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/ ## Using To use this crate, your `Cargo.toml` file should contain: ```toml waveshare-rp2040-zero = "0.8.0" ``` In your program, you will need to call `waveshare_rp2040_zero::Pins::new` to create a new `Pins` structure. This will set up all the GPIOs for any on-board devices. See the [examples](./examples) folder for more details. ## Examples ### General Instructions To compile an example, clone the _rp-hal-boards_ repository and run: ```console rp-hal-boards/boards/waveshare-rp2040-zero $ cargo build --release --example ``` You will get an ELF file called `./target/thumbv6m-none-eabi/release/examples/`, where the `target` folder is located at the top of the _rp-hal-boards_ repository checkout. Normally you would also need to specify `--target=thumbv6m-none-eabi` but when building examples from this git repository, that is set as the default. If you want to convert the ELF file to a UF2 and automatically copy it to the USB drive exported by the RP2040 bootloader, simply boot your board into bootloader mode and run: ```console rp-hal-boards/boards/waveshare-rp2040-zero $ cargo run --release --example ``` If you get an error about not being able to find `elf2uf2-rs`, try: ```console $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ``` ### [waveshare_rp2040_zero_neopixel_rainbow](./examples/waveshare_rp2040_zero_neopixel_rainbow.rs) Flows smoothly through various colors on the onboard NeoPixel LED. ## Contributing Contributions are what make the open source community such an amazing place to be, learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: 1. Fork the Project by clicking the 'Fork' button at the top of the page. 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Make some changes to the code or documentation. 4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) 6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) 7. An admin will review the Pull Request and discuss any changes that may be required. 8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md [rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs ## License The contents of this repository are dual-licensed under the _MIT OR Apache 2.0_ License. That means you can choose either the MIT license or the Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more information on each specific license. Any submissions to this project (e.g. as Pull Requests) must be made available under these terms. ================================================ FILE: boards/waveshare-rp2040-zero/examples/waveshare_rp2040_zero_neopixel_rainbow.rs ================================================ //! Rainbow effect color wheel using the onboard NeoPixel on an Waveshare RP2040-Zero board //! //! This flows smoothly through various colours on the onboard NeoPixel. //! Uses the `ws2812_pio` driver to control the NeoPixel, which in turns uses the //! RP2040's PIO block. #![no_std] #![no_main] use core::iter::once; use embedded_hal::delay::DelayNs; use panic_halt as _; use smart_leds::{brightness, SmartLedsWrite, RGB8}; use waveshare_rp2040_zero::entry; use waveshare_rp2040_zero::{ hal::{ clocks::{init_clocks_and_plls, Clock}, pac, pio::PIOExt, timer::Timer, watchdog::Watchdog, Sio, }, Pins, XOSC_CRYSTAL_FREQ, }; use ws2812_pio::Ws2812; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then infinitely cycles the built-in LED colour from red, to green, /// to blue and back to red. #[entry] fn main() -> ! { let mut pac = pac::Peripherals::take().unwrap(); let mut watchdog = Watchdog::new(pac.WATCHDOG); let clocks = init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); let sio = Sio::new(pac.SIO); let pins = Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); // Configure the addressable LED let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let mut ws = Ws2812::new( // The onboard NeoPixel is attached to GPIO pin #16 on the Waveshare RP2040-Zero. pins.neopixel.into_function(), &mut pio, sm0, clocks.peripheral_clock.freq(), timer.count_down(), ); // Infinite colour wheel loop let mut n: u8 = 128; let mut timer = timer; // rebind to force a copy of the timer loop { ws.write(brightness(once(wheel(n)), 32)).unwrap(); n = n.wrapping_add(1); timer.delay_ms(25); } } /// Convert a number from `0..=255` to an RGB color triplet. /// /// The colours are a transition from red, to green, to blue and back to red. fn wheel(mut wheel_pos: u8) -> RGB8 { wheel_pos = 255 - wheel_pos; if wheel_pos < 85 { // No green in this sector - red and blue only (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() } else if wheel_pos < 170 { // No red in this sector - green and blue only wheel_pos -= 85; (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() } else { // No blue in this sector - red and green only wheel_pos -= 170; (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() } } ================================================ FILE: boards/waveshare-rp2040-zero/src/lib.rs ================================================ #![no_std] pub extern crate rp2040_hal as hal; #[cfg(feature = "rt")] extern crate cortex_m_rt; #[cfg(feature = "rt")] pub use hal::entry; /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. #[cfg(feature = "boot2")] #[link_section = ".boot2"] #[no_mangle] #[used] pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; pub use hal::pac; hal::bsp_pins!( /// GPIO 0 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp0Spi0Rx] | /// | `UART0 TX` | [crate::Gp0Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp0I2C0Sda] | /// | `PWM0 A` | [crate::Gp0Pwm0A] | /// | `PIO0` | [crate::Gp0Pio0] | /// | `PIO1` | [crate::Gp0Pio1] | Gpio0 { name: gp0, aliases: { /// UART Function alias for pin [crate::Pins::gpio0]. FunctionUart, PullNone: Gp0Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio0]. FunctionSpi, PullNone: Gp0Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio0]. FunctionI2C, PullUp: Gp0I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio0]. FunctionPwm, PullNone: Gp0Pwm0A, /// PIO0 Function alias for pin [crate::Pins::gpio0]. FunctionPio0, PullNone: Gp0Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio0]. FunctionPio1, PullNone: Gp0Pio1 } }, /// GPIO 1 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp1Spi0Csn] | /// | `UART0 RX` | [crate::Gp1Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp1I2C0Scl] | /// | `PWM0 B` | [crate::Gp1Pwm0B] | /// | `PIO0` | [crate::Gp1Pio0] | /// | `PIO1` | [crate::Gp1Pio1] | Gpio1 { name: gp1, aliases: { /// UART Function alias for pin [crate::Pins::gpio1]. FunctionUart, PullNone: Gp1Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio1]. FunctionSpi, PullNone: Gp1Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio1]. FunctionI2C, PullUp: Gp1I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio1]. FunctionPwm, PullNone: Gp1Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio1]. FunctionPio0, PullNone: Gp1Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio1]. FunctionPio1, PullNone: Gp1Pio1 } }, /// GPIO 2 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp2Spi0Sck] | /// | `UART0 CTS` | [crate::Gp2Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp2I2C1Sda] | /// | `PWM1 A` | [crate::Gp2Pwm1A] | /// | `PIO0` | [crate::Gp2Pio0] | /// | `PIO1` | [crate::Gp2Pio1] | Gpio2 { name: gp2, aliases: { /// UART Function alias for pin [crate::Pins::gpio2]. FunctionUart, PullNone: Gp2Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio2]. FunctionSpi, PullNone: Gp2Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio2]. FunctionI2C, PullUp: Gp2I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio2]. FunctionPwm, PullNone: Gp2Pwm1A, /// PIO0 Function alias for pin [crate::Pins::gpio2]. FunctionPio0, PullNone: Gp2Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio2]. FunctionPio1, PullNone: Gp2Pio1 } }, /// GPIO 3 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp3Spi0Tx] | /// | `UART0 RTS` | [crate::Gp3Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp3I2C1Scl] | /// | `PWM1 B` | [crate::Gp3Pwm1B] | /// | `PIO0` | [crate::Gp3Pio0] | /// | `PIO1` | [crate::Gp3Pio1] | Gpio3 { name: gp3, aliases: { /// UART Function alias for pin [crate::Pins::gpio3]. FunctionUart, PullNone: Gp3Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio3]. FunctionSpi, PullNone: Gp3Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio3]. FunctionI2C, PullUp: Gp3I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio3]. FunctionPwm, PullNone: Gp3Pwm1B, /// PIO0 Function alias for pin [crate::Pins::gpio3]. FunctionPio0, PullNone: Gp3Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio3]. FunctionPio1, PullNone: Gp3Pio1 } }, /// GPIO 4 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp4Spi0Rx] | /// | `UART1 TX` | [crate::Gp4Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp4I2C0Sda] | /// | `PWM2 A` | [crate::Gp4Pwm2A] | /// | `PIO0` | [crate::Gp4Pio0] | /// | `PIO1` | [crate::Gp4Pio1] | Gpio4 { name: gp4, aliases: { /// UART Function alias for pin [crate::Pins::gpio4]. FunctionUart, PullNone: Gp4Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio4]. FunctionSpi, PullNone: Gp4Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio4]. FunctionI2C, PullUp: Gp4I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio4]. FunctionPwm, PullNone: Gp4Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio4]. FunctionPio0, PullNone: Gp4Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio4]. FunctionPio1, PullNone: Gp4Pio1 } }, /// GPIO 5 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp5Spi0Csn] | /// | `UART1 RX` | [crate::Gp5Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp5I2C0Scl] | /// | `PWM2 B` | [crate::Gp5Pwm2B] | /// | `PIO0` | [crate::Gp5Pio0] | /// | `PIO1` | [crate::Gp5Pio1] | Gpio5 { name: gp5, aliases: { /// UART Function alias for pin [crate::Pins::gpio5]. FunctionUart, PullNone: Gp5Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio5]. FunctionSpi, PullNone: Gp5Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio5]. FunctionI2C, PullUp: Gp5I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio5]. FunctionPwm, PullNone: Gp5Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio5]. FunctionPio0, PullNone: Gp5Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio5]. FunctionPio1, PullNone: Gp5Pio1 } }, /// GPIO 6 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp6Spi0Sck] | /// | `UART1 CTS` | [crate::Gp6Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp6I2C1Sda] | /// | `PWM3 A` | [crate::Gp6Pwm3A] | /// | `PIO0` | [crate::Gp6Pio0] | /// | `PIO1` | [crate::Gp6Pio1] | Gpio6 { name: gp6, aliases: { /// UART Function alias for pin [crate::Pins::gpio6]. FunctionUart, PullNone: Gp6Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio6]. FunctionSpi, PullNone: Gp6Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio6]. FunctionI2C, PullUp: Gp6I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio6]. FunctionPwm, PullNone: Gp6Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio6]. FunctionPio0, PullNone: Gp6Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio6]. FunctionPio1, PullNone: Gp6Pio1 } }, /// GPIO 7 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp7Spi0Tx] | /// | `UART1 RTS` | [crate::Gp7Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp7I2C1Scl] | /// | `PWM3 B` | [crate::Gp7Pwm3B] | /// | `PIO0` | [crate::Gp7Pio0] | /// | `PIO1` | [crate::Gp7Pio1] | Gpio7 { name: gp7, aliases: { /// UART Function alias for pin [crate::Pins::gpio7]. FunctionUart, PullNone: Gp7Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio7]. FunctionSpi, PullNone: Gp7Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio7]. FunctionI2C, PullUp: Gp7I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio7]. FunctionPwm, PullNone: Gp7Pwm3B, /// PIO0 Function alias for pin [crate::Pins::gpio7]. FunctionPio0, PullNone: Gp7Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio7]. FunctionPio1, PullNone: Gp7Pio1 } }, /// GPIO 8 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp8Spi1Rx] | /// | `UART1 TX` | [crate::Gp8Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp8I2C0Sda] | /// | `PWM4 A` | [crate::Gp8Pwm4A] | /// | `PIO0` | [crate::Gp8Pio0] | /// | `PIO1` | [crate::Gp8Pio1] | Gpio8 { name: gp8, aliases: { /// UART Function alias for pin [crate::Pins::gpio8]. FunctionUart, PullNone: Gp8Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio8]. FunctionSpi, PullNone: Gp8Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio8]. FunctionI2C, PullUp: Gp8I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio8]. FunctionPwm, PullNone: Gp8Pwm4A, /// PIO0 Function alias for pin [crate::Pins::gpio8]. FunctionPio0, PullNone: Gp8Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio8]. FunctionPio1, PullNone: Gp8Pio1 } }, /// GPIO 9 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp9Spi1Csn] | /// | `UART1 RX` | [crate::Gp9Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp9I2C0Scl] | /// | `PWM4 B` | [crate::Gp9Pwm4B] | /// | `PIO0` | [crate::Gp9Pio0] | /// | `PIO1` | [crate::Gp9Pio1] | Gpio9 { name: gp9, aliases: { /// UART Function alias for pin [crate::Pins::gpio9]. FunctionUart, PullNone: Gp9Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio9]. FunctionSpi, PullNone: Gp9Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio9]. FunctionI2C, PullUp: Gp9I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio9]. FunctionPwm, PullNone: Gp9Pwm4B, /// PIO0 Function alias for pin [crate::Pins::gpio9]. FunctionPio0, PullNone: Gp9Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio9]. FunctionPio1, PullNone: Gp9Pio1 } }, /// GPIO 10 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp10Spi1Sck] | /// | `UART1 CTS` | [crate::Gp10Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp10I2C1Sda] | /// | `PWM5 A` | [crate::Gp10Pwm5A] | /// | `PIO0` | [crate::Gp10Pio0] | /// | `PIO1` | [crate::Gp10Pio1] | Gpio10 { name: gp10, aliases: { /// UART Function alias for pin [crate::Pins::gpio10]. FunctionUart, PullNone: Gp10Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio10]. FunctionSpi, PullNone: Gp10Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio10]. FunctionI2C, PullUp: Gp10I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio10]. FunctionPwm, PullNone: Gp10Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio10]. FunctionPio0, PullNone: Gp10Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio10]. FunctionPio1, PullNone: Gp10Pio1 } }, /// GPIO 11 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp11Spi1Tx] | /// | `UART1 RTS` | [crate::Gp11Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp11I2C1Scl] | /// | `PWM5 B` | [crate::Gp11Pwm5B] | /// | `PIO0` | [crate::Gp11Pio0] | /// | `PIO1` | [crate::Gp11Pio1] | Gpio11 { name: gp11, aliases: { /// UART Function alias for pin [crate::Pins::gpio11]. FunctionUart, PullNone: Gp11Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio11]. FunctionSpi, PullNone: Gp11Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio11]. FunctionI2C, PullUp: Gp11I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio11]. FunctionPwm, PullNone: Gp11Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio11]. FunctionPio0, PullNone: Gp11Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio11]. FunctionPio1, PullNone: Gp11Pio1 } }, /// GPIO 12 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp12Spi1Rx] | /// | `UART0 TX` | [crate::Gp12Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp12I2C0Sda] | /// | `PWM6 A` | [crate::Gp12Pwm6A] | /// | `PIO0` | [crate::Gp12Pio0] | /// | `PIO1` | [crate::Gp12Pio1] | Gpio12 { name: gp12, aliases: { /// UART Function alias for pin [crate::Pins::gpio12]. FunctionUart, PullNone: Gp12Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio12]. FunctionSpi, PullNone: Gp12Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio12]. FunctionI2C, PullUp: Gp12I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio12]. FunctionPwm, PullNone: Gp12Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio12]. FunctionPio0, PullNone: Gp12Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio12]. FunctionPio1, PullNone: Gp12Pio1 } }, /// GPIO 13 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 CSn` | [crate::Gp13Spi1Csn] | /// | `UART0 RX` | [crate::Gp13Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp13I2C0Scl] | /// | `PWM6 B` | [crate::Gp13Pwm6B] | /// | `PIO0` | [crate::Gp13Pio0] | /// | `PIO1` | [crate::Gp13Pio1] | Gpio13 { name: gp13, aliases: { /// UART Function alias for pin [crate::Pins::gpio13]. FunctionUart, PullNone: Gp13Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio13]. FunctionSpi, PullNone: Gp13Spi1Csn, /// I2C Function alias for pin [crate::Pins::gpio13]. FunctionI2C, PullUp: Gp13I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio13]. FunctionPwm, PullNone: Gp13Pwm6B, /// PIO0 Function alias for pin [crate::Pins::gpio13]. FunctionPio0, PullNone: Gp13Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio13]. FunctionPio1, PullNone: Gp13Pio1 } }, /// GPIO 14 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp14Spi1Sck] | /// | `UART0 CTS` | [crate::Gp14Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp14I2C1Sda] | /// | `PWM7 A` | [crate::Gp14Pwm7A] | /// | `PIO0` | [crate::Gp14Pio0] | /// | `PIO1` | [crate::Gp14Pio1] | Gpio14 { name: gp14, aliases: { /// UART Function alias for pin [crate::Pins::gpio14]. FunctionUart, PullNone: Gp14Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio14]. FunctionSpi, PullNone: Gp14Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio14]. FunctionI2C, PullUp: Gp14I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio14]. FunctionPwm, PullNone: Gp14Pwm7A, /// PIO0 Function alias for pin [crate::Pins::gpio14]. FunctionPio0, PullNone: Gp14Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio14]. FunctionPio1, PullNone: Gp14Pio1 } }, /// GPIO 15 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp15Spi1Tx] | /// | `UART0 RTS` | [crate::Gp15Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp15I2C1Scl] | /// | `PWM7 B` | [crate::Gp15Pwm7B] | /// | `PIO0` | [crate::Gp15Pio0] | /// | `PIO1` | [crate::Gp15Pio1] | Gpio15 { name: gp15, aliases: { /// UART Function alias for pin [crate::Pins::gpio15]. FunctionUart, PullNone: Gp15Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio15]. FunctionSpi, PullNone: Gp15Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio15]. FunctionI2C, PullUp: Gp15I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio15]. FunctionPwm, PullNone: Gp15Pwm7B, /// PIO0 Function alias for pin [crate::Pins::gpio15]. FunctionPio0, PullNone: Gp15Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio15]. FunctionPio1, PullNone: Gp15Pio1 } }, /// GPIO 16 is connected internally to a single Neopixel RGB LED Gpio16 { name: neopixel }, /// GPIO 17 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp17Spi0Csn] | /// | `UART0 RX` | [crate::Gp17Uart0Rx] | /// | `I2C0 SCL` | [crate::Gp17I2C0Scl] | /// | `PWM0 B` | [crate::Gp17Pwm0B] | /// | `PIO0` | [crate::Gp17Pio0] | /// | `PIO1` | [crate::Gp17Pio1] | Gpio17 { name: gpio17, aliases: { /// UART Function alias for pin [crate::Pins::gpio17]. FunctionUart, PullNone: Gp17Uart0Rx, /// SPI Function alias for pin [crate::Pins::gpio17]. FunctionSpi, PullNone: Gp17Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio17]. FunctionI2C, PullUp: Gp17I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio17]. FunctionPwm, PullNone: Gp17Pwm0B, /// PIO0 Function alias for pin [crate::Pins::gpio17]. FunctionPio0, PullNone: Gp17Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio17]. FunctionPio1, PullNone: Gp17Pio1 } }, /// GPIO 18 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp18Spi0Sck] | /// | `UART0 CTS` | [crate::Gp18Uart0Cts] | /// | `I2C1 SDA` | [crate::Gp18I2C1Sda] | /// | `PWM1 A` | [crate::Gp18Pwm1A] | /// | `PIO0` | [crate::Gp18Pio0] | /// | `PIO1` | [crate::Gp18Pio1] | Gpio18 { name: gpio18, aliases: { /// UART Function alias for pin [crate::Pins::gpio18]. FunctionUart, PullNone: Gp18Uart0Cts, /// SPI Function alias for pin [crate::Pins::gpio18]. FunctionSpi, PullNone: Gp18Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio18]. FunctionI2C, PullUp: Gp18I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio18]. FunctionPwm, PullNone: Gp18Pwm1A, /// PIO0 Function alias for pin [crate::Pins::gpio18]. FunctionPio0, PullNone: Gp18Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio18]. FunctionPio1, PullNone: Gp18Pio1 } }, /// GPIO 19 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 TX` | [crate::Gp19Spi0Tx] | /// | `UART0 RTS` | [crate::Gp19Uart0Rts] | /// | `I2C1 SCL` | [crate::Gp19I2C1Scl] | /// | `PWM1 B` | [crate::Gp19Pwm1B] | /// | `PIO0` | [crate::Gp19Pio0] | /// | `PIO1` | [crate::Gp19Pio1] | Gpio19 { name: gpio19, aliases: { /// UART Function alias for pin [crate::Pins::gpio19]. FunctionUart, PullNone: Gp19Uart0Rts, /// SPI Function alias for pin [crate::Pins::gpio19]. FunctionSpi, PullNone: Gp19Spi0Tx, /// I2C Function alias for pin [crate::Pins::gpio19]. FunctionI2C, PullUp: Gp19I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio19]. FunctionPwm, PullNone: Gp19Pwm1B, /// PIO0 Function alias for pin [crate::Pins::gpio19]. FunctionPio0, PullNone: Gp19Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio19]. FunctionPio1, PullNone: Gp19Pio1 } }, /// GPIO 20 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 RX` | [crate::Gp20Spi0Rx] | /// | `UART1 TX` | [crate::Gp20Uart1Tx] | /// | `I2C0 SDA` | [crate::Gp20I2C0Sda] | /// | `PWM2 A` | [crate::Gp20Pwm2A] | /// | `PIO0` | [crate::Gp20Pio0] | /// | `PIO1` | [crate::Gp20Pio1] | Gpio20 { name: gpio20, aliases: { /// UART Function alias for pin [crate::Pins::gpio20]. FunctionUart, PullNone: Gp20Uart1Tx, /// SPI Function alias for pin [crate::Pins::gpio20]. FunctionSpi, PullNone: Gp20Spi0Rx, /// I2C Function alias for pin [crate::Pins::gpio20]. FunctionI2C, PullUp: Gp20I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio20]. FunctionPwm, PullNone: Gp20Pwm2A, /// PIO0 Function alias for pin [crate::Pins::gpio20]. FunctionPio0, PullNone: Gp20Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio20]. FunctionPio1, PullNone: Gp20Pio1 } }, /// GPIO 21 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 CSn` | [crate::Gp21Spi0Csn] | /// | `UART1 RX` | [crate::Gp21Uart1Rx] | /// | `I2C0 SCL` | [crate::Gp21I2C0Scl] | /// | `PWM2 B` | [crate::Gp21Pwm2B] | /// | `PIO0` | [crate::Gp21Pio0] | /// | `PIO1` | [crate::Gp21Pio1] | Gpio21 { name: gpio21, aliases: { /// UART Function alias for pin [crate::Pins::gpio21]. FunctionUart, PullNone: Gp21Uart1Rx, /// SPI Function alias for pin [crate::Pins::gpio21]. FunctionSpi, PullNone: Gp21Spi0Csn, /// I2C Function alias for pin [crate::Pins::gpio21]. FunctionI2C, PullUp: Gp21I2C0Scl, /// PWM Function alias for pin [crate::Pins::gpio21]. FunctionPwm, PullNone: Gp21Pwm2B, /// PIO0 Function alias for pin [crate::Pins::gpio21]. FunctionPio0, PullNone: Gp21Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio21]. FunctionPio1, PullNone: Gp21Pio1 } }, /// GPIO 22 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI0 SCK` | [crate::Gp22Spi0Sck] | /// | `UART1 CTS` | [crate::Gp22Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp22I2C1Sda] | /// | `PWM3 A` | [crate::Gp22Pwm3A] | /// | `PIO0` | [crate::Gp22Pio0] | /// | `PIO1` | [crate::Gp22Pio1] | Gpio22 { name: gpio22, aliases: { /// UART Function alias for pin [crate::Pins::gpio22]. FunctionUart, PullNone: Gp22Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio22]. FunctionSpi, PullNone: Gp22Spi0Sck, /// I2C Function alias for pin [crate::Pins::gpio22]. FunctionI2C, PullUp: Gp22I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio22]. FunctionPwm, PullNone: Gp22Pwm3A, /// PIO0 Function alias for pin [crate::Pins::gpio22]. FunctionPio0, PullNone: Gp22Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio22]. FunctionPio1, PullNone: Gp22Pio1 } }, /// GPIO 23 Gpio23 { name: gp23, aliases: { FunctionUart, PullNone: Gp23Uart1Rts, FunctionSpi, PullNone: Gp23Spi0Tx, FunctionI2C, PullUp: Gp23I2C1Scl, FunctionPwm, PullNone: Gp23Pwm3B, FunctionPio0, PullNone: Gp23Pio0, FunctionPio1, PullNone: Gp23Pio1 } }, /// GPIO 24 Gpio24 { name: gp24, aliases: { FunctionUart, PullNone: Gp24Uart1Tx, FunctionSpi, PullNone: Gp24Spi1Rx, FunctionI2C, PullUp: Gp24I2C0Sda, FunctionPwm, PullNone: Gp24Pwm4A, FunctionPio0, PullNone: Gp24Pio0, FunctionPio1, PullNone: Gp24Pio1 } }, /// GPIO 25 Gpio25 { name: gp25, aliases: { FunctionUart, PullNone: Gp25Uart1Rx, FunctionSpi, PullNone: Gp25Spi1Csn, FunctionI2C, PullUp: Gp25I2C0Scl, FunctionPwm, PullNone: Gp25Pwm4B, FunctionPio0, PullNone: Gp25Pio0, FunctionPio1, PullNone: Gp25Pio1 } }, /// GPIO 26 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 SCK` | [crate::Gp26Spi1Sck] | /// | `UART1 CTS` | [crate::Gp26Uart1Cts] | /// | `I2C1 SDA` | [crate::Gp26I2C1Sda] | /// | `PWM5 A` | [crate::Gp26Pwm5A] | /// | `PIO0` | [crate::Gp26Pio0] | /// | `PIO1` | [crate::Gp26Pio1] | /// /// ADC0 Gpio26 { name: gp26, aliases: { /// UART Function alias for pin [crate::Pins::gpio26]. FunctionUart, PullNone: Gp26Uart1Cts, /// SPI Function alias for pin [crate::Pins::gpio26]. FunctionSpi, PullNone: Gp26Spi1Sck, /// I2C Function alias for pin [crate::Pins::gpio26]. FunctionI2C, PullUp: Gp26I2C1Sda, /// PWM Function alias for pin [crate::Pins::gpio26]. FunctionPwm, PullNone: Gp26Pwm5A, /// PIO0 Function alias for pin [crate::Pins::gpio26]. FunctionPio0, PullNone: Gp26Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio26]. FunctionPio1, PullNone: Gp26Pio1 } }, /// GPIO 27 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 TX` | [crate::Gp27Spi1Tx] | /// | `UART1 RTS` | [crate::Gp27Uart1Rts] | /// | `I2C1 SCL` | [crate::Gp27I2C1Scl] | /// | `PWM5 B` | [crate::Gp27Pwm5B] | /// | `PIO0` | [crate::Gp27Pio0] | /// | `PIO1` | [crate::Gp27Pio1] | /// /// ADC1 Gpio27 { name: gp27, aliases: { /// UART Function alias for pin [crate::Pins::gpio27]. FunctionUart, PullNone: Gp27Uart1Rts, /// SPI Function alias for pin [crate::Pins::gpio27]. FunctionSpi, PullNone: Gp27Spi1Tx, /// I2C Function alias for pin [crate::Pins::gpio27]. FunctionI2C, PullUp: Gp27I2C1Scl, /// PWM Function alias for pin [crate::Pins::gpio27]. FunctionPwm, PullNone: Gp27Pwm5B, /// PIO0 Function alias for pin [crate::Pins::gpio27]. FunctionPio0, PullNone: Gp27Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio27]. FunctionPio1, PullNone: Gp27Pio1 } }, /// GPIO 28 supports following functions: /// /// | Function | Alias with applied function | /// |--------------|-----------------------------| /// | `SPI1 RX` | [crate::Gp28Spi1Rx] | /// | `UART0 TX` | [crate::Gp28Uart0Tx] | /// | `I2C0 SDA` | [crate::Gp28I2C0Sda] | /// | `PWM6 A` | [crate::Gp28Pwm6A] | /// | `PIO0` | [crate::Gp28Pio0] | /// | `PIO1` | [crate::Gp28Pio1] | /// /// ADC2 Gpio28 { name: gp28, aliases: { /// UART Function alias for pin [crate::Pins::gpio28]. FunctionUart, PullNone: Gp28Uart0Tx, /// SPI Function alias for pin [crate::Pins::gpio28]. FunctionSpi, PullNone: Gp28Spi1Rx, /// I2C Function alias for pin [crate::Pins::gpio28]. FunctionI2C, PullUp: Gp28I2C0Sda, /// PWM Function alias for pin [crate::Pins::gpio28]. FunctionPwm, PullNone: Gp28Pwm6A, /// PIO0 Function alias for pin [crate::Pins::gpio28]. FunctionPio0, PullNone: Gp28Pio0, /// PIO1 Function alias for pin [crate::Pins::gpio28]. FunctionPio1, PullNone: Gp28Pio1 } }, /// GPIO 29 /// /// ADC3 Gpio29 { name: gp29, aliases: { FunctionUart, PullNone: Gp29Uart0Rx, FunctionSpi, PullNone: Gp29Spi1Csn, FunctionI2C, PullUp: Gp29I2C0Scl, FunctionPwm, PullNone: Gp29Pwm6B, FunctionPio0, PullNone: Gp29Pio0, FunctionPio1, PullNone: Gp29Pio1 } }, ); pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; ================================================ FILE: memory.x ================================================ MEMORY { BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100 RAM : ORIGIN = 0x20000000, LENGTH = 256K } EXTERN(BOOT2_FIRMWARE) SECTIONS { /* ### Boot loader */ .boot2 ORIGIN(BOOT2) : { KEEP(*(.boot2)); } > BOOT2 } INSERT BEFORE .text;