mirror of
https://github.com/italicsjenga/rp-hal-boards.git
synced 2024-12-23 20:51:31 +11:00
Merge pull request #137 from 42-technology-ltd/ensure-hal-examples-non-board-specific
Working on README and examples
This commit is contained in:
commit
da89888ccb
|
@ -10,3 +10,4 @@ rustflags = [
|
|||
"-C", "no-vectorize-loops",
|
||||
]
|
||||
runner = "elf2uf2-rs -d"
|
||||
# runner = "probe-run-rp --chip RP2040"
|
||||
|
|
188
README.md
188
README.md
|
@ -8,26 +8,26 @@
|
|||
<h3 align="center">rp-hal</h3>
|
||||
|
||||
<p align="center">
|
||||
A Rust HAL and board support packages for the RP family of microcontrollers from the Raspberry Pi Foundation
|
||||
Rust support for the "Raspberry Silicon" family of microcontrollers
|
||||
<br />
|
||||
<a href="https://github.com/rp-rs/rp-hal"><strong>Explore the docs »</strong></a>
|
||||
<a href="https://docs.rs/rp2040-hal"><strong>Explore the API docs »</strong></a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://github.com/rp-rs/rp-hal">View Demo</a>
|
||||
<a href="https://github.com/rp-rs/rp-hal/tree/main/boards/pico/examples">View Demos</a>
|
||||
·
|
||||
<a href="https://github.com/rp-rs/rp-hal/issues">Report Bug</a>
|
||||
<a href="https://github.com/rp-rs/rp-hal/issues">Report a Bug</a>
|
||||
·
|
||||
<a href="https://github.com/rp-rs/rp-hal/issues">Request Feature</a>
|
||||
<a href="https://matrix.to/#/#rp-rs:matrix.org">Chat on Matrix</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<!-- TABLE OF CONTENTS -->
|
||||
<details open="open">
|
||||
<summary><h2 style="display: inline-block">Table of Contents</h2></summary>
|
||||
<ol>
|
||||
<li><a href="#packages">Packages</a></li>
|
||||
<li><a href="#gettting_started">Getting Started</a></li>
|
||||
<li><a href="#programming">Programming</a></li>
|
||||
<li><a href="#roadmap">Roadmap</a></li>
|
||||
<li><a href="#contributing">Contributing</a></li>
|
||||
<li><a href="#license">License</a></li>
|
||||
|
@ -37,6 +37,45 @@
|
|||
</details>
|
||||
|
||||
<!-- GETTING STARTED -->
|
||||
|
||||
## Getting Started
|
||||
|
||||
So, you want to program your new Raspberry Silicon microcontroller, using the
|
||||
Rust programming language. You've come to the right place!
|
||||
|
||||
This repository is `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 write code that uses the Raspberry Silicon PIO State Machines,
|
||||
check out [pio-rs](https://github.com/rp-rs/pio-rs). You can even compile PIO
|
||||
programs at run-time, on the RP2040 itself!
|
||||
|
||||
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 elf2uf2-rs
|
||||
# Useful for flashing over the SWD pins using a supported JTAG probe
|
||||
cargo install --git https://github.com/rp-rs/probe-run.git --branch rp2040-support
|
||||
```
|
||||
|
||||
## Packages
|
||||
|
||||
This git repository is organised as a [Cargo Workspace].
|
||||
|
@ -52,16 +91,16 @@ 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 will include some examples to show off the features of that particular board.
|
||||
Each BSP includes some examples to show off the features of that particular board.
|
||||
|
||||
[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] - The HAL for the [Raspberry Pi Silicon RP2040]
|
||||
### [rp2040-hal] - The HAL for the [Raspberry Silicon RP2040]
|
||||
|
||||
You should include this crate in your project if you want to write a driver or
|
||||
library that runs on the [Raspberry Pi Silicon RP2040], or if you are writing a Board
|
||||
library that runs on the [Raspberry Silicon RP2040], or if you are writing a Board
|
||||
Support Package (see later on).
|
||||
|
||||
The crate provides high-level drivers for the RP2040's internal peripherals,
|
||||
|
@ -74,7 +113,7 @@ There are examples in this crate to show how to use various peripherals
|
|||
particular board.
|
||||
|
||||
[rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal
|
||||
[Raspberry Pi Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/
|
||||
[Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/
|
||||
|
||||
### [pico] - Board Support for the [Raspberry Pi Pico]
|
||||
|
||||
|
@ -147,12 +186,130 @@ RP2040 chip according to how it is connected up on the Pro Micro RP2040.
|
|||
[Sparkfun Pro Micro RP2040]: https://www.sparkfun.com/products/18288
|
||||
[pro_micro_rp2040]: https://github.com/rp-rs/rp-hal/tree/main/boards/pro_micro_rp2040
|
||||
|
||||
<!-- PROGRAMMING -->
|
||||
## 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
|
||||
```
|
||||
|
||||
*Step 2* - Make sure your .cargo/config 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-run
|
||||
|
||||
The Knurling project has a tool called
|
||||
[probe-run](https://github.com/knurling-rs/probe-run). This is a command-line
|
||||
tool which can flash a wide variety of microcontrollers using a wide variety of
|
||||
debug/JTAG probes. It is based on a library called
|
||||
[probe-rs](https://github.com/probe-rs/probe-rs). Unlike using, say, OpenOCD,
|
||||
probe-rs can autodetect your debug probe, which can make it easier to use.
|
||||
|
||||
Currently, probe-rs supports the slightly unusual debug hardware in the RP2040,
|
||||
but the last released probe-run tool (v0.2.6, as of September 2021), does not.
|
||||
However, there is a special version of probe-run for the RP2040 called
|
||||
[probe-run-rp](https://github.com/rp-rs/probe-run/tree/rp2040-support).
|
||||
|
||||
*Step 1* - Install `probe-run-rp`:
|
||||
|
||||
```console
|
||||
$ cargo install --git https://github.com/rp-rs/probe-run.git --branch rp2040-support
|
||||
```
|
||||
|
||||
*Step 2* - Make sure your .cargo/config contains the following:
|
||||
|
||||
```toml
|
||||
[target.thumbv6m-none-eabi]
|
||||
runner = "probe-run-rp --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-run-rp --chip RP2040 --list-probes
|
||||
The following devices 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-run-rp` 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 [picoprobe](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 -->
|
||||
## Roadmap
|
||||
|
||||
NOTE These packages are under active development. As such, it is likely to remain volatile until a 1.0.0 release.
|
||||
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).
|
||||
See the [open issues](https://github.com/rp-rs/rp-hal/issues) for a list of
|
||||
proposed features (and known issues).
|
||||
|
||||
|
||||
<!-- CONTRIBUTING -->
|
||||
|
@ -195,9 +352,8 @@ under these terms.
|
|||
<!-- CONTACT -->
|
||||
## Contact
|
||||
|
||||
Project Link: [https://github.com/rp-rs/rp-hal/issues](https://github.com/rp-rs/rp-hal/issues)
|
||||
Matrix: [#rp-rs:matrix.org](https://matrix.to/#/#rp-rs:matrix.org)
|
||||
|
||||
Raise an issue: [https://github.com/rp-rs/rp-hal/issues](https://github.com/rp-rs/rp-hal/issues)
|
||||
Chat to us on Matrix: [#rp-rs:matrix.org](https://matrix.to/#/#rp-rs:matrix.org)
|
||||
|
||||
<!-- ACKNOWLEDGEMENTS -->
|
||||
## Acknowledgements
|
||||
|
|
|
@ -9,7 +9,7 @@ RP2040 chip according to how it is connected up on the Feather.
|
|||
[adafruit_macropad]: https://github.com/rp-rs/rp-hal/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 Pi Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/
|
||||
[Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/
|
||||
|
||||
## Using
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ RP2040 chip according to how it is connected up on the Feather.
|
|||
[Adafruit Feather RP2040]: https://www.adafruit.com/product/4884
|
||||
[feather_rp2040]: https://github.com/rp-rs/rp-hal/tree/main/boards/feather_rp2040
|
||||
[rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal
|
||||
[Raspberry Pi Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/
|
||||
[Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/
|
||||
|
||||
## Using
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ RP2040 chip according to how it is connected up on the Pico.
|
|||
[Raspberry Pi Pico]: https://www.raspberrypi.org/products/raspberry-pi-pico/
|
||||
[pico]: https://github.com/rp-rs/rp-hal/tree/main/boards/pico
|
||||
[rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal
|
||||
[Raspberry Pi Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/
|
||||
[Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/
|
||||
|
||||
## Using
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@ use pico::hal::pac;
|
|||
// higher-level drivers.
|
||||
use pico::hal;
|
||||
|
||||
/// 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.
|
||||
//// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
@ -58,7 +58,7 @@ fn main() -> ! {
|
|||
|
||||
// Configure the clocks
|
||||
//
|
||||
// Our default is 12 MHz crystal input, 125 MHz system clock
|
||||
// The default is to generate a 125 MHz system clock
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
pico::XOSC_CRYSTAL_FREQ,
|
||||
pac.XOSC,
|
||||
|
|
|
@ -47,7 +47,7 @@ fn main() -> ! {
|
|||
|
||||
// Configure the clocks
|
||||
//
|
||||
// Our default is 12 MHz crystal input, 125 MHz system clock
|
||||
// The default is to generate a 125 MHz system clock
|
||||
let _clocks = hal::clocks::init_clocks_and_plls(
|
||||
pico::XOSC_CRYSTAL_FREQ,
|
||||
pac.XOSC,
|
||||
|
|
|
@ -30,8 +30,8 @@ use pico::hal::pac;
|
|||
// higher-level drivers.
|
||||
use pico::hal;
|
||||
|
||||
/// 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.
|
||||
//// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
|
|
@ -34,8 +34,8 @@ use pico::hal::pac;
|
|||
// higher-level drivers.
|
||||
use pico::hal;
|
||||
|
||||
/// 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.
|
||||
//// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
@ -64,7 +64,7 @@ fn main() -> ! {
|
|||
|
||||
// Configure the clocks
|
||||
//
|
||||
// Our default is 12 MHz crystal input, 125 MHz system clock
|
||||
// The default is to generate a 125 MHz system clock
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
pico::XOSC_CRYSTAL_FREQ,
|
||||
pac.XOSC,
|
||||
|
|
|
@ -33,8 +33,8 @@ use usb_device::{class_prelude::*, prelude::*};
|
|||
// USB Communications Class Device support
|
||||
use usbd_serial::SerialPort;
|
||||
|
||||
/// 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.
|
||||
//// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
@ -56,7 +56,7 @@ fn main() -> ! {
|
|||
|
||||
// Configure the clocks
|
||||
//
|
||||
// Our default is 12 MHz crystal input, 125 MHz system clock
|
||||
// The default is to generate a 125 MHz system clock
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
pico::XOSC_CRYSTAL_FREQ,
|
||||
pac.XOSC,
|
||||
|
|
|
@ -45,8 +45,8 @@ use usb_device::{class_prelude::*, prelude::*};
|
|||
// USB Communications Class Device support
|
||||
use usbd_serial::SerialPort;
|
||||
|
||||
/// 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.
|
||||
//// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
@ -78,7 +78,7 @@ fn main() -> ! {
|
|||
|
||||
// Configure the clocks
|
||||
//
|
||||
// Our default is 12 MHz crystal input, 125 MHz system clock
|
||||
// The default is to generate a 125 MHz system clock
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
pico::XOSC_CRYSTAL_FREQ,
|
||||
pac.XOSC,
|
||||
|
|
|
@ -44,8 +44,8 @@ use usbd_hid::descriptor::generator_prelude::*;
|
|||
use usbd_hid::descriptor::MouseReport;
|
||||
use usbd_hid::hid_class::HIDClass;
|
||||
|
||||
/// 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.
|
||||
//// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
@ -76,7 +76,7 @@ fn main() -> ! {
|
|||
|
||||
// Configure the clocks
|
||||
//
|
||||
// Our default is 12 MHz crystal input, 125 MHz system clock
|
||||
// The default is to generate a 125 MHz system clock
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
pico::XOSC_CRYSTAL_FREQ,
|
||||
pac.XOSC,
|
||||
|
|
|
@ -10,7 +10,7 @@ RP2040 chip according to how it is connected up on the Pico Explorer.
|
|||
[Pimoroni Pico Explorer]: https://shop.pimoroni.com/products/pico-explorer-base
|
||||
[pico_explorer]: https://github.com/rp-rs/rp-hal/tree/main/boards/pico_explorer
|
||||
[rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal
|
||||
[Raspberry Pi Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/
|
||||
[Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/
|
||||
|
||||
## Using
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@ use pico_lipo_16_mb::hal::pac;
|
|||
// higher-level drivers.
|
||||
use pico_lipo_16_mb::hal;
|
||||
|
||||
/// 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.
|
||||
//// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
@ -58,7 +58,7 @@ fn main() -> ! {
|
|||
|
||||
// Configure the clocks
|
||||
//
|
||||
// Our default is 12 MHz crystal input, 125 MHz system clock
|
||||
// The default is to generate a 125 MHz system clock
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
pico_lipo_16_mb::XOSC_CRYSTAL_FREQ,
|
||||
pac.XOSC,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# [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 Pi Silicon RP2040] board with USB-C and a WS2812B addressable LED.
|
||||
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.
|
||||
|
@ -9,7 +9,7 @@ RP2040 chip according to how it is connected up on the Pro Micro RP2040.
|
|||
[Sparkfun Pro Micro RP2040]: https://www.sparkfun.com/products/18288
|
||||
[pro_micro_rp2040]: https://github.com/rp-rs/rp-hal/tree/main/boards/pro_micro_rp2040
|
||||
[rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal
|
||||
[Raspberry Pi Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/
|
||||
[Raspberry Silicon RP2040]: https://www.raspberrypi.org/products/rp2040/
|
||||
|
||||
## Using
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ use pro_micro_rp2040::{
|
|||
use smart_leds::{brightness, SmartLedsWrite, RGB8};
|
||||
use ws2812_pio::Ws2812;
|
||||
|
||||
/// The linker will place this boot block at the start of our program image.
|
||||
//// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
|
@ -80,7 +80,7 @@ fn main() -> ! {
|
|||
25,
|
||||
pac.PIO0,
|
||||
&mut pac.RESETS,
|
||||
clocks.system_clock.freq(),
|
||||
clocks.peripheral_clock.freq(),
|
||||
timer.count_down(),
|
||||
);
|
||||
|
||||
|
|
|
@ -8,16 +8,16 @@
|
|||
<h3 align="center">rp-hal</h3>
|
||||
|
||||
<p align="center">
|
||||
A Rust HAL impl for the RP family of microcontrollers from the Raspberry Pi Foundation
|
||||
High-level Rust drivers for the Raspberry Silicon RP2040 Microcontroller
|
||||
<br />
|
||||
<a href="https://github.com/rp-rs/rp-hal"><strong>Explore the docs »</strong></a>
|
||||
<a href="https://docs.rs/rp2040-hal"><strong>Explore the API docs »</strong></a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://github.com/rp-rs/rp-hal">View Demo</a>
|
||||
<a href="https://github.com/rp-rs/rp-hal/tree/main/boards/pico/examples">View Demos</a>
|
||||
·
|
||||
<a href="https://github.com/rp-rs/rp-hal/issues">Report Bug</a>
|
||||
<a href="https://github.com/rp-rs/rp-hal/issues">Report a Bug</a>
|
||||
·
|
||||
<a href="https://github.com/rp-rs/rp-hal/issues">Request Feature</a>
|
||||
<a href="https://matrix.to/#/#rp-rs:matrix.org">Chat on Matrix</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
|||
<details open="open">
|
||||
<summary><h2 style="display: inline-block">Table of Contents</h2></summary>
|
||||
<ol>
|
||||
<li><a href="#introduction">Introduction</a></li>
|
||||
<li>
|
||||
<a href="#getting-started">Getting Started</a>
|
||||
<ul>
|
||||
|
@ -34,7 +35,6 @@
|
|||
<li><a href="#installation">Installation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#usage">Usage</a></li>
|
||||
<li><a href="#roadmap">Roadmap</a></li>
|
||||
<li><a href="#contributing">Contributing</a></li>
|
||||
<li><a href="#license">License</a></li>
|
||||
|
@ -43,70 +43,60 @@
|
|||
</ol>
|
||||
</details>
|
||||
|
||||
<!-- INTRODUCTION -->
|
||||
## Introduction
|
||||
|
||||
This is the `rp2040-hal` package - a library crate of high-level Rust drivers
|
||||
for the Raspberry Silicon RP2040 microcontroller, along with a collection of
|
||||
non-board specific example programs for you to study. You should use this crate
|
||||
in your application if you want to write code for the RP2040 microcontroller.
|
||||
The *HAL* in the name standards for *Hardware Abstraction Layer*, and comes from
|
||||
the fact that many of the drivers included implement the generic
|
||||
hardware-abstraction interfaces defined in the Rust Embedded Working Group's
|
||||
[embedded-hal](https://github.com/rust-embedded/embedded-hal) crate.
|
||||
|
||||
We also provide a series of *Board Support Package* (BSP) crates, which take
|
||||
this HAL crate and pre-configure the pins according to a specific PCB design. If
|
||||
you are using on of the supported boards, you should use one of those crates in
|
||||
preference, and return here to see documentation about specific peripherals on
|
||||
the RP2040 and how to use them. See the `boards` folder in
|
||||
https://github.com/rp-rs/rp-hal/ for more details.
|
||||
|
||||
<!-- GETTING STARTED -->
|
||||
## Getting Started
|
||||
|
||||
To get a local copy up and running follow these simple steps.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* A [Rust](https://www.rust-lang.org/tools/install) toolchain
|
||||
|
||||
### Installation
|
||||
|
||||
1. Clone the repo or use the crate
|
||||
|
||||
```sh
|
||||
git clone https://github.com/rp-rs/rp-hal
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```sh
|
||||
cargo install rp2040-hal
|
||||
```
|
||||
|
||||
<!-- USAGE EXAMPLES -->
|
||||
## Usage
|
||||
|
||||
Use this space to show useful examples of how a project can be used. Additional screenshots, code examples and demos work well in this space. You may also link to more resources.
|
||||
|
||||
For more examples, please refer to the [Documentation](https://github.com/rp-rs/rp-hal)
|
||||
|
||||
### Run examples
|
||||
|
||||
#### UF2
|
||||
|
||||
For boards with uf2 flashloaders like the raspberry pi pico. Install [`elf2uf2-rs`](https://github.com/JoNil/elf2uf2-rs):
|
||||
|
||||
```sh
|
||||
cargo install elf2uf2-rs
|
||||
```
|
||||
|
||||
Make sure .cargo/config contains the following (it should by default):
|
||||
To include this crate in your project, amend your `Cargo.toml` file to include
|
||||
|
||||
```toml
|
||||
runner = "elf2uf2-rs -d"
|
||||
rp2040-hal = "0.3"
|
||||
```
|
||||
|
||||
**IMPORTANT: Make sure you've put your device into bootloader mode and the drive is showing as mounted before executing the next command.**
|
||||
To obtain a copy of the source code (e.g. if you want to propose a bug-fix or
|
||||
new feature, or simply to study the code), run:
|
||||
|
||||
```sh
|
||||
cargo run --example pico_pwm_blink # Run `cargo run --example` for more examples
|
||||
```console
|
||||
$ git clone https://github.com/rp-rs/rp-hal.git
|
||||
```
|
||||
|
||||
For details on how to program an RP2040 microcontroller, see the [top-level
|
||||
rp-hal README](https://github.com/rp-rs/rp-hal/).
|
||||
|
||||
<!-- ROADMAP -->
|
||||
## Roadmap
|
||||
|
||||
NOTE This HAL is under active development. As such, it is likely to remain volatile until a 1.0.0 release.
|
||||
NOTE This HAL is 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).
|
||||
See the [open issues](https://github.com/rp-rs/rp-hal/issues) for a list of
|
||||
proposed features (and known issues).
|
||||
|
||||
|
||||
<!-- CONTRIBUTING -->
|
||||
## 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**.
|
||||
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**.
|
||||
|
||||
1. Fork the Project
|
||||
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
|
||||
|
|
|
@ -1,40 +1,63 @@
|
|||
//! Read ADC samples from the temperature sensor and pin and
|
||||
//! output them to the UART on pins 1 and 2 at 9600 baud
|
||||
//! # ADC Example
|
||||
//!
|
||||
//! This application demonstrates how to read ADC samples from the temperature
|
||||
//! sensor and pin and output them to the UART on pins 1 and 2 at 9600 baud.
|
||||
//!
|
||||
//! It may need to be adapted to your particular board layout and/or pin assignment.
|
||||
//!
|
||||
//! See the `Cargo.toml` file for Copyright and licence details.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::fmt::Write;
|
||||
use cortex_m::prelude::_embedded_hal_adc_OneShot;
|
||||
// The macro for our start-up function
|
||||
use cortex_m_rt::entry;
|
||||
use hal::adc::Adc;
|
||||
use hal::clocks::init_clocks_and_plls;
|
||||
use hal::gpio::{self, Pins};
|
||||
use hal::pac;
|
||||
use hal::sio::Sio;
|
||||
use hal::uart::UartPeripheral;
|
||||
use hal::watchdog::Watchdog;
|
||||
|
||||
// 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;
|
||||
|
||||
// Some traits we need
|
||||
use core::fmt::Write;
|
||||
use embedded_hal::adc::OneShot;
|
||||
use embedded_time::fixed_point::FixedPoint;
|
||||
use rp2040_hal::clocks::Clock;
|
||||
|
||||
// A shorter alias for the Peripheral Access Crate, which provides low-level
|
||||
// register access
|
||||
use hal::pac;
|
||||
|
||||
/// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
||||
// External high-speed crystal on the pico board is 12Mhz
|
||||
// Adjust if your board has a different frequency
|
||||
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
|
||||
/// if your board has a different frequency
|
||||
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
||||
const SYS_FREQ_HZ: u32 = hal::pll::common_configs::PLL_SYS_125MHZ.vco_freq.0;
|
||||
|
||||
/// 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 prints the temperature
|
||||
/// in an infinite loop.
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
// Grab our singleton objects
|
||||
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);
|
||||
|
||||
// External high-speed crystal on the pico board is 12Mhz
|
||||
// Set up the watchdog driver - needed by the clock setup code
|
||||
let mut watchdog = hal::watchdog::Watchdog::new(pac.WATCHDOG);
|
||||
|
||||
let clocks = init_clocks_and_plls(
|
||||
// Configure the clocks
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
XTAL_FREQ_HZ,
|
||||
pac.XOSC,
|
||||
pac.CLOCKS,
|
||||
|
@ -46,16 +69,23 @@ fn main() -> ! {
|
|||
.ok()
|
||||
.unwrap();
|
||||
|
||||
let mut delay = cortex_m::delay::Delay::new(core.SYST, SYS_FREQ_HZ);
|
||||
// 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().integer());
|
||||
|
||||
let pins = Pins::new(
|
||||
// The single-cycle I/O block controls our GPIO pins
|
||||
let sio = hal::sio::Sio::new(pac.SIO);
|
||||
|
||||
// Set the pins to their default state
|
||||
let pins = hal::gpio::Pins::new(
|
||||
pac.IO_BANK0,
|
||||
pac.PADS_BANK0,
|
||||
sio.gpio_bank0,
|
||||
&mut pac.RESETS,
|
||||
);
|
||||
|
||||
let mut uart = UartPeripheral::<_, _>::enable(
|
||||
// Create a UART driver
|
||||
let mut uart = hal::uart::UartPeripheral::<_, _>::enable(
|
||||
pac.UART0,
|
||||
&mut pac.RESETS,
|
||||
hal::uart::common_configs::_9600_8_N_1,
|
||||
|
@ -64,14 +94,19 @@ fn main() -> ! {
|
|||
.unwrap();
|
||||
|
||||
// UART TX (characters sent from pico) on pin 1 (GPIO0) and RX (on pin 2 (GPIO1)
|
||||
let _tx_pin = pins.gpio0.into_mode::<gpio::FunctionUart>();
|
||||
let _rx_pin = pins.gpio1.into_mode::<gpio::FunctionUart>();
|
||||
let _tx_pin = pins.gpio0.into_mode::<hal::gpio::FunctionUart>();
|
||||
let _rx_pin = pins.gpio1.into_mode::<hal::gpio::FunctionUart>();
|
||||
|
||||
// Write to the UART
|
||||
uart.write_full_blocking(b"ADC example\r\n");
|
||||
// Enable adc
|
||||
let mut adc = Adc::new(pac.ADC, &mut pac.RESETS);
|
||||
|
||||
// Enable ADC
|
||||
let mut adc = hal::adc::Adc::new(pac.ADC, &mut pac.RESETS);
|
||||
|
||||
// Enable the temperature sense channel
|
||||
let mut temperature_sensor = adc.enable_temp_sensor();
|
||||
// Configure one of the pins as an ADC input as well.
|
||||
|
||||
// Configure GPIO26 as an ADC input
|
||||
let mut adc_pin_0 = pins.gpio26.into_floating_input();
|
||||
loop {
|
||||
// Read the raw ADC counts from the temperature sensor channel.
|
||||
|
@ -86,3 +121,5 @@ fn main() -> ! {
|
|||
delay.delay_ms(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
|
|
@ -1,38 +1,94 @@
|
|||
//! Blinks the LED on a Pico board
|
||||
//! # GPIO 'Blinky' Example
|
||||
//!
|
||||
//! This will blink an LED attached to GP25, which is the pin the Pico uses for the on-board LED.
|
||||
//! This application demonstrates how to control a GPIO pin on the RP2040.
|
||||
//!
|
||||
//! It may need to be adapted to your particular board layout and/or pin assignment.
|
||||
//!
|
||||
//! See the `Cargo.toml` file for Copyright and licence details.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
// The macro for our start-up function
|
||||
use cortex_m_rt::entry;
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
use hal::pac;
|
||||
use hal::sio::Sio;
|
||||
|
||||
// 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;
|
||||
|
||||
// Some traits we need
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
use embedded_time::fixed_point::FixedPoint;
|
||||
use rp2040_hal::clocks::Clock;
|
||||
|
||||
/// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
||||
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
|
||||
/// if your board has a different frequency
|
||||
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
||||
|
||||
/// 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();
|
||||
|
||||
let sio = Sio::new(pac.SIO);
|
||||
// Set up the watchdog driver - needed by the clock setup code
|
||||
let mut watchdog = hal::watchdog::Watchdog::new(pac.WATCHDOG);
|
||||
|
||||
// Configure the clocks
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
XTAL_FREQ_HZ,
|
||||
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().integer());
|
||||
|
||||
// The single-cycle I/O block controls our GPIO pins
|
||||
let sio = hal::sio::Sio::new(pac.SIO);
|
||||
|
||||
// Set the pins to their default state
|
||||
let pins = hal::gpio::Pins::new(
|
||||
pac.IO_BANK0,
|
||||
pac.PADS_BANK0,
|
||||
sio.gpio_bank0,
|
||||
&mut pac.RESETS,
|
||||
);
|
||||
let mut led_pin = pins.gpio25.into_push_pull_output();
|
||||
|
||||
// Configure GPIO25 as an output
|
||||
let mut led_pin = pins.gpio25.into_push_pull_output();
|
||||
loop {
|
||||
led_pin.set_high().unwrap();
|
||||
// TODO: Replace with proper 1s delays once we have clocks working
|
||||
cortex_m::asm::delay(500_000);
|
||||
delay.delay_ms(500);
|
||||
led_pin.set_low().unwrap();
|
||||
cortex_m::asm::delay(500_000);
|
||||
delay.delay_ms(500);
|
||||
}
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
|
|
@ -1,41 +1,95 @@
|
|||
//! Toggle LED based on GPIO input
|
||||
//! # GPIO 'Blinky' Example
|
||||
//!
|
||||
//! This will control an LED on GP25 based on a button hooked up to GP15. The button should be tied
|
||||
//! to ground, as the input pin is pulled high internally by this example. When the button is
|
||||
//! pressed, the LED will turn off.
|
||||
//! This application demonstrates how to control a GPIO pin on the RP2040.
|
||||
//!
|
||||
//! It may need to be adapted to your particular board layout and/or pin assignment.
|
||||
//!
|
||||
//! See the `Cargo.toml` file for Copyright and licence details.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
// The macro for our start-up function
|
||||
use cortex_m_rt::entry;
|
||||
use embedded_hal::digital::v2::{InputPin, OutputPin};
|
||||
use hal::pac;
|
||||
use hal::sio::Sio;
|
||||
|
||||
// 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;
|
||||
|
||||
// Some traits we need
|
||||
use embedded_hal::digital::v2::InputPin;
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
|
||||
/// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
||||
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
|
||||
/// if your board has a different frequency
|
||||
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
||||
|
||||
/// 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 sio = Sio::new(pac.SIO);
|
||||
// Set up the watchdog driver - needed by the clock setup code
|
||||
let mut watchdog = hal::watchdog::Watchdog::new(pac.WATCHDOG);
|
||||
|
||||
// Configure the clocks
|
||||
let _clocks = hal::clocks::init_clocks_and_plls(
|
||||
XTAL_FREQ_HZ,
|
||||
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::Sio::new(pac.SIO);
|
||||
|
||||
// Set the pins to their default state
|
||||
let pins = hal::gpio::Pins::new(
|
||||
pac.IO_BANK0,
|
||||
pac.PADS_BANK0,
|
||||
sio.gpio_bank0,
|
||||
&mut pac.RESETS,
|
||||
);
|
||||
let mut led_pin = pins.gpio25.into_push_pull_output();
|
||||
let button_pin = pins.gpio23.into_pull_down_input();
|
||||
|
||||
// Configure GPIO 25 as an output
|
||||
let mut out_pin = pins.gpio25.into_push_pull_output();
|
||||
|
||||
// Configure GPIO 23 as an input
|
||||
let in_pin = pins.gpio23.into_pull_down_input();
|
||||
|
||||
// Output is the opposite of the input
|
||||
loop {
|
||||
if button_pin.is_low().unwrap() {
|
||||
led_pin.set_high().unwrap();
|
||||
if in_pin.is_low().unwrap() {
|
||||
out_pin.set_high().unwrap();
|
||||
} else {
|
||||
led_pin.set_low().unwrap();
|
||||
out_pin.set_low().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
|
|
@ -1,28 +1,73 @@
|
|||
//! Sends a message using i2c
|
||||
//! # I²C Example
|
||||
//!
|
||||
//! This application demonstrates how to talk to I²C devices with an RP2040.
|
||||
//!
|
||||
//! It may need to be adapted to your particular board layout and/or pin assignment.
|
||||
//!
|
||||
//! See the `Cargo.toml` file for Copyright and licence details.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
// The macro for our start-up function
|
||||
use cortex_m_rt::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::blocking::i2c::Write;
|
||||
use embedded_time::rate::Extensions;
|
||||
use hal::gpio::FunctionI2C;
|
||||
use hal::i2c::I2C;
|
||||
use hal::pac;
|
||||
use hal::sio::Sio;
|
||||
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;
|
||||
|
||||
/// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
||||
const SYS_HZ: u32 = 125_000_000_u32;
|
||||
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
|
||||
/// if your board has a different frequency
|
||||
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
||||
|
||||
/// 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 performs a single I²C
|
||||
/// write to a fixed address.
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let mut pac = pac::Peripherals::take().unwrap();
|
||||
|
||||
let sio = Sio::new(pac.SIO);
|
||||
// Set up the watchdog driver - needed by the clock setup code
|
||||
let mut watchdog = hal::watchdog::Watchdog::new(pac.WATCHDOG);
|
||||
|
||||
// Configure the clocks
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
XTAL_FREQ_HZ,
|
||||
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::Sio::new(pac.SIO);
|
||||
|
||||
// Set the pins to their default state
|
||||
let pins = hal::gpio::Pins::new(
|
||||
pac.IO_BANK0,
|
||||
pac.PADS_BANK0,
|
||||
|
@ -30,20 +75,32 @@ fn main() -> ! {
|
|||
&mut pac.RESETS,
|
||||
);
|
||||
|
||||
let sda_pin = pins.gpio18.into_mode::<FunctionI2C>();
|
||||
let scl_pin = pins.gpio19.into_mode::<FunctionI2C>();
|
||||
// Configure two pins as being I²C, not GPIO
|
||||
let sda_pin = pins.gpio18.into_mode::<hal::gpio::FunctionI2C>();
|
||||
let scl_pin = pins.gpio19.into_mode::<hal::gpio::FunctionI2C>();
|
||||
// let not_an_scl_pin = pins.gpio20.into_mode::<hal::gpio::FunctionI2C>();
|
||||
|
||||
let mut i2c = I2C::i2c1(
|
||||
// Create the I²C drive, 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 mut i2c = hal::i2c::I2C::i2c1(
|
||||
pac.I2C1,
|
||||
sda_pin,
|
||||
scl_pin,
|
||||
scl_pin, // Try `not_an_scl_pin` here
|
||||
400.kHz(),
|
||||
&mut pac.RESETS,
|
||||
SYS_HZ.Hz(),
|
||||
clocks.peripheral_clock,
|
||||
);
|
||||
|
||||
// Write three bytes to the I²C device with 7-bit address 0x2C
|
||||
i2c.write(0x2c, &[1, 2, 3]).unwrap();
|
||||
|
||||
// Demo finish - just loop until reset
|
||||
|
||||
#[allow(clippy::empty_loop)]
|
||||
loop {}
|
||||
loop {
|
||||
// Empty loop
|
||||
}
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
|
|
@ -1,26 +1,85 @@
|
|||
//! # 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.
|
||||
//!
|
||||
//! It drives the LCD by pushing data out of six GPIO pins. It may need to be
|
||||
//! adapted to your particular board layout and/or pin assignment.
|
||||
//!
|
||||
//! See the `Cargo.toml` file for Copyright and licence details.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
// The macro for our start-up function
|
||||
use cortex_m_rt::entry;
|
||||
use hal::pac;
|
||||
use hal::sio::Sio;
|
||||
use hd44780_driver as hd44780;
|
||||
|
||||
// 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;
|
||||
|
||||
// Our LCD driver
|
||||
use hd44780_driver as hd44780;
|
||||
|
||||
// Some traits we need
|
||||
use embedded_time::fixed_point::FixedPoint;
|
||||
use rp2040_hal::clocks::Clock;
|
||||
|
||||
// A shorter alias for the Peripheral Access Crate, which provides low-level
|
||||
// register access
|
||||
use hal::pac;
|
||||
|
||||
/// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
||||
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
|
||||
/// if your board has a different frequency
|
||||
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
||||
|
||||
/// 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, writes to the LCD, then goes
|
||||
/// to sleep.
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
// Grab our singleton objects
|
||||
let mut pac = pac::Peripherals::take().unwrap();
|
||||
let core = pac::CorePeripherals::take().unwrap();
|
||||
|
||||
// AHL bus speed default
|
||||
let mut delay_provider = cortex_m::delay::Delay::new(core.SYST, 12_000_000);
|
||||
// Set up the watchdog driver - needed by the clock setup code
|
||||
let mut watchdog = hal::watchdog::Watchdog::new(pac.WATCHDOG);
|
||||
|
||||
let sio = Sio::new(pac.SIO);
|
||||
// Configure the clocks
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
XTAL_FREQ_HZ,
|
||||
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().integer());
|
||||
|
||||
// The single-cycle I/O block controls our GPIO pins
|
||||
let sio = hal::sio::Sio::new(pac.SIO);
|
||||
|
||||
// Set the pins to their default state
|
||||
let pins = hal::gpio::Pins::new(
|
||||
pac.IO_BANK0,
|
||||
pac.PADS_BANK0,
|
||||
|
@ -28,26 +87,36 @@ fn main() -> ! {
|
|||
&mut pac.RESETS,
|
||||
);
|
||||
|
||||
let lcd = hd44780::HD44780::new_4bit(
|
||||
// Create the LCD driver from some GPIO pins
|
||||
let mut lcd = hd44780::HD44780::new_4bit(
|
||||
pins.gpio16.into_push_pull_output(), // Register Select
|
||||
pins.gpio17.into_push_pull_output(), // Enable
|
||||
pins.gpio18.into_push_pull_output(), // d4
|
||||
pins.gpio19.into_push_pull_output(), // d5
|
||||
pins.gpio20.into_push_pull_output(), // d6
|
||||
pins.gpio21.into_push_pull_output(), // d7
|
||||
&mut delay_provider,
|
||||
);
|
||||
&mut delay,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut lcd = lcd.unwrap();
|
||||
// Clear the screen
|
||||
lcd.reset(&mut delay).unwrap();
|
||||
lcd.clear(&mut delay).unwrap();
|
||||
|
||||
lcd.reset(&mut delay_provider).unwrap();
|
||||
lcd.clear(&mut delay_provider).unwrap();
|
||||
lcd.write_str("rp-hal on", &mut delay_provider).unwrap();
|
||||
lcd.set_cursor_pos(40, &mut delay_provider).unwrap();
|
||||
lcd.set_cursor_visibility(hd44780::Cursor::Visible, &mut delay_provider)
|
||||
.unwrap();
|
||||
lcd.write_str("HD44780!", &mut delay_provider).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();
|
||||
|
||||
// Do nothing - we're finished
|
||||
#[allow(clippy::empty_loop)]
|
||||
loop {}
|
||||
loop {
|
||||
// Empty loop
|
||||
}
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
|
|
@ -1,43 +1,124 @@
|
|||
//! # PWM Blink Example
|
||||
//!
|
||||
//! If you have an LED connected to pin 25, it will fade the LED using the PWM
|
||||
//! peripheral.
|
||||
//!
|
||||
//! It may need to be adapted to your particular board layout and/or pin assignment.
|
||||
//!
|
||||
//! See the `Cargo.toml` file for Copyright and licence details.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
// The macro for our start-up function
|
||||
use cortex_m_rt::entry;
|
||||
use embedded_hal::PwmPin;
|
||||
use panic_halt as _;
|
||||
use rp2040_hal::{gpio::Pins, pwm::*, sio::Sio};
|
||||
|
||||
// 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;
|
||||
|
||||
// Some traits we need
|
||||
use embedded_hal::PwmPin;
|
||||
use embedded_time::rate::*;
|
||||
use rp2040_hal::clocks::Clock;
|
||||
|
||||
// A shorter alias for the Peripheral Access Crate, which provides low-level
|
||||
// register access
|
||||
use hal::pac;
|
||||
|
||||
//// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
||||
/// 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;
|
||||
|
||||
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
|
||||
/// if your board has a different frequency
|
||||
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
||||
|
||||
/// 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() -> ! {
|
||||
let mut pac = rp2040_pac::Peripherals::take().unwrap();
|
||||
// Grab our singleton objects
|
||||
let mut pac = pac::Peripherals::take().unwrap();
|
||||
let core = pac::CorePeripherals::take().unwrap();
|
||||
|
||||
let sio = Sio::new(pac.SIO);
|
||||
let pins = Pins::new(
|
||||
// Set up the watchdog driver - needed by the clock setup code
|
||||
let mut watchdog = hal::watchdog::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(
|
||||
XTAL_FREQ_HZ,
|
||||
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::Sio::new(pac.SIO);
|
||||
|
||||
// Set the pins up according to their function on this particular board
|
||||
let pins = hal::gpio::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().integer());
|
||||
|
||||
// Init PWMs
|
||||
let pwm_slices = Slices::new(pac.PWM, &mut pac.RESETS);
|
||||
let mut pwm_slices = hal::pwm::Slices::new(pac.PWM, &mut pac.RESETS);
|
||||
|
||||
// Configure PWM4
|
||||
let mut pwm = pwm_slices.pwm4;
|
||||
let pwm = &mut pwm_slices.pwm4;
|
||||
pwm.set_ph_correct();
|
||||
pwm.enable();
|
||||
|
||||
// Use B channel (which outputs to GPIO 25)
|
||||
let mut channel = pwm.channel_b;
|
||||
// Output channel B on PWM4 to GPIO 25
|
||||
let channel = &mut pwm.channel_b;
|
||||
channel.output_to(pins.gpio25);
|
||||
|
||||
// Infinite loop, fading LED up and down
|
||||
loop {
|
||||
channel.set_duty(15000);
|
||||
// TODO: Replace with proper delays once we have clocks working
|
||||
cortex_m::asm::delay(5_000_000);
|
||||
channel.set_duty(30000);
|
||||
cortex_m::asm::delay(5_000_000);
|
||||
// Ramp brightness up
|
||||
for i in (LOW..=HIGH).skip(100) {
|
||||
delay.delay_us(8);
|
||||
channel.set_duty(i);
|
||||
}
|
||||
|
||||
// Ramp brightness down
|
||||
for i in (LOW..=HIGH).rev().skip(100) {
|
||||
delay.delay_us(8);
|
||||
channel.set_duty(i);
|
||||
}
|
||||
|
||||
delay.delay_ms(500);
|
||||
}
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
|
|
@ -1,29 +1,78 @@
|
|||
//! Perform ]
|
||||
//! # SPI Example
|
||||
//!
|
||||
//! This application demonstrates how to use the SPI Driver to talk to a remote
|
||||
//! SPI device.
|
||||
//!
|
||||
//!
|
||||
//! It may need to be adapted to your particular board layout and/or pin
|
||||
//! assignment.
|
||||
//!
|
||||
//! See the `Cargo.toml` file for Copyright and licence details.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use cortex_m::prelude::{
|
||||
_embedded_hal_blocking_spi_Transfer, _embedded_hal_blocking_spi_Write,
|
||||
_embedded_hal_spi_FullDuplex,
|
||||
};
|
||||
// The macro for our start-up function
|
||||
use cortex_m_rt::entry;
|
||||
use embedded_hal::spi::MODE_0;
|
||||
use embedded_time::rate::Extensions;
|
||||
use hal::{gpio::FunctionSpi, pac, sio::Sio, spi::Spi};
|
||||
|
||||
// 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;
|
||||
|
||||
// Some traits we need
|
||||
use cortex_m::prelude::*;
|
||||
use embedded_time::rate::Extensions;
|
||||
use rp2040_hal::clocks::Clock;
|
||||
|
||||
// A shorter alias for the Peripheral Access Crate, which provides low-level
|
||||
// register access
|
||||
use hal::pac;
|
||||
|
||||
/// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
||||
const SYS_HZ: u32 = 125_000_000_u32;
|
||||
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
|
||||
/// if your board has a different frequency
|
||||
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
||||
|
||||
/// 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 performs some example
|
||||
/// SPI transactions, then goes to sleep.
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
// Grab our singleton objects
|
||||
let mut pac = pac::Peripherals::take().unwrap();
|
||||
|
||||
let sio = Sio::new(pac.SIO);
|
||||
// Set up the watchdog driver - needed by the clock setup code
|
||||
let mut watchdog = hal::watchdog::Watchdog::new(pac.WATCHDOG);
|
||||
|
||||
// Configure the clocks
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
XTAL_FREQ_HZ,
|
||||
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::Sio::new(pac.SIO);
|
||||
|
||||
// Set the pins to their default state
|
||||
let pins = hal::gpio::Pins::new(
|
||||
pac.IO_BANK0,
|
||||
pac.PADS_BANK0,
|
||||
|
@ -32,19 +81,22 @@ fn main() -> ! {
|
|||
);
|
||||
|
||||
// These are implicitly used by the spi driver if they are in the correct mode
|
||||
let _spi_sclk = pins.gpio6.into_mode::<FunctionSpi>();
|
||||
let _spi_mosi = pins.gpio7.into_mode::<FunctionSpi>();
|
||||
let _spi_miso = pins.gpio4.into_mode::<FunctionSpi>();
|
||||
let mut spi = Spi::<_, _, 8>::new(pac.SPI0).init(
|
||||
let _spi_sclk = pins.gpio6.into_mode::<hal::gpio::FunctionSpi>();
|
||||
let _spi_mosi = pins.gpio7.into_mode::<hal::gpio::FunctionSpi>();
|
||||
let _spi_miso = pins.gpio4.into_mode::<hal::gpio::FunctionSpi>();
|
||||
let spi = hal::spi::Spi::<_, _, 8>::new(pac.SPI0);
|
||||
|
||||
// Exchange the uninitialised SPI driver for an initialised one
|
||||
let mut spi = spi.init(
|
||||
&mut pac.RESETS,
|
||||
SYS_HZ.Hz(),
|
||||
clocks.peripheral_clock.freq(),
|
||||
16_000_000u32.Hz(),
|
||||
&MODE_0,
|
||||
&embedded_hal::spi::MODE_0,
|
||||
);
|
||||
|
||||
// Write out 0, ignore return value
|
||||
if let Ok(..) = spi.write(&[0]) {
|
||||
// Handle success
|
||||
if spi.write(&[0]).is_ok() {
|
||||
// SPI write was succesful
|
||||
};
|
||||
|
||||
// write 50, then check the return
|
||||
|
@ -52,17 +104,17 @@ fn main() -> ! {
|
|||
match send_success {
|
||||
Ok(_) => {
|
||||
// We succeeded, check the read value
|
||||
if spi.read().is_ok() {
|
||||
// Output our read value
|
||||
if let Ok(_x) = spi.read() {
|
||||
// We got back `x` in exchange for the 0x50 we sent.
|
||||
};
|
||||
}
|
||||
Err(_) => todo!(),
|
||||
}
|
||||
|
||||
// Do a read+write at the same time.
|
||||
// Data in read_write_cache will be replaced with the read data
|
||||
let mut read_write_cache: [u8; 4] = [1, 2, 3, 4];
|
||||
let transfer_success = spi.transfer(&mut read_write_cache);
|
||||
// Do a read+write at the same time. Data in `buffer` will be replaced with
|
||||
// the data read from the SPI device.
|
||||
let mut buffer: [u8; 4] = [1, 2, 3, 4];
|
||||
let transfer_success = spi.transfer(&mut buffer);
|
||||
#[allow(clippy::single_match)]
|
||||
match transfer_success {
|
||||
Ok(_) => {} // Handle success
|
||||
|
@ -70,5 +122,9 @@ fn main() -> ! {
|
|||
};
|
||||
|
||||
#[allow(clippy::empty_loop)]
|
||||
loop {}
|
||||
loop {
|
||||
// Empty loop
|
||||
}
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
|
|
@ -1,32 +1,64 @@
|
|||
//! Print an incrementing number to UART0 in a loop
|
||||
//! # UART Example
|
||||
//!
|
||||
//! This application demonstrates how to use the UART Driver to talk to a serial
|
||||
//! connection.
|
||||
//!
|
||||
//! It may need to be adapted to your particular board layout and/or pin
|
||||
//! assignment.
|
||||
//!
|
||||
//! See the `Cargo.toml` file for Copyright and licence details.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::fmt::Write;
|
||||
// The macro for our start-up function
|
||||
use cortex_m_rt::entry;
|
||||
use hal::clocks::init_clocks_and_plls;
|
||||
use hal::gpio::{self, Pins};
|
||||
use hal::pac;
|
||||
use hal::sio::Sio;
|
||||
use hal::uart::UartPeripheral;
|
||||
use hal::watchdog::Watchdog;
|
||||
|
||||
// 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;
|
||||
|
||||
// Some traits we need
|
||||
use core::fmt::Write;
|
||||
use embedded_time::fixed_point::FixedPoint;
|
||||
use rp2040_hal::clocks::Clock;
|
||||
|
||||
/// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
||||
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
|
||||
/// if your board has a different frequency
|
||||
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
||||
|
||||
/// 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 inifinite loop.
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
// Grab our singleton objects
|
||||
let mut pac = pac::Peripherals::take().unwrap();
|
||||
let mut watchdog = Watchdog::new(pac.WATCHDOG);
|
||||
let sio = Sio::new(pac.SIO);
|
||||
let core = pac::CorePeripherals::take().unwrap();
|
||||
|
||||
// External high-speed crystal on the pico board is 12Mhz
|
||||
let external_xtal_freq_hz = 12_000_000u32;
|
||||
let clocks = init_clocks_and_plls(
|
||||
external_xtal_freq_hz,
|
||||
// Set up the watchdog driver - needed by the clock setup code
|
||||
let mut watchdog = hal::watchdog::Watchdog::new(pac.WATCHDOG);
|
||||
|
||||
// Configure the clocks
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
XTAL_FREQ_HZ,
|
||||
pac.XOSC,
|
||||
pac.CLOCKS,
|
||||
pac.PLL_SYS,
|
||||
|
@ -37,14 +69,20 @@ fn main() -> ! {
|
|||
.ok()
|
||||
.unwrap();
|
||||
|
||||
let pins = Pins::new(
|
||||
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().integer());
|
||||
|
||||
// The single-cycle I/O block controls our GPIO pins
|
||||
let sio = hal::sio::Sio::new(pac.SIO);
|
||||
|
||||
// Set the pins to their default state
|
||||
let pins = hal::gpio::Pins::new(
|
||||
pac.IO_BANK0,
|
||||
pac.PADS_BANK0,
|
||||
sio.gpio_bank0,
|
||||
&mut pac.RESETS,
|
||||
);
|
||||
|
||||
let mut uart = UartPeripheral::<_, _>::enable(
|
||||
let mut uart = hal::uart::UartPeripheral::<_, _>::enable(
|
||||
pac.UART0,
|
||||
&mut pac.RESETS,
|
||||
hal::uart::common_configs::_9600_8_N_1,
|
||||
|
@ -52,16 +90,19 @@ fn main() -> ! {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
// UART TX (characters sent from pico) on pin 1 (GPIO0) and RX (on pin 2 (GPIO1)
|
||||
let _tx_pin = pins.gpio0.into_mode::<gpio::FunctionUart>();
|
||||
let _rx_pin = pins.gpio1.into_mode::<gpio::FunctionUart>();
|
||||
// UART TX (characters sent from RP2040) on pin 1 (GPIO0)
|
||||
let _tx_pin = pins.gpio0.into_mode::<hal::gpio::FunctionUart>();
|
||||
// UART RX (characters reveived by RP2040) on pin 2 (GPIO1)
|
||||
let _rx_pin = pins.gpio1.into_mode::<hal::gpio::FunctionUart>();
|
||||
|
||||
uart.write_full_blocking(b"UART example\r\n");
|
||||
|
||||
let mut value = 0u32;
|
||||
loop {
|
||||
writeln!(uart, "value: {:02}\r", value).unwrap();
|
||||
cortex_m::asm::delay(10_000_000);
|
||||
delay.delay_ms(1000);
|
||||
value += 1
|
||||
}
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
|
|
@ -1,37 +1,65 @@
|
|||
//! How to use the watchdog peripheral to reset the system in case something takes too long
|
||||
//! # Watchdog Example
|
||||
//!
|
||||
//! This application demonstrates how to use the RP2040 Watchdog.
|
||||
//!
|
||||
//! It may need to be adapted to your particular board layout and/or pin assignment.
|
||||
//!
|
||||
//! See the `Cargo.toml` file for Copyright and licence details.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use cortex_m::prelude::{_embedded_hal_watchdog_Watchdog, _embedded_hal_watchdog_WatchdogEnable};
|
||||
// The macro for our start-up function
|
||||
use cortex_m_rt::entry;
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
use embedded_time::duration::units::*;
|
||||
use embedded_time::fixed_point::FixedPoint;
|
||||
use hal::clocks::{init_clocks_and_plls, Clock};
|
||||
use hal::gpio::Pins;
|
||||
use hal::pac;
|
||||
use hal::sio::Sio;
|
||||
use hal::watchdog::Watchdog;
|
||||
|
||||
// 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;
|
||||
|
||||
// Some traits we need
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
use embedded_hal::watchdog::{Watchdog, WatchdogEnable};
|
||||
use embedded_time::duration::Extensions;
|
||||
use embedded_time::fixed_point::FixedPoint;
|
||||
use rp2040_hal::clocks::Clock;
|
||||
|
||||
/// 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.
|
||||
#[link_section = ".boot2"]
|
||||
#[used]
|
||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||
|
||||
// External high-speed crystal on the pico board is 12Mhz
|
||||
// Adjust for your board if this isn't the same
|
||||
const EXTERNAL_XTAL_FREQ_HZ: u32 = 12_000_000;
|
||||
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
|
||||
/// if your board has a different frequency
|
||||
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
||||
|
||||
/// 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. After a period of time, the watchdog will kick in to reset
|
||||
/// the CPU.
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
// Grab our singleton objects
|
||||
let mut pac = pac::Peripherals::take().unwrap();
|
||||
let cp = pac::CorePeripherals::take().unwrap();
|
||||
let mut watchdog = Watchdog::new(pac.WATCHDOG);
|
||||
let sio = Sio::new(pac.SIO);
|
||||
let core = pac::CorePeripherals::take().unwrap();
|
||||
|
||||
let clocks = init_clocks_and_plls(
|
||||
EXTERNAL_XTAL_FREQ_HZ,
|
||||
// Set up the watchdog driver - needed by the clock setup code
|
||||
let mut watchdog = hal::watchdog::Watchdog::new(pac.WATCHDOG);
|
||||
|
||||
// Configure the clocks
|
||||
let clocks = hal::clocks::init_clocks_and_plls(
|
||||
XTAL_FREQ_HZ,
|
||||
pac.XOSC,
|
||||
pac.CLOCKS,
|
||||
pac.PLL_SYS,
|
||||
|
@ -42,16 +70,19 @@ fn main() -> ! {
|
|||
.ok()
|
||||
.unwrap();
|
||||
|
||||
let pins = Pins::new(
|
||||
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().integer());
|
||||
|
||||
// The single-cycle I/O block controls our GPIO pins
|
||||
let sio = hal::sio::Sio::new(pac.SIO);
|
||||
|
||||
// Set the pins to their default state
|
||||
let pins = hal::gpio::Pins::new(
|
||||
pac.IO_BANK0,
|
||||
pac.PADS_BANK0,
|
||||
sio.gpio_bank0,
|
||||
&mut pac.RESETS,
|
||||
);
|
||||
|
||||
// We need to accurately delay to give feedback that the watchdog is working correctly
|
||||
let mut delay = cortex_m::delay::Delay::new(cp.SYST, clocks.system_clock.freq().integer());
|
||||
|
||||
// Configure an LED so we can show the current state of the watchdog
|
||||
let mut led_pin = pins.gpio25.into_push_pull_output();
|
||||
|
||||
|
@ -60,7 +91,7 @@ fn main() -> ! {
|
|||
delay.delay_ms(2000);
|
||||
|
||||
// Set to watchdog to reset if it's not reloaded within 1.05 seconds, and start it
|
||||
watchdog.start(1_050_000.microseconds());
|
||||
watchdog.start(1_050_000u32.microseconds());
|
||||
|
||||
// Blink once a second for 5 seconds, refreshing the watchdog timer once a second to avoid a reset
|
||||
for _ in 1..=5 {
|
||||
|
@ -80,3 +111,5 @@ fn main() -> ! {
|
|||
delay.delay_ms(100);
|
||||
}
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
|
Loading…
Reference in a new issue