compiled and working
This commit is contained in:
10
dma_gpio/Cargo.lock
generated
10
dma_gpio/Cargo.lock
generated
@@ -279,6 +279,7 @@ dependencies = [
|
|||||||
"micromath",
|
"micromath",
|
||||||
"panic-halt",
|
"panic-halt",
|
||||||
"panic-probe",
|
"panic-probe",
|
||||||
|
"static_cell",
|
||||||
"tinybmp",
|
"tinybmp",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1033,6 +1034,15 @@ 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 = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_cell"
|
||||||
|
version = "2.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0530892bb4fa575ee0da4b86f86c667132a94b74bb72160f58ee5a4afec74c23"
|
||||||
|
dependencies = [
|
||||||
|
"portable-atomic",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stm32-fmc"
|
name = "stm32-fmc"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
|
|||||||
@@ -26,3 +26,4 @@ tinybmp = "0.6.0"
|
|||||||
panic-probe = { version = "1.0.0", features = ["defmt"] }
|
panic-probe = { version = "1.0.0", features = ["defmt"] }
|
||||||
defmt-rtt = "1.1.0"
|
defmt-rtt = "1.1.0"
|
||||||
defmt = "1.0.1"
|
defmt = "1.0.1"
|
||||||
|
static_cell = "2.1.1"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::gpio::{Input, Output, Level, Pull, Speed};
|
use embassy_stm32::gpio::{Input, Output, Level, Pull, Speed};
|
||||||
|
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe};
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use dma_gpio::software_uart::{
|
use dma_gpio::software_uart::{
|
||||||
dma_timer::{init_tim6_for_uart, init_tim7_for_uart},
|
dma_timer::{init_tim6_for_uart, init_tim7_for_uart},
|
||||||
@@ -12,6 +13,7 @@ use dma_gpio::software_uart::{
|
|||||||
runtime::{rx_dma_task, tx_dma_task},
|
runtime::{rx_dma_task, tx_dma_task},
|
||||||
debug::dump_tim6_regs,
|
debug::dump_tim6_regs,
|
||||||
};
|
};
|
||||||
|
use static_cell::StaticCell;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
/// SOFTWARE UART CONFIGURATION
|
/// SOFTWARE UART CONFIGURATION
|
||||||
@@ -25,36 +27,33 @@ const RX_RING_BYTES: usize = 4096;
|
|||||||
|
|
||||||
static PIPE_TX: Pipe<CriticalSectionRawMutex, PIPE_TX_SIZE> = Pipe::new();
|
static PIPE_TX: Pipe<CriticalSectionRawMutex, PIPE_TX_SIZE> = Pipe::new();
|
||||||
static PIPE_RX: Pipe<CriticalSectionRawMutex, PIPE_RX_SIZE> = Pipe::new();
|
static PIPE_RX: Pipe<CriticalSectionRawMutex, PIPE_RX_SIZE> = Pipe::new();
|
||||||
// Large hardware RX DMA circular buffer, scales with oversampling rate
|
static RX_RING: StaticCell<[u8; RX_RING_BYTES]> = StaticCell::new();
|
||||||
static mut RX_RING: [u8; RX_RING_BYTES] = [0; RX_RING_BYTES];
|
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
// Initialize peripheral access
|
let p = embassy_stm32::init(Default::default());
|
||||||
let mut p = embassy_stm32::init(Default::default());
|
info!("Hehe");
|
||||||
info!("UART DMA demo starting...");
|
|
||||||
|
|
||||||
// GPIO setup
|
let _rx = Input::new(p.PA3, Pull::Up);
|
||||||
let rx = Input::new(p.PA3, Pull::Up);
|
|
||||||
let _tx = Output::new(p.PA2, Level::High, Speed::VeryHigh);
|
let _tx = Output::new(p.PA2, Level::High, Speed::VeryHigh);
|
||||||
|
|
||||||
// Timer setup
|
|
||||||
init_tim6_for_uart(p.TIM6, BAUD, TX_OVERSAMPLE);
|
init_tim6_for_uart(p.TIM6, BAUD, TX_OVERSAMPLE);
|
||||||
init_tim7_for_uart(p.TIM7, BAUD, RX_OVERSAMPLE);
|
init_tim7_for_uart(p.TIM7, BAUD, RX_OVERSAMPLE);
|
||||||
dump_tim6_regs(); // debug
|
dump_tim6_regs();
|
||||||
|
|
||||||
// Spawn DMA tasks
|
// Safe one-time init from StaticCell
|
||||||
spawner.spawn(tx_dma_task(p.GPDMA1_CH0)).unwrap();
|
let ring: &mut [u8; RX_RING_BYTES] = RX_RING.init([0; RX_RING_BYTES]);
|
||||||
spawner.spawn(rx_dma_task(p.GPDMA1_CH1)).unwrap();
|
|
||||||
|
// Spawn tasks
|
||||||
|
spawner.spawn(tx_dma_task(p.GPDMA1_CH0, &PIPE_TX).unwrap());
|
||||||
|
spawner.spawn(rx_dma_task(p.GPDMA1_CH1, &PIPE_RX, ring).unwrap());
|
||||||
|
|
||||||
// UART config (8N1 default)
|
|
||||||
let uart_cfg = UartConfig {
|
let uart_cfg = UartConfig {
|
||||||
data_bits: 8,
|
data_bits: 8,
|
||||||
parity: Parity::None,
|
parity: Parity::None,
|
||||||
stop_bits: StopBits::One,
|
stop_bits: StopBits::One,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Main loop: send data periodically
|
|
||||||
loop {
|
loop {
|
||||||
write_uart_frames_to_pipe(&PIPE_TX, TX_PIN_BIT, b"Hello marshmallow\r\n", &uart_cfg).await;
|
write_uart_frames_to_pipe(&PIPE_TX, TX_PIN_BIT, b"Hello marshmallow\r\n", &uart_cfg).await;
|
||||||
Timer::after(Duration::from_secs(2)).await;
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
|
|||||||
@@ -9,39 +9,47 @@ use embassy_stm32::{
|
|||||||
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe};
|
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe};
|
||||||
use embassy_time::Duration;
|
use embassy_time::Duration;
|
||||||
use crate::software_uart::{
|
use crate::software_uart::{
|
||||||
gpio_dma_uart_rx::TIM7_UP_REQ, gpio_dma_uart_tx::GpioDmaBsrrTx,
|
gpio_dma_uart_rx::TIM7_UP_REQ,
|
||||||
|
gpio_dma_uart_tx::GpioDmaBsrrTx,
|
||||||
debug::{dump_dma_ch0_regs, dump_tim6_regs},
|
debug::{dump_dma_ch0_regs, dump_tim6_regs},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// RX DMA task: reads GPIO samples paced by TIM7 and fills PIPE_RX
|
/// RX DMA task: reads GPIO samples paced by TIM7 and fills PIPE_RX
|
||||||
#[task]
|
#[task]
|
||||||
pub async fn rx_dma_task(ch: Peri<'static, GPDMA1_CH1>) {
|
pub async fn rx_dma_task(
|
||||||
let ring = unsafe { &mut RX_RING };
|
ch: Peri<'static, GPDMA1_CH1>,
|
||||||
|
pipe_rx: &'static Pipe<CriticalSectionRawMutex, 256>,
|
||||||
|
ring: &'static mut [u8],
|
||||||
|
) {
|
||||||
let gpioa_idr = embassy_stm32::pac::GPIOA.idr().as_ptr() as *mut u8;
|
let gpioa_idr = embassy_stm32::pac::GPIOA.idr().as_ptr() as *mut u8;
|
||||||
|
|
||||||
let mut opts = TransferOptions::default();
|
let mut opts = TransferOptions::default();
|
||||||
opts.half_transfer_ir = true;
|
opts.half_transfer_ir = true;
|
||||||
opts.complete_transfer_ir = true;
|
opts.complete_transfer_ir = true;
|
||||||
|
|
||||||
|
// SAFETY: ring is exclusive to this task
|
||||||
let mut rx = unsafe { DmaRingRx::new(ch, TIM7_UP_REQ, gpioa_idr, ring, opts) };
|
let mut rx = unsafe { DmaRingRx::new(ch, TIM7_UP_REQ, gpioa_idr, ring, opts) };
|
||||||
rx.start();
|
rx.start();
|
||||||
|
|
||||||
let mut chunk = [0u8; 256];
|
let mut chunk = [0u8; 256];
|
||||||
loop {
|
loop {
|
||||||
let _ = rx.read_exact(&mut chunk).await;
|
let _ = rx.read_exact(&mut chunk).await;
|
||||||
PIPE_RX.write(&chunk).await;
|
pipe_rx.write(&chunk).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TX DMA task: dequeues prebuilt frames from PIPE_TX and writes to GPIOA.BSRR
|
/// TX DMA task: dequeues prebuilt frames from PIPE_TX and writes to GPIOA.BSRR
|
||||||
#[task]
|
#[task]
|
||||||
pub async fn tx_dma_task(ch: Peri<'static, GPDMA1_CH0>) {
|
pub async fn tx_dma_task(
|
||||||
|
ch: Peri<'static, GPDMA1_CH0>,
|
||||||
|
pipe_tx: &'static Pipe<CriticalSectionRawMutex, 256>,
|
||||||
|
) {
|
||||||
let mut tx = GpioDmaBsrrTx::new(ch);
|
let mut tx = GpioDmaBsrrTx::new(ch);
|
||||||
info!("DMA TX task started");
|
info!("DMA TX task started");
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut b = [0u8; 4];
|
let mut b = [0u8; 4];
|
||||||
let n = PIPE_TX.read(&mut b).await;
|
let n = pipe_tx.read(&mut b).await;
|
||||||
if n != 4 {
|
if n != 4 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user