aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuliDi <[email protected]>2023-06-18 18:51:36 +0200
committerJuliDi <[email protected]>2023-06-18 18:51:36 +0200
commitf8ee33abb9943d6fe57c126eeecb36db9935c4ba (patch)
tree8764043bc2cd73527a0a013eac0e889010f564ab
parent78a2ca8a0e5af3fe2c76a6cd025b74ea4322f6cf (diff)
add half transfer interrupt and circular dma
-rw-r--r--embassy-stm32/src/dac/mod.rs17
-rw-r--r--embassy-stm32/src/dma/bdma.rs26
2 files changed, 36 insertions, 7 deletions
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs
index 7b81ec1f2..525d45d72 100644
--- a/embassy-stm32/src/dac/mod.rs
+++ b/embassy-stm32/src/dac/mod.rs
@@ -2,7 +2,7 @@
2 2
3use embassy_hal_common::{into_ref, PeripheralRef}; 3use embassy_hal_common::{into_ref, PeripheralRef};
4 4
5use crate::dma::Transfer; 5use crate::dma::{Transfer, TransferOptions};
6use crate::pac::dac; 6use crate::pac::dac;
7use crate::rcc::RccPeripheral; 7use crate::rcc::RccPeripheral;
8use crate::{peripherals, Peripheral}; 8use crate::{peripherals, Peripheral};
@@ -237,7 +237,7 @@ impl<'d, T: Instance, Tx> Dac<'d, T, Tx> {
237 } 237 }
238 238
239 /// TODO: Allow an array of Value instead of only u16, right-aligned 239 /// TODO: Allow an array of Value instead of only u16, right-aligned
240 pub async fn write(&mut self, data: &[u16]) -> Result<(), Error> 240 pub async fn write(&mut self, data: &[u16], circular: bool) -> Result<(), Error>
241 where 241 where
242 Tx: Dma<T>, 242 Tx: Dma<T>,
243 { 243 {
@@ -257,7 +257,18 @@ impl<'d, T: Instance, Tx> Dac<'d, T, Tx> {
257 // Use the 12 bit right-aligned register for now. TODO: distinguish values 257 // Use the 12 bit right-aligned register for now. TODO: distinguish values
258 let tx_dst = T::regs().dhr12r(CHANNEL).ptr() as *mut u16; 258 let tx_dst = T::regs().dhr12r(CHANNEL).ptr() as *mut u16;
259 259
260 let tx_f = unsafe { Transfer::new_write(&mut self.txdma, tx_request, data, tx_dst, Default::default()) }; 260 let tx_f = unsafe {
261 Transfer::new_write(
262 &mut self.txdma,
263 tx_request,
264 data,
265 tx_dst,
266 TransferOptions {
267 circular,
268 halt_transfer_ir: false,
269 },
270 )
271 };
261 272
262 //debug!("Awaiting tx_f"); 273 //debug!("Awaiting tx_f");
263 274
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs
index c0a503e25..ca18047e7 100644
--- a/embassy-stm32/src/dma/bdma.rs
+++ b/embassy-stm32/src/dma/bdma.rs
@@ -1,6 +1,7 @@
1#![macro_use] 1#![macro_use]
2 2
3use core::future::Future; 3use core::future::Future;
4use core::option;
4use core::pin::Pin; 5use core::pin::Pin;
5use core::sync::atomic::{fence, Ordering}; 6use core::sync::atomic::{fence, Ordering};
6use core::task::{Context, Poll, Waker}; 7use core::task::{Context, Poll, Waker};
@@ -21,11 +22,17 @@ use crate::pac::bdma::{regs, vals};
21#[derive(Debug, Copy, Clone, PartialEq, Eq)] 22#[derive(Debug, Copy, Clone, PartialEq, Eq)]
22#[cfg_attr(feature = "defmt", derive(defmt::Format))] 23#[cfg_attr(feature = "defmt", derive(defmt::Format))]
23#[non_exhaustive] 24#[non_exhaustive]
24pub struct TransferOptions {} 25pub struct TransferOptions {
26 pub circular: bool,
27 pub halt_transfer_ir: bool,
28}
25 29
26impl Default for TransferOptions { 30impl Default for TransferOptions {
27 fn default() -> Self { 31 fn default() -> Self {
28 Self {} 32 Self {
33 circular: false,
34 halt_transfer_ir: false,
35 }
29 } 36 }
30} 37}
31 38
@@ -253,7 +260,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
253 mem_len: usize, 260 mem_len: usize,
254 incr_mem: bool, 261 incr_mem: bool,
255 data_size: WordSize, 262 data_size: WordSize,
256 _options: TransferOptions, 263 options: TransferOptions,
257 ) -> Self { 264 ) -> Self {
258 let ch = channel.regs().ch(channel.num()); 265 let ch = channel.regs().ch(channel.num());
259 266
@@ -284,6 +291,14 @@ impl<'a, C: Channel> Transfer<'a, C> {
284 w.set_dir(dir.into()); 291 w.set_dir(dir.into());
285 w.set_teie(true); 292 w.set_teie(true);
286 w.set_tcie(true); 293 w.set_tcie(true);
294 w.set_htie(options.halt_transfer_ir);
295 if options.circular {
296 w.set_circ(vals::Circ::ENABLED);
297 debug!("Setting circular mode");
298 } else {
299 w.set_circ(vals::Circ::DISABLED);
300 }
301 w.set_pl(vals::Pl::VERYHIGH);
287 w.set_en(true); 302 w.set_en(true);
288 }); 303 });
289 304
@@ -314,8 +329,9 @@ impl<'a, C: Channel> Transfer<'a, C> {
314 pub fn is_running(&mut self) -> bool { 329 pub fn is_running(&mut self) -> bool {
315 let ch = self.channel.regs().ch(self.channel.num()); 330 let ch = self.channel.regs().ch(self.channel.num());
316 let en = unsafe { ch.cr().read() }.en(); 331 let en = unsafe { ch.cr().read() }.en();
332 let circular = unsafe { ch.cr().read() }.circ() == vals::Circ::ENABLED;
317 let tcif = STATE.complete_count[self.channel.index()].load(Ordering::Acquire) != 0; 333 let tcif = STATE.complete_count[self.channel.index()].load(Ordering::Acquire) != 0;
318 en && !tcif 334 en && (circular || !tcif)
319 } 335 }
320 336
321 /// Gets the total remaining transfers for the channel 337 /// Gets the total remaining transfers for the channel
@@ -482,6 +498,8 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> {
482 let ch = self.channel.regs().ch(self.channel.num()); 498 let ch = self.channel.regs().ch(self.channel.num());
483 499
484 // Disable the channel. Keep the IEs enabled so the irqs still fire. 500 // Disable the channel. Keep the IEs enabled so the irqs still fire.
501 // If the channel is enabled and transfer is not completed, we need to perform
502 // two separate write access to the CR register to disable the channel.
485 unsafe { 503 unsafe {
486 ch.cr().write(|w| { 504 ch.cr().write(|w| {
487 w.set_teie(true); 505 w.set_teie(true);