aboutsummaryrefslogtreecommitdiff
path: root/drivers/edma/src/dma.rs
blob: 8f4cb9a3ac510f8108665e245a122586c8992885 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
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};
}