Skip to content

Commit 8c197ed

Browse files
committed
spi: add RTIC async example
1 parent 39e21d0 commit 8c197ed

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ cortex-m-semihosting = "0.5.0"
9494
panic-itm = { version = "~0.4.1" }
9595
panic-probe = "0.3.2"
9696
panic-semihosting = "0.6"
97+
rtic = { version = "2.2", features = ["thumbv8main-backend"] }
98+
rtic-monotonics = { version = "2.0", features = ["cortex-m-systick"]}
9799
usbd-serial = "0.2.2"
98100
usb-device = { version = "0.3.2", features = ["defmt", "log"] }
99101

examples/spi-async-rtic.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#![no_main]
2+
#![no_std]
3+
4+
// use defmt_rtt as _;
5+
use panic_probe as _;
6+
7+
use embedded_hal_async::spi::SpiBus;
8+
use rtic::app;
9+
use stm32h5xx_hal::{
10+
gpdma::{periph::DmaDuplex, DmaChannel0, DmaChannel1},
11+
gpio::{Output, PA5},
12+
pac,
13+
prelude::*,
14+
spi::{self, dma::SpiDma, Config as SpiConfig},
15+
};
16+
17+
use rtic_monotonics::systick::prelude::*;
18+
systick_monotonic!(Mono, 1000);
19+
20+
#[app(device = pac, dispatchers = [USART1, USART2], peripherals = true)]
21+
mod app {
22+
23+
use stm32h5::stm32h503::GPDMA1;
24+
25+
use super::*;
26+
27+
#[shared]
28+
struct Shared {}
29+
30+
#[local]
31+
struct Local {
32+
led: PA5<Output>,
33+
spi: SpiDma<
34+
pac::SPI2,
35+
DmaDuplex<pac::SPI2, u8, DmaChannel0<GPDMA1>, DmaChannel1<GPDMA1>>,
36+
>,
37+
source: [u8; 40],
38+
dest: [u8; 40],
39+
}
40+
41+
#[init]
42+
fn init(ctx: init::Context) -> (Shared, Local) {
43+
let pwr = ctx.device.PWR.constrain();
44+
let pwrcfg = pwr.vos0().freeze();
45+
46+
let rcc = ctx.device.RCC.constrain();
47+
let ccdr = rcc.sys_ck(250.MHz()).freeze(pwrcfg, &ctx.device.SBS);
48+
49+
// Uncomment if use SysTick as monotonic timer
50+
Mono::start(ctx.core.SYST, ccdr.clocks.sysclk().raw());
51+
52+
let gpioa = ctx.device.GPIOA.split(ccdr.peripheral.GPIOA);
53+
let gpiob = ctx.device.GPIOB.split(ccdr.peripheral.GPIOB);
54+
55+
let led = gpioa.pa5.into_push_pull_output();
56+
57+
let sck = gpiob.pb13.into_alternate();
58+
let miso = gpiob.pb14.into_alternate();
59+
let mosi = gpiob.pb15.into_alternate();
60+
61+
let channels = ctx.device.GPDMA1.channels(ccdr.peripheral.GPDMA1);
62+
let tx_ch = channels.0;
63+
let rx_ch = channels.1;
64+
65+
let spi = ctx.device.SPI2.spi(
66+
(sck, miso, mosi),
67+
SpiConfig::new(spi::MODE_0),
68+
1.MHz(),
69+
ccdr.peripheral.SPI2,
70+
&ccdr.clocks,
71+
).use_dma_duplex(tx_ch, rx_ch);
72+
73+
tick::spawn().ok();
74+
(
75+
Shared {},
76+
Local {
77+
led,
78+
spi,
79+
source: [0; 40],
80+
dest: [0; 40],
81+
82+
},
83+
)
84+
}
85+
86+
#[task(local = [led, count: u32 = 0], priority = 1)]
87+
async fn tick(ctx: tick::Context) {
88+
loop {
89+
ctx.local.led.toggle();
90+
*ctx.local.count += 1;
91+
// defmt::info!("Tick {}", *ctx.local.count);
92+
Mono::delay(1000.millis()).await;
93+
}
94+
}
95+
96+
#[task(local = [spi, count: u32 = 0, source, dest], priority = 2)]
97+
async fn spi_transfer(ctx: spi_transfer::Context) {
98+
loop {
99+
ctx.local.source.fill(*ctx.local.count as u8);
100+
*ctx.local.count += 1;
101+
ctx.local.spi.transfer(ctx.local.dest, ctx.local.source).await.unwrap();
102+
Mono::delay(1000.millis()).await;
103+
}
104+
}
105+
}

0 commit comments

Comments
 (0)