diff options
Diffstat (limited to 'drivers/edma/src/tcd.rs')
| -rw-r--r-- | drivers/edma/src/tcd.rs | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/drivers/edma/src/tcd.rs b/drivers/edma/src/tcd.rs new file mode 100644 index 0000000..1e76533 --- /dev/null +++ b/drivers/edma/src/tcd.rs @@ -0,0 +1,174 @@ +//! Transfer control descriptor. + +/// Common TCD layout for all eDMA implementations. +/// +/// Fields may vary. See inline notes. +mod common { + #[repr(C, align(32))] + #[allow(non_snake_case)] + pub struct RegisterBlock { + pub SADDR: u32, + // Signed numbers for offsets / 'last' members intentional. + // The hardware treats them as signed numbers. + pub SOFF: i16, + pub ATTR: u16, + pub NBYTES: u32, + pub SLAST: i32, + pub DADDR: u32, + pub DOFF: i16, + /// The minor loop channel link field may vary in size + /// depending on the implementation. Not worried right + /// now, since we don't support minor loop linking. + pub CITER: u16, + pub DLAST_SGA: i32, + /// These fields vary across all of eDMA, eDMA3 and + /// eDMA4! + /// + /// Major loop channel linking field size changes as + /// a function of the number of DMA channels. + /// + /// eDMA and eDMA3 have bandwidth control. eDMA4 has + /// transfer mode control for read-only / write-only + /// DMA transfers. Field is the same size. + /// + /// In the low byte, high nibble, eDMA has DONE and + /// ACTIVE. eDMA3 and eDMA4 have things we probably don't + /// need. Low byte, low nibble is the same. + /// + /// So we'll need to change how we handle DONE and + /// ACTIVE access. They can't always dispatch to this + /// register. + pub CSR: u16, + /// See CITER documentation note about eDMA3 bitfield + /// size when minor loop channel linking is enabled. + pub BITER: u16, + } + + const _: () = assert!(32 == size_of::<RegisterBlock>()); + + ral_registers::register! { + pub SADDR<u32> RW [] + } + + ral_registers::register! { + pub SOFF<i16> RW [] + } + + ral_registers::register! { + pub ATTR<u16> RW [ + #[doc = "Destination data transfer size"] + DSIZE start(0) width(3) RW {} + #[doc = "Destination Address Modulo"] + DMOD start(3) width(5) RW {} + #[doc = "Source data transfer size"] + SSIZE start(8) width(3) RW {} + #[doc = "Source Address Modulo"] + SMOD start(11) width(5) RW {} + ] + } + + ral_registers::register! { + pub NBYTES<u32> RW [] + } + + ral_registers::register! { + pub SLAST<i32> RW [] + } + + ral_registers::register! { + pub DADDR<u32> RW [] + } + + ral_registers::register! { + pub DOFF<i16> RW [] + } + + ral_registers::register! { + pub CITER<u16> RW [] + } + + ral_registers::register! { + pub DLAST_SGA<i32> RW [] + } + + ral_registers::register! { + pub CSR<u16> RW [ + START start(0) width(1) RW {} + INTMAJOR start(1) width(1) RW {} + DREQ start(3) width(1) RW {} + ACTIVE start(6) width(1) RW {} + DONE start(7) width(1) RW {} + ] + } + + ral_registers::register! { + pub BITER<u16> RW [] + } +} + +pub mod edma { + pub use super::common::*; +} + +pub mod edma34 { + #[repr(C, align(32))] + #[allow(non_snake_case)] + pub struct RegisterBlock { + pub CSR: u32, + pub ES: u32, + pub INT: u32, + pub SBR: u32, + pub PRI: u32, + pub MUX: u32, + /// Available on eDMA4, and reserved on eDMA3. + _mattr: u32, + pub TCD: super::common::RegisterBlock, + _reserved: [u8; 0x1_0000 - (4 * 8 + size_of::<super::common::RegisterBlock>())], + } + + const _: () = assert!(core::mem::offset_of!(RegisterBlock, TCD) == 0x20); + const _: () = assert!(size_of::<RegisterBlock>() == 0x1_0000); + + ral_registers::register! { + pub CSR<u32> RW [ + ACTIVE start(31) width(1) RW {} + DONE start(30) width(1) RW {} + ERQ start(0) width(1) RW {} + ] + } + + ral_registers::register! { + pub SBR<u32> RW [ + EMI start(16) width(1) RW {} + PAL start(15) width(1) RW {} + SEC start(14) width(1) RW {} + ] + } + + ral_registers::register! { + pub INT<u32> RW [] + } + + ral_registers::register! { + pub ES<u32> RW [ + ERR start(31) width(1) RW {} + ] + } + + ral_registers::register! { + pub MUX<u32> RW [ + SRC start(0) width(6) RW {} + ] + } + + #[allow(non_snake_case)] + pub mod TCD { + pub use crate::tcd::common::{ + ATTR, BITER, CITER, DADDR, DLAST_SGA, DOFF, NBYTES, SADDR, SLAST, SOFF, + }; + + pub mod CSR { + pub use crate::tcd::common::CSR::{DREQ, INTMAJOR, START, access}; + } + } +} |
