Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kjagiello committed Aug 29, 2022
0 parents commit 01ab85f
Show file tree
Hide file tree
Showing 25 changed files with 1,092 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/target
/Cargo.lock

examples/*/Cargo.lock
examples/*/target
13 changes: 13 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "hub75-pio"
version = "0.1.0"
edition = "2021"
description = "A HUB75 driver for RP2040. Utilizes PIO and DMA to achieve zero CPU overhead."
license = "MIT"

[dependencies]
pio-proc = "0.2.1"
pio = "0.2.0"

rp2040-hal = "0.6.0"
embedded-graphics = "0.7.1"
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2022 Krzysztof Jagiello

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# hub75-pio-rs

An **experimental** HUB75 driver for
[RP2040](https://www.raspberrypi.com/products/rp2040/). Utilizes Programmable
I/O (PIO) units in combination with DMA to achieve high refresh rates, true
color depth and zero CPU overhead without sacrificing quality.

https://user-images.githubusercontent.com/74944/187094663-2f52e020-ccb2-4103-b69b-af8ee2185dd0.mp4

## Features

- Supports LED matrices up to 64x32 pixels with 1:16 scanline
- High refresh rate (approx. 2100 Hz with 24 bit color depth on a 64x32
display)
- Does not utilize CPU for clocking out data to the display – all the work is
done by the PIOs and the DMA controller
- Uses binary color modulation
- Double buffered
- Implements [embedded-graphics](https://github.com/embedded-graphics/embedded-graphics) traits

## Requirements

The current implementation assumes that the following groups of data outputs
are assigned to consecutive pins on the RP2040:

- R1, G1, B1, R2, G2, B2
- ADDRA, ADDRB, ADDRC, ADDRD
22 changes: 22 additions & 0 deletions examples/nyan/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "probe-run --chip RP2040"

rustflags = [
"-C", "linker=flip-link",
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",

# Code-size optimizations.
# trap unreachable can save a lot of space, but requires nightly compiler.
# uncomment the next line if you wish to enable it
# "-Z", "trap-unreachable=no",
"-C", "inline-threshold=5",
"-C", "no-vectorize-loops",
]

[build]
target = "thumbv6m-none-eabi"

[env]
DEFMT_LOG = "debug"
73 changes: 73 additions & 0 deletions examples/nyan/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
[package]
edition = "2021"
name = "dashy"
version = "0.1.0"

[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
embedded-hal = { version = "0.2.5", features = ["unproven"] }
embedded-time = "0.12"

defmt = "0.3"
defmt-rtt = "0.3"
panic-probe = { version = "0.3", features = ["print-defmt"] }

rp-pico = "0.5.0"

embedded-graphics = "0.7.1"
tinyqoi = "0.1.0"

hub75-pio = { path = "../../" }

# cargo build/run
[profile.dev]
codegen-units = 1
debug = 2
debug-assertions = true
incremental = false
opt-level = 3
overflow-checks = true

# cargo build/run --release
[profile.release]
codegen-units = 1
debug = 2
debug-assertions = false
incremental = false
lto = 'fat'
opt-level = 3
overflow-checks = false

# do not optimize proc-macro crates = faster builds from scratch
[profile.dev.build-override]
codegen-units = 8
debug = false
debug-assertions = false
opt-level = 0
overflow-checks = false

[profile.release.build-override]
codegen-units = 8
debug = false
debug-assertions = false
opt-level = 0
overflow-checks = false

# cargo test
[profile.test]
codegen-units = 1
debug = 2
debug-assertions = true
incremental = false
opt-level = 3
overflow-checks = true

# cargo test --release
[profile.bench]
codegen-units = 1
debug = 2
debug-assertions = false
incremental = false
lto = 'fat'
opt-level = 3
39 changes: 39 additions & 0 deletions examples/nyan/Embed.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
[default.probe]
protocol = "Swd"
speed = 20000
# If you only have one probe cargo embed will pick automatically
# Otherwise: add your probe's VID/PID/serial to filter

## rust-dap
# usb_vid = "6666"
# usb_pid = "4444"
# serial = "test"


[default.flashing]
enabled = true

[default.reset]
enabled = true
halt_afterwards = false

[default.general]
chip = "RP2040"
log_level = "WARN"
# RP2040 does not support connect_under_reset
connect_under_reset = false

[default.rtt]
enabled = true
up_mode = "NoBlockSkip"
channels = [
{ up = 0, down = 0, name = "name", up_mode = "NoBlockSkip", format = "Defmt" },
]
timeout = 3000
show_timestamps = true
log_enabled = false
log_path = "./logs"

[default.gdb]
enabled = false
gdb_connection_string = "127.0.0.1:2345"
Binary file added examples/nyan/assets/01.qoi
Binary file not shown.
Binary file added examples/nyan/assets/02.qoi
Binary file not shown.
Binary file added examples/nyan/assets/03.qoi
Binary file not shown.
Binary file added examples/nyan/assets/04.qoi
Binary file not shown.
Binary file added examples/nyan/assets/05.qoi
Binary file not shown.
Binary file added examples/nyan/assets/06.qoi
Binary file not shown.
Binary file added examples/nyan/assets/07.qoi
Binary file not shown.
Binary file added examples/nyan/assets/08.qoi
Binary file not shown.
Binary file added examples/nyan/assets/09.qoi
Binary file not shown.
Binary file added examples/nyan/assets/10.qoi
Binary file not shown.
Binary file added examples/nyan/assets/11.qoi
Binary file not shown.
Binary file added examples/nyan/assets/12.qoi
Binary file not shown.
31 changes: 31 additions & 0 deletions examples/nyan/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//! 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");
}
36 changes: 36 additions & 0 deletions examples/nyan/debug_probes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Compatible CMSIS-DAP debug probes

## Raspberry Pi Pico

You can use a second Pico as your debugger.

- Download this file: https://github.com/majbthrd/DapperMime/releases/download/20210225/raspberry_pi_pico-DapperMime.uf2
- Boot the Pico in bootloader mode by holding the bootset button while plugging it in
- Open the drive RPI-RP2 when prompted
- Copy raspberry_pi_pico-DapperMime.uf2 from Downloads into RPI-RP2
- Connect the debug pins of your CMSIS-DAP Pico to the target one
- Connect GP2 on the Probe to SWCLK on the Target
- Connect GP3 on the Probe to SWDIO on the Target
- Connect a ground line from the CMSIS-DAP Probe to the Target too

## WeAct MiniF4
https://therealprof.github.io/blog/usb-c-pill-part1/

## HS-Probe
https://github.com/probe-rs/hs-probe

## ST-LINK v2 clone
It's getting harder to source these with stm32f103's as time goes on, so you might be better off choosing a stm32f103 dev board

Firmware: https://github.com/devanlai/dap42

## LPC-Link2
https://www.nxp.com/design/microcontrollers-developer-resources/lpc-link2:OM13054

## MCU-Link
https://www.nxp.com/part/MCU-LINK#/

## DAPLink
You can use DAPLink firmware with any of it's supported chips (LPC4322, LPC11U35, K20, K22, KL26). You'll need to use the 'develop' branch to use GCC to build it. You'll need to find a chip with the correct

Firmware source: https://github.com/ARMmbed/DAPLink/tree/develop
15 changes: 15 additions & 0 deletions examples/nyan/memory.x
Original file line number Diff line number Diff line change
@@ -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;
Loading

0 comments on commit 01ab85f

Please sign in to comment.