switch to rp2350

This commit is contained in:
2025-06-24 19:02:30 -06:00
parent 3392dec944
commit f8325a7750
9 changed files with 207 additions and 1213 deletions

View File

@@ -1,9 +1,10 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "probe-rs run --chip RP2040"
runner = "probe-rs run --chip RP2350"
# runner = "elf2uf2-rs -d"
[build]
target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
# target = "thumbv6m-none-eabi" # rp2040: Cortex-M0 and Cortex-M0+
target = "thumbv8m.main-none-eabihf" # rp235x: Cortex-M33
[env]
DEFMT_LOG = "info"

1221
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,13 +3,17 @@ name = "picocalc-os-rs"
version = "0.1.0"
edition = "2024"
[build-dependencies]
reqwest = { version = "0.12.20", features = ["blocking"] }
[profile.release]
debug = 2
[profile.dev]
lto = true
opt-level = "z"
[features]
default = ["rp2040"]
default = ["rp235x", "defmt"]
rp2040 = ["embassy-rp/rp2040"]
rp2350 = ["embassy-rp/_rp235x"]
rp235x = ["embassy-rp/rp235xb"]
trouble = ["dep:bt-hci", "dep:cyw43", "dep:cyw43-pio", "dep:trouble-host"]
defmt = [
"dep:defmt",
@@ -35,13 +39,14 @@ embassy-executor = { version = "0.7", features = [
] }
embassy-rp = { version = "0.4.0", features = [
"critical-section-impl",
"unstable-pac",
"time-driver",
"intrinsics",
"binary-info",
] }
embassy-futures = "0.1.0"
embassy-futures = "0.1.1"
embassy-time = "0.4.0"
embassy-embedded-hal = "0.3.0"
embassy-sync = { version = "0.6" }
embassy-sync = { version = "0.7" }
trouble-host = { version = "0.1", features = [
"derive",
"scan",
@@ -66,5 +71,6 @@ defmt-rtt = "0.4.2"
embedded-graphics = { version = "0.8.1" }
embedded-sdmmc = { git = "https://github.com/Be-ing/embedded-sdmmc-rs", branch = "bisync", default-features = false }
st7365p-lcd = { git = "https://github.com/legitcamper/st7365p-lcd-rs" }
static_cell = "2.1.0"
static_cell = "2.1.1"

View File

@@ -18,7 +18,7 @@ enabled = true
halt_afterwards = false
[default.general]
chip = "RP2040"
chip = "RP2350"
log_level = "WARN"
# RP2040 does not support connect_under_reset
connect_under_reset = false

View File

@@ -31,6 +31,5 @@ fn main() {
println!("cargo:rustc-link-arg-bins=--nmagic");
println!("cargo:rustc-link-arg-bins=-Tlink.x");
println!("cargo:rustc-link-arg-bins=-Tlink-rp.x");
println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
}

View File

@@ -1,17 +1,75 @@
MEMORY {
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
/* Pick one of the two options for RAM layout */
/* OPTION A: Use all RAM banks as one big block */
/* Reasonable, unless you are doing something */
/* really particular with DMA or other concurrent */
/* access that would benefit from striping */
RAM : ORIGIN = 0x20000000, LENGTH = 264K
/* OPTION B: Keep the unstriped sections separate */
/* RAM: ORIGIN = 0x20000000, LENGTH = 256K */
/* SCRATCH_A: ORIGIN = 0x20040000, LENGTH = 4K */
/* SCRATCH_B: ORIGIN = 0x20041000, LENGTH = 4K */
/*
* 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
}
SECTIONS {
/* ### Boot ROM info
*
* Goes after .vector_table, to keep it in the first 4K of flash
* where the Boot ROM (and picotool) can find it
*/
.start_block : ALIGN(4)
{
__start_block_addr = .;
KEEP(*(.start_block));
KEEP(*(.boot_info));
} > FLASH
} INSERT AFTER .vector_table;
/* move .text to start /after/ the boot info */
_stext = ADDR(.start_block) + SIZEOF(.start_block);
SECTIONS {
/* ### 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
} INSERT AFTER .text;
SECTIONS {
/* ### Boot ROM extra info
*
* Goes after everything in our program, so it can contain a signature.
*/
.end_block : ALIGN(4)
{
__end_block_addr = .;
KEEP(*(.end_block));
} > FLASH
} INSERT AFTER .uninit;
PROVIDE(start_to_end = __end_block_addr - __start_block_addr);
PROVIDE(end_to_start = __start_block_addr - __end_block_addr);

47
src/display.rs Normal file
View File

@@ -0,0 +1,47 @@
use embassy_rp::{
gpio::{Level, Output},
peripherals::{PIN_13, PIN_14, PIN_15, SPI1},
spi::{Blocking, Spi},
};
use embassy_time::Delay;
use embedded_graphics::{
Drawable,
pixelcolor::{BinaryColor, Rgb555, Rgb565},
prelude::{Point, Primitive, RgbColor},
primitives::{PrimitiveStyle, Triangle},
};
use embedded_hal_bus::spi::ExclusiveDevice;
use st7365p_lcd::ST7365P;
#[embassy_executor::task]
pub async fn display_task(
spi: Spi<'static, SPI1, Blocking>,
cs: PIN_13,
data: PIN_14,
reset: PIN_15,
) {
let spi_device = ExclusiveDevice::new(spi, Output::new(cs, Level::Low), Delay).unwrap();
let mut display = ST7365P::new(
spi_device,
Output::new(data, Level::Low),
Some(Output::new(reset, Level::High)),
true,
false,
320,
320,
);
let thin_stroke = PrimitiveStyle::with_stroke(Rgb565::RED, 1);
let yoffset = 10;
// Draw a triangle.
Triangle::new(
Point::new(16, 16 + yoffset),
Point::new(16 + 16, 16 + yoffset),
Point::new(16 + 8, yoffset),
)
.into_styled(thin_stroke)
.draw(&mut display)
.unwrap();
}

View File

@@ -7,10 +7,15 @@ use defmt::*;
use {defmt_rtt as _, panic_probe as _};
use embassy_executor::Spawner;
use embassy_rp::gpio::{Level, Output};
use embassy_rp::peripherals::I2C1;
use embassy_rp::spi::{self, Spi};
use embassy_rp::{bind_interrupts, i2c};
use embassy_rp::spi::Spi;
use embassy_rp::{
bind_interrupts,
gpio::{Level, Output},
i2c,
i2c::I2c,
spi,
};
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use embassy_sync::channel::Channel;
use embassy_time::Timer;
@@ -20,6 +25,8 @@ use static_cell::StaticCell;
mod peripherals;
use peripherals::{keyboard::KeyEvent, peripherals_task};
mod display;
use display::display_task;
embassy_rp::bind_interrupts!(struct Irqs {
I2C1_IRQ => i2c::InterruptHandler<I2C1>;
@@ -32,10 +39,23 @@ async fn main(spawner: Spawner) {
static KEYBOARD_EVENTS: StaticCell<Channel<NoopRawMutex, KeyEvent, 10>> = StaticCell::new();
let keyboard_events = KEYBOARD_EVENTS.init(Channel::new());
loop {
info!("im alive");
Timer::after_secs(1).await;
}
// configure keyboard event handler
let config = embassy_rp::i2c::Config::default();
let bus = embassy_rp::i2c::I2c::new_async(p.I2C1, p.PIN_27, p.PIN_26, Irqs, config);
let config = i2c::Config::default();
let i2c1 = I2c::new_async(p.I2C1, p.PIN_7, p.PIN_6, Irqs, config);
spawner
.spawn(peripherals_task(bus, keyboard_events.sender()))
.spawn(peripherals_task(i2c1, keyboard_events.sender()))
.unwrap();
// configure display handler
let mut config = spi::Config::default();
config.frequency = 10_000_000;
let spi1 = spi::Spi::new_blocking(p.SPI1, p.PIN_10, p.PIN_11, p.PIN_12, config);
spawner
.spawn(display_task(spi1, p.PIN_13, p.PIN_14, p.PIN_15))
.unwrap();
}

View File

@@ -1,4 +1,4 @@
//! handles polling keyboard events and battery levels from mcu over i2c1
//! handles all the peripherals exposed by mcu through i2c (keyboard & battery registers)
//!
use embassy_futures::join::join;