#![no_main]
#![no_std]
use core::cell::{Cell, RefCell};
use cortex_m::peripheral::NVIC;
use cortex_m_rt::entry;
use critical_section::{with, Mutex};
use hal::{
clocks::Clocks,
dma::{self, Dma, DmaChannel, DmaConfig, DmaPeriph},
gpio::{Pin, PinMode, Port},
low_power,
pac::{self, interrupt},
usart::{Usart, UsartConfig, UsartDevice, UsartInterrupt},
};
const BUF_SIZE: usize = 10;
static UART: Mutex<RefCell<Option<Usart<pac::USART1>>>> = Mutex::new(RefCell::new(None));
static READ_BUF: Mutex<RefCell<[u8; BUF_SIZE]>> = Mutex::new(RefCell::new([0; BUF_SIZE]));
static READ_I: Mutex<Cell<usize>> = Mutex::new(Cell::new(0));
static mut RX_BUF: [u8; BUF_SIZE] = [0; BUF_SIZE];
const DMA_PERIPH: DmaPeriph = DmaPeriph::Dma1;
const DMA_CH: DmaChannel = DmaChannel::C1;
#[entry]
fn main() -> ! {
let mut cp = cortex_m::Peripherals::take().unwrap();
let mut dp = pac::Peripherals::take().unwrap();
let clock_cfg = Clocks::default();
clock_cfg.setup().unwrap();
let _uart_tx = Pin::new(Port::A, 9, PinMode::Alt(7));
let _uart_rx = Pin::new(Port::A, 10, PinMode::Alt(7));
let mut uart = Usart::new(
dp.USART1,
UsartDevice::One,
9_600,
UsartConfig::default(),
&clock_cfg,
);
uart.enable_interrupt(UsartInterrupt::ReadNotEmpty);
unsafe {
NVIC::unmask(interrupt::USART1);
}
with(|cs| {
UART.borrow(cs).replace(Some(uart));
});
let mut dma = Dma::new(dp.DMA1);
dma::mux(DMA_PERIPH, DMA_CH, DmaInput::Usart1Tx);
dma.enable_interrupt(DMA_CH, DmaInterrupt::TransferComplete);
unsafe {
uart.read_dma(&mut RX_BUF, DMA_CH, ChannelCfg::default(), DMA_PERIPH);
}
loop {
low_power::sleep_now();
}
}
#[interrupt]
fn USART1() {
with(|cs| {
let mut u = UART.borrow(cs).borrow_mut();
let uart = u.as_mut().unwrap();
uart.clear_interrupt(UsartInterrupt::ReadNotEmpty);
let mut buf = READ_BUF.borrow(cs).borrow_mut();
let i = READ_I.borrow(cs);
let i_val = i.get();
if i_val == BUF_SIZE {
}
buf[i_val] = uart.read_one();
i.set(i_val + 1);
});
}
#[interrupt]
fn DMA1_CH1() {
with(|cs| {
let mut u = UART.borrow(cs).borrow_mut();
let uart = u.as_mut().unwrap();
dma::clear_interrupt(DMA_PERIPH, DMA_CH, DmaInterrupt::TransferComplete);
dma::stop(DMA_PERIPH, DMA_CH);
unsafe {
uart.read_dma(&mut RX_BUF, DMA_CH, ChannelCfg::default(), DMA_PERIPH);
}
});
}
#[defmt::panic_handler]
fn panic() -> ! {
cortex_m::asm::udf()
}