Properly reset peripherals, update README.

This commit is contained in:
Dario Nieuwenhuis 2021-01-26 04:46:48 +01:00
parent 8f38b191ab
commit 9dc0745950
5 changed files with 113 additions and 26 deletions

View File

@ -1,5 +1,6 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "./probe-run.sh"
#runner = "./probe-run.sh"
runner = "probe-run-rp --chip RP2040"
rustflags = [
"-C", "link-arg=--nmagic",

View File

@ -6,16 +6,15 @@ name = "rp-test"
version = "0.1.0"
[dependencies]
cortex-m = { version = "0.7.0", features = ["inline-asm"] }
cortex-m = { version = "0.7.1", features = ["inline-asm"] }
cortex-m-rt = "0.6.10"
cortex-m-semihosting = "0.3.3"
defmt = "0.1.3"
defmt-rtt = "0.1.0"
panic-probe = "0.1.0"
rp2040-pac = { git = "https://github.com/rp-rs/rp2040-pac", branch="main" }
rp2040-boot2 = { git = "https://github.com/rp-rs/rp2040-boot2-rs", branch="vector" }
rp2040-boot2 = { git = "https://github.com/rp-rs/rp2040-boot2-rs", branch="main" }
#rp2040-pac = { path = "../rp2040-pac" }
#rp2040-boot2 = { path = "../rp2040-boot2-rs" }

View File

@ -1,17 +1,25 @@
# Raspberry pico RP2040 rust test!
How to run:
## Requirements
git clone https://github.com/Dirbaio/rp2040-rust-test
git clone https://github.com/Dirbaio/rp2040-pac
git clone https://github.com/Dirbaio/probe-run
git clone https://github.com/Dirbaio/probe-rs
cd rp2040-rust-test
cargo run
- Recent nightly Rust
- `probe-run-rp` installed.
- A CMSIS-DAP probe. (JLink probes sort of work but are very unstable. Other probes won't work at all)
`probe-run-rp` is a version of `probe-run` using a `probe-rs` fork with support for the RP2040 chip. To install it use the following command.
cargo install --git https://github.com/rp-rs/probe-run --branch main
Note that this installs the binary with name `probe-run-rp`, so you can still have the original `probe-run` installed in parallel. This is important because `probe-run-rp` ONLY works with the RP2040 chip.
## Running
Just do `cargo run` :)
# License
## License
This thingy is licensed under either of
This project is icensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)

View File

@ -1,13 +1,13 @@
MEMORY {
BOOT_LOADER : ORIGIN = 0x10000000, LENGTH = 0x100
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
RAM : ORIGIN = 0x20000000, LENGTH = 256K
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
RAM : ORIGIN = 0x20000000, LENGTH = 256K
}
SECTIONS {
/* ### Boot loader */
.boot_loader ORIGIN(BOOT_LOADER) :
.boot2 ORIGIN(BOOT2) :
{
KEEP(*(.boot_loader));
} > BOOT_LOADER
KEEP(*(.boot2));
} > BOOT2
} INSERT BEFORE .text;

View File

@ -1,17 +1,18 @@
#![no_std]
#![no_main]
#![feature(asm)]
use core::sync::atomic::{AtomicUsize, Ordering};
use cortex_m_rt::entry;
use defmt::*;
use defmt_rtt as _; // global logger
use defmt_rtt as _;
use panic_probe as _;
// this adds boot2 to the .boot_loader section
// linker script then places that at start of flash.
use rp2040_boot2 as _;
use rp2040_pac as pac;
#[link_section = ".boot2"]
#[used]
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
#[defmt::timestamp]
fn timestamp() -> u64 {
static COUNT: AtomicUsize = AtomicUsize::new(0);
@ -21,12 +22,90 @@ fn timestamp() -> u64 {
n as u64
}
mod reset_bits {
pub const ALL: u32 = 0x01ffffff;
pub const USBCTRL: u32 = 0x01000000;
pub const UART1: u32 = 0x00800000;
pub const UART0: u32 = 0x00400000;
pub const TIMER: u32 = 0x00200000;
pub const TBMAN: u32 = 0x00100000;
pub const SYSINFO: u32 = 0x00080000;
pub const SYSCFG: u32 = 0x00040000;
pub const SPI1: u32 = 0x00020000;
pub const SPI0: u32 = 0x00010000;
pub const RTC: u32 = 0x00008000;
pub const PWM: u32 = 0x00004000;
pub const PLL_USB: u32 = 0x00002000;
pub const PLL_SYS: u32 = 0x00001000;
pub const PIO1: u32 = 0x00000800;
pub const PIO0: u32 = 0x00000400;
pub const PADS_QSPI: u32 = 0x00000200;
pub const PADS_BANK0: u32 = 0x00000100;
pub const JTAG: u32 = 0x00000080;
pub const IO_QSPI: u32 = 0x00000040;
pub const IO_BANK0: u32 = 0x00000020;
pub const I2C1: u32 = 0x00000010;
pub const I2C0: u32 = 0x00000008;
pub const DMA: u32 = 0x00000004;
pub const BUSCTRL: u32 = 0x00000002;
pub const ADC: u32 = 0x00000001;
}
struct Resets {
inner: pac::RESETS,
}
impl Resets {
fn new(inner: pac::RESETS) -> Self {
Self { inner }
}
fn reset(&self, bits: u32) {
self.inner.reset.write(|w| unsafe { w.bits(bits) })
}
fn unreset_wait(&self, bits: u32) {
// TODO use the "atomic clear" register version
self.inner
.reset
.modify(|r, w| unsafe { w.bits(r.bits() & !bits) });
while ((!self.inner.reset_done.read().bits()) & bits) != 0 {}
}
}
fn setup_chip(resets: pac::RESETS) {
// Now reset all the peripherals, except QSPI and XIP (we're using those
// to execute from external flash!)
let resets = Resets::new(resets);
// Reset everything except:
// - QSPI (we're using it to run this code!)
// - PLLs (it may be suicide if that's what's clocking us)
resets.reset(
!(reset_bits::IO_QSPI | reset_bits::PADS_QSPI | reset_bits::PLL_SYS | reset_bits::PLL_USB),
);
resets.unreset_wait(
reset_bits::ALL
& !(reset_bits::ADC
| reset_bits::RTC
| reset_bits::SPI0
| reset_bits::SPI1
| reset_bits::UART0
| reset_bits::UART1
| reset_bits::USBCTRL),
);
}
#[entry]
fn main() -> ! {
info!("Hello World!");
let p = pac::Peripherals::take().unwrap();
setup_chip(p.RESETS);
loop {
info!("on!");
p.IO_BANK0.gpio25_ctrl.write(|w| {
@ -35,7 +114,7 @@ fn main() -> ! {
w
});
cortex_m::asm::delay(64_000_000);
cortex_m::asm::delay(1_000_000);
info!("off!");
p.IO_BANK0.gpio25_ctrl.write(|w| {
@ -44,6 +123,6 @@ fn main() -> ! {
w
});
cortex_m::asm::delay(64_000_000);
cortex_m::asm::delay(1_000_000);
}
}