firstadd
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||
runner = "elf2uf2-rs -d"
|
||||
|
||||
|
||||
[build]
|
||||
target = "thumbv6m-none-eabi"
|
||||
@@ -0,0 +1,39 @@
|
||||
[package]
|
||||
name = "rp_pico_example"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
embassy-usb-logger = { git = "https://github.com/embassy-rs/embassy.git" }
|
||||
rfe = { path = "../../rfe", default-features = false }
|
||||
to = { path = "../../apps/to", default-features = false }
|
||||
anyhow.workspace = true
|
||||
anyhow.default_features = false
|
||||
embedded-alloc = "0.6.0"
|
||||
embedded-hal = { version = "0.2.7", features = ["unproven"] }
|
||||
embassy-rp = { git = "https://github.com/embassy-rs/embassy.git", default-features = false, features = [
|
||||
"rp2040",
|
||||
"log",
|
||||
] }
|
||||
log.workspace = true
|
||||
static_cell = "2.1.0"
|
||||
portable-atomic = { version = "1.9.0", features = ["critical-section"] }
|
||||
rtic = { version = "2.1.2", features = ["thumbv6-backend"] }
|
||||
rtic-monotonics = { version = "2.0.3", features = ["rp2040"] }
|
||||
rp-pico = { version = "0.9.0", default-features = false, features = [
|
||||
"rt",
|
||||
"critical-section-impl",
|
||||
"disable-intrinsics",
|
||||
] }
|
||||
panic-halt = "1.0.0"
|
||||
hashbrown.workspace = true
|
||||
|
||||
[profile.release]
|
||||
debug = 2
|
||||
lto = true
|
||||
opt-level = 'z'
|
||||
|
||||
[profile.dev]
|
||||
debug = 2
|
||||
lto = true
|
||||
opt-level = "z"
|
||||
@@ -0,0 +1,25 @@
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
// Put `memory.x` in our output directory and ensure it's
|
||||
// on the linker search path.
|
||||
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||
File::create(out.join("memory.x"))
|
||||
.unwrap()
|
||||
.write_all(include_bytes!("memory.x"))
|
||||
.unwrap();
|
||||
println!("cargo:rustc-link-search={}", out.display());
|
||||
|
||||
// By default, Cargo will re-run a build script whenever
|
||||
// any file in the project changes. By specifying `memory.x`
|
||||
// here, we ensure the build script is only re-run when
|
||||
// `memory.x` is changed.
|
||||
println!("cargo:rerun-if-changed=memory.x");
|
||||
|
||||
println!("cargo:rustc-link-arg-bins=--nmagic");
|
||||
println!("cargo:rustc-link-arg-bins=-Tlink.x");
|
||||
// println!("cargo:rustc-link-arg-bins=-Tlink-rp.x");
|
||||
}
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
cargo run --release --target thumbv6m-none-eabi
|
||||
@@ -0,0 +1,15 @@
|
||||
MEMORY {
|
||||
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
|
||||
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 256K
|
||||
}
|
||||
|
||||
EXTERN(BOOT2_FIRMWARE)
|
||||
|
||||
SECTIONS {
|
||||
/* ### Boot loader */
|
||||
.boot2 ORIGIN(BOOT2) :
|
||||
{
|
||||
KEEP(*(.boot2));
|
||||
} > BOOT2
|
||||
} INSERT BEFORE .text;
|
||||
@@ -0,0 +1,204 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use rtic_monotonics::rp2040::prelude::*;
|
||||
|
||||
rp2040_timer_monotonic!(Mono);
|
||||
|
||||
#[rtic::app(device = rp_pico::hal::pac, dispatchers = [SW0_IRQ])]
|
||||
mod app {
|
||||
use super::*;
|
||||
|
||||
use embassy_rp::{
|
||||
interrupt::typelevel,
|
||||
peripherals::USB,
|
||||
usb::{self, Driver},
|
||||
};
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
use fugit::Duration;
|
||||
use log::info;
|
||||
use msg::{ExampleHk, Instance, MsgKind, MsgPacket, TargetMsg, TlmSetItem, ToTlmSet};
|
||||
use rfe::{connector::Connector, Rate, *};
|
||||
use rp_pico::hal::{
|
||||
clocks,
|
||||
gpio::{bank0::Gpio25, FunctionSio, Pin, PullNone, SioOutput},
|
||||
Sio, Watchdog,
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use core::{mem::MaybeUninit, ptr::addr_of_mut};
|
||||
use embedded_alloc::LlffHeap as Heap;
|
||||
use panic_halt as _;
|
||||
use rp_pico::XOSC_CRYSTAL_FREQ;
|
||||
use time::SchTimeDriver;
|
||||
extern crate alloc;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
use hashbrown::HashMap;
|
||||
use to::*;
|
||||
|
||||
#[global_allocator]
|
||||
static HEAP: Heap = Heap::empty();
|
||||
|
||||
/// will log messages to log
|
||||
#[derive(Debug)]
|
||||
struct LogConnector;
|
||||
|
||||
impl Connector for LogConnector {
|
||||
fn send(&mut self, msgs: Vec<MsgPacket>) {
|
||||
info!("got msgs: {:?}", msgs);
|
||||
}
|
||||
fn recv(&mut self) -> Option<Vec<MsgPacket>> {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
struct BlinkApp<'a> {
|
||||
led_pin: &'a mut Pin<Gpio25, FunctionSio<SioOutput>, PullNone>,
|
||||
on: bool,
|
||||
counter: u32,
|
||||
}
|
||||
|
||||
impl App for BlinkApp<'_> {
|
||||
fn init(&mut self, _rfe: &mut Rfe) -> Result<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn run(&mut self, _rfe: &mut Rfe) {
|
||||
self.counter += 1;
|
||||
self.on = !self.on;
|
||||
if self.on {
|
||||
info!("led on!");
|
||||
self.led_pin.set_high().ok();
|
||||
} else {
|
||||
info!("led off!");
|
||||
self.led_pin.set_low().ok();
|
||||
}
|
||||
}
|
||||
|
||||
fn hk(&mut self, rfe: &mut Rfe) {
|
||||
rfe.send(msg::Msg::ExampleHk(ExampleHk {
|
||||
counter: self.counter,
|
||||
}));
|
||||
}
|
||||
|
||||
fn out_data(&mut self, _rfe: &mut Rfe) {}
|
||||
|
||||
fn get_app_rate(&self) -> Rate {
|
||||
return Rate::Hz10;
|
||||
}
|
||||
}
|
||||
|
||||
#[shared]
|
||||
struct Shared {}
|
||||
|
||||
#[local]
|
||||
struct Local {
|
||||
led: Pin<Gpio25, FunctionSio<SioOutput>, PullNone>,
|
||||
usb: Option<Driver<'static, USB>>,
|
||||
}
|
||||
|
||||
struct UsbBinding;
|
||||
unsafe impl typelevel::Binding<typelevel::USBCTRL_IRQ, usb::InterruptHandler<USB>> for UsbBinding {}
|
||||
|
||||
#[init()]
|
||||
fn init(mut ctx: init::Context) -> (Shared, Local) {
|
||||
let p = embassy_rp::init(Default::default());
|
||||
// Configure the clocks, watchdog - The default is to generate a 125 MHz system clock
|
||||
Mono::start(ctx.device.TIMER, &mut ctx.device.RESETS); // default rp2040 clock-rate is 125MHz
|
||||
let mut watchdog = Watchdog::new(ctx.device.WATCHDOG);
|
||||
let _clocks = clocks::init_clocks_and_plls(
|
||||
XOSC_CRYSTAL_FREQ,
|
||||
ctx.device.XOSC,
|
||||
ctx.device.CLOCKS,
|
||||
ctx.device.PLL_SYS,
|
||||
ctx.device.PLL_USB,
|
||||
&mut ctx.device.RESETS,
|
||||
&mut watchdog,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
const HEAP_SIZE: usize = 1024 * 16;
|
||||
static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
|
||||
unsafe { HEAP.init(addr_of_mut!(HEAP_MEM) as usize, HEAP_SIZE) }
|
||||
}
|
||||
|
||||
let driver = Driver::new(p.USB, UsbBinding {});
|
||||
let sio = Sio::new(ctx.device.SIO);
|
||||
let gpioa = rp_pico::Pins::new(
|
||||
ctx.device.IO_BANK0,
|
||||
ctx.device.PADS_BANK0,
|
||||
sio.gpio_bank0,
|
||||
&mut ctx.device.RESETS,
|
||||
);
|
||||
let led = gpioa
|
||||
.led
|
||||
.into_pull_type::<PullNone>()
|
||||
.into_push_pull_output();
|
||||
|
||||
// Spawn heartbeat task
|
||||
blink_instance::spawn().ok();
|
||||
usb_logger::spawn().ok();
|
||||
|
||||
// Return resources and timer
|
||||
(
|
||||
Shared {},
|
||||
Local {
|
||||
led,
|
||||
usb: Some(driver),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[task(local = [usb])]
|
||||
async fn usb_logger(ctx: usb_logger::Context) {
|
||||
let driver = Option::take(ctx.local.usb).unwrap();
|
||||
embassy_usb_logger::run!(1024, log::LevelFilter::Info, driver);
|
||||
}
|
||||
|
||||
#[task(binds = USBCTRL_IRQ)]
|
||||
fn usbctrl(_cx: usbctrl::Context) {
|
||||
unsafe {
|
||||
<usb::InterruptHandler<USB> as typelevel::Handler<typelevel::USBCTRL_IRQ>>::on_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
#[task(local = [led], priority = 1)]
|
||||
async fn blink_instance(mut ctx: blink_instance::Context) {
|
||||
let mut blink_app = BlinkApp {
|
||||
led_pin: &mut ctx.local.led,
|
||||
on: false,
|
||||
counter: 0,
|
||||
};
|
||||
|
||||
let mut log_connector = LogConnector {};
|
||||
let mut tlmsets = HashMap::new();
|
||||
tlmsets.insert(
|
||||
0,
|
||||
ToTlmSet {
|
||||
items: vec![TlmSetItem {
|
||||
target: TargetMsg::new(Instance::All, MsgKind::ExampleHk),
|
||||
counter: 0,
|
||||
decimation: 0,
|
||||
}],
|
||||
id: 0,
|
||||
enabled: true,
|
||||
},
|
||||
);
|
||||
let mut to = To::new(&mut log_connector, tlmsets);
|
||||
let time_driver = SchTimeDriver::new();
|
||||
let mut instance = RfeInstance::new(Instance::Example, &time_driver);
|
||||
instance.add_app("blink_app", &mut blink_app).unwrap();
|
||||
instance.add_app("to", &mut to).unwrap();
|
||||
|
||||
let mut next_time = Mono::now() + Duration::<u64, 1, 1000000>::from_ticks(10000);
|
||||
|
||||
loop {
|
||||
instance.run();
|
||||
Mono::delay_until(next_time).await;
|
||||
next_time += Duration::<u64, 1, 1000000>::from_ticks(10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user