Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Architecture.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1,898 changes: 1,898 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

62 changes: 60 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,60 @@
[workspace]
members = ["firmware/lab01"]
[package]
name = "lab-2025-main"
version = "0.1.0"
edition = "2024"


[dependencies]
embassy-rp = { version = "0.3.0", git = "https://github.com/embassy-rs/embassy", rev = "2e7a2b6", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl", "rp235xa", "binary-info"] }

# Embedded HAL utilities
embassy-embedded-hal = { version = "0.3.0", git = "https://github.com/embassy-rs/embassy", rev = "2e7a2b6", features = ["defmt"] }

# Synchronization primitives and data structures with async support
embassy-sync = { version = "0.6.2", git = "https://github.com/embassy-rs/embassy", rev = "2e7a2b6", features = ["defmt"] }

# Async/await executor
embassy-executor = { version = "0.7.0", git = "https://github.com/embassy-rs/embassy", rev = "2e7a2b6", features = ["task-arena-size-98304", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }

# Utilities for working with futures, compatible with no_std and not using alloc
embassy-futures = { version = "0.1.0", git = "https://github.com/embassy-rs/embassy", rev = "2e7a2b6" }

# Timekeeping, delays and timeouts
embassy-time = { version = "0.4.0", git = "https://github.com/embassy-rs/embassy", rev = "2e7a2b6", features = ["defmt", "defmt-timestamp-uptime"] }

# Network stack
embassy-net = { version = "0.7.0", git = "https://github.com/embassy-rs/embassy", rev = "2e7a2b6", features = ["defmt", "tcp", "udp", "raw", "dhcpv4", "medium-ethernet", "dns"] }
embassy-net-wiznet = { version = "0.2.0", git = "https://github.com/embassy-rs/embassy", rev = "2e7a2b6", features = ["defmt"] }

# WiFi Chip
cyw43 = { version = "0.3.0", git = "https://github.com/embassy-rs/embassy", rev = "2e7a2b6", features = ["defmt", "firmware-logs"] }
cyw43-pio = { version = "0.3.0", git = "https://github.com/embassy-rs/embassy", rev = "2e7a2b6", features = ["defmt"] }

# Defmt support
defmt = "0.3"
defmt-rtt = "0.4"

# Low level access to Cortex-M processors
cortex-m-rt = "0.7.0"

# Panic handler that exits probe-run with an error code
panic-probe = { version = "0.3", features = ["print-defmt"] }
embedded-hal-async = "1.0.0"
embedded-graphics = "0.8.1"
display-interface-spi = "0.4.1"
ili9341 = {version = "0.6.0", features = ["graphics"] }
heapless = "0.8.0"
xpt2046 = { git = "https://github.com/nullstalgia/mff-hr-v1", package = "xpt2046" }
micromath = "2.1.0"
embedded-alloc = "0.6.0"
embedded-canvas = "0.3.1"
mlx9061x = { version = "0.3.0", features = ["defmt-03"] }
max3010x = "0.2.0"
mipidsi = "0.9.0"
embedded-hal = "1.0.0"


display-interface = "0.4.1"
ssd1306 = "0.8.4"
serde = { version = "1.0", default-features = false, features = ["derive"] }
serde-json-core = "0.6.0"
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
# MA Website

This is the website for the MA course delivered to ACS CC and FILS English.
[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/eG_xYHDU)
![Architecture](./Architecture.png)
35 changes: 35 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! This build script copies the `memory.x` file from the crate root into
//! a directory where the linker can always find it at build time.
//! For many projects this is optional, as the linker always searches the
//! project root directory -- wherever `Cargo.toml` is. However, if you
//! are using a workspace or have a more complicated build setup, this
//! build script becomes required. Additionally, by requesting that
//! Cargo re-run the build script whenever `memory.x` is changed,
//! updating `memory.x` ensures a rebuild of the application with the
//! new memory settings.

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=-Tdefmt.x");
}
Binary file added cyw43-firmware/43439A0.bin
Binary file not shown.
Binary file added cyw43-firmware/43439A0_btfw.bin
Binary file not shown.
Binary file added cyw43-firmware/43439A0_clm.bin
Binary file not shown.
49 changes: 49 additions & 0 deletions cyw43-firmware/LICENSE-permissive-binary-license-1.0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Permissive Binary License

Version 1.0, July 2019

Redistribution. Redistribution and use in binary form, without
modification, are permitted provided that the following conditions are
met:

1) Redistributions must reproduce the above copyright notice and the
following disclaimer in the documentation and/or other materials
provided with the distribution.

2) Unless to the extent explicitly permitted by law, no reverse
engineering, decompilation, or disassembly of this software is
permitted.

3) Redistribution as part of a software development kit must include the
accompanying file named �DEPENDENCIES� and any dependencies listed in
that file.

4) Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

