Skip to content

Commit

Permalink
Merge pull request #886 from andrewdavidmackenzie/pigg_669
Browse files Browse the repository at this point in the history
pigg_669
  • Loading branch information
andrewdavidmackenzie authored Mar 5, 2025
2 parents 46b1067 + c17770f commit 847349e
Show file tree
Hide file tree
Showing 16 changed files with 95 additions and 45 deletions.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
$(eval PI = $(shell cat /proc/cpuinfo 2>&1 | grep "Raspberry Pi"))

.PHONY: all
all: clippy build build-arm build-porky build-web test
all: clippy format-check build build-arm build-porky build-web test

.PHONY: clean
clean:
Expand All @@ -34,6 +34,10 @@ setup:
clippy:
cargo clippy --tests --no-deps

.PHONY: format-check
format-check:
cargo fmt --all -- --check

.PHONY: build
build:
cargo build
Expand Down
5 changes: 4 additions & 1 deletion dist-workspace.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ armv7-unknown-linux-musleabihf = "ubuntu-24.04"
[[dist.extra-artifacts]]
artifacts = [
"porky/target/thumbv6m-none-eabi/release/porky_pico_w.uf2",
"porky/target/thumbv6m-none-eabi/release/porky_pico_w2.uf2",
"porky/target/thumbv6m-none-eabi/release/porky_pico.uf2",
"porky/target/thumbv6m-none-eabi/release/porky_pico2.uf2",
"70.pigg.rules"
]
build = ["make", "-C", "porky", "install-uf2", "uf2-w", "uf2"]
# For porky binary builds - install the 'elf2uf2-rs' tool, then build the uf2 files for artifacts above
build = ["make", "-C", "porky", "install-uf2", "uf2s"]
2 changes: 1 addition & 1 deletion pigdef/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use std::time::Duration;

