add dma transfer example

This commit is contained in:
xoviat 2020-12-28 16:43:29 -06:00
parent b5e0116f76
commit 3cf85df176

View File

@ -17,20 +17,23 @@ use cortex_m::singleton;
use crate::hal::dma::config::DmaConfig; use crate::hal::dma::config::DmaConfig;
use crate::hal::dma::{Channel4, PeripheralToMemory, Stream2, StreamsTuple, Transfer}; use crate::hal::dma::{Channel4, PeripheralToMemory, Stream2, StreamsTuple, Transfer};
use crate::hal::gpio::{Alternate, AF10, AF7, AF9}; use crate::hal::gpio::{Alternate, AF10, AF7, AF9};
use crate::hal::gpio::{ use crate::hal::gpio::{Floating, Input, Output, PushPull};
Floating, Input, Output, Pin as GpioPin, Port as GpioPort, PushPull, Rx, Tx, use crate::hal::rcc::Clocks;
use crate::hal::serial::config::{
Config as SerialConfig, DmaConfig as SerialDmaConfig, Parity, StopBits, WordLength,
}; };
use crate::hal::serial::{DmaConfig, Event, Parity, StopBits, WordLength}; use crate::hal::serial::Serial;
use crate::hal::time::Bps;
use crate::interrupt; use crate::interrupt;
use crate::interrupt::CriticalSection; use crate::interrupt::CriticalSection;
use crate::pac::{uarte0, Interrupt, UARTE0, USART1}; use crate::pac::Interrupt;
#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))] use crate::pac::{DMA2, USART1};
use crate::pac::{DMA2, UARTE1};
use embedded_hal::digital::v2::OutputPin; use embedded_hal::digital::v2::OutputPin;
// Re-export SVD variants to allow user to directly set values // Re-export SVD variants to allow user to directly set values
pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; // pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
use embassy::io::{AsyncBufRead, AsyncWrite, Result}; use embassy::io::{AsyncBufRead, AsyncWrite, Result};
use embassy::util::WakerStore; use embassy::util::WakerStore;
@ -171,26 +174,29 @@ fn port_bit(port: GpioPort) -> bool {
} }
impl<T: Instance> Uarte<T> { impl<T: Instance> Uarte<T> {
pub fn new(uarte: T, mut pins: Pins, parity: Parity, baudrate: Baudrate) -> Self { pub fn new(uarte: T, mut pins: Pins, parity: Parity, baudrate: Bps, clocks: Clocks) -> Self {
// Select pins // Select pins
// Serial<USART1, (PA9<Alternate<AF7>>, PA10<Alternate<AF7>>)> // Serial<USART1, (PA9<Alternate<AF7>>, PA10<Alternate<AF7>>)>
let mut serial = Serial::usart1( let mut serial = Serial::usart1(
dp.USART1, pins.usart,
(pins.txd, pins.rxd), (pins.txd, pins.rxd),
Config { SerialConfig {
baudrate: 9600.bps(), baudrate: baudrate,
wordlength: WordLength::DataBits8, wordlength: WordLength::DataBits8,
parity: Parity::ParityNone, parity: Parity::ParityNone,
stopbits: StopBits::STOP1, stopbits: StopBits::STOP1,
dma: DmaConfig::TxRx, dma: SerialDmaConfig::TxRx,
}, },
clocks, clocks,
) )
.unwrap(); .unwrap();
let isr = pins.dma.hisr;
// self.isr().$tcifX().bit_is_clear()
// Enable interrupts // Enable interrupts
serial.listen(Event::Txe); // serial.listen(Event::Txe);
serial.listen(Event::Txe); // serial.listen(Event::Txe);
// TODO: Enable idle interrupt? Use DMA interrupt? // TODO: Enable idle interrupt? Use DMA interrupt?
@ -207,13 +213,6 @@ impl<T: Instance> Uarte<T> {
Taken from https://gist.github.com/thalesfragoso/a07340c5df6eee3b04c42fdc69ecdcb1 Taken from https://gist.github.com/thalesfragoso/a07340c5df6eee3b04c42fdc69ecdcb1
*/ */
// configure dma transfer
let stream_7 = StreamsTuple::new(pins.dma).7;
let config = DmaConfig::default()
.transfer_complete_interrupt(true)
.memory_increment(true)
.double_buffer(true);
// let rcc = unsafe { &*RCC::ptr() }; // let rcc = unsafe { &*RCC::ptr() };
// rcc.apb2enr.modify(|_, w| w.adc1en().enabled()); // rcc.apb2enr.modify(|_, w| w.adc1en().enabled());
// rcc.apb2rstr.modify(|_, w| w.adcrst().set_bit()); // rcc.apb2rstr.modify(|_, w| w.adcrst().set_bit());
@ -230,18 +229,6 @@ impl<T: Instance> Uarte<T> {
// .enabled() // .enabled()
// }); // });
let first_buffer = singleton!(: [u8; 128] = [0; 128]).unwrap();
let second_buffer = singleton!(: [u8; 128] = [0; 128]).unwrap();
let triple_buffer = Some(singleton!(: [u8; 128] = [0; 128]).unwrap());
let transfer = Transfer::init(
stream_7,
pins.usart,
first_buffer,
Some(second_buffer),
config,
);
// Configure // Configure
//let hardware_flow_control = pins.rts.is_some() && pins.cts.is_some(); //let hardware_flow_control = pins.rts.is_some() && pins.cts.is_some();
//uarte //uarte
@ -510,6 +497,25 @@ impl<T: Instance> UarteState<T> {
} }
TxState::Transmitting(n) => { TxState::Transmitting(n) => {
trace!(" irq_tx: in state Transmitting"); trace!(" irq_tx: in state Transmitting");
// Start the DMA transfer
// See https://github.com/mwkroening/async-stm32f1xx/blob/78c46d1bff124eae4ebc7a2f4d40e6ed74def8b5/src/serial.rs#L118-L129
// https://github.com/stm32-rs/stm32f1xx-hal/blob/68fd3d6f282173816fd3181e795988d314cb17d0/src/serial.rs#L649-L671
let first_buffer = singleton!(: [u8; 128] = [0; 128]).unwrap();
let second_buffer = singleton!(: [u8; 128] = [0; 128]).unwrap();
let triple_buffer = Some(singleton!(: [u8; 128] = [0; 128]).unwrap());
let transfer = Transfer::init(
StreamsTuple::new(pins.dma).7,
pins.usart,
first_buffer,
Some(second_buffer),
DmaConfig::default()
.transfer_complete_interrupt(true)
.memory_increment(true)
.double_buffer(true),
);
if self.inner.events_endtx.read().bits() != 0 { if self.inner.events_endtx.read().bits() != 0 {
self.inner.events_endtx.reset(); self.inner.events_endtx.reset();