Skip to content

Commit

Permalink
fix!: Changes to the dmac public API
Browse files Browse the repository at this point in the history
* Remove `BlockTransferControl` and `DmacDescriptor`
structs from the API
* Add getters/setters for level0, level1, level2
and level3 for `PriorityLevelMask` and `RoundRobinMask`
structs
  • Loading branch information
jbeaurivage committed Oct 1, 2024
1 parent cbbd4f0 commit 3dff3a6
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 87 deletions.
2 changes: 2 additions & 0 deletions hal/src/dmac/channel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
//! `Uninitialized` state. You will be required to call [`Channel::init`]
//! again before being able to use it with a `Transfer`.
#![allow(unused_braces)]

use atsamd_hal_macros::{hal_cfg, hal_macro_helper};

use super::dma_controller::{ChId, PriorityLevel, TriggerAction, TriggerSource};
Expand Down
36 changes: 16 additions & 20 deletions hal/src/dmac/dma_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
//!
//! Using the [`DmaController::free`] method will
//! deinitialize the DMAC and return the underlying PAC object.
#![allow(unused_braces)]

use atsamd_hal_macros::{hal_cfg, hal_macro_helper};

Expand All @@ -40,7 +41,7 @@ pub use crate::pac::dmac::channel::{

use super::{
channel::{new_chan, Channel, Uninitialized},
DESCRIPTOR_SECTION, WRITEBACK,
sram,
};
use crate::pac::{Dmac, Pm};

Expand Down Expand Up @@ -93,17 +94,13 @@ pub struct PriorityLevelMask {
#[skip]
_reserved: B8,
/// Level 0
#[allow(dead_code)]
level0: bool,
pub level0: bool,
/// Level 1
#[allow(dead_code)]
level1: bool,
pub level1: bool,
/// Level 2
#[allow(dead_code)]
level2: bool,
pub level2: bool,
/// Level 3
#[allow(dead_code)]
level3: bool,
pub level3: bool,
#[skip]
_reserved: B4,
}
Expand All @@ -121,23 +118,19 @@ pub struct RoundRobinMask {
#[skip]
_reserved: B7,
/// Level 0
#[allow(dead_code)]
level0: bool,
pub level0: bool,
#[skip]
_reserved: B7,
/// Level 1
#[allow(dead_code)]
level1: bool,
pub level1: bool,
#[skip]
_reserved: B7,
/// Level 2
#[allow(dead_code)]
level2: bool,
pub level2: bool,
#[skip]
_reserved: B7,
/// Level 3
#[allow(dead_code)]
level3: bool,
pub level3: bool,
}

impl DmaController {
Expand All @@ -162,11 +155,14 @@ impl DmaController {
// and the descriptor array addesses will never change since they are static.
// We just need to ensure the writeback and descriptor_section addresses
// are valid.
#[allow(static_mut_refs)]
unsafe {
dmac.baseaddr()
.write(|w| w.baseaddr().bits(DESCRIPTOR_SECTION.as_ptr() as u32));
dmac.baseaddr().write(|w| {
w.baseaddr()
.bits(sram::DESCRIPTOR_SECTION.as_mut_ptr() as u32)
});
dmac.wrbaddr()
.write(|w| w.wrbaddr().bits(WRITEBACK.as_ptr() as u32));
.write(|w| w.wrbaddr().bits(sram::WRITEBACK.as_mut_ptr() as u32));
}

// ----- Select priority levels ----- //
Expand Down
122 changes: 60 additions & 62 deletions hal/src/dmac/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![allow(unused_braces)]

//! # Direct Memory Access Controller
//!
//! This library provides a type-safe API with compile-time guarantees
Expand Down Expand Up @@ -253,8 +251,6 @@

use atsamd_hal_macros::hal_cfg;

use modular_bitfield::prelude::*;

pub use channel::*;
pub use dma_controller::*;
pub use transfer::*;
Expand Down Expand Up @@ -342,69 +338,71 @@ macro_rules! get {
/// Number of DMA channels used by the driver
pub const NUM_CHANNELS: usize = with_num_channels!(get);

// ----- DMAC SRAM registers ----- //
impl Default for BlockTransferControl {
fn default() -> Self {
Self::new()
/// DMAC SRAM registers
mod sram {
#![allow(dead_code, unused_braces)]

use super::{BeatSize, NUM_CHANNELS};

use modular_bitfield::{
bitfield,
specifiers::{B2, B3},
};

/// Bitfield representing the BTCTRL SRAM DMAC register
#[allow(unused_braces)]
#[bitfield]
#[derive(Clone, Copy)]
#[repr(u16)]
pub(super) struct BlockTransferControl {
pub(super) valid: bool,
pub(super) evosel: B2,
pub(super) blockact: B2,
#[skip]
_reserved: B3,
#[bits = 2]
pub(super) beatsize: BeatSize,
pub(super) srcinc: bool,
pub(super) dstinc: bool,
pub(super) stepsel: bool,
pub(super) stepsize: B3,
}
}

/// Bitfield representing the BTCTRL SRAM DMAC register
#[bitfield]
#[derive(Clone, Copy)]
#[repr(u16)]
#[doc(hidden)]
pub struct BlockTransferControl {
#[allow(dead_code)]
valid: bool,
#[allow(dead_code)]
evosel: B2,
#[allow(dead_code)]
blockact: B2,
#[skip]
_reserved: B3,
#[bits = 2]
#[allow(dead_code)]
beatsize: BeatSize,
#[allow(dead_code)]
srcinc: bool,
#[allow(dead_code)]
dstinc: bool,
#[allow(dead_code)]
stepsel: bool,
#[allow(dead_code)]
stepsize: B3,
}
impl Default for BlockTransferControl {
fn default() -> Self {
Self::new()
}
}

/// Descriptor representing a SRAM register. Datasheet section 19.8.2
#[derive(Clone, Copy)]
#[repr(C, align(16))]
#[doc(hidden)]
pub struct DmacDescriptor {
btctrl: BlockTransferControl,
btcnt: u16,
srcaddr: *const (),
dstaddr: *const (),
descaddr: *const DmacDescriptor,
}
/// Descriptor representing a SRAM register. Datasheet section 19.8.2
#[derive(Clone, Copy)]
#[repr(C, align(16))]
pub(super) struct DmacDescriptor {
pub(super) btctrl: BlockTransferControl,
pub(super) btcnt: u16,
pub(super) srcaddr: *const (),
pub(super) dstaddr: *const (),
pub(super) descaddr: *const DmacDescriptor,
}

#[doc(hidden)]
pub const DEFAULT_DESCRIPTOR: DmacDescriptor = DmacDescriptor {
btctrl: BlockTransferControl::new(),
btcnt: 0,
srcaddr: 0 as *mut _,
dstaddr: 0 as *mut _,
descaddr: 0 as *mut _,
};
pub(super) const DEFAULT_DESCRIPTOR: DmacDescriptor = DmacDescriptor {
btctrl: BlockTransferControl::new(),
btcnt: 0,
srcaddr: 0 as *mut _,
dstaddr: 0 as *mut _,
descaddr: 0 as *mut _,
};

/// Writeback section. This static variable should never be written to in an
/// interrupt or thread context.
pub(super) static mut WRITEBACK: [DmacDescriptor; NUM_CHANNELS] =
[DEFAULT_DESCRIPTOR; NUM_CHANNELS];

// Writeback section. This static variable should never be written to in an
// interrupt or thread context.
#[doc(hidden)]
static mut WRITEBACK: [DmacDescriptor; NUM_CHANNELS] = [DEFAULT_DESCRIPTOR; NUM_CHANNELS];
// Descriptor section. This static variable should never be written to in an
// interrupt or thread context.
#[doc(hidden)]
static mut DESCRIPTOR_SECTION: [DmacDescriptor; NUM_CHANNELS] = [DEFAULT_DESCRIPTOR; NUM_CHANNELS];
/// Descriptor section. This static variable should never be written to in
/// an interrupt or thread context.
pub(super) static mut DESCRIPTOR_SECTION: [DmacDescriptor; NUM_CHANNELS] =
[DEFAULT_DESCRIPTOR; NUM_CHANNELS];
}

pub mod channel;
pub mod dma_controller;
Expand Down
10 changes: 5 additions & 5 deletions hal/src/dmac/transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
use super::{
channel::{AnyChannel, Busy, CallbackStatus, Channel, ChannelId, InterruptFlags, Ready},
dma_controller::{ChId, TriggerAction, TriggerSource},
BlockTransferControl, DmacDescriptor, Error, Result, DESCRIPTOR_SECTION,
sram, Error, Result,
};
use crate::typelevel::{Is, Sealed};
use core::{ptr::null_mut, sync::atomic};
Expand Down Expand Up @@ -378,7 +378,7 @@ where
// SAFETY This is safe as we are only reading the descriptor's address,
// and not actually writing any data to it. We also assume the descriptor
// will never be moved.
&mut DESCRIPTOR_SECTION[id] as *mut _
&mut sram::DESCRIPTOR_SECTION[id] as *mut _
} else {
null_mut()
};
Expand All @@ -397,13 +397,13 @@ where
// that a transfer has completed iff the blockact field in btctrl is not
// set to SUSPEND. We implicitly leave blockact set to NOACT here; if
// that changes Channel::xfer_complete() may need to be modified.
let btctrl = BlockTransferControl::new()
let btctrl = sram::BlockTransferControl::new()
.with_srcinc(src_inc)
.with_dstinc(dst_inc)
.with_beatsize(S::Beat::BEATSIZE)
.with_valid(true);

let xfer_descriptor = DmacDescriptor {
let xfer_descriptor = sram::DmacDescriptor {
// Next descriptor address: 0x0 terminates the transaction (no linked list),
// any other address points to the next block descriptor
descaddr,
Expand All @@ -421,7 +421,7 @@ where
// belonging to OUR channel. We assume this is the only place
// in the entire library that this section or the array
// will be written to.
DESCRIPTOR_SECTION[id] = xfer_descriptor;
sram::DESCRIPTOR_SECTION[id] = xfer_descriptor;
}
}

Expand Down

0 comments on commit 3dff3a6

Please sign in to comment.