diff --git a/hal/src/dmac/channel/mod.rs b/hal/src/dmac/channel/mod.rs index 9f10486f2fd..7967effe4d3 100644 --- a/hal/src/dmac/channel/mod.rs +++ b/hal/src/dmac/channel/mod.rs @@ -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}; diff --git a/hal/src/dmac/dma_controller.rs b/hal/src/dmac/dma_controller.rs index 090af4ac273..b84c4353f6b 100644 --- a/hal/src/dmac/dma_controller.rs +++ b/hal/src/dmac/dma_controller.rs @@ -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}; @@ -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}; @@ -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, } @@ -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 { @@ -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 ----- // diff --git a/hal/src/dmac/mod.rs b/hal/src/dmac/mod.rs index e5c539bd767..e9cb8450a7b 100644 --- a/hal/src/dmac/mod.rs +++ b/hal/src/dmac/mod.rs @@ -1,5 +1,3 @@ -#![allow(unused_braces)] - //! # Direct Memory Access Controller //! //! This library provides a type-safe API with compile-time guarantees @@ -253,8 +251,6 @@ use atsamd_hal_macros::hal_cfg; -use modular_bitfield::prelude::*; - pub use channel::*; pub use dma_controller::*; pub use transfer::*; @@ -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; diff --git a/hal/src/dmac/transfer.rs b/hal/src/dmac/transfer.rs index 657c7970791..89c9da8c19a 100644 --- a/hal/src/dmac/transfer.rs +++ b/hal/src/dmac/transfer.rs @@ -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}; @@ -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() }; @@ -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, @@ -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; } }