peripherals

This commit is contained in:
Alexey 2026-06-08 16:42:09 +03:00
commit fec40d4322
6 changed files with 396 additions and 5 deletions

131
Cargo.lock generated
View file

@ -3,10 +3,16 @@
version = 4
[[package]]
name = "az"
version = "1.3.0"
name = "autocfg"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7"
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
[[package]]
name = "az"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973"
[[package]]
name = "bare-metal"
@ -61,6 +67,7 @@ checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9"
dependencies = [
"bare-metal",
"bitfield",
"critical-section",
"embedded-hal 0.2.7",
"volatile-register",
]
@ -91,6 +98,15 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
[[package]]
name = "critical-section-lock-mut"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbb9762738c1ef9d31b7586c00c0158d20025a734f9f6905282c1fc5a2e182f0"
dependencies = [
"critical-section",
]
[[package]]
name = "crunchy"
version = "0.2.4"
@ -106,6 +122,29 @@ dependencies = [
"stable_deref_trait",
]
[[package]]
name = "embedded-graphics"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e8da660bb0c829b34a56a965490597f82a55e767b91f9543be80ce8ccb416fe"
dependencies = [
"az",
"byteorder",
"embedded-graphics-core",
"float-cmp",
"micromath",
]
[[package]]
name = "embedded-graphics-core"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95743bef3ff70fcba3930246c4e6872882bbea0dcc6da2ca860112e0cd4bd09f"
dependencies = [
"az",
"byteorder",
]
[[package]]
name = "embedded-hal"
version = "0.2.7"
@ -122,6 +161,16 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
[[package]]
name = "embedded-hal-bus"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "513e0b3a8fb7d3013a8ae17a834283f170deaf7d0eeab0a7c1a36ad4dd356d22"
dependencies = [
"critical-section",
"embedded-hal 1.0.0",
]
[[package]]
name = "embedded-io"
version = "0.7.1"
@ -136,9 +185,9 @@ checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032"
[[package]]
name = "fixed"
version = "1.31.0"
version = "1.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9af2cbf772fa6d1c11358f92ef554cb6b386201210bcf0e91fb7fba8a907fb40"
checksum = "707070ccf8c4173548210893a0186e29c266901b71ed20cd9e2ca0193dfe95c3"
dependencies = [
"az",
"bytemuck",
@ -146,6 +195,15 @@ dependencies = [
"typenum",
]
[[package]]
name = "float-cmp"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
dependencies = [
"num-traits",
]
[[package]]
name = "half"
version = "2.7.1"
@ -253,13 +311,21 @@ version = "0.1.0"
dependencies = [
"cortex-m",
"cortex-m-rt",
"critical-section",
"critical-section-lock-mut",
"embedded-graphics",
"embedded-hal 1.0.0",
"embedded-hal-bus",
"embedded-io",
"heapless 0.9.3",
"libm",
"lsm303agr",
"microbit-v2",
"mipidsi",
"nrf52833-hal",
"panic-halt",
"panic-rtt-target",
"rtt-target",
]
[[package]]
@ -282,6 +348,23 @@ dependencies = [
"microbit-common",
]
[[package]]
name = "micromath"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815"
[[package]]
name = "mipidsi"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790ebd28bd67addbccf41b1c0c188c26bb9f5bdcd91d4d6da9bd558e20d97a1d"
dependencies = [
"embedded-graphics-core",
"embedded-hal 1.0.0",
"heapless 0.8.0",
]
[[package]]
name = "nb"
version = "0.1.3"
@ -307,6 +390,7 @@ dependencies = [
"cfg-if",
"cortex-m",
"embedded-dma",
"embedded-hal 0.2.7",
"embedded-hal 1.0.0",
"embedded-io",
"embedded-storage",
@ -351,12 +435,32 @@ dependencies = [
"vcell",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "panic-halt"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a513e167849a384b7f9b746e517604398518590a9142f4846a32e3c2a4de7b11"
[[package]]
name = "panic-rtt-target"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8116ffce1f89818647b84fba66d16cfdf3c0bee3c9320e606588d3e7415ce7"
dependencies = [
"critical-section",
"portable-atomic",
"rtt-target",
]
[[package]]
name = "portable-atomic"
version = "1.13.1"
@ -409,6 +513,17 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
[[package]]
name = "rtt-target"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7afed1f4302eeba88c601636cf2c554c45e1cbb464bab44c6012bab0e71473c"
dependencies = [
"critical-section",
"portable-atomic",
"ufmt-write",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
@ -479,6 +594,12 @@ version = "1.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
[[package]]
name = "ufmt-write"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69"
[[package]]
name = "unicase"
version = "2.9.0"

View file

@ -8,8 +8,16 @@ cortex-m-rt = "0.7.5"
microbit-v2 = "0.16.0"
embedded-hal = "1.0.0"
panic-halt = "1.0.0"
cortex-m = "0.7.7"
cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] }
embedded-io = "0.7.1"
heapless = "0.9.3"
lsm303agr = "1.1.0"
libm = "0.2.16"
panic-rtt-target = "0.2.0"
rtt-target = "0.6.2"
critical-section = "1.2.0"
critical-section-lock-mut = "0.1.2"
nrf52833-hal = "0.19.0"
mipidsi = "0.10.0"
embedded-graphics = "0.8.2"
embedded-hal-bus = "0.3.0"

60
src/bin/analog.rs Normal file
View file

@ -0,0 +1,60 @@
#![no_main]
#![no_std]
use cortex_m_rt::entry;
use embedded_hal::delay::DelayNs;
use microbit::{Board, adc::Default};
use nrf52833_hal::{Saadc, Timer, saadc::SaadcConfig};
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
const THRESHOLD: i16 = 16;
const LEFT_VALUE: i16 = -1;
const LEFT_NAME: &str = "LEFT";
const UP_VALUE: i16 = 117;
const UP_NAME: &str = "UP";
const DOWN_VALUE: i16 = 269;
const DOWN_NAME: &str = "DOWN";
const RIGHT_VALUE: i16 = 413;
const RIGHT_NAME: &str = "RIGHT";
const SEL_VALUE: i16 = 609;
const SEL_NAME: &str = "SELECT";
const NO_VALUE: i16 = 845;
const NO_NAME: &str = "NO";
#[entry]
fn main() -> ! {
rtt_init_print!();
let board = Board::take().unwrap();
let mut timer = Timer::new(board.TIMER0);
let saadc_config = SaadcConfig::default_10bit();
let mut saadc = Saadc::new(board.ADC, saadc_config);
let mut saadc_pin = board.edge.e00;
loop {
if let Ok(value) = saadc.read_channel(&mut saadc_pin) {
rprintln!("value is {}", value);
for (test, name) in [
( LEFT_VALUE, LEFT_NAME ),
( UP_VALUE, UP_NAME ),
( DOWN_VALUE, DOWN_NAME ),
( RIGHT_VALUE, RIGHT_NAME ),
( SEL_VALUE, SEL_NAME ),
( NO_VALUE, NO_NAME ),
] {
if value > test - THRESHOLD && value < test + THRESHOLD {
rprintln!("detected {}", name);
}
}
}
timer.delay_ms(1000);
}
}

75
src/bin/compass.rs Normal file
View file

@ -0,0 +1,75 @@
#![no_main]
#![no_std]
use core::f32::consts::PI;
use cortex_m_rt::entry;
use embedded_hal::delay::DelayNs;
use libm::{atan2f, floorf};
use lsm303agr::{Lsm303agr, MagMode, MagOutputDataRate};
use microbit::{display::blocking::Display, hal::{Timer, Twim}, pac::twim0::frequency::FREQUENCY_A};
use panic_halt as _;
mod calibration {
type Vec = (i32, i32, i32);
const CAL_CENTER: Vec = (-12892, 21810, -1080);
const CAL_SCALE: Vec = (1066, 1049, 1072);
pub fn calibrate(v: Vec) -> Vec {
let mut out = (-v.1, -v.0, v.2);
out.0 = ((out.0 - CAL_CENTER.0) * CAL_SCALE.0) >> 10;
out.1 = ((out.1 - CAL_CENTER.1) * CAL_SCALE.1) >> 10;
out.2 = ((out.2 - CAL_CENTER.2) * CAL_SCALE.2) >> 10;
(-out.1, out.0, out.2)
}
}
#[entry]
fn main() -> ! {
let board = microbit::Board::take().unwrap();
let i2c = Twim::new(board.TWIM0, board.i2c_internal.into(), FREQUENCY_A::K100);
let mut timer = Timer::new(board.TIMER0);
let mut display = Display::new(board.display_pins);
let mut sensor = Lsm303agr::new_with_i2c(i2c);
sensor.init().unwrap();
sensor.set_mag_mode_and_odr(&mut timer, MagMode::HighResolution, MagOutputDataRate::Hz10).unwrap();
let mut sensor = sensor.into_mag_continuous().ok().unwrap();
let mut leds = [[0u8; 5]; 5];
let indices = [
(2, 0) /* W */, (3, 0) /* W-SW */, (4, 0) /* SW */, (4, 1) /* S-SW */,
(4, 2) /* S */, (4, 3) /* S-SE */, (4, 4) /* SE */, (3, 4) /* E-SE */,
(2, 4) /* E */, (1, 4) /* E-NE */, (0, 4) /* NE */, (0, 3) /* N-NE */,
(0, 2) /* N */, (0, 1) /* N-NW */, (0, 0) /* NW */, (1, 0) /* W-NW */,
];
loop {
while !sensor.mag_status().unwrap().xyz_new_data() {
timer.delay_ms(1u32);
}
let (x, y, _) = calibration::calibrate(sensor.magnetic_field().unwrap().xyz_nt());
//let (x, y, _) = sensor.magnetic_field().unwrap().xyz_nt();
let theta = atan2f(y as f32, x as f32);
let seg = floorf(16.0 * theta / PI) as i8;
let index = if seg >= 15 || seg <= -15 {
8
} else if seg >= 0 {
(seg / 2) as usize
} else {
((31 + seg) / 2) as usize
};
let (r, c) = indices[index];
leds[r][c] = 255u8;
display.show(&mut timer, leds, 100);
leds[r][c] = 0u8;
display.clear();
}
}

64
src/bin/display.rs Normal file
View file

@ -0,0 +1,64 @@
#![no_main]
#![no_std]
use cortex_m_rt::entry;
use embedded_graphics::{pixelcolor::Rgb565, prelude::{DrawTarget, Point, WebColors}, primitives::Rectangle};
use embedded_hal::digital::OutputPin;
use embedded_hal_bus::spi::ExclusiveDevice;
use microbit::Board;
use mipidsi::{Builder, interface::SpiInterface, models, options::ColorInversion};
use nrf52833_hal::{Timer, gpio::Level, spi::{self, Spi}, spim};
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
#[entry]
fn main() -> ! {
rtt_init_print!();
let board = Board::take().unwrap();
let mut timer0 = Timer::new(board.TIMER0);
let mut timer1 = Timer::new(board.TIMER1);
board.pins.p0_01.into_push_pull_output(Level::Low).set_high();
let spi_pins = spi::Pins {
sck: Some(board.pins.p0_17.into_push_pull_output(Level::Low).degrade()),
mosi: Some(board.pins.p0_13.into_push_pull_output(Level::Low).degrade()),
miso: None,
};
let bus = Spi::new(board.SPI0, spi_pins, spi::Frequency::M8, spim::MODE_3);
let spi = ExclusiveDevice::new(
bus,
board.edge.e16.into_push_pull_output(Level::Low),
&mut timer0,
).unwrap();
let mut buffer = [0u8; 512];
let interface = SpiInterface::new(
spi,
board.edge.e08.into_push_pull_output(Level::Low),
&mut buffer,
);
let mut display = Builder::new(models::ST7789, interface)
.display_size(240, 320)
.invert_colors(ColorInversion::Inverted)
.init(&mut timer1).unwrap();
display.clear(Rgb565::CSS_GREEN).unwrap();
display.fill_solid(
&Rectangle::with_corners(
Point::new(100, 100),
Point::new(150, 150),
),
Rgb565::CSS_ROYAL_BLUE,
).unwrap();
rprintln!("Should be done here");
loop {
continue;
}
}

63
src/bin/interrupt.rs Normal file
View file

@ -0,0 +1,63 @@
#![no_main]
#![no_std]
use core::sync::atomic::AtomicUsize;
use cortex_m::asm;
use cortex_m_rt::entry;
use critical_section_lock_mut::LockMut;
use microbit::{Board, hal::{Timer, gpiote::Gpiote}, pac::{self, interrupt}};
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
static COUNTER: AtomicUsize = AtomicUsize::new(0);
static GPIOTE_PERIPHERAL: LockMut<Gpiote> = LockMut::new();
static DEBOUNCE_TIMER: LockMut<Timer<pac::TIMER0>> = LockMut::new();
const DEBOUNCE_TIME: u32 = 100 * 1_000_000 / 1000;
#[interrupt]
fn GPIOTE() {
DEBOUNCE_TIMER.with_lock(|t| {
if t.read() == 0 {
let _ = COUNTER.fetch_add(1, core::sync::atomic::Ordering::AcqRel);
t.start(DEBOUNCE_TIME);
}
});
GPIOTE_PERIPHERAL.with_lock(|g| {
g.channel0().reset_events();
});
}
#[entry]
fn main() -> ! {
rtt_init_print!();
let board = Board::take().unwrap();
let button_a = board.buttons.button_a.into_floating_input();
let gpiote = Gpiote::new(board.GPIOTE);
let channel = gpiote.channel0();
channel.input_pin(&button_a.degrade())
.hi_to_lo()
.enable_interrupt();
channel.reset_events();
GPIOTE_PERIPHERAL.init(gpiote);
let mut timer = Timer::new(board.TIMER0);
timer.disable_interrupt();
timer.reset_event();
DEBOUNCE_TIMER.init(timer);
unsafe { pac::NVIC::unmask(pac::Interrupt::GPIOTE) };
pac::NVIC::unpend(pac::Interrupt::GPIOTE);
let mut cur_count = 0;
loop {
asm::wfi();
let count = COUNTER.load(core::sync::atomic::Ordering::Acquire);
if count > cur_count {
rprintln!("ouch {}", count);
cur_count = count;
}
}
}