13 changed files with 64 additions and 950 deletions
Generated
-168
View File
@@ -229,16 +229,6 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "ch1115"
version = "0.1.2"
source = "git+https://github.com/ede1998/ch1115.git?rev=2d3a3ba38050efe012e6a210afe3e125ec280c37#2d3a3ba38050efe012e6a210afe3e125ec280c37"
dependencies = [
"display-interface",
"embedded-graphics-core",
"embedded-hal 1.0.0",
]
[[package]] [[package]]
name = "cobs" name = "cobs"
version = "0.3.0" version = "0.3.0"
@@ -313,7 +303,6 @@ name = "creaturedex"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.22.1",
"ch1115",
"critical-section", "critical-section",
"display-interface-spi", "display-interface-spi",
"embassy-executor", "embassy-executor",
@@ -322,7 +311,6 @@ dependencies = [
"embedded-graphics-core", "embedded-graphics-core",
"embedded-hal 1.0.0", "embedded-hal 1.0.0",
"embedded-hal-bus", "embedded-hal-bus",
"embedded-hal-compat",
"embedded-io 0.7.1", "embedded-io 0.7.1",
"esp-alloc", "esp-alloc",
"esp-bootloader-esp-idf", "esp-bootloader-esp-idf",
@@ -332,10 +320,6 @@ dependencies = [
"esp-rtos", "esp-rtos",
"ili9341", "ili9341",
"log", "log",
"ndef",
"pn532",
"sh1106",
"ssd1306",
] ]
[[package]] [[package]]
@@ -584,26 +568,6 @@ dependencies = [
"syn 2.0.119", "syn 2.0.119",
] ]
[[package]]
name = "derive_more"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05"
dependencies = [
"derive_more-impl",
]
[[package]]
name = "derive_more-impl"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.119",
]
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.10.7" version = "0.10.7"
@@ -620,17 +584,6 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ba2aab1ef3793e6f7804162debb5ac5edb93b3d650fbcc5aeb72fcd0e6c03a0" checksum = "7ba2aab1ef3793e6f7804162debb5ac5edb93b3d650fbcc5aeb72fcd0e6c03a0"
[[package]]
name = "display-interface-i2c"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d964fa85bbbb5a6ecd06e58699407ac5dc3e3ad72dac0ab7e6b0d00a1cd262d"
dependencies = [
"display-interface",
"embedded-hal 1.0.0",
"embedded-hal-async",
]
[[package]] [[package]]
name = "display-interface-spi" name = "display-interface-spi"
version = "0.5.0" version = "0.5.0"
@@ -970,17 +923,6 @@ dependencies = [
"embedded-hal 1.0.0", "embedded-hal 1.0.0",
] ]
[[package]]
name = "embedded-hal-compat"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08ecac72f6be75ad2d4809c9f07d45502e2e5c9a4e9579077f28d7135de81df3"
dependencies = [
"embedded-hal 0.2.7",
"embedded-hal 1.0.0",
"nb 1.1.0",
]
[[package]] [[package]]
name = "embedded-io" name = "embedded-io"
version = "0.4.0" version = "0.4.0"
@@ -1952,30 +1894,6 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
[[package]]
name = "manyhow"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587"
dependencies = [
"manyhow-macros",
"proc-macro2",
"quote",
"syn 1.0.109",
"syn 2.0.119",
]
[[package]]
name = "manyhow-macros"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495"
dependencies = [
"proc-macro-utils",
"proc-macro2",
"quote",
]
[[package]] [[package]]
name = "matchers" name = "matchers"
version = "0.2.0" version = "0.2.0"
@@ -1991,19 +1909,6 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
[[package]]
name = "maybe-async-cfg"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8dbfaa67a76e2623580df07d6bb5e7956c0a4bae4b418314083a9c619bd66627"
dependencies = [
"manyhow",
"proc-macro2",
"pulldown-cmark",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.8.3" version = "2.8.3"
@@ -2075,17 +1980,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
[[package]]
name = "ndef"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39081400340c14a9fcbb0122c311aca4e34ec2d19e3136613638ae7e2a362dbc"
dependencies = [
"derive_more",
"heapless 0.8.0",
"rustversion",
]
[[package]] [[package]]
name = "nonmax" name = "nonmax"
version = "0.5.5" version = "0.5.5"
@@ -2690,16 +2584,6 @@ version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
name = "pn532"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce656b2f9335bedbd8806597f6f78e644a955366673cd9280a0fb67a0d7b35a1"
dependencies = [
"embedded-hal 1.0.0",
"nb 1.1.0",
]
[[package]] [[package]]
name = "portable-atomic" name = "portable-atomic"
version = "1.14.0" version = "1.14.0"
@@ -2763,17 +2647,6 @@ dependencies = [
"toml_edit", "toml_edit",
] ]
[[package]]
name = "proc-macro-utils"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071"
dependencies = [
"proc-macro2",
"quote",
"smallvec",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.107" version = "1.0.107"
@@ -2803,17 +2676,6 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "pulldown-cmark"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625"
dependencies = [
"bitflags 2.13.1",
"memchr",
"unicase",
]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.47" version = "1.0.47"
@@ -3140,16 +3002,6 @@ dependencies = [
"unsafe-libyaml", "unsafe-libyaml",
] ]
[[package]]
name = "sh1106"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc12a0563ec9b3b1f99b1f64613581ebbade1347416a34766564f406c15d1bf3"
dependencies = [
"embedded-graphics-core",
"embedded-hal 0.2.7",
]
[[package]] [[package]]
name = "sharded-slab" name = "sharded-slab"
version = "0.1.7" version = "0.1.7"
@@ -3238,20 +3090,6 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0f368519fc6c85fc1afdb769fb5a51123f6158013e143656e25a3485a0d401c" checksum = "a0f368519fc6c85fc1afdb769fb5a51123f6158013e143656e25a3485a0d401c"
[[package]]
name = "ssd1306"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ed51935bdc6e9e976d3d9a747e768589eaea0cf26f483213bfededc947c8624"
dependencies = [
"display-interface",
"display-interface-i2c",
"display-interface-spi",
"embedded-graphics-core",
"embedded-hal 1.0.0",
"maybe-async-cfg",
]
[[package]] [[package]]
name = "stable_deref_trait" name = "stable_deref_trait"
version = "1.2.1" version = "1.2.1"
@@ -3519,12 +3357,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69" checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69"
[[package]]
name = "unicase"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
[[package]] [[package]]
name = "unicode-id-start" name = "unicode-id-start"
version = "1.4.0" version = "1.4.0"
-9
View File
@@ -34,22 +34,13 @@ esp-hal-wifimanager = { git = "https://github.com/InvisibleUSA/esp-hal-wifimanag
esp-println = { version = "0.17.0", features = ["esp32s3", "log-04"] } esp-println = { version = "0.17.0", features = ["esp32s3", "log-04"] }
display-interface-spi = "0.5.0" display-interface-spi = "0.5.0"
ili9341 = "0.6.0" ili9341 = "0.6.0"
ssd1306 = "0.9.0"
embedded-hal = "1.0.0" embedded-hal = "1.0.0"
embedded-hal-bus = "0.3.0" embedded-hal-bus = "0.3.0"
embedded-graphics = "0.8.2" embedded-graphics = "0.8.2"
embedded-graphics-core = "0.4.1" embedded-graphics-core = "0.4.1"
base64 = { version = "0.22", default-features = false, features = ["alloc"] } base64 = { version = "0.22", default-features = false, features = ["alloc"] }
pn532 = "0.5.0"
ndef = "0.5.0"
ch1115 = { version = "0.1.2", features = ["graphics"] }
sh1106 = "0.5.0"
embedded-hal-compat = "0.13.0"
[patch.crates-io]
ch1115 = { git = "https://github.com/ede1998/ch1115.git", rev = "2d3a3ba38050efe012e6a210afe3e125ec280c37" }
# For fine tuning these settings, please refer to https://doc.rust-lang.org/cargo/reference/profiles.html # For fine tuning these settings, please refer to https://doc.rust-lang.org/cargo/reference/profiles.html
[profile.dev] [profile.dev]
# The default debug profile is too slow and too big for resource-constrained devices. # The default debug profile is too slow and too big for resource-constrained devices.
+2
View File
@@ -30,6 +30,8 @@
[ "lcd1:MOSI", "esp1:35", "violet", [ "v105.6", "h-124.8", "v-144" ] ], [ "lcd1:MOSI", "esp1:35", "violet", [ "v105.6", "h-124.8", "v-144" ] ],
[ "lcd1:SCK", "esp1:36", "white", [ "v115.2", "h-144", "v-86.4" ] ], [ "lcd1:SCK", "esp1:36", "white", [ "v115.2", "h-144", "v-86.4" ] ],
[ "esp1:37", "lcd1:MISO", "magenta", [ "h57.6", "v105.6", "h172.8" ] ], [ "esp1:37", "lcd1:MISO", "magenta", [ "h57.6", "v105.6", "h172.8" ] ],
[ "esp1:22", "lcd1:SCL", "yellow", [ "h48", "v163.2", "h192" ] ],
[ "esp1:21", "lcd1:SDA", "cyan", [ "h38.4", "v144", "h211.2" ] ],
[ "btn1:1.l", "esp1:GND.2", "green", [ "h-9.6", "v-48" ] ], [ "btn1:1.l", "esp1:GND.2", "green", [ "h-9.6", "v-48" ] ],
[ "btn1:2.l", "esp1:38", "green", [ "h-9.6", "v19.4" ] ] [ "btn1:2.l", "esp1:38", "green", [ "h-9.6", "v19.4" ] ]
], ],
-57
View File
@@ -1,57 +0,0 @@
{
pkgs ? import <nixpkgs> { },
}:
let
host-triple = "x86_64-unknown-linux-gnu";
gcc-arch = "xtensa-esp-elf";
gcc-release = "16.1.0_20260609";
toolchain-pkg = pkgs.stdenv.mkDerivation rec {
pname = "esp32-xtensa-rust-toolchain";
version = "1.97.0.0";
srcs = [
(pkgs.fetchurl {
url = "https://github.com/esp-rs/rust-build/releases/download/v${version}/rust-${version}-${host-triple}.tar.xz";
hash = "sha256-qZv+5pIh6f9thjiPaBHuaIzUBeagQAo80XhOjUY+nZk=";
})
(pkgs.fetchurl {
url =
let
gcc-file = "${gcc-arch}-${gcc-release}-x86_64-linux-gnu.tar.xz";
in
"https://github.com/espressif/crosstool-NG/releases/download/esp-${gcc-release}/${gcc-file}";
hash = "sha256-9wh1Lrs1yrIfGEsldBFO0Rh2GdsO24pLqRPAbKL6Z14=";
})
(pkgs.fetchurl {
url = "https://github.com/esp-rs/rust-build/releases/download/v${version}/rust-src-${version}.tar.xz";
hash = "sha256-Vo1oi5+PMy7E0EZXVE+tI+mc4R6ebPWDWXnmiijGi3M=";
})
# TODO maybe I need clang but so far it works without https://github.com/esp-rs/espup/blob/main/src/toolchain/llvm.rs
];
sourceRoot = ".";
nativeBuildInputs = [ pkgs.autoPatchelfHook ];
buildInputs = [
pkgs.zlib
pkgs.stdenv.cc.cc.lib
];
installPhase = ''
runHook preInstall
patchShebangs --build rust-nightly-x86_64-unknown-linux-gnu/install.sh rust-src-nightly/install.sh
rust-nightly-x86_64-unknown-linux-gnu/install.sh --destdir="$out" --prefix="" --without=rust-docs-json-preview,rust-docs --disable-ldconfig
rust-src-nightly/install.sh --destdir="$out" --prefix="" --disable-ldconfig
cp -pr --reflink=auto -- xtensa-esp-elf "$out";
# ensure linker is in PATH
ln -s $out/xtensa-esp-elf/bin/* "$out/bin/"
runHook postInstall
'';
};
in
(pkgs.mkShell {
packages = with pkgs; [
espflash
toolchain-pkg
];
})
-106
View File
@@ -1,106 +0,0 @@
#![no_std]
#![no_main]
#![deny(
clippy::mem_forget,
reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
holding buffers for the duration of a data transfer."
)]
use ch1115::Ch1115;
use core::cell::RefCell;
use creaturedex::display::shared_bus::SharedPin;
use embassy_executor::Spawner;
use embassy_time::Timer;
use embedded_graphics::pixelcolor::BinaryColor;
use embedded_graphics::{
mono_font::{MonoTextStyle, ascii::FONT_6X10},
prelude::*,
text::Text,
};
use esp_hal::clock::CpuClock;
use esp_hal::delay::Delay;
use esp_hal::gpio::{Level, Output, OutputConfig};
use esp_hal::spi::Mode;
use esp_hal::spi::master::{Config as SpiConfig, Spi};
use esp_hal::time::Rate;
use esp_hal::timer::timg::TimerGroup;
use log::error;
#[panic_handler]
fn panic(panic_info: &core::panic::PanicInfo) -> ! {
error!("{}", panic_info);
loop {}
}
extern crate alloc;
esp_bootloader_esp_idf::esp_app_desc!();
#[esp_rtos::main]
async fn main(_spawner: Spawner) {
esp_println::logger::init_logger_from_env();
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
// The following GPIO pins are in use by some feature of the module and should not be used.
let _ = peripherals.GPIO27;
let _ = peripherals.GPIO28;
let _ = peripherals.GPIO29;
let _ = peripherals.GPIO30;
let _ = peripherals.GPIO31;
let _ = peripherals.GPIO32;
let _ = peripherals.GPIO33;
let _ = peripherals.GPIO34;
esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 73744);
let mut delay = Delay::new();
let timg0 = TimerGroup::new(peripherals.TIMG0);
let sw_interrupt =
esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);
let spi = peripherals.SPI2;
let sck = peripherals.GPIO36;
let mosi = peripherals.GPIO35;
let cs = peripherals.GPIO13;
let reset = peripherals.GPIO10;
let dc = peripherals.GPIO12;
let miso = peripherals.GPIO37;
let cs = Output::new(cs, Level::High, OutputConfig::default());
let dc = Output::new(dc, Level::Low, OutputConfig::default());
let reset = Output::new(reset, Level::High, OutputConfig::default());
let spi = Spi::new(
spi,
SpiConfig::default()
.with_frequency(Rate::from_khz(5000))
.with_mode(Mode::_0),
)
.unwrap()
.with_sck(sck)
.with_mosi(mosi)
.with_miso(miso);
let spi = RefCell::new(spi);
let spi_dev = embedded_hal_bus::spi::RefCellDevice::new(&spi, cs, delay).unwrap();
let interface = display_interface_spi::SPIInterface::new(spi_dev, dc);
let mut display = Ch1115::new(interface, reset, ch1115::Size128x64);
display.init(&mut delay).unwrap();
loop {
log::info!("Init finished");
let text_style = MonoTextStyle::new(&FONT_6X10, BinaryColor::On);
Text::new("Hello OLED", Point::new(10, 20), text_style)
.draw(&mut display)
.unwrap();
display.flush().unwrap();
Timer::after_millis(1000).await;
}
}
-121
View File
@@ -1,121 +0,0 @@
#![no_std]
#![no_main]
#![deny(
clippy::mem_forget,
reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
holding buffers for the duration of a data transfer."
)]
use embassy_executor::Spawner;
use embassy_time::Timer;
use embedded_graphics::pixelcolor::BinaryColor;
use embedded_graphics::{
mono_font::{MonoTextStyle, ascii::FONT_6X10},
prelude::*,
text::Text,
};
use embedded_hal_compat::ReverseCompat;
use esp_hal::clock::CpuClock;
use esp_hal::delay::Delay;
use esp_hal::gpio::{Level, Output, OutputConfig};
use esp_hal::spi::Mode;
use esp_hal::spi::master::{Config as SpiConfig, Spi};
use esp_hal::time::Rate;
use esp_hal::timer::timg::TimerGroup;
use log::error;
#[panic_handler]
fn panic(panic_info: &core::panic::PanicInfo) -> ! {
error!("{}", panic_info);
loop {}
}
extern crate alloc;
esp_bootloader_esp_idf::esp_app_desc!();
// This creates a defaembedded_hal_compatedReverseCompat::reverse(Output::new(cs,Level::High,OutputConfig::default()))vel::High,OutputConfig::default())) more information see: embedded_hal_compat::ForwardCompat::forward(Spi::new(spi,SpiConfig::default().with_frequency(Rate::from_khz(100)).with_mode(Mode::_0),).unwrap().with_sck(sck).with_mosi(mosi))rward(Spi::new(spi,SpiConfig::default().with_frequency(Rate::from_khz(100)).with_mode(Mode::_0),).unwrap().with_sck(sck).with_mosi(mosi)) to allocate larger buffers etc. in main"
#[esp_rtos::main]
async fn main(_spawner: Spawner) {
esp_println::logger::init_logger_from_env();
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
// The following GPIO pins are in use by some feature of the module and should not be used.
let _ = peripherals.GPIO27;
let _ = peripherals.GPIO28;
let _ = peripherals.GPIO29;
let _ = peripherals.GPIO30;
let _ = peripherals.GPIO31;
let _ = peripherals.GPIO32;
let _ = peripherals.GPIO33;
let _ = peripherals.GPIO34;
esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 73744);
let delay = Delay::new();
let timg0 = TimerGroup::new(peripherals.TIMG0);
let sw_interrupt =
esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);
let spi = peripherals.SPI2;
let sck = peripherals.GPIO36;
let mosi = peripherals.GPIO35;
let cs = peripherals.GPIO13;
let reset = peripherals.GPIO10;
let dc = peripherals.GPIO12;
let miso = peripherals.GPIO37;
let cs = Output::new(cs, Level::High, OutputConfig::default()).reverse_cell();
let dc = Output::new(dc, Level::Low, OutputConfig::default()).reverse_cell();
let mut reset = Output::new(reset, Level::High, OutputConfig::default());
let spi = Spi::new(
spi,
SpiConfig::default()
.with_frequency(Rate::from_khz(5000))
.with_mode(Mode::_0),
)
.unwrap()
.with_sck(sck)
.with_mosi(mosi)
.with_miso(miso)
.reverse();
let mut display: sh1106::mode::GraphicsMode<_> =
sh1106::Builder::new().connect_spi(spi, dc, cs).into();
display.init().unwrap();
// Hard reset the OLED
reset.set_high();
delay.delay_millis(1);
reset.set_low();
delay.delay_millis(10);
reset.set_high();
display.flush().unwrap();
display.set_pixel(10, 20, 1);
display.flush().unwrap();
let mut oled = display;
oled.clear();
let text_style = MonoTextStyle::new(&FONT_6X10, BinaryColor::On);
Text::new("Hello OLED", Point::new(10, 20), text_style)
.draw(&mut oled)
.unwrap();
oled.flush().unwrap();
loop {
log::info!("Init finished");
Timer::after_millis(1000).await;
}
}
-122
View File
@@ -1,122 +0,0 @@
#![no_std]
#![no_main]
#![deny(
clippy::mem_forget,
reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
holding buffers for the duration of a data transfer."
)]
#![deny(clippy::large_stack_frames)]
use embassy_executor::Spawner;
use embassy_time::Timer;
use embedded_graphics::draw_target::DrawTarget;
use embedded_graphics::pixelcolor::BinaryColor;
use embedded_graphics::text::Text;
use embedded_graphics::{
mono_font::{MonoTextStyle, ascii::FONT_6X10},
prelude::*,
};
use core::cell::RefCell;
use esp_hal::clock::CpuClock;
use esp_hal::delay::Delay;
use esp_hal::gpio::{Level, Output, OutputConfig};
use esp_hal::spi::Mode;
use esp_hal::spi::master::{Config as SpiConfig, Spi};
use esp_hal::time::Rate;
use esp_hal::timer::timg::TimerGroup;
use log::error;
use ssd1306::Ssd1306;
use ssd1306::mode::DisplayConfig;
use ssd1306::rotation::DisplayRotation;
use ssd1306::size::DisplaySize128x64;
#[panic_handler]
fn panic(panic_info: &core::panic::PanicInfo) -> ! {
error!("{}", panic_info);
loop {}
}
extern crate alloc;
esp_bootloader_esp_idf::esp_app_desc!();
// This creates a defaembedded_hal_compatedReverseCompat::reverse(Output::new(cs,Level::High,OutputConfig::default()))vel::High,OutputConfig::default())) more information see: embedded_hal_compat::ForwardCompat::forward(Spi::new(spi,SpiConfig::default().with_frequency(Rate::from_khz(100)).with_mode(Mode::_0),).unwrap().with_sck(sck).with_mosi(mosi))rward(Spi::new(spi,SpiConfig::default().with_frequency(Rate::from_khz(100)).with_mode(Mode::_0),).unwrap().with_sck(sck).with_mosi(mosi)) to allocate larger buffers etc. in main"
#[esp_rtos::main]
async fn main(_spawner: Spawner) {
esp_println::logger::init_logger_from_env();
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
// The following GPIO pins are in use by some feature of the module and should not be used.
let _ = peripherals.GPIO27;
let _ = peripherals.GPIO28;
let _ = peripherals.GPIO29;
let _ = peripherals.GPIO30;
let _ = peripherals.GPIO31;
let _ = peripherals.GPIO32;
let _ = peripherals.GPIO33;
let _ = peripherals.GPIO34;
esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 73744);
let mut delay = Delay::new();
let timg0 = TimerGroup::new(peripherals.TIMG0);
let sw_interrupt =
esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);
let spi = peripherals.SPI2;
let sck = peripherals.GPIO36;
let mosi = peripherals.GPIO35;
let cs = peripherals.GPIO13;
let reset = peripherals.GPIO10;
let dc = peripherals.GPIO12;
let miso = peripherals.GPIO37;
let cs = Output::new(cs, Level::High, OutputConfig::default());
let dc = Output::new(dc, Level::Low, OutputConfig::default());
let mut reset = Output::new(reset, Level::High, OutputConfig::default());
let spi = Spi::new(
spi,
SpiConfig::default()
.with_frequency(Rate::from_khz(5000))
.with_mode(Mode::_0),
)
.unwrap()
.with_sck(sck)
.with_mosi(mosi)
.with_miso(miso);
let spi = RefCell::new(spi);
let spi_dev = embedded_hal_bus::spi::RefCellDevice::new(&spi, cs, delay).unwrap();
let interface = display_interface_spi::SPIInterface::new(spi_dev, dc);
let mut display = Ssd1306::new(
interface,
DisplaySize128x64,
DisplayRotation::Rotate0,
)
.into_buffered_graphics_mode();
display.reset(&mut reset, &mut delay).unwrap();
display.init().unwrap();
display.clear(BinaryColor::Off).unwrap();
let mut oled = display;
let text_style = MonoTextStyle::new(&FONT_6X10, BinaryColor::On);
Text::new("Hello OLED", Point::new(10, 20), text_style)
.draw(&mut oled)
.unwrap();
oled.flush().unwrap();
loop {
log::info!("Init finished");
Timer::after_millis(1000).await;
}
}
+23 -40
View File
@@ -8,26 +8,18 @@
#![deny(clippy::large_stack_frames)] #![deny(clippy::large_stack_frames)]
use creaturedex::card::mock::{MOCK_PAYLOAD, MOCK_PAYLOAD2}; use creaturedex::card::mock::{MOCK_PAYLOAD, MOCK_PAYLOAD2};
use creaturedex::display::shared_bus::init_dual_displays; use creaturedex::display::primary_lcd::init_primary_lcd;
use creaturedex::display::views::card_view::render_nfc_payload; use creaturedex::display::views::card_view::render_nfc_payload;
use creaturedex::drivers::nfc_pn532::NfcPn532Driver;
use creaturedex::navigation::input::init_navigation_button; use creaturedex::navigation::input::init_navigation_button;
use creaturedex::navigation::state::NavigationState; use creaturedex::navigation::state::NavigationState;
use creaturedex::network::wifi::setup_wifi; use creaturedex::network::wifi::setup_wifi;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_time::Timer; use embassy_time::Timer;
use embedded_graphics::draw_target::DrawTarget; use embedded_graphics::draw_target::DrawTarget;
use embedded_graphics::pixelcolor::{BinaryColor, Rgb565}; use embedded_graphics::pixelcolor::Rgb565;
use embedded_graphics::prelude::RgbColor; use embedded_graphics::prelude::RgbColor;
use embedded_graphics::{
mono_font::{MonoTextStyle, ascii::FONT_6X10},
prelude::*,
text::Text,
};
use esp_hal::clock::CpuClock; use esp_hal::clock::CpuClock;
use esp_hal::delay::Delay; use esp_hal::delay::Delay;
use esp_hal::time::Duration;
use esp_hal::timer::timg::TimerGroup; use esp_hal::timer::timg::TimerGroup;
use log::error; use log::error;
@@ -74,44 +66,35 @@ async fn main(spawner: Spawner) {
esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0); esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);
let (mut display, mut oled) = init_dual_displays( let mut display = init_primary_lcd(
peripherals.SPI2, peripherals.SPI2,
peripherals.GPIO36, // sck peripherals.GPIO36,
peripherals.GPIO35, // mosi peripherals.GPIO35,
peripherals.GPIO37, // miso peripherals.GPIO37,
peripherals.GPIO11, // primary cs peripherals.GPIO11,
peripherals.GPIO13, // oled cs peripherals.GPIO10,
peripherals.GPIO10, // shared reset peripherals.GPIO12,
peripherals.GPIO12, // shared dc
&mut delay, &mut delay,
); );
setup_wifi(peripherals.WIFI, peripherals.FLASH, &spawner).await; // setup_wifi(peripherals.WIFI, peripherals.FLASH, &spawner).await;
log::info!("Setup complete, entering main loop");
let mut nav_state = NavigationState::new(); let mut nav_state = NavigationState::new();
oled.clear(BinaryColor::Off).unwrap();
let text_style = MonoTextStyle::new(&FONT_6X10, BinaryColor::On);
Text::new("Hello OLED", Point::new(10, 20), text_style)
.draw(&mut oled)
.unwrap();
oled.flush().unwrap();
let text_style = MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE);
display.clear_screen(0).unwrap();
Text::new("Hello OLED", Point::new(10, 20), text_style).draw(&mut display).unwrap();
let mut nfc_driver =
NfcPn532Driver::new(peripherals.I2C0, peripherals.GPIO17, peripherals.GPIO18);
let timeout = Duration::from_millis(1000);
if nfc_driver.configure_sam(timeout).is_ok() {
log::info!("NFC SAM configuration successful");
} else {
log::error!("NFC SAM configuration failed");
}
loop { loop {
if button1.is_low() {
log::info!("Button pressed!");
display.clear(Rgb565::BLACK).unwrap();
let payload = if nav_state.toggle_payload() {
&MOCK_PAYLOAD
} else {
&MOCK_PAYLOAD2
};
render_nfc_payload(&mut display, payload);
}
Timer::after_millis(10).await; Timer::after_millis(10).await;
} }
} }
-2
View File
@@ -1,8 +1,6 @@
pub mod palette; pub mod palette;
pub mod primary_lcd; pub mod primary_lcd;
pub mod secondary_oled; pub mod secondary_oled;
pub mod shared_bus;
pub mod sprite; pub mod sprite;
pub mod tertiary_lcd; pub mod tertiary_lcd;
pub mod views; pub mod views;
+36 -26
View File
@@ -1,42 +1,54 @@
use core::cell::RefCell;
use display_interface_spi::SPIInterface; use display_interface_spi::SPIInterface;
use embedded_graphics::draw_target::DrawTarget; use embedded_graphics::draw_target::DrawTarget;
use embedded_graphics::pixelcolor::Rgb565; use embedded_graphics::pixelcolor::Rgb565;
use embedded_graphics::prelude::RgbColor; use embedded_graphics::prelude::RgbColor;
use embedded_hal::digital::OutputPin as EhOutputPin; use embedded_hal_bus::spi::ExclusiveDevice;
use embedded_hal_bus::spi::RefCellDevice;
use esp_hal::delay::Delay; use esp_hal::delay::Delay;
use esp_hal::gpio::{Level, Output, OutputConfig, OutputPin}; use esp_hal::gpio::{Level, Output, OutputConfig};
use esp_hal::peripherals::{GPIO10, GPIO11, GPIO12, GPIO35, GPIO36, GPIO37, SPI2};
use esp_hal::spi::{master::{Config, Spi}, Mode};
use esp_hal::time::Rate;
use ili9341::{DisplaySize240x320, Ili9341, Orientation}; use ili9341::{DisplaySize240x320, Ili9341, Orientation};
pub type PrimaryLcdDisplay<'a, BUS, DC, RES> = Ili9341< pub type PrimaryLcdDisplay<'a> = Ili9341<
SPIInterface< SPIInterface<
RefCellDevice<'a, BUS, Output<'a>, Delay>, ExclusiveDevice<Spi<'a, esp_hal::Blocking>, Output<'a>, Delay>,
DC, Output<'a>,
>, >,
RES, Output<'a>,
>; >;
pub fn init_primary_lcd_on_bus<'a, BUS, CS, RES, DC>( pub fn init_primary_lcd(
spi_bus: &'a RefCell<BUS>, spi2: SPI2<'static>,
cs: CS, sck: GPIO36<'static>,
reset: RES, mosi: GPIO35<'static>,
dc: DC, miso: GPIO37<'static>,
cs: GPIO11<'static>,
reset: GPIO10<'static>,
dc: GPIO12<'static>,
delay: &mut Delay, delay: &mut Delay,
) -> PrimaryLcdDisplay<'a, BUS, DC, RES> ) -> PrimaryLcdDisplay<'static> {
where let freq = Rate::from_khz(60_000);
BUS: embedded_hal::spi::SpiBus, log::info!("Display freq: {freq}");
CS: OutputPin + 'static,
RES: EhOutputPin, let spi_bus = Spi::new(
DC: EhOutputPin, spi2,
{ Config::default().with_frequency(freq).with_mode(Mode::_0),
let cs_pin = Output::new(cs, Level::High, OutputConfig::default()); )
let spi_dev = RefCellDevice::new(spi_bus, cs_pin, *delay).unwrap(); .unwrap()
let iface = SPIInterface::new(spi_dev, dc); .with_sck(sck)
.with_mosi(mosi)
.with_miso(miso);
let cs_main = Output::new(cs, Level::High, OutputConfig::default());
let spi_dev = ExclusiveDevice::new(spi_bus, cs_main, *delay).unwrap();
let reset_main = Output::new(reset, Level::High, OutputConfig::default());
let spi_dc = Output::new(dc, Level::High, OutputConfig::default());
let iface = SPIInterface::new(spi_dev, spi_dc);
let mut display = Ili9341::new( let mut display = Ili9341::new(
iface, iface,
reset, reset_main,
delay, delay,
Orientation::Portrait, Orientation::Portrait,
DisplaySize240x320, DisplaySize240x320,
@@ -46,5 +58,3 @@ where
display.clear(Rgb565::BLACK).unwrap(); display.clear(Rgb565::BLACK).unwrap();
display display
} }
+1 -54
View File
@@ -1,54 +1 @@
use core::cell::RefCell; // Secondary OLED module
use display_interface_spi::SPIInterface;
use embedded_graphics::pixelcolor::BinaryColor;
use embedded_graphics::prelude::*;
use embedded_hal::digital::OutputPin as EhOutputPin;
use embedded_hal_bus::spi::RefCellDevice;
use esp_hal::delay::Delay;
use esp_hal::gpio::{Level, Output, OutputConfig, OutputPin};
use ssd1306::mode::BufferedGraphicsMode;
use ssd1306::prelude::*;
use ssd1306::Ssd1306;
pub type SecondaryOledDisplay<'a, BUS, DC> = Ssd1306<
SPIInterface<
RefCellDevice<'a, BUS, Output<'a>, Delay>,
DC,
>,
DisplaySize128x64,
BufferedGraphicsMode<DisplaySize128x64>,
>;
pub fn init_secondary_oled_on_bus<'a, BUS, CS, RES, DC>(
spi_bus: &'a RefCell<BUS>,
cs: CS,
mut res: RES,
dc: DC,
delay: &mut Delay,
) -> SecondaryOledDisplay<'a, BUS, DC>
where
BUS: embedded_hal::spi::SpiBus,
CS: OutputPin + 'static,
RES: EhOutputPin,
DC: EhOutputPin,
{
let cs_pin = Output::new(cs, Level::High, OutputConfig::default());
let spi_dev = RefCellDevice::new(spi_bus, cs_pin, *delay).unwrap();
let interface = SPIInterface::new(spi_dev, dc);
let mut display = Ssd1306::new(
interface,
DisplaySize128x64,
DisplayRotation::Rotate0,
)
.into_buffered_graphics_mode();
display.reset(&mut res, delay).unwrap();
display.init().unwrap();
display.clear(BinaryColor::Off).unwrap();
display.flush().unwrap();
display
}
-98
View File
@@ -1,98 +0,0 @@
use alloc::boxed::Box;
use core::cell::RefCell;
use embedded_hal::digital::{ErrorType, OutputPin as EhOutputPin, PinState};
use esp_hal::delay::Delay;
use esp_hal::gpio::interconnect::{PeripheralInput, PeripheralOutput};
use esp_hal::gpio::{Level, Output, OutputConfig, OutputPin};
use esp_hal::spi::master::{Config as SpiConfig, Spi};
use esp_hal::spi::Mode;
use esp_hal::time::Rate;
use crate::display::primary_lcd::{init_primary_lcd_on_bus, PrimaryLcdDisplay};
use crate::display::secondary_oled::{init_secondary_oled_on_bus, SecondaryOledDisplay};
pub struct SharedPin<'a>(pub &'a RefCell<Output<'static>>);
impl<'a> ErrorType for SharedPin<'a> {
type Error = core::convert::Infallible;
}
impl<'a> EhOutputPin for SharedPin<'a> {
fn set_low(&mut self) -> Result<(), Self::Error> {
self.0.borrow_mut().set_low();
Ok(())
}
fn set_high(&mut self) -> Result<(), Self::Error> {
self.0.borrow_mut().set_high();
Ok(())
}
fn set_state(&mut self, state: PinState) -> Result<(), Self::Error> {
self.0.borrow_mut().set_state(state);
Ok(())
}
}
pub type DisplaySpiBus = Spi<'static, esp_hal::Blocking>;
pub type DualPrimaryDisplay<'a> = PrimaryLcdDisplay<'a, DisplaySpiBus, SharedPin<'a>, SharedPin<'a>>;
pub type DualSecondaryDisplay<'a> = SecondaryOledDisplay<'a, DisplaySpiBus, SharedPin<'a>>;
pub fn init_dual_displays<SPI, SCK, MOSI, MISO, CS1, CS2, RES, DC>(
spi_peripheral: SPI,
sck: SCK,
mosi: MOSI,
miso: MISO,
cs_primary: CS1,
cs_secondary: CS2,
reset_pin: RES,
dc_pin: DC,
delay: &mut Delay,
) -> (DualPrimaryDisplay<'static>, DualSecondaryDisplay<'static>)
where
SPI: esp_hal::spi::master::Instance + 'static,
SCK: PeripheralOutput<'static>,
MOSI: PeripheralOutput<'static>,
MISO: PeripheralInput<'static>,
CS1: OutputPin + 'static,
CS2: OutputPin + 'static,
RES: OutputPin + 'static,
DC: OutputPin + 'static,
{
let spi = Spi::new(
spi_peripheral,
SpiConfig::default().with_frequency(Rate::from_khz(20_000)).with_mode(Mode::_0),
)
.unwrap()
.with_sck(sck)
.with_mosi(mosi)
.with_miso(miso);
let bus_static: &'static RefCell<DisplaySpiBus> = Box::leak(Box::new(RefCell::new(spi)));
let reset_static: &'static RefCell<Output<'static>> = Box::leak(Box::new(RefCell::new(
Output::new(reset_pin, Level::High, OutputConfig::default()),
)));
let dc_static: &'static RefCell<Output<'static>> = Box::leak(Box::new(RefCell::new(
Output::new(dc_pin, Level::High, OutputConfig::default()),
)));
let primary = init_primary_lcd_on_bus(
bus_static,
cs_primary,
SharedPin(reset_static),
SharedPin(dc_static),
delay,
);
let secondary = init_secondary_oled_on_bus(
bus_static,
cs_secondary,
SharedPin(reset_static),
SharedPin(dc_static),
delay,
);
(primary, secondary)
}
+1 -146
View File
@@ -1,146 +1 @@
use alloc::vec::Vec; // Drivers nfc_pn532 module
use core::convert::Infallible;
use esp_hal::gpio::interconnect::{PeripheralInput, PeripheralOutput};
use esp_hal::i2c::master::{Config as I2cConfig, I2c};
use esp_hal::peripherals::I2C0;
use esp_hal::time::{Duration, Instant, Rate};
use log::{error, info};
use pn532::i2c::I2CInterface;
use pn532::requests::SAMMode;
use pn532::{nb, Pn532, Request};
/// Timer implementation required by `pn532::CountDown`.
pub struct TimerWrapper {
start: Instant,
duration: Duration,
counter: u32,
}
impl TimerWrapper {
pub fn new() -> Self {
Self {
start: Instant::now(),
duration: Duration::ZERO,
counter: 0,
}
}
}
impl Default for TimerWrapper {
fn default() -> Self {
Self::new()
}
}
impl pn532::CountDown for TimerWrapper {
type Time = Duration;
fn start<T>(&mut self, timeout: T)
where
T: Into<Self::Time>,
{
self.start = Instant::now();
self.duration = timeout.into();
self.counter = 0;
}
fn wait(&mut self) -> nb::Result<(), Infallible> {
let elapsed = self.start.elapsed();
self.counter += 1;
if elapsed >= self.duration {
Ok(())
} else {
Err(nb::Error::WouldBlock)
}
}
}
pub type Pn532Device<'a> = Pn532<I2CInterface<I2c<'a, esp_hal::Blocking>>, TimerWrapper, 32>;
/// PN532 NFC reader driver.
pub struct NfcPn532Driver<'a> {
pn532: Pn532Device<'a>,
}
impl<'a> NfcPn532Driver<'a> {
pub fn new<SDA, SCL>(i2c0: I2C0<'static>, sda: SDA, scl: SCL) -> Self
where
SDA: PeripheralInput<'static> + PeripheralOutput<'static>,
SCL: PeripheralInput<'static> + PeripheralOutput<'static>,
{
let config = I2cConfig::default().with_frequency(Rate::from_khz(20));
let i2c = I2c::new(i2c0, config)
.expect("Failed to init I2C")
.with_sda(sda)
.with_scl(scl);
let pn532 = Pn532::new(I2CInterface { i2c }, TimerWrapper::new());
Self { pn532 }
}
pub fn configure_sam(&mut self, timeout: Duration) -> Result<(), ()> {
if let Err(e) = self.pn532.process(
&Request::sam_configuration(SAMMode::Normal, false),
0,
timeout,
) {
error!("Could not initialize PN532: {e:?}");
Err(())
} else {
info!("Successfully init'ed PN532");
Ok(())
}
}
pub fn poll_target(&mut self, timeout: Duration) -> Result<(), ()> {
match self.pn532.process(&Request::INLIST_ONE_ISO_A_TARGET, 23, timeout) {
Ok(uid) => {
info!("uid = {uid:?}");
Ok(())
}
Err(e) => {
info!("No NFC card found: {e:?}");
Err(())
}
}
}
pub fn parse_nfc_page(iteration: u8, bytes: &[u8]) -> Result<[u8; 4], ()> {
let success = bytes.first().is_some_and(|x| *x == 0);
if success {
let mut arr = [0; 4];
arr.copy_from_slice(&bytes[1..5]);
Ok(arr)
} else {
info!("err {iteration}: {:02x?}", bytes);
Err(())
}
}
pub fn read_card_data(&mut self) -> Result<Vec<u8>, ()> {
let ms_1000 = Duration::from_millis(1000);
self.poll_target(Duration::from_secs(10))?;
let mut data: Vec<u8> = Vec::with_capacity(858);
for i in 0x04..=230 {
let mut parse_result = Err(());
while parse_result.is_err() {
let Ok(result) = self.pn532.process(&Request::ntag_read(i), 17, ms_1000) else {
continue;
};
parse_result = Self::parse_nfc_page(i, result);
}
let bytes = parse_result.unwrap();
data.extend(bytes);
}
info!("Full data: {data:02x?}");
Ok(data)
}
pub fn device_mut(&mut self) -> &mut Pn532Device<'a> {
&mut self.pn532
}
}