aboutsummaryrefslogtreecommitdiff
path: root/drivers/edma/src/dma.rs
diff options
context:
space:
mode:
authorIan McIntyre <me@mciantyre.dev>2025-11-30 18:52:34 -0500
committerIan McIntyre <me@mciantyre.dev>2025-11-30 19:10:51 -0500
commit76199f21616ad86cf68f3b063c1ce23c6fc5a52f (patch)
tree4c076d0afd649803a2bd9a5ed5cbb1f1c74fb459 /drivers/edma/src/dma.rs
First commit
Diffstat (limited to 'drivers/edma/src/dma.rs')
-rw-r--r--drivers/edma/src/dma.rs161
1 files changed, 161 insertions, 0 deletions
diff --git a/drivers/edma/src/dma.rs b/drivers/edma/src/dma.rs
new file mode 100644
index 0000000..8f4cb9a
--- /dev/null
+++ b/drivers/edma/src/dma.rs
@@ -0,0 +1,161 @@
+//! DMA controllers.
+
+pub mod edma {
+ use crate::tcd::edma as tcd;
+
+ #[repr(C)]
+ #[allow(non_snake_case)]
+ pub struct RegisterBlock {
+ /// Control Register
+ pub CR: u32,
+ /// Error Status Register
+ pub ES: u32,
+ _reserved1: [u32; 1],
+ /// Enable Request Register
+ pub ERQ: u32,
+ _reserved2: [u32; 1],
+ /// Enable Error Interrupt Register
+ pub EEI: u32,
+ /// Clear Enable Error Interrupt Register
+ pub CEEI: u8,
+ /// Set Enable Error Interrupt Register
+ pub SEEI: u8,
+ /// Clear Enable Request Register
+ pub CERQ: u8,
+ /// Set Enable Request Register
+ pub SERQ: u8,
+ /// Clear DONE Status Bit Register
+ pub CDNE: u8,
+ /// Set START Bit Register
+ pub SSRT: u8,
+ /// Clear Error Register
+ pub CERR: u8,
+ /// Clear Interrupt Request Register
+ pub CINT: u8,
+ _reserved3: [u32; 1],
+ /// Interrupt Request Register
+ pub INT: u32,
+ _reserved4: [u32; 1],
+ /// Error Register
+ pub ERR: u32,
+ _reserved5: [u32; 1],
+ /// Hardware Request Status Register
+ pub HRS: u32,
+ _reserved6: [u32; 3],
+ /// Enable Asynchronous Request in Stop Register
+ pub EARS: u32,
+ _reserved7: [u32; 46],
+ /// Channel Priority Registers
+ pub DCHPRI: [u8; 32],
+ _reserved8: [u32; 952],
+ /// Transfer Control Descriptors
+ pub TCD: [tcd::RegisterBlock; 32],
+ }
+
+ const _: () = assert!(core::mem::offset_of!(RegisterBlock, DCHPRI) == 0x100);
+ const _: () = assert!(core::mem::offset_of!(RegisterBlock, TCD) == 0x1000);
+
+ /// Produce an index into `DCHPRI` for the given channel.
+ pub const fn dchpri_index(channel: usize) -> usize {
+ const X: [usize; 32] = [
+ 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12, 19, 18, 17, 16, 23, 22, 21, 20,
+ 27, 26, 25, 24, 31, 30, 29, 28,
+ ];
+ X[channel]
+ }
+
+ ral_registers::register! {
+ pub SERQ<u8> WO []
+ }
+
+ ral_registers::register! {
+ pub CERQ<u8> WO []
+ }
+
+ ral_registers::register! {
+ pub HRS<u32> RO []
+ }
+
+ ral_registers::register! {
+ pub INT<u32> RW []
+ }
+
+ ral_registers::register! {
+ pub CINT<u8> WO []
+ }
+
+ ral_registers::register! {
+ pub CDNE<u8> WO []
+ }
+
+ ral_registers::register! {
+ pub ERR<u32> RW []
+ }
+
+ ral_registers::register! {
+ pub CERR<u8> WO []
+ }
+
+ ral_registers::register! {
+ pub ERQ<u32> RW []
+ }
+}
+
+pub mod edma3 {
+ use crate::tcd::edma34 as tcd;
+
+ #[repr(C)]
+ #[allow(non_snake_case)]
+ pub struct RegisterBlock {
+ pub CSR: u32,
+ pub ES: u32,
+ pub INT: u32,
+ pub HRS: u32,
+ _reserved0: [u8; 0x100 - 0x10],
+ pub GRPRI: [u32; 32],
+ _reserved1: [u8; 0x1_0000 - 0x180],
+ pub TCD: [tcd::RegisterBlock; 32],
+ }
+
+ const _: () = assert!(core::mem::offset_of!(RegisterBlock, GRPRI) == 0x100);
+ const _: () = assert!(core::mem::offset_of!(RegisterBlock, TCD) == 0x1_0000);
+
+ ral_registers::register! {
+ pub CSR<u32> RW [
+ GMRC start(7) width(1) RW {}
+ ]
+ }
+
+ ral_registers::register! {
+ pub HRS<u32> RO []
+ }
+
+ ral_registers::register! {
+ pub INT<u32> RO []
+ }
+}
+
+pub mod edma4 {
+ use crate::tcd::edma34 as tcd;
+
+ #[repr(C)]
+ #[allow(non_snake_case)]
+ pub struct RegisterBlock {
+ pub CSR: u32,
+ pub ES: u32,
+ pub INT_LOW: u32,
+ pub INT_HIGH: u32,
+ pub HRS_LOW: u32,
+ pub HRS_HIGH: u32,
+ _reserved0: [u8; 0x100 - 0x18],
+ pub GRPRI: [u32; 64],
+ _reserved1: [u8; 0x1_0000 - 0x200],
+ pub TCD: [tcd::RegisterBlock; 64],
+ }
+
+ const _: () = assert!(core::mem::offset_of!(RegisterBlock, GRPRI) == 0x100);
+ const _: () = assert!(core::mem::offset_of!(RegisterBlock, TCD) == 0x1_0000);
+
+ pub use super::edma3::CSR;
+ pub use super::edma3::{HRS as HRS_LOW, HRS as HRS_HIGH};
+}