mirror of
https://github.com/italicsjenga/rp-hal-boards.git
synced 2024-12-24 05:01: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",
|
"-C", "no-vectorize-loops",
|
||||||
]
|
]
|
||||||
runner = "elf2uf2-rs -d"
|
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>
|
<h3 align="center">rp-hal</h3>
|
||||||
|
|
||||||
<p align="center">
|
<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 />
|
<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 />
|
||||||
<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>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- TABLE OF CONTENTS -->
|
<!-- TABLE OF CONTENTS -->
|
||||||
<details open="open">
|
<details open="open">
|
||||||
<summary><h2 style="display: inline-block">Table of Contents</h2></summary>
|
<summary><h2 style="display: inline-block">Table of Contents</h2></summary>
|
||||||
<ol>
|
<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="#roadmap">Roadmap</a></li>
|
||||||
<li><a href="#contributing">Contributing</a></li>
|
<li><a href="#contributing">Contributing</a></li>
|
||||||
<li><a href="#license">License</a></li>
|
<li><a href="#license">License</a></li>
|
||||||
|
@ -37,6 +37,45 @@
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<!-- GETTING STARTED -->
|
<!-- 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
|
## Packages
|
||||||
|
|
||||||
This git repository is organised as a [Cargo Workspace].
|
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]
|
depend on multiple _BSP_ crates; you have to pick one, or use [Cargo Features]
|
||||||
to select one at build time.
|
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]
|
[Cargo Workspace]: https://doc.rust-lang.org/cargo/reference/workspaces.html]
|
||||||
[Embedded HAL]: https://github.com/rust-embedded/embedded-hal
|
[Embedded HAL]: https://github.com/rust-embedded/embedded-hal
|
||||||
[Cargo Features]: https://doc.rust-lang.org/cargo/reference/features.html
|
[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
|
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).
|
Support Package (see later on).
|
||||||
|
|
||||||
The crate provides high-level drivers for the RP2040's internal peripherals,
|
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.
|
particular board.
|
||||||
|
|
||||||
[rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal
|
[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]
|
### [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
|
[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
|
[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 -->
|
||||||
## 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 -->
|
<!-- CONTRIBUTING -->
|
||||||
|
@ -195,9 +352,8 @@ under these terms.
|
||||||
<!-- CONTACT -->
|
<!-- CONTACT -->
|
||||||
## Contact
|
## Contact
|
||||||
|
|
||||||
Project Link: [https://github.com/rp-rs/rp-hal/issues](https://github.com/rp-rs/rp-hal/issues)
|
Raise an issue: [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)
|
Chat to us on Matrix: [#rp-rs:matrix.org](https://matrix.to/#/#rp-rs:matrix.org)
|
||||||
|
|
||||||
|
|
||||||
<!-- ACKNOWLEDGEMENTS -->
|
<!-- ACKNOWLEDGEMENTS -->
|
||||||
## 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://github.com/rp-rs/rp-hal/tree/main/boards/adafruit_macropad
|
||||||
[Adafruit Macropad]: https://www.adafruit.com/product/5128
|
[Adafruit Macropad]: https://www.adafruit.com/product/5128
|
||||||
[rp2040-hal]: https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal
|
[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
|
## 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
|
[Adafruit Feather RP2040]: https://www.adafruit.com/product/4884
|
||||||
[feather_rp2040]: https://github.com/rp-rs/rp-hal/tree/main/boards/feather_rp2040
|
[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
|
[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
|
## 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/
|
[Raspberry Pi Pico]: https://www.raspberrypi.org/products/raspberry-pi-pico/
|
||||||
[pico]: https://github.com/rp-rs/rp-hal/tree/main/boards/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
|
[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
|
## Using
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@ use pico::hal::pac;
|
||||||
// higher-level drivers.
|
// higher-level drivers.
|
||||||
use pico::hal;
|
use pico::hal;
|
||||||
|
|
||||||
/// The linker will place this boot block at the start of our program image. We
|
//// 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.
|
//// need this to help the ROM bootloader get our code up and running.
|
||||||
#[link_section = ".boot2"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||||
|
@ -58,7 +58,7 @@ fn main() -> ! {
|
||||||
|
|
||||||
// Configure the clocks
|
// 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(
|
let clocks = hal::clocks::init_clocks_and_plls(
|
||||||
pico::XOSC_CRYSTAL_FREQ,
|
pico::XOSC_CRYSTAL_FREQ,
|
||||||
pac.XOSC,
|
pac.XOSC,
|
||||||
|
|
|
@ -47,7 +47,7 @@ fn main() -> ! {
|
||||||
|
|
||||||
// Configure the clocks
|
// 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(
|
let _clocks = hal::clocks::init_clocks_and_plls(
|
||||||
pico::XOSC_CRYSTAL_FREQ,
|
pico::XOSC_CRYSTAL_FREQ,
|
||||||
pac.XOSC,
|
pac.XOSC,
|
||||||
|
|
|
@ -30,8 +30,8 @@ use pico::hal::pac;
|
||||||
// higher-level drivers.
|
// higher-level drivers.
|
||||||
use pico::hal;
|
use pico::hal;
|
||||||
|
|
||||||
/// The linker will place this boot block at the start of our program image. We
|
//// 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.
|
//// need this to help the ROM bootloader get our code up and running.
|
||||||
#[link_section = ".boot2"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||||
|
|
|
@ -34,8 +34,8 @@ use pico::hal::pac;
|
||||||
// higher-level drivers.
|
// higher-level drivers.
|
||||||
use pico::hal;
|
use pico::hal;
|
||||||
|
|
||||||
/// The linker will place this boot block at the start of our program image. We
|
//// 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.
|
//// need this to help the ROM bootloader get our code up and running.
|
||||||
#[link_section = ".boot2"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||||
|
@ -64,7 +64,7 @@ fn main() -> ! {
|
||||||
|
|
||||||
// Configure the clocks
|
// 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(
|
let clocks = hal::clocks::init_clocks_and_plls(
|
||||||
pico::XOSC_CRYSTAL_FREQ,
|
pico::XOSC_CRYSTAL_FREQ,
|
||||||
pac.XOSC,
|
pac.XOSC,
|
||||||
|
|
|
@ -33,8 +33,8 @@ use usb_device::{class_prelude::*, prelude::*};
|
||||||
// USB Communications Class Device support
|
// USB Communications Class Device support
|
||||||
use usbd_serial::SerialPort;
|
use usbd_serial::SerialPort;
|
||||||
|
|
||||||
/// The linker will place this boot block at the start of our program image. We
|
//// 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.
|
//// need this to help the ROM bootloader get our code up and running.
|
||||||
#[link_section = ".boot2"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||||
|
@ -56,7 +56,7 @@ fn main() -> ! {
|
||||||
|
|
||||||
// Configure the clocks
|
// 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(
|
let clocks = hal::clocks::init_clocks_and_plls(
|
||||||
pico::XOSC_CRYSTAL_FREQ,
|
pico::XOSC_CRYSTAL_FREQ,
|
||||||
pac.XOSC,
|
pac.XOSC,
|
||||||
|
|
|
@ -45,8 +45,8 @@ use usb_device::{class_prelude::*, prelude::*};
|
||||||
// USB Communications Class Device support
|
// USB Communications Class Device support
|
||||||
use usbd_serial::SerialPort;
|
use usbd_serial::SerialPort;
|
||||||
|
|
||||||
/// The linker will place this boot block at the start of our program image. We
|
//// 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.
|
//// need this to help the ROM bootloader get our code up and running.
|
||||||
#[link_section = ".boot2"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||||
|
@ -78,7 +78,7 @@ fn main() -> ! {
|
||||||
|
|
||||||
// Configure the clocks
|
// 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(
|
let clocks = hal::clocks::init_clocks_and_plls(
|
||||||
pico::XOSC_CRYSTAL_FREQ,
|
pico::XOSC_CRYSTAL_FREQ,
|
||||||
pac.XOSC,
|
pac.XOSC,
|
||||||
|
|
|
@ -44,8 +44,8 @@ use usbd_hid::descriptor::generator_prelude::*;
|
||||||
use usbd_hid::descriptor::MouseReport;
|
use usbd_hid::descriptor::MouseReport;
|
||||||
use usbd_hid::hid_class::HIDClass;
|
use usbd_hid::hid_class::HIDClass;
|
||||||
|
|
||||||
/// The linker will place this boot block at the start of our program image. We
|
//// 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.
|
//// need this to help the ROM bootloader get our code up and running.
|
||||||
#[link_section = ".boot2"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||||
|
@ -76,7 +76,7 @@ fn main() -> ! {
|
||||||
|
|
||||||
// Configure the clocks
|
// 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(
|
let clocks = hal::clocks::init_clocks_and_plls(
|
||||||
pico::XOSC_CRYSTAL_FREQ,
|
pico::XOSC_CRYSTAL_FREQ,
|
||||||
pac.XOSC,
|
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
|
[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
|
[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
|
[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
|
## Using
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@ use pico_lipo_16_mb::hal::pac;
|
||||||
// higher-level drivers.
|
// higher-level drivers.
|
||||||
use pico_lipo_16_mb::hal;
|
use pico_lipo_16_mb::hal;
|
||||||
|
|
||||||
/// The linker will place this boot block at the start of our program image. We
|
//// 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.
|
//// need this to help the ROM bootloader get our code up and running.
|
||||||
#[link_section = ".boot2"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||||
|
@ -58,7 +58,7 @@ fn main() -> ! {
|
||||||
|
|
||||||
// Configure the clocks
|
// 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(
|
let clocks = hal::clocks::init_clocks_and_plls(
|
||||||
pico_lipo_16_mb::XOSC_CRYSTAL_FREQ,
|
pico_lipo_16_mb::XOSC_CRYSTAL_FREQ,
|
||||||
pac.XOSC,
|
pac.XOSC,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# [pro_micro_rp2040] - Board Support for the [Sparkfun Pro Micro RP2040]
|
# [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
|
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
|
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.
|
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
|
[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
|
[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
|
[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
|
## Using
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ use pro_micro_rp2040::{
|
||||||
use smart_leds::{brightness, SmartLedsWrite, RGB8};
|
use smart_leds::{brightness, SmartLedsWrite, RGB8};
|
||||||
use ws2812_pio::Ws2812;
|
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.
|
/// We need this to help the ROM bootloader get our code up and running.
|
||||||
#[link_section = ".boot2"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
|
@ -80,7 +80,7 @@ fn main() -> ! {
|
||||||
25,
|
25,
|
||||||
pac.PIO0,
|
pac.PIO0,
|
||||||
&mut pac.RESETS,
|
&mut pac.RESETS,
|
||||||
clocks.system_clock.freq(),
|
clocks.peripheral_clock.freq(),
|
||||||
timer.count_down(),
|
timer.count_down(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
<h3 align="center">rp-hal</h3>
|
<h3 align="center">rp-hal</h3>
|
||||||
|
|
||||||
<p align="center">
|
<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 />
|
<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 />
|
||||||
<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>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
<details open="open">
|
<details open="open">
|
||||||
<summary><h2 style="display: inline-block">Table of Contents</h2></summary>
|
<summary><h2 style="display: inline-block">Table of Contents</h2></summary>
|
||||||
<ol>
|
<ol>
|
||||||
|
<li><a href="#introduction">Introduction</a></li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#getting-started">Getting Started</a>
|
<a href="#getting-started">Getting Started</a>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -34,7 +35,6 @@
|
||||||
<li><a href="#installation">Installation</a></li>
|
<li><a href="#installation">Installation</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#usage">Usage</a></li>
|
|
||||||
<li><a href="#roadmap">Roadmap</a></li>
|
<li><a href="#roadmap">Roadmap</a></li>
|
||||||
<li><a href="#contributing">Contributing</a></li>
|
<li><a href="#contributing">Contributing</a></li>
|
||||||
<li><a href="#license">License</a></li>
|
<li><a href="#license">License</a></li>
|
||||||
|
@ -43,70 +43,60 @@
|
||||||
</ol>
|
</ol>
|
||||||
</details>
|
</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 -->
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
To get a local copy up and running follow these simple steps.
|
To include this crate in your project, amend your `Cargo.toml` file to include
|
||||||
|
|
||||||
### 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):
|
|
||||||
|
|
||||||
```toml
|
```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
|
```console
|
||||||
cargo run --example pico_pwm_blink # Run `cargo run --example` for more examples
|
$ 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 -->
|
||||||
## 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 -->
|
||||||
## 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
|
1. Fork the Project
|
||||||
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
|
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
|
||||||
|
|
|
@ -1,40 +1,63 @@
|
||||||
//! Read ADC samples from the temperature sensor and pin and
|
//! # ADC Example
|
||||||
//! output them to the UART on pins 1 and 2 at 9600 baud
|
//!
|
||||||
|
//! 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_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use core::fmt::Write;
|
// The macro for our start-up function
|
||||||
use cortex_m::prelude::_embedded_hal_adc_OneShot;
|
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use hal::adc::Adc;
|
|
||||||
use hal::clocks::init_clocks_and_plls;
|
// Ensure we halt the program on panic (if we don't mention this crate it won't
|
||||||
use hal::gpio::{self, Pins};
|
// be linked)
|
||||||
use hal::pac;
|
|
||||||
use hal::sio::Sio;
|
|
||||||
use hal::uart::UartPeripheral;
|
|
||||||
use hal::watchdog::Watchdog;
|
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
|
// Alias for our HAL crate
|
||||||
use rp2040_hal as hal;
|
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"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||||
|
|
||||||
// External high-speed crystal on the pico board is 12Mhz
|
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
|
||||||
// Adjust if your board has a different frequency
|
/// if your board has a different frequency
|
||||||
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
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]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
|
// Grab our singleton objects
|
||||||
let mut pac = pac::Peripherals::take().unwrap();
|
let mut pac = pac::Peripherals::take().unwrap();
|
||||||
let core = pac::CorePeripherals::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,
|
XTAL_FREQ_HZ,
|
||||||
pac.XOSC,
|
pac.XOSC,
|
||||||
pac.CLOCKS,
|
pac.CLOCKS,
|
||||||
|
@ -46,16 +69,23 @@ fn main() -> ! {
|
||||||
.ok()
|
.ok()
|
||||||
.unwrap();
|
.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.IO_BANK0,
|
||||||
pac.PADS_BANK0,
|
pac.PADS_BANK0,
|
||||||
sio.gpio_bank0,
|
sio.gpio_bank0,
|
||||||
&mut pac.RESETS,
|
&mut pac.RESETS,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut uart = UartPeripheral::<_, _>::enable(
|
// Create a UART driver
|
||||||
|
let mut uart = hal::uart::UartPeripheral::<_, _>::enable(
|
||||||
pac.UART0,
|
pac.UART0,
|
||||||
&mut pac.RESETS,
|
&mut pac.RESETS,
|
||||||
hal::uart::common_configs::_9600_8_N_1,
|
hal::uart::common_configs::_9600_8_N_1,
|
||||||
|
@ -64,14 +94,19 @@ fn main() -> ! {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// UART TX (characters sent from pico) on pin 1 (GPIO0) and RX (on pin 2 (GPIO1)
|
// 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 _tx_pin = pins.gpio0.into_mode::<hal::gpio::FunctionUart>();
|
||||||
let _rx_pin = pins.gpio1.into_mode::<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");
|
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
|
// Enable the temperature sense channel
|
||||||
let mut temperature_sensor = adc.enable_temp_sensor();
|
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();
|
let mut adc_pin_0 = pins.gpio26.into_floating_input();
|
||||||
loop {
|
loop {
|
||||||
// Read the raw ADC counts from the temperature sensor channel.
|
// Read the raw ADC counts from the temperature sensor channel.
|
||||||
|
@ -86,3 +121,5 @@ fn main() -> ! {
|
||||||
delay.delay_ms(1000);
|
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_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
|
// The macro for our start-up function
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use embedded_hal::digital::v2::OutputPin;
|
|
||||||
use hal::pac;
|
// Ensure we halt the program on panic (if we don't mention this crate it won't
|
||||||
use hal::sio::Sio;
|
// be linked)
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
|
// Alias for our HAL crate
|
||||||
use rp2040_hal as hal;
|
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"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
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]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
|
// Grab our singleton objects
|
||||||
let mut pac = pac::Peripherals::take().unwrap();
|
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(
|
let pins = hal::gpio::Pins::new(
|
||||||
pac.IO_BANK0,
|
pac.IO_BANK0,
|
||||||
pac.PADS_BANK0,
|
pac.PADS_BANK0,
|
||||||
sio.gpio_bank0,
|
sio.gpio_bank0,
|
||||||
&mut pac.RESETS,
|
&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 {
|
loop {
|
||||||
led_pin.set_high().unwrap();
|
led_pin.set_high().unwrap();
|
||||||
// TODO: Replace with proper 1s delays once we have clocks working
|
// 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();
|
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
|
//! This application demonstrates how to control a GPIO pin on the RP2040.
|
||||||
//! to ground, as the input pin is pulled high internally by this example. When the button is
|
//!
|
||||||
//! pressed, the LED will turn off.
|
//! 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_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
|
// The macro for our start-up function
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use embedded_hal::digital::v2::{InputPin, OutputPin};
|
|
||||||
use hal::pac;
|
// Ensure we halt the program on panic (if we don't mention this crate it won't
|
||||||
use hal::sio::Sio;
|
// be linked)
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
|
// Alias for our HAL crate
|
||||||
use rp2040_hal as hal;
|
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"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
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]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
|
// Grab our singleton objects
|
||||||
let mut pac = pac::Peripherals::take().unwrap();
|
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(
|
let pins = hal::gpio::Pins::new(
|
||||||
pac.IO_BANK0,
|
pac.IO_BANK0,
|
||||||
pac.PADS_BANK0,
|
pac.PADS_BANK0,
|
||||||
sio.gpio_bank0,
|
sio.gpio_bank0,
|
||||||
&mut pac.RESETS,
|
&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 {
|
loop {
|
||||||
if button_pin.is_low().unwrap() {
|
if in_pin.is_low().unwrap() {
|
||||||
led_pin.set_high().unwrap();
|
out_pin.set_high().unwrap();
|
||||||
} else {
|
} 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_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
|
// The macro for our start-up function
|
||||||
use cortex_m_rt::entry;
|
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_hal::blocking::i2c::Write;
|
||||||
use embedded_time::rate::Extensions;
|
use embedded_time::rate::Extensions;
|
||||||
use hal::gpio::FunctionI2C;
|
|
||||||
use hal::i2c::I2C;
|
// Alias for our HAL crate
|
||||||
use hal::pac;
|
|
||||||
use hal::sio::Sio;
|
|
||||||
use panic_halt as _;
|
|
||||||
use rp2040_hal as hal;
|
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"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
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]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
let mut pac = pac::Peripherals::take().unwrap();
|
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(
|
let pins = hal::gpio::Pins::new(
|
||||||
pac.IO_BANK0,
|
pac.IO_BANK0,
|
||||||
pac.PADS_BANK0,
|
pac.PADS_BANK0,
|
||||||
|
@ -30,20 +75,32 @@ fn main() -> ! {
|
||||||
&mut pac.RESETS,
|
&mut pac.RESETS,
|
||||||
);
|
);
|
||||||
|
|
||||||
let sda_pin = pins.gpio18.into_mode::<FunctionI2C>();
|
// Configure two pins as being I²C, not GPIO
|
||||||
let scl_pin = pins.gpio19.into_mode::<FunctionI2C>();
|
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,
|
pac.I2C1,
|
||||||
sda_pin,
|
sda_pin,
|
||||||
scl_pin,
|
scl_pin, // Try `not_an_scl_pin` here
|
||||||
400.kHz(),
|
400.kHz(),
|
||||||
&mut pac.RESETS,
|
&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();
|
i2c.write(0x2c, &[1, 2, 3]).unwrap();
|
||||||
|
|
||||||
|
// Demo finish - just loop until reset
|
||||||
|
|
||||||
#[allow(clippy::empty_loop)]
|
#[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_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
|
// The macro for our start-up function
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use hal::pac;
|
|
||||||
use hal::sio::Sio;
|
// Ensure we halt the program on panic (if we don't mention this crate it won't
|
||||||
use hd44780_driver as hd44780;
|
// be linked)
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
|
// Alias for our HAL crate
|
||||||
use rp2040_hal as hal;
|
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"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
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]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
|
// Grab our singleton objects
|
||||||
let mut pac = pac::Peripherals::take().unwrap();
|
let mut pac = pac::Peripherals::take().unwrap();
|
||||||
let core = pac::CorePeripherals::take().unwrap();
|
let core = pac::CorePeripherals::take().unwrap();
|
||||||
|
|
||||||
// AHL bus speed default
|
// Set up the watchdog driver - needed by the clock setup code
|
||||||
let mut delay_provider = cortex_m::delay::Delay::new(core.SYST, 12_000_000);
|
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(
|
let pins = hal::gpio::Pins::new(
|
||||||
pac.IO_BANK0,
|
pac.IO_BANK0,
|
||||||
pac.PADS_BANK0,
|
pac.PADS_BANK0,
|
||||||
|
@ -28,26 +87,36 @@ fn main() -> ! {
|
||||||
&mut pac.RESETS,
|
&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.gpio16.into_push_pull_output(), // Register Select
|
||||||
pins.gpio17.into_push_pull_output(), // Enable
|
pins.gpio17.into_push_pull_output(), // Enable
|
||||||
pins.gpio18.into_push_pull_output(), // d4
|
pins.gpio18.into_push_pull_output(), // d4
|
||||||
pins.gpio19.into_push_pull_output(), // d5
|
pins.gpio19.into_push_pull_output(), // d5
|
||||||
pins.gpio20.into_push_pull_output(), // d6
|
pins.gpio20.into_push_pull_output(), // d6
|
||||||
pins.gpio21.into_push_pull_output(), // d7
|
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();
|
// Write to the top line
|
||||||
lcd.clear(&mut delay_provider).unwrap();
|
lcd.write_str("rp-hal on", &mut delay).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();
|
|
||||||
|
|
||||||
|
// 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)]
|
#[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_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
|
// The macro for our start-up function
|
||||||
use cortex_m_rt::entry;
|
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"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
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]
|
#[entry]
|
||||||
fn main() -> ! {
|
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);
|
// Set up the watchdog driver - needed by the clock setup code
|
||||||
let pins = Pins::new(
|
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.IO_BANK0,
|
||||||
pac.PADS_BANK0,
|
pac.PADS_BANK0,
|
||||||
sio.gpio_bank0,
|
sio.gpio_bank0,
|
||||||
&mut pac.RESETS,
|
&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
|
// 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
|
// Configure PWM4
|
||||||
let mut pwm = pwm_slices.pwm4;
|
let pwm = &mut pwm_slices.pwm4;
|
||||||
pwm.set_ph_correct();
|
pwm.set_ph_correct();
|
||||||
pwm.enable();
|
pwm.enable();
|
||||||
|
|
||||||
// Use B channel (which outputs to GPIO 25)
|
// Output channel B on PWM4 to GPIO 25
|
||||||
let mut channel = pwm.channel_b;
|
let channel = &mut pwm.channel_b;
|
||||||
channel.output_to(pins.gpio25);
|
channel.output_to(pins.gpio25);
|
||||||
|
|
||||||
|
// Infinite loop, fading LED up and down
|
||||||
loop {
|
loop {
|
||||||
channel.set_duty(15000);
|
// Ramp brightness up
|
||||||
// TODO: Replace with proper delays once we have clocks working
|
for i in (LOW..=HIGH).skip(100) {
|
||||||
cortex_m::asm::delay(5_000_000);
|
delay.delay_us(8);
|
||||||
channel.set_duty(30000);
|
channel.set_duty(i);
|
||||||
cortex_m::asm::delay(5_000_000);
|
}
|
||||||
|
|
||||||
|
// 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_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use cortex_m::prelude::{
|
// The macro for our start-up function
|
||||||
_embedded_hal_blocking_spi_Transfer, _embedded_hal_blocking_spi_Write,
|
|
||||||
_embedded_hal_spi_FullDuplex,
|
|
||||||
};
|
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use embedded_hal::spi::MODE_0;
|
|
||||||
use embedded_time::rate::Extensions;
|
// Ensure we halt the program on panic (if we don't mention this crate it won't
|
||||||
use hal::{gpio::FunctionSpi, pac, sio::Sio, spi::Spi};
|
// be linked)
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
|
// Alias for our HAL crate
|
||||||
use rp2040_hal as hal;
|
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"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
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]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
|
// Grab our singleton objects
|
||||||
let mut pac = pac::Peripherals::take().unwrap();
|
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(
|
let pins = hal::gpio::Pins::new(
|
||||||
pac.IO_BANK0,
|
pac.IO_BANK0,
|
||||||
pac.PADS_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
|
// 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_sclk = pins.gpio6.into_mode::<hal::gpio::FunctionSpi>();
|
||||||
let _spi_mosi = pins.gpio7.into_mode::<FunctionSpi>();
|
let _spi_mosi = pins.gpio7.into_mode::<hal::gpio::FunctionSpi>();
|
||||||
let _spi_miso = pins.gpio4.into_mode::<FunctionSpi>();
|
let _spi_miso = pins.gpio4.into_mode::<hal::gpio::FunctionSpi>();
|
||||||
let mut spi = Spi::<_, _, 8>::new(pac.SPI0).init(
|
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,
|
&mut pac.RESETS,
|
||||||
SYS_HZ.Hz(),
|
clocks.peripheral_clock.freq(),
|
||||||
16_000_000u32.Hz(),
|
16_000_000u32.Hz(),
|
||||||
&MODE_0,
|
&embedded_hal::spi::MODE_0,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Write out 0, ignore return value
|
// Write out 0, ignore return value
|
||||||
if let Ok(..) = spi.write(&[0]) {
|
if spi.write(&[0]).is_ok() {
|
||||||
// Handle success
|
// SPI write was succesful
|
||||||
};
|
};
|
||||||
|
|
||||||
// write 50, then check the return
|
// write 50, then check the return
|
||||||
|
@ -52,17 +104,17 @@ fn main() -> ! {
|
||||||
match send_success {
|
match send_success {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
// We succeeded, check the read value
|
// We succeeded, check the read value
|
||||||
if spi.read().is_ok() {
|
if let Ok(_x) = spi.read() {
|
||||||
// Output our read value
|
// We got back `x` in exchange for the 0x50 we sent.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Err(_) => todo!(),
|
Err(_) => todo!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do a read+write at the same time.
|
// Do a read+write at the same time. Data in `buffer` will be replaced with
|
||||||
// Data in read_write_cache will be replaced with the read data
|
// the data read from the SPI device.
|
||||||
let mut read_write_cache: [u8; 4] = [1, 2, 3, 4];
|
let mut buffer: [u8; 4] = [1, 2, 3, 4];
|
||||||
let transfer_success = spi.transfer(&mut read_write_cache);
|
let transfer_success = spi.transfer(&mut buffer);
|
||||||
#[allow(clippy::single_match)]
|
#[allow(clippy::single_match)]
|
||||||
match transfer_success {
|
match transfer_success {
|
||||||
Ok(_) => {} // Handle success
|
Ok(_) => {} // Handle success
|
||||||
|
@ -70,5 +122,9 @@ fn main() -> ! {
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(clippy::empty_loop)]
|
#[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_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use core::fmt::Write;
|
// The macro for our start-up function
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use hal::clocks::init_clocks_and_plls;
|
|
||||||
use hal::gpio::{self, Pins};
|
// Ensure we halt the program on panic (if we don't mention this crate it won't
|
||||||
use hal::pac;
|
// be linked)
|
||||||
use hal::sio::Sio;
|
|
||||||
use hal::uart::UartPeripheral;
|
|
||||||
use hal::watchdog::Watchdog;
|
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
|
// Alias for our HAL crate
|
||||||
use rp2040_hal as hal;
|
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"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
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]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
|
// Grab our singleton objects
|
||||||
let mut pac = pac::Peripherals::take().unwrap();
|
let mut pac = pac::Peripherals::take().unwrap();
|
||||||
let mut watchdog = Watchdog::new(pac.WATCHDOG);
|
let core = pac::CorePeripherals::take().unwrap();
|
||||||
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 external_xtal_freq_hz = 12_000_000u32;
|
let mut watchdog = hal::watchdog::Watchdog::new(pac.WATCHDOG);
|
||||||
let clocks = init_clocks_and_plls(
|
|
||||||
external_xtal_freq_hz,
|
// Configure the clocks
|
||||||
|
let clocks = hal::clocks::init_clocks_and_plls(
|
||||||
|
XTAL_FREQ_HZ,
|
||||||
pac.XOSC,
|
pac.XOSC,
|
||||||
pac.CLOCKS,
|
pac.CLOCKS,
|
||||||
pac.PLL_SYS,
|
pac.PLL_SYS,
|
||||||
|
@ -37,14 +69,20 @@ fn main() -> ! {
|
||||||
.ok()
|
.ok()
|
||||||
.unwrap();
|
.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.IO_BANK0,
|
||||||
pac.PADS_BANK0,
|
pac.PADS_BANK0,
|
||||||
sio.gpio_bank0,
|
sio.gpio_bank0,
|
||||||
&mut pac.RESETS,
|
&mut pac.RESETS,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut uart = UartPeripheral::<_, _>::enable(
|
let mut uart = hal::uart::UartPeripheral::<_, _>::enable(
|
||||||
pac.UART0,
|
pac.UART0,
|
||||||
&mut pac.RESETS,
|
&mut pac.RESETS,
|
||||||
hal::uart::common_configs::_9600_8_N_1,
|
hal::uart::common_configs::_9600_8_N_1,
|
||||||
|
@ -52,16 +90,19 @@ fn main() -> ! {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// UART TX (characters sent from pico) on pin 1 (GPIO0) and RX (on pin 2 (GPIO1)
|
// UART TX (characters sent from RP2040) on pin 1 (GPIO0)
|
||||||
let _tx_pin = pins.gpio0.into_mode::<gpio::FunctionUart>();
|
let _tx_pin = pins.gpio0.into_mode::<hal::gpio::FunctionUart>();
|
||||||
let _rx_pin = pins.gpio1.into_mode::<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");
|
uart.write_full_blocking(b"UART example\r\n");
|
||||||
|
|
||||||
let mut value = 0u32;
|
let mut value = 0u32;
|
||||||
loop {
|
loop {
|
||||||
writeln!(uart, "value: {:02}\r", value).unwrap();
|
writeln!(uart, "value: {:02}\r", value).unwrap();
|
||||||
cortex_m::asm::delay(10_000_000);
|
delay.delay_ms(1000);
|
||||||
value += 1
|
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_std]
|
||||||
#![no_main]
|
#![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 cortex_m_rt::entry;
|
||||||
use embedded_hal::digital::v2::OutputPin;
|
|
||||||
use embedded_time::duration::units::*;
|
// Ensure we halt the program on panic (if we don't mention this crate it won't
|
||||||
use embedded_time::fixed_point::FixedPoint;
|
// be linked)
|
||||||
use hal::clocks::{init_clocks_and_plls, Clock};
|
|
||||||
use hal::gpio::Pins;
|
|
||||||
use hal::pac;
|
|
||||||
use hal::sio::Sio;
|
|
||||||
use hal::watchdog::Watchdog;
|
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
|
// Alias for our HAL crate
|
||||||
use rp2040_hal as hal;
|
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"]
|
#[link_section = ".boot2"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
|
||||||
|
|
||||||
// External high-speed crystal on the pico board is 12Mhz
|
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
|
||||||
// Adjust for your board if this isn't the same
|
/// if your board has a different frequency
|
||||||
const EXTERNAL_XTAL_FREQ_HZ: u32 = 12_000_000;
|
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]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
|
// Grab our singleton objects
|
||||||
let mut pac = pac::Peripherals::take().unwrap();
|
let mut pac = pac::Peripherals::take().unwrap();
|
||||||
let cp = pac::CorePeripherals::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(
|
// Set up the watchdog driver - needed by the clock setup code
|
||||||
EXTERNAL_XTAL_FREQ_HZ,
|
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.XOSC,
|
||||||
pac.CLOCKS,
|
pac.CLOCKS,
|
||||||
pac.PLL_SYS,
|
pac.PLL_SYS,
|
||||||
|
@ -42,16 +70,19 @@ fn main() -> ! {
|
||||||
.ok()
|
.ok()
|
||||||
.unwrap();
|
.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.IO_BANK0,
|
||||||
pac.PADS_BANK0,
|
pac.PADS_BANK0,
|
||||||
sio.gpio_bank0,
|
sio.gpio_bank0,
|
||||||
&mut pac.RESETS,
|
&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
|
// Configure an LED so we can show the current state of the watchdog
|
||||||
let mut led_pin = pins.gpio25.into_push_pull_output();
|
let mut led_pin = pins.gpio25.into_push_pull_output();
|
||||||
|
|
||||||
|
@ -60,7 +91,7 @@ fn main() -> ! {
|
||||||
delay.delay_ms(2000);
|
delay.delay_ms(2000);
|
||||||
|
|
||||||
// Set to watchdog to reset if it's not reloaded within 1.05 seconds, and start it
|
// 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
|
// Blink once a second for 5 seconds, refreshing the watchdog timer once a second to avoid a reset
|
||||||
for _ in 1..=5 {
|
for _ in 1..=5 {
|
||||||
|
@ -80,3 +111,5 @@ fn main() -> ! {
|
||||||
delay.delay_ms(100);
|
delay.delay_ms(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// End of file
|
||||||
|
|
Loading…
Reference in a new issue