/// [HardwareConfig] captures the current configuration of programmable GPIO pins
#[cfg_attr(feature = "std", derive(Debug))]
#[cfg_attr(debug_assertions, derive(PartialEq))]
#[cfg_attr(all(debug_assertions, feature = "std"), derive(PartialEq))]
#[derive(Clone, Serialize, Deserialize, Default)]
pub struct HardwareConfig {
#[cfg(feature = "std")]
Expand Down
38 changes: 25 additions & 13 deletions porky/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# See https://doc.rust-lang.org/cargo/reference/config.html for details of possible config keys and values

# Choose a default "cargo run" tool (see README for more info)
# - `probe-rs` provides flashing and defmt via a hardware debugger, and stack unwind on panic
# - `picotool`- used while the pico2 was lacking probe-rs support
# - elf2uf2-rs loads firmware over USB when the rp2040 is in boot mode
runner = ["probe-rs",
# - probe-rs - provides flashing and defmt via a hardware debugger, and stack unwind on panic
# - picotool - used while the pico2 was lacking probe-rs support
# - runner = "picotool load -u -v -x -t elf"
# - elf2uf2-rs - loads firmware over USB when the rp2040 is in boot mode
# - runner = "elf2uf2-rs -d"

# Runner to use for pico
[target.thumbv6m-none-eabi]
runner = [
"probe-rs",
"run",
"--chip",
"RP2040",
# "RP235x",
"--protocol",
"swd",
"--log-format",
"{[{L}]%bold} {s} {{c}",
"--restore-unwritten"
]
#runner = "picotool load -u -v -x -t elf"
#runner = "elf2uf2-rs -d"

#[build]
# Since we are now switching target between building for Pico and Pico 2 - we cannot have a static target here.
#it is specified on the command line to the compiler from the Makrfile
#target = "thumbv6m-none-eabi" # Pico
#target = "thumbv8m.main-none-eabihf" # Pico 2
# Runner to use for pico 2
[target.thumbv8m.main-none-eabihf]
runner = [
"probe-rs",
"run",
"--chip",
"RP235x",
"--protocol",
"swd",
"--log-format",
"{[{L}]%bold} {s} {{c}",
"--restore-unwritten"
]

[env]
DEFMT_LOG = "info"
16 changes: 12 additions & 4 deletions porky/BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,24 @@ Wi-Fi network, and the output of its IP and the port it is listening for TCP con

## Creating a UF2 file

Use `make uf2` Makefile target.
The `porky/Makefile` has 5 targets for uf2 files:

This uses [`elf2usb2-rs`](https://github.com/JoNil/elf2uf2-rs). This can be installed using:
- `uf2-w`: Build UF2 file (`target/thumbv6m-none-eabi/release/porky_pico_w.uf2`) for Pico 1 W (Wi-Fi)
- `uf2-w2`: Build UF2 file (`target/thumbv6m-none-eabi/release/porky_pico_w2.uf2`)for Pico 2 W (Wi-Fi)
- `uf2`: Build UF2 file (`target/thumbv6m-none-eabi/release/porky_pico.uf2`) for Pico 1 (no Wi-Fi)
- `uf2-2`: Build UF2 file (`target/thumbv6m-none-eabi/release/porky_pico2.uf2`) for Pico 2 (no Wi-Fi)
- `uf2s`: Build all of the above

This uses [`elf2usb2-rs`](https://github.com/JoNil/elf2uf2-rs). This can be installed using the `porky/Makefile` target
`install-uf2` or
manually:

- `cargo binstall elf2uf2-rs` if you use `cargo binstall` to install a pre-compiled binary
- `cargo install elf2uf2-rs` to build it from source and install it

This will produce the file `target/thumbv6m-none-eabi/release/porky_pico_w.uf2`
You can check the generated files using: `file`.

You can check its type using: `file target/thumbv6m-none-eabi/release/porky_pico_w.uf2`:
For example: `file target/thumbv6m-none-eabi/release/porky_pico_w.uf2`:

```
target/thumbv6m-none-eabi/release/porky_pico_w.uf2: UF2 firmware image, family Raspberry Pi RP2040, address 0x10000000, 1608 total blocks
Expand Down
9 changes: 4 additions & 5 deletions porky/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ path = "src/porky.rs"
default = []
pico1 = ["embassy-rp/rp2040"]
pico2 = ["embassy-rp/rp235xa"]
wifi = ["dep:cyw43", "tcp", "discovery"]
wifi = ["dep:cyw43", "discovery", "tcp"]
debug-probe = []
usb = ["pigdef/usb", "dep:embassy-usb"]
discovery = ["pigdef/discovery", "dep:edge-mdns", "dep:edge-nal-embassy", "dep:edge-nal"]
Expand All @@ -28,11 +28,11 @@ pigdef = { path = "../pigdef" }
# Embassy Dependencies (crates in https://github.com/embassy-rs/embassy)
embassy-time = { version = "0.4.0", default-features = false, features = ["defmt", "defmt-timestamp-uptime"] }
embassy-executor = { version = "0.7.0", default-features = false, features = ["task-arena-size-65536", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
embassy-rp = { version = "0.3.1", default-features = false, features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl"] }
embassy-rp = { version = "0.3", default-features = false, features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl"] }
embassy-sync = { version = "0.6.2", default-features = false }
embassy-futures = { version = "0.1.1", default-features = false }

# Needed even when no wifi - I don't know why yet. Reported to Embassy
# Needed even when no Wi-Fi - I don't know why yet. Reported to Embassy
cyw43-pio = { version = "0.3.0", default-features = false, features = ["defmt"] }

# Optional Embassy Dependencies
Expand All @@ -54,14 +54,13 @@ cortex-m-rt = { version = "0.7.5", default-features = false }

embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
rand = { version = "0.8.5", default-features = false }
# To convert device_id into hex for use as a string
faster-hex = { version = "0.10.0", default-features = false }

serde = { version = "1.0.208", default-features = false, features = ["derive"] }
postcard = { version = "1.0.10", default-features = false, features = ["heapless"] }
heapless = { version = "0.8.0", default-features = false, features = ["serde"] }

edge-mdns = { version = "0.5.0", optional = true, features = ["io"] }
edge-mdns = { version = "0.5.0", default-features = false, optional = true, features = ["io"] } #TODO check out "embassy" https://github.com/ivmarkov/edge-net/issues/63
edge-nal-embassy = { version = "0.5.0", default-features = false, optional = true }
edge-nal = { version = "0.5.0", default-features = false, optional = true }

Expand Down
4 changes: 2 additions & 2 deletions porky/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ install-uf2:
curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
cargo binstall elf2uf2-rs

uf2s: uf2-w uf2-w2 uf2 uf22
uf2s: uf2-w uf2-w2 uf2 uf2-2

uf2-w: build-w
elf2uf2-rs target/thumbv6m-none-eabi/release/porky target/thumbv6m-none-eabi/release/porky_pico_w.uf2
Expand All @@ -57,5 +57,5 @@ uf2-w2: build-w2
uf2: build
elf2uf2-rs target/thumbv6m-none-eabi/release/porky target/thumbv6m-none-eabi/release/porky_pico.uf2

uf22: build2
uf2-2: build2
elf2uf2-rs target/thumbv6m-none-eabi/release/porky target/thumbv6m-none-eabi/release/porky_pico2.uf2
Binary file modified porky/assets/43439A0.bin
Binary file not shown.
Binary file modified porky/assets/43439A0_clm.bin
Binary file not shown.
2 changes: 1 addition & 1 deletion porky/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ fn main() -> io::Result<()> {
#[cfg(feature = "pico1")]
file.write_all(include_bytes!("memory1.x"))?;
#[cfg(feature = "pico2")]
file.write_all(include_bytes!("memory2.x")).unwrap();
file.write_all(include_bytes!("memory2.x"))?;
println!("cargo:rustc-link-search={}", out.display());

println!("cargo:rerun-if-changed={}", SSID_FILE_NAME);
Expand Down
2 changes: 1 addition & 1 deletion porky/memory2.x
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
MEMORY {
FLASH : ORIGIN = 0x10000000, LENGTH = 1024K
FLASH : ORIGIN = 0x10000000, LENGTH = 2048K
CONFIG : ORIGIN = ORIGIN(FLASH) + LENGTH(FLASH), LENGTH = 256K
RAM : ORIGIN = 0x20000000, LENGTH = 512K
SRAM4 : ORIGIN = 0x20080000, LENGTH = 4K
Expand Down
26 changes: 20 additions & 6 deletions porky/src/flash.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[cfg(feature = "pico1")]
use core::str;
use defmt::info;
use defmt::{error, info};
use ekv::flash::{self, PageID};
use ekv::{config, Database};
use embassy_rp::flash::{Blocking, Flash};
Expand All @@ -13,7 +13,13 @@ use faster_hex::hex_encode;
use static_cell::StaticCell;
use {defmt_rtt as _, panic_probe as _};

#[cfg(not(any(feature = "pico1", feature = "pico2")))]
compile_error!("You must choose either feature \"pico1\" or \"pico2\"");

#[cfg(all(feature = "pico1", not(feature = "pico2")))]
pub const FLASH_SIZE: usize = 2 * 1024 * 1024;
#[cfg(all(feature = "pico2", not(feature = "pico1")))]
pub const FLASH_SIZE: usize = 4 * 1024 * 1024;

extern "C" {
// Flash storage used for configuration
Expand Down Expand Up @@ -93,18 +99,26 @@ pub fn get_flash<'a>(flash_pin: FLASH) -> Flash<'a, FLASH, Blocking, FLASH_SIZE>

pub async fn db_init(
flash: Flash<'static, FLASH, Blocking, FLASH_SIZE>,
) -> Database<DbFlash<Flash<'static, FLASH, Blocking, FLASH_SIZE>>, NoopRawMutex> {
) -> Database<DbFlash<Flash<'static, FLASH, Blocking, FLASH_SIZE>>, NoopRawMutex>{

#[cfg(feature = "pico1")]
const OFFSET: usize = 0x0;
#[cfg(not(feature = "pico1"))] // The start of flash address needs adjusting on pico 2
const OFFSET: usize = 0x1000_0000;

let flash: DbFlash<Flash<_, _, FLASH_SIZE>> = DbFlash {
flash,
start: unsafe { &__config_start as *const u32 as usize },
start: unsafe { &__config_start as *const u32 as usize - OFFSET},
};
let db = Database::<_, NoopRawMutex>::new(flash, ekv::Config::default());

if db.mount().await.is_err() {
info!("Initializing Flash DB...");
db.format().await.unwrap();
info!("Formatting Flash DB...");
match db.format().await {
Ok(..) => info!("Flash Database is up"),
Err(_e) => error!("Error initializing Flash DB"),
}
}

info!("Flash Database is up");
db
}
16 changes: 8 additions & 8 deletions porky/src/persistence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ use pigdef::pin_function::PinFunction::Output;
const SSID_SPEC_KEY: &[u8] = b"ssid_spec";

/// Load any pre-existing config from flash, if there is none then just return a default config
pub async fn get_config<'p>(
db: &Database<DbFlash<Flash<'p, FLASH, Blocking, { flash::FLASH_SIZE }>>, NoopRawMutex>,
pub async fn get_config(
db: &Database<DbFlash<Flash<'_, FLASH, Blocking, { flash::FLASH_SIZE }>>, NoopRawMutex>,
) -> HardwareConfig {
let mut pin_functions: FnvIndexMap<BCMPinNumber, PinFunction, 32> = FnvIndexMap::new();
let mut buf: [u8; 1024] = [0; 1024];
Expand All @@ -56,8 +56,8 @@ pub async fn get_config<'p>(
HardwareConfig { pin_functions }
}

pub async fn store_config_change<'p>(
db: &Database<DbFlash<Flash<'p, FLASH, Blocking, { flash::FLASH_SIZE }>>, NoopRawMutex>,
pub async fn store_config_change(
db: &Database<DbFlash<Flash<'_, FLASH, Blocking, { flash::FLASH_SIZE }>>, NoopRawMutex>,
hardware_config_message: &HardwareConfigMessage,
) -> Result<(), &'static str> {
let mut buf: [u8; 1024] = [0; 1024];
Expand Down Expand Up @@ -130,8 +130,8 @@ pub async fn get_ssid_spec<'a>(
#[allow(dead_code)] // Not used in porky
#[cfg(feature = "wifi")]
/// Write the [SsidSpec] to the flash database
pub async fn store_ssid_spec<'p>(
db: &Database<DbFlash<Flash<'p, FLASH, Blocking, { flash::FLASH_SIZE }>>, NoopRawMutex>,
pub async fn store_ssid_spec(
db: &Database<DbFlash<Flash<'_, FLASH, Blocking, { flash::FLASH_SIZE }>>, NoopRawMutex>,
ssid_spec: SsidSpec,
) -> Result<(), &'static str> {
let mut buf: [u8; 1024] = [0; 1024];
Expand All @@ -147,8 +147,8 @@ pub async fn store_ssid_spec<'p>(
#[allow(dead_code)] // Not used in porky
#[cfg(feature = "wifi")]
/// Delete the [SsidSpec] from the flash database
pub async fn delete_ssid_spec<'p>(
db: &Database<DbFlash<Flash<'p, FLASH, Blocking, { flash::FLASH_SIZE }>>, NoopRawMutex>,
pub async fn delete_ssid_spec(
db: &Database<DbFlash<Flash<'_, FLASH, Blocking, { flash::FLASH_SIZE }>>, NoopRawMutex>,
) -> Result<(), &'static str> {
let mut wtx = db.write_transaction().await;
wtx.delete(SSID_SPEC_KEY)
Expand Down
10 changes: 10 additions & 0 deletions porky/src/porky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use embassy_executor::Spawner;
#[cfg(all(feature = "usb", feature = "wifi"))]
use embassy_futures::select::{select, Either};
use embassy_rp::bind_interrupts;
#[cfg(feature = "pico2")]
use embassy_rp::block::ImageDef;
use embassy_rp::flash::{Blocking, Flash};
#[cfg(feature = "wifi")]
use embassy_rp::gpio::{Level, Output};
Expand Down Expand Up @@ -80,6 +82,11 @@ mod mdns;
/// The Pi Pico GPIO [PinDefinition]s that get passed to the GUI
mod pin_descriptions;

#[cfg(feature = "pico2")]
#[link_section = ".start_block"]
#[used]
pub static IMAGE_DEF: ImageDef = ImageDef::secure_exe();

#[cfg(feature = "usb")]
bind_interrupts!(struct Irqs {
PIO0_IRQ_0 => PioInterruptHandler<PIO0>;
Expand Down Expand Up @@ -241,6 +248,8 @@ async fn main(spawner: Spawner) {
// create hardware description
#[allow(unused_mut)]
let mut flash = flash::get_flash(peripherals.FLASH);
#[cfg(feature = "pico2")] // pico2 needs a delay
embassy_time::Timer::after_millis(10).await;
#[cfg(feature = "pico1")]
let serial_number = flash::serial_number(&mut flash);
#[cfg(feature = "pico2")]
Expand All @@ -256,6 +265,7 @@ async fn main(spawner: Spawner) {
Database<DbFlash<Flash<'static, FLASH, Blocking, { flash::FLASH_SIZE }>>, NoopRawMutex>,
> = StaticCell::new();
let db = DATABASE.init(flash::db_init(flash).await);
// TODO log flash/db error here

#[cfg(feature = "wifi")]
static STATIC_BUF: StaticCell<[u8; 200]> = StaticCell::new();
Expand Down
2 changes: 1 addition & 1 deletion porky/src/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub async fn wait_connection<'a>(
accept(tcp_socket).await
}

pub async fn message_loop<'a>(
pub async fn message_loop(
gpio: &mut Gpio,
mut socket: TcpSocket<'_>,
hw_desc: &HardwareDescription<'_>,
Expand Down
2 changes: 1 addition & 1 deletion porky/src/usb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ pub async fn wait_connection(
/// Enter a loop waiting for messages either via USB (from Piggui) or from the Hardware.
/// - When receive a message over USB from Piggui, apply to the hardware, save in Flash
/// - WHen receiving from hardware, send the message to Piggui over USB
pub async fn message_loop<'a>(
pub async fn message_loop(
gpio: &mut Gpio,
usb_connection: &mut UsbConnection<Endpoint<'static, USB, In>, Endpoint<'static, USB, Out>>,
hw_config: &mut HardwareConfig,
Expand Down

0 comments on commit 847349e

Please sign in to comment.