#![deny(warnings)]
#![allow(clippy::type_complexity)]
#![no_main]
#![no_std]
use core::mem::MaybeUninit;
#[macro_use]
mod utilities;
const BUFFER_SIZE: usize = 100;
#[link_section = ".axisram.buffers"]
static mut BUFFER: MaybeUninit<[u8; BUFFER_SIZE]> = MaybeUninit::uninit();
#[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true)]
mod app {
use hal::prelude::*;
use stm32h7xx_hal as hal;
use super::*;
#[shared]
struct SharedResources {
cs: hal::gpio::gpiob::PB12<hal::gpio::Output<hal::gpio::PushPull>>,
transfer: hal::dma::Transfer<
hal::dma::dma::Stream1<hal::stm32::DMA1>,
hal::spi::Spi<hal::stm32::SPI2, hal::spi::Disabled, u8>,
hal::dma::MemoryToPeripheral,
&'static mut [u8; BUFFER_SIZE],
hal::dma::DBTransfer,
>,
}
#[local]
struct LocalResources {}
#[init]
fn init(
ctx: init::Context,
) -> (SharedResources, LocalResources, init::Monotonics) {
utilities::logger::init();
let pwr = ctx.device.PWR.constrain();
let pwrcfg = example_power!(pwr).freeze();
let rcc = ctx.device.RCC.constrain();
let ccdr = rcc
.sys_ck(200.MHz())
.hclk(200.MHz())
.pll1_q_ck(200.MHz())
.freeze(pwrcfg, &ctx.device.SYSCFG);
let gpiob = ctx.device.GPIOB.split(ccdr.peripheral.GPIOB);
let spi = {
let mosi = gpiob
.pb15
.into_alternate()
.speed(hal::gpio::Speed::VeryHigh);
let sck = gpiob
.pb10
.into_alternate()
.speed(hal::gpio::Speed::VeryHigh);
let config = hal::spi::Config::new(hal::spi::MODE_0)
.communication_mode(hal::spi::CommunicationMode::Transmitter);
let spi: hal::spi::Spi<_, _, u8> = ctx.device.SPI2.spi(
(sck, hal::spi::NoMiso, mosi),
config,
3.MHz(),
ccdr.peripheral.SPI2,
&ccdr.clocks,
);
spi.disable()
};
let mut cs = gpiob
.pb12
.into_push_pull_output()
.speed(hal::gpio::Speed::VeryHigh);
cs.set_high();
let buffer: &'static mut [u8; BUFFER_SIZE] = {
let buf: &mut [MaybeUninit<u8>; BUFFER_SIZE] = unsafe {
&mut *(&mut BUFFER as *mut MaybeUninit<[u8; BUFFER_SIZE]>
as *mut [MaybeUninit<u8>; BUFFER_SIZE])
};
for (i, value) in buf.iter_mut().enumerate() {
unsafe {
value.as_mut_ptr().write(i as u8 + 0x60); }
}
unsafe {
&mut *(buf as *mut [MaybeUninit<u8>; BUFFER_SIZE]
as *mut [u8; BUFFER_SIZE])
}
};
let streams = hal::dma::dma::StreamsTuple::new(
ctx.device.DMA1,
ccdr.peripheral.DMA1,
);
let config = hal::dma::dma::DmaConfig::default()
.memory_increment(true)
.transfer_complete_interrupt(true);
let transfer: hal::dma::Transfer<
_,
_,
hal::dma::MemoryToPeripheral,
_,
_,
> = hal::dma::Transfer::init(streams.1, spi, buffer, None, config);
(
SharedResources { cs, transfer },
LocalResources {},
init::Monotonics(),
)
}
#[task(binds=DMA1_STR1, shared = [transfer, cs], priority=2)]
fn dma_complete(ctx: dma_complete::Context) {
(ctx.shared.transfer, ctx.shared.cs).lock(|transfer, cs| {
transfer.clear_transfer_complete_interrupt();
transfer.pause(|spi| {
while spi.inner().sr.read().txc().bit_is_clear() {}
cs.set_high();
});
});
}
#[idle(shared = [transfer, cs])]
fn idle(ctx: idle::Context) -> ! {
(ctx.shared.transfer, ctx.shared.cs).lock(|transfer, cs| {
transfer.start(|spi| {
cs.set_low();
spi.enable_dma_tx();
spi.inner_mut().cr1.modify(|_, w| w.spe().enabled());
spi.inner_mut().cr1.modify(|_, w| w.cstart().started());
});
});
loop {
cortex_m::asm::nop();
}
}
}