Limited patent license. The copyright holders (and contributors) grant a
worldwide, non-exclusive, no-charge, royalty-free patent license to
make, have made, use, offer to sell, sell, import, and otherwise
transfer this software, where such license applies only to those patent
claims licensable by the copyright holders (and contributors) that are
necessarily infringed by this software. This patent license shall not
apply to any combinations that include this software. No hardware is
licensed hereunder.

If you institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the software
itself infringes your patent(s), then your rights granted under this
license shall terminate as of the date such litigation is filed.

DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS." ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6 changes: 6 additions & 0 deletions cyw43-firmware/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# WiFi + Bluetooth firmware blobs

Firmware obtained from https://github.com/georgerobotics/cyw43-driver/tree/main/firmware

Licensed under the [Infineon Permissive Binary License](./LICENSE-permissive-binary-license-1.0.txt)

117 changes: 117 additions & 0 deletions embassy-lab-utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// +---------------------------------------------------------------------------+
// | PM/MA lab embassy utilities |
// +---------------------------------------------------------------------------+

//! This crate contains functions and types that act as wrappers over embassy's
//! and embedded-hal more complex routines.

#![no_std]

use cyw43::{Control, NetDriver, PowerManagementMode};
use cyw43_pio::PioSpi;
use defmt::*;
use embassy_net::StackResources;
use embassy_rp::clocks::RoscRng;
use embassy_rp::{
gpio::Output,
peripherals::{DMA_CH2, PIO0},
};
use rand::RngCore as _;
use static_cell::StaticCell;

pub use cyw43;
pub use cyw43_pio;
pub use embassy_rp;

#[macro_export]
macro_rules! init_wifi {
($spawner_ref:expr, $p:expr) => {
async {
$crate::embassy_rp::bind_interrupts!(struct PioIrq {
PIO0_IRQ_0 => $crate::embassy_rp::pio::InterruptHandler<$crate::embassy_rp::peripherals::PIO0>;
});

// Move the function directly here
let pwr = $crate::embassy_rp::gpio::Output::new($p.PIN_23, $crate::embassy_rp::gpio::Level::Low);
let cs = $crate::embassy_rp::gpio::Output::new($p.PIN_25, $crate::embassy_rp::gpio::Level::High);
let mut pio = $crate::embassy_rp::pio::Pio::new($p.PIO0, PioIrq);

let spi = $crate::cyw43_pio::PioSpi::new(
&mut pio.common,
pio.sm0,
$crate::cyw43_pio::RM2_CLOCK_DIVIDER,
pio.irq0,
cs,
$p.PIN_24,
$p.PIN_29,
$p.DMA_CH2,
);

let (net_driver, mut ctrl) = $crate::init_cy43w(pwr, spi, $spawner_ref).await;
$crate::init_controller(&mut ctrl, $crate::cyw43::PowerManagementMode::None).await;
(net_driver, ctrl)
}
};
}

/// This task runs the wifi chip driver. This will need to run in an infinite loop.
#[embassy_executor::task]
async fn cyw43_task(
runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH2>>,
) -> ! {
runner.run().await
}

/// This task runs the network stack, used for processing network events.
#[embassy_executor::task]
async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! {
runner.run().await
}

/// Initialize the CYW43 Wifi chip driver and spawn the task that runs the driver.
///
/// Returns a handle to the network device, control handle and a runner for driving the low level
/// stack.
pub async fn init_cy43w(
pwr: Output<'static>,
spi: PioSpi<'static, PIO0, 0, DMA_CH2>,
spawner: &embassy_executor::Spawner,
) -> (NetDriver<'static>, Control<'static>) {
let fw = include_bytes!("../../cyw43-firmware/43439A0.bin");

static STATE: StaticCell<cyw43::State> = StaticCell::new();
let state = STATE.init(cyw43::State::new());
let (net_device, control, runner) = cyw43::new(state, pwr, spi, fw).await;
unwrap!(spawner.spawn(cyw43_task(runner)));

(net_device, control)
}

/// Initialize the WiFi controller with the given power management mode.
pub async fn init_controller(controller: &mut Control<'static>, mode: PowerManagementMode) {
let clm = include_bytes!("../../cyw43-firmware/43439A0_clm.bin");
controller.init(clm).await;
controller.set_power_management(mode).await;
}

/// Initialize the network stack.
pub fn init_network_stack<const SOCK: usize>(
spawner: &embassy_executor::Spawner,
net_device: NetDriver<'static>,
resources: &'static StaticCell<StackResources<SOCK>>,
config: embassy_net::Config,
) -> embassy_net::Stack<'static> {
// Generate random seed
let seed = RoscRng.next_u64();

let (stack, runner) = embassy_net::new(
net_device,
config,
resources.init(StackResources::new()),
seed,
);

unwrap!(spawner.spawn(net_task(runner)));

stack
}
75 changes: 75 additions & 0 deletions memory.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
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
}

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);
Loading