embassy-rp
This commit is contained in:
parent
eb63191b08
commit
dbdaee9c6d
1110
Cargo.lock
generated
1110
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
27
Cargo.toml
27
Cargo.toml
@ -8,20 +8,27 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rp235x-hal = { version = "0.2.0", features = [
|
# Embassy
|
||||||
"critical-section-impl",
|
embassy-rp = { version = "0.3.1", features = [
|
||||||
|
"rp235xa",
|
||||||
"binary-info",
|
"binary-info",
|
||||||
|
"critical-section-impl",
|
||||||
|
"time-driver",
|
||||||
] }
|
] }
|
||||||
|
embassy-executor = { version = "0.7.0", features = [
|
||||||
|
"arch-cortex-m",
|
||||||
|
"executor-thread",
|
||||||
|
"executor-interrupt",
|
||||||
|
"task-arena-size-65536",
|
||||||
|
] }
|
||||||
|
embassy-time = "0.4.0"
|
||||||
|
|
||||||
|
cortex-m-rt = "0.7.5"
|
||||||
critical-section = "1.2.0"
|
critical-section = "1.2.0"
|
||||||
embedded-hal = "1.0.0"
|
|
||||||
fugit = "0.3.7"
|
|
||||||
scd4x = { git = "https://github.com/twokilohertz/scd4x-rs.git", branch = "conversion-fixes", features = [
|
|
||||||
"scd41",
|
|
||||||
] }
|
|
||||||
rtt-target = "0.6.1"
|
rtt-target = "0.6.1"
|
||||||
ssd1351 = "0.5.0"
|
|
||||||
embedded-hal-bus = "0.3.0"
|
[profile.dev]
|
||||||
embedded-graphics = "0.8.1"
|
opt-level = "s"
|
||||||
|
|
||||||
# Super-optimised release build, maximum performance, minimal debuggability
|
# Super-optimised release build, maximum performance, minimal debuggability
|
||||||
# Build with cargo build --profile dist
|
# Build with cargo build --profile dist
|
||||||
|
12
build.rs
12
build.rs
@ -3,16 +3,22 @@ use std::io::Write;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Put the linker script somewhere the linker can find it
|
|
||||||
let out = PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
|
let out = PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
|
||||||
println!("cargo:rustc-link-search={}", out.display());
|
println!("cargo:rustc-link-search={}", out.display());
|
||||||
|
|
||||||
// The file `memory.x` is loaded by cortex-m-rt's `link.x` script, which
|
// ARM build
|
||||||
// is what we specify in `.cargo/config.toml` for Arm builds
|
|
||||||
let memory_x = include_bytes!("memory.x");
|
let memory_x = include_bytes!("memory.x");
|
||||||
let mut f = File::create(out.join("memory.x")).unwrap();
|
let mut f = File::create(out.join("memory.x")).unwrap();
|
||||||
f.write_all(memory_x).unwrap();
|
f.write_all(memory_x).unwrap();
|
||||||
println!("cargo:rerun-if-changed=memory.x");
|
println!("cargo:rerun-if-changed=memory.x");
|
||||||
|
|
||||||
|
// RISC-V build
|
||||||
|
|
||||||
|
let rp235x_riscv_x = include_bytes!("rp235x_riscv.x");
|
||||||
|
let mut f = File::create(out.join("rp235x_riscv.x")).unwrap();
|
||||||
|
f.write_all(rp235x_riscv_x).unwrap();
|
||||||
|
println!("cargo:rerun-if-changed=rp235x_riscv.x");
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
}
|
}
|
||||||
|
2
memory.x
2
memory.x
@ -73,5 +73,3 @@ SECTIONS {
|
|||||||
|
|
||||||
PROVIDE(start_to_end = __end_block_addr - __start_block_addr);
|
PROVIDE(start_to_end = __end_block_addr - __start_block_addr);
|
||||||
PROVIDE(end_to_start = __start_block_addr - __end_block_addr);
|
PROVIDE(end_to_start = __start_block_addr - __end_block_addr);
|
||||||
|
|
||||||
|
|
||||||
|
252
rp235x_riscv.x
Normal file
252
rp235x_riscv.x
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
MEMORY {
|
||||||
|
/*
|
||||||
|
* The RP2350 has either external or internal flash.
|
||||||
|
*
|
||||||
|
* 2 MiB is a safe default here, although a Pico 2 has 4 MiB.
|
||||||
|
*/
|
||||||
|
FLASH : ORIGIN = 0x10000000, LENGTH = 2048K
|
||||||
|
/*
|
||||||
|
* RAM consists of 8 banks, SRAM0-SRAM7, with a striped mapping.
|
||||||
|
* This is usually good for performance, as it distributes load on
|
||||||
|
* those banks evenly.
|
||||||
|
*/
|
||||||
|
RAM : ORIGIN = 0x20000000, LENGTH = 512K
|
||||||
|
/*
|
||||||
|
* RAM banks 8 and 9 use a direct mapping. They can be used to have
|
||||||
|
* memory areas dedicated for some specific job, improving predictability
|
||||||
|
* of access times.
|
||||||
|
* Example: Separate stacks for core0 and core1.
|
||||||
|
*/
|
||||||
|
SRAM4 : ORIGIN = 0x20080000, LENGTH = 4K
|
||||||
|
SRAM5 : ORIGIN = 0x20081000, LENGTH = 4K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* # Developer notes
|
||||||
|
|
||||||
|
- Symbols that start with a double underscore (__) are considered "private"
|
||||||
|
|
||||||
|
- Symbols that start with a single underscore (_) are considered "semi-public"; they can be
|
||||||
|
overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" {
|
||||||
|
static mut _heap_size }`).
|
||||||
|
|
||||||
|
- `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a
|
||||||
|
symbol is not dropped if it appears in or near the front of the linker arguments and "it's not
|
||||||
|
needed" by any of the preceding objects (linker arguments)
|
||||||
|
|
||||||
|
- `PROVIDE` is used to provide default values that can be overridden by a user linker script
|
||||||
|
|
||||||
|
- On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and*
|
||||||
|
the LMA of .data are all `32`-byte aligned. These alignments are assumed by the RAM
|
||||||
|
initialization routine. There's also a second benefit: `32`-byte aligned boundaries
|
||||||
|
means that you won't see "Address (..) is out of bounds" in the disassembly produced by `objdump`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
PROVIDE(_stext = ORIGIN(FLASH));
|
||||||
|
PROVIDE(_stack_start = ORIGIN(RAM) + LENGTH(RAM));
|
||||||
|
PROVIDE(_max_hart_id = 0);
|
||||||
|
PROVIDE(_hart_stack_size = 2K);
|
||||||
|
PROVIDE(_heap_size = 0);
|
||||||
|
|
||||||
|
PROVIDE(InstructionMisaligned = ExceptionHandler);
|
||||||
|
PROVIDE(InstructionFault = ExceptionHandler);
|
||||||
|
PROVIDE(IllegalInstruction = ExceptionHandler);
|
||||||
|
PROVIDE(Breakpoint = ExceptionHandler);
|
||||||
|
PROVIDE(LoadMisaligned = ExceptionHandler);
|
||||||
|
PROVIDE(LoadFault = ExceptionHandler);
|
||||||
|
PROVIDE(StoreMisaligned = ExceptionHandler);
|
||||||
|
PROVIDE(StoreFault = ExceptionHandler);
|
||||||
|
PROVIDE(UserEnvCall = ExceptionHandler);
|
||||||
|
PROVIDE(SupervisorEnvCall = ExceptionHandler);
|
||||||
|
PROVIDE(MachineEnvCall = ExceptionHandler);
|
||||||
|
PROVIDE(InstructionPageFault = ExceptionHandler);
|
||||||
|
PROVIDE(LoadPageFault = ExceptionHandler);
|
||||||
|
PROVIDE(StorePageFault = ExceptionHandler);
|
||||||
|
|
||||||
|
PROVIDE(SupervisorSoft = DefaultHandler);
|
||||||
|
PROVIDE(MachineSoft = DefaultHandler);
|
||||||
|
PROVIDE(SupervisorTimer = DefaultHandler);
|
||||||
|
PROVIDE(MachineTimer = DefaultHandler);
|
||||||
|
PROVIDE(SupervisorExternal = DefaultHandler);
|
||||||
|
PROVIDE(MachineExternal = DefaultHandler);
|
||||||
|
|
||||||
|
PROVIDE(DefaultHandler = DefaultInterruptHandler);
|
||||||
|
PROVIDE(ExceptionHandler = DefaultExceptionHandler);
|
||||||
|
|
||||||
|
/* # Pre-initialization function */
|
||||||
|
/* If the user overrides this using the `#[pre_init]` attribute or by creating a `__pre_init` function,
|
||||||
|
then the function this points to will be called before the RAM is initialized. */
|
||||||
|
PROVIDE(__pre_init = default_pre_init);
|
||||||
|
|
||||||
|
/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */
|
||||||
|
PROVIDE(_setup_interrupts = default_setup_interrupts);
|
||||||
|
|
||||||
|
/* # Multi-processing hook function
|
||||||
|
fn _mp_hook() -> bool;
|
||||||
|
|
||||||
|
This function is called from all the harts and must return true only for one hart,
|
||||||
|
which will perform memory initialization. For other harts it must return false
|
||||||
|
and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
|
||||||
|
*/
|
||||||
|
PROVIDE(_mp_hook = default_mp_hook);
|
||||||
|
|
||||||
|
/* # Start trap function override
|
||||||
|
By default uses the riscv crates default trap handler
|
||||||
|
but by providing the `_start_trap` symbol external crates can override.
|
||||||
|
*/
|
||||||
|
PROVIDE(_start_trap = default_start_trap);
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text.dummy (NOLOAD) :
|
||||||
|
{
|
||||||
|
/* This section is intended to make _stext address work */
|
||||||
|
. = ABSOLUTE(_stext);
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.text _stext :
|
||||||
|
{
|
||||||
|
/* Put reset handler first in .text section so it ends up as the entry */
|
||||||
|
/* point of the program. */
|
||||||
|
KEEP(*(.init));
|
||||||
|
KEEP(*(.init.rust));
|
||||||
|
. = ALIGN(4);
|
||||||
|
__start_block_addr = .;
|
||||||
|
KEEP(*(.start_block));
|
||||||
|
KEEP(*(.boot_info));
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.trap);
|
||||||
|
*(.trap.rust);
|
||||||
|
*(.text.abort);
|
||||||
|
*(.text .text.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
/* ### Picotool 'Binary Info' Entries
|
||||||
|
*
|
||||||
|
* Picotool looks through this block (as we have pointers to it in our
|
||||||
|
* header) to find interesting information.
|
||||||
|
*/
|
||||||
|
.bi_entries : ALIGN(4)
|
||||||
|
{
|
||||||
|
/* We put this in the header */
|
||||||
|
__bi_entries_start = .;
|
||||||
|
/* Here are the entries */
|
||||||
|
KEEP(*(.bi_entries));
|
||||||
|
/* Keep this block a nice round size */
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* We put this in the header */
|
||||||
|
__bi_entries_end = .;
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.rodata : ALIGN(4)
|
||||||
|
{
|
||||||
|
*(.srodata .srodata.*);
|
||||||
|
*(.rodata .rodata.*);
|
||||||
|
|
||||||
|
/* 4-byte align the end (VMA) of this section.
|
||||||
|
This is required by LLD to ensure the LMA of the following .data
|
||||||
|
section will have the correct alignment. */
|
||||||
|
. = ALIGN(4);
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.data : ALIGN(32)
|
||||||
|
{
|
||||||
|
_sidata = LOADADDR(.data);
|
||||||
|
__sidata = LOADADDR(.data);
|
||||||
|
_sdata = .;
|
||||||
|
__sdata = .;
|
||||||
|
/* Must be called __global_pointer$ for linker relaxations to work. */
|
||||||
|
PROVIDE(__global_pointer$ = . + 0x800);
|
||||||
|
*(.sdata .sdata.* .sdata2 .sdata2.*);
|
||||||
|
*(.data .data.*);
|
||||||
|
. = ALIGN(32);
|
||||||
|
_edata = .;
|
||||||
|
__edata = .;
|
||||||
|
} > RAM AT > FLASH
|
||||||
|
|
||||||
|
.bss (NOLOAD) : ALIGN(32)
|
||||||
|
{
|
||||||
|
_sbss = .;
|
||||||
|
*(.sbss .sbss.* .bss .bss.*);
|
||||||
|
. = ALIGN(32);
|
||||||
|
_ebss = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.end_block : ALIGN(4)
|
||||||
|
{
|
||||||
|
__end_block_addr = .;
|
||||||
|
KEEP(*(.end_block));
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
/* fictitious region that represents the memory available for the heap */
|
||||||
|
.heap (NOLOAD) :
|
||||||
|
{
|
||||||
|
_sheap = .;
|
||||||
|
. += _heap_size;
|
||||||
|
. = ALIGN(4);
|
||||||
|
_eheap = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* fictitious region that represents the memory available for the stack */
|
||||||
|
.stack (NOLOAD) :
|
||||||
|
{
|
||||||
|
_estack = .;
|
||||||
|
. = ABSOLUTE(_stack_start);
|
||||||
|
_sstack = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* fake output .got section */
|
||||||
|
/* Dynamic relocations are unsupported. This section is only used to detect
|
||||||
|
relocatable code in the input files and raise an error if relocatable code
|
||||||
|
is found */
|
||||||
|
.got (INFO) :
|
||||||
|
{
|
||||||
|
KEEP(*(.got .got.*));
|
||||||
|
}
|
||||||
|
|
||||||
|
.eh_frame (INFO) : { KEEP(*(.eh_frame)) }
|
||||||
|
.eh_frame_hdr (INFO) : { *(.eh_frame_hdr) }
|
||||||
|
}
|
||||||
|
|
||||||
|
PROVIDE(start_to_end = __end_block_addr - __start_block_addr);
|
||||||
|
PROVIDE(end_to_start = __start_block_addr - __end_block_addr);
|
||||||
|
|
||||||
|
|
||||||
|
/* Do not exceed this mark in the error messages above | */
|
||||||
|
ASSERT(ORIGIN(FLASH) % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): the start of the FLASH must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(ORIGIN(RAM) % 32 == 0, "
|
||||||
|
ERROR(riscv-rt): the start of the RAM must be 32-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_stext % 4 == 0, "
|
||||||
|
ERROR(riscv-rt): `_stext` must be 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_sdata % 32 == 0 && _edata % 32 == 0, "
|
||||||
|
BUG(riscv-rt): .data is not 32-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_sidata % 32 == 0, "
|
||||||
|
BUG(riscv-rt): the LMA of .data is not 32-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_sbss % 32 == 0 && _ebss % 32 == 0, "
|
||||||
|
BUG(riscv-rt): .bss is not 32-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_sheap % 4 == 0, "
|
||||||
|
BUG(riscv-rt): start of .heap is not 4-byte aligned");
|
||||||
|
|
||||||
|
ASSERT(_stext + SIZEOF(.text) < ORIGIN(FLASH) + LENGTH(FLASH), "
|
||||||
|
ERROR(riscv-rt): The .text section must be placed inside the FLASH region.
|
||||||
|
Set _stext to an address smaller than 'ORIGIN(FLASH) + LENGTH(FLASH)'");
|
||||||
|
|
||||||
|
ASSERT(SIZEOF(.stack) > (_max_hart_id + 1) * _hart_stack_size, "
|
||||||
|
ERROR(riscv-rt): .stack section is too small for allocating stacks for all the harts.
|
||||||
|
Consider changing `_max_hart_id` or `_hart_stack_size`.");
|
||||||
|
|
||||||
|
ASSERT(SIZEOF(.got) == 0, "
|
||||||
|
.got section detected in the input files. Dynamic relocations are not
|
||||||
|
supported. If you are linking to C code compiled using the `gcc` crate
|
||||||
|
then modify your build script to compile the C code _without_ the
|
||||||
|
-fPIC flag. See the documentation of the `gcc::Config.fpic` method for
|
||||||
|
details.");
|
||||||
|
|
||||||
|
/* Do not exceed this mark in the error messages above | */
|
@ -1,2 +0,0 @@
|
|||||||
/// Pico 2 W on-board crystal oscillator frequency (AEL 12.0)
|
|
||||||
pub const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
|
203
src/main.rs
203
src/main.rs
@ -1,179 +1,50 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
// RP235x HAL
|
use core::panic::PanicInfo;
|
||||||
use rp235x_hal as hal;
|
|
||||||
|
|
||||||
use hal::gpio::FunctionSpi;
|
|
||||||
use hal::spi::Spi;
|
|
||||||
|
|
||||||
// Display
|
|
||||||
use ssd1351::{
|
|
||||||
mode::GraphicsMode,
|
|
||||||
prelude::SPIInterface,
|
|
||||||
properties::{DisplayRotation, DisplaySize},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sensor
|
|
||||||
// use scd4x::Scd4x;
|
|
||||||
|
|
||||||
use embedded_graphics::{
|
|
||||||
pixelcolor::Rgb565,
|
|
||||||
prelude::{Point, Primitive, RgbColor, Size},
|
|
||||||
primitives::{PrimitiveStyleBuilder, Rectangle},
|
|
||||||
Drawable,
|
|
||||||
};
|
|
||||||
|
|
||||||
use embedded_hal::spi::MODE_0;
|
|
||||||
use fugit::RateExtU32;
|
|
||||||
use rtt_target::{rprintln, rtt_init_print};
|
use rtt_target::{rprintln, rtt_init_print};
|
||||||
|
|
||||||
mod constants;
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_rp::block::ImageDef;
|
||||||
|
|
||||||
|
#[embassy_executor::main]
|
||||||
|
async fn main(_spawner: Spawner) {
|
||||||
|
rtt_init_print!();
|
||||||
|
rprintln!("RTT logging initialised");
|
||||||
|
|
||||||
|
let _peripherals = embassy_rp::init(Default::default());
|
||||||
|
|
||||||
|
loop {
|
||||||
|
unsafe {
|
||||||
|
core::arch::asm!("wfi");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(info: &PanicInfo) -> ! {
|
||||||
|
rprintln!("Panicked! {}", info);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
unsafe {
|
||||||
|
core::arch::asm!("wfi");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[link_section = ".start_block"]
|
#[link_section = ".start_block"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static IMAGE_DEF: hal::block::ImageDef = hal::block::ImageDef::secure_exe();
|
static IMAGE_DEF: ImageDef = ImageDef::secure_exe();
|
||||||
|
|
||||||
#[hal::entry]
|
// Program metadata for picotool
|
||||||
fn main() -> ! {
|
|
||||||
rtt_init_print!();
|
|
||||||
rprintln!("Logging over RTT initialised");
|
|
||||||
|
|
||||||
let mut peripherals = hal::pac::Peripherals::take().unwrap();
|
|
||||||
|
|
||||||
let mut watchdog = hal::Watchdog::new(peripherals.WATCHDOG);
|
|
||||||
|
|
||||||
let clocks = hal::clocks::init_clocks_and_plls(
|
|
||||||
constants::XTAL_FREQ_HZ,
|
|
||||||
peripherals.XOSC,
|
|
||||||
peripherals.CLOCKS,
|
|
||||||
peripherals.PLL_SYS,
|
|
||||||
peripherals.PLL_USB,
|
|
||||||
&mut peripherals.RESETS,
|
|
||||||
&mut watchdog,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut timer = hal::Timer::new_timer0(peripherals.TIMER0, &mut peripherals.RESETS, &clocks);
|
|
||||||
|
|
||||||
let sio = hal::Sio::new(peripherals.SIO);
|
|
||||||
|
|
||||||
let pins = hal::gpio::Pins::new(
|
|
||||||
peripherals.IO_BANK0,
|
|
||||||
peripherals.PADS_BANK0,
|
|
||||||
sio.gpio_bank0,
|
|
||||||
&mut peripherals.RESETS,
|
|
||||||
);
|
|
||||||
|
|
||||||
rprintln!("Core RP2350 hardware initialisation successful");
|
|
||||||
|
|
||||||
// Display
|
|
||||||
|
|
||||||
let mosi_pin = pins.gpio19.into_function::<FunctionSpi>();
|
|
||||||
let sclk_pin = pins.gpio18.into_function::<FunctionSpi>();
|
|
||||||
let cs_pin = pins.gpio17.into_push_pull_output();
|
|
||||||
let dc_pin = pins.gpio20.into_push_pull_output();
|
|
||||||
let mut rst_pin = pins.gpio21.into_push_pull_output();
|
|
||||||
|
|
||||||
// SPI initialisation
|
|
||||||
let spi_pins = (mosi_pin, sclk_pin);
|
|
||||||
let spi = Spi::<_, _, _, 8>::new(peripherals.SPI0, spi_pins).init(
|
|
||||||
&mut peripherals.RESETS,
|
|
||||||
&clocks.peripheral_clock,
|
|
||||||
16_u32.MHz(),
|
|
||||||
MODE_0,
|
|
||||||
);
|
|
||||||
let spi_device = embedded_hal_bus::spi::ExclusiveDevice::new_no_delay(spi, cs_pin).unwrap();
|
|
||||||
let spi_interface = SPIInterface::new(spi_device, dc_pin);
|
|
||||||
|
|
||||||
let mut display: GraphicsMode<_> = ssd1351::builder::Builder::new()
|
|
||||||
.with_size(DisplaySize::Display128x128)
|
|
||||||
.with_rotation(DisplayRotation::Rotate0)
|
|
||||||
.connect_interface(spi_interface)
|
|
||||||
.into();
|
|
||||||
display.reset(&mut rst_pin, &mut timer).unwrap();
|
|
||||||
display.init().unwrap();
|
|
||||||
|
|
||||||
let rect = Rectangle::new(Point::new(0, 40), Size::new(40, 20)).into_styled(
|
|
||||||
PrimitiveStyleBuilder::new()
|
|
||||||
.fill_color(Rgb565::CYAN)
|
|
||||||
.build(),
|
|
||||||
);
|
|
||||||
rect.draw(&mut display).unwrap();
|
|
||||||
|
|
||||||
// // Initialise SCD41 sensor
|
|
||||||
// let i2c0 = hal::I2C::i2c0(
|
|
||||||
// peripherals.I2C0,
|
|
||||||
// pins.gpio4.reconfigure(), // Pin 6 on Pico 2 (SDA)
|
|
||||||
// pins.gpio5.reconfigure(), // Pin 7 on Pico 2 (SCL)
|
|
||||||
// 400.kHz(),
|
|
||||||
// &mut peripherals.RESETS,
|
|
||||||
// &clocks.peripheral_clock,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// timer.delay_ms(30); // Power-up delay
|
|
||||||
// let mut scd41 = Scd4x::new(i2c0, timer);
|
|
||||||
// scd41.wake_up();
|
|
||||||
|
|
||||||
// match scd41.reinit() {
|
|
||||||
// Ok(_) => rprintln!("Initialised SCD41"),
|
|
||||||
// Err(error) => rprintln!("Failed to initialise SCD41: {:?}", error),
|
|
||||||
// }
|
|
||||||
// timer.delay_ms(30); // Soft reset delay
|
|
||||||
|
|
||||||
// match scd41.serial_number() {
|
|
||||||
// Ok(serial) => rprintln!("SCD41 serial number: {}", serial),
|
|
||||||
// Err(error) => rprintln!("SCD41 did not respond to get_serial_number: {:?}", error),
|
|
||||||
// }
|
|
||||||
|
|
||||||
// match scd41.self_test_is_ok() {
|
|
||||||
// Ok(ok) => {
|
|
||||||
// if ok {
|
|
||||||
// rprintln!("SCD41 reported successful self-test")
|
|
||||||
// } else {
|
|
||||||
// rprintln!("SCD41 reported unsuccessful self-test!")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Err(_) => rprintln!("SCD41 failed to perform self-test"),
|
|
||||||
// }
|
|
||||||
|
|
||||||
// match scd41.start_periodic_measurement() {
|
|
||||||
// Ok(_) => rprintln!("Configured sensor to measure every 5 seconds"),
|
|
||||||
// Err(error) => rprintln!("SCD41 start_periodic_measurement() failed: {:?}", error),
|
|
||||||
// }
|
|
||||||
|
|
||||||
// loop {
|
|
||||||
// timer.delay_ms(5010);
|
|
||||||
// match scd41.measurement() {
|
|
||||||
// Ok(data) => rprintln!(
|
|
||||||
// "CO2: {}, temperature: {}, humidity: {}",
|
|
||||||
// data.co2,
|
|
||||||
// data.temperature,
|
|
||||||
// data.humidity
|
|
||||||
// ),
|
|
||||||
// Err(error) => rprintln!("SCD41 get_measurement() failed: {:?}", error),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
loop {
|
|
||||||
hal::arch::wfi();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(never)]
|
|
||||||
#[panic_handler]
|
|
||||||
fn panic(info: &core::panic::PanicInfo) -> ! {
|
|
||||||
rprintln!("Panicked! {}", info);
|
|
||||||
loop {
|
|
||||||
hal::arch::nop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Program metadata for `picotool info`
|
|
||||||
#[link_section = ".bi_entries"]
|
#[link_section = ".bi_entries"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static PICOTOOL_ENTRIES: [hal::binary_info::EntryAddr; 3] = [
|
pub static PICOTOOL_ENTRIES: [embassy_rp::binary_info::EntryAddr; 4] = [
|
||||||
hal::binary_info::rp_program_name!(c"Pico Environment Sensor"),
|
embassy_rp::binary_info::rp_program_name!(c"Pico Environment Sensor"),
|
||||||
hal::binary_info::rp_cargo_version!(),
|
embassy_rp::binary_info::rp_program_description!(
|
||||||
hal::binary_info::rp_program_build_attribute!(),
|
c"A CO2, temperature & humidity sensing application for the RPi Pico 2 W"
|
||||||
|
),
|
||||||
|
embassy_rp::binary_info::rp_cargo_version!(),
|
||||||
|
embassy_rp::binary_info::rp_program_build_attribute!(),
|
||||||
];
|
];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user