stm32f303xc/
dma.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5use kernel::platform::chip::ClockInterface;
6use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite};
7use kernel::utilities::StaticRef;
8
9use crate::rcc;
10
11/// DMA controller
12#[repr(C)]
13struct Dma1Registers {
14    /// interrupt status register
15    isr: ReadOnly<u32, ISR::Register>,
16    /// interrupt flag clear register
17    ifcr: ReadWrite<u32, IFCR::Register>,
18
19    /// channel 1 configuration register
20    ccr1: ReadWrite<u32, CCR::Register>,
21    /// channel 1 number of data register
22    cndtr1: ReadWrite<u32, CNDTR::Register>,
23    /// channel 1 peripheral address register
24    cpar1: ReadWrite<u32, CPAR::Register>,
25    /// channel 1 memory address register
26    cmar1: ReadWrite<u32, CMAR::Register>,
27
28    _reserved0: [u8; 4],
29
30    /// channel 2 configuration register
31    ccr2: ReadWrite<u32, CCR::Register>,
32    /// channel 2 number of data register
33    cndtr2: ReadWrite<u32, CNDTR::Register>,
34    /// channel 2 peripheral address register
35    cpar2: ReadWrite<u32, CPAR::Register>,
36    /// channel 2 memory address register
37    cmar2: ReadWrite<u32, CMAR::Register>,
38
39    _reserved1: [u8; 4],
40
41    /// channel 3 configuration register
42    ccr3: ReadWrite<u32, CCR::Register>,
43    /// channel 3 number of data register
44    cndtr3: ReadWrite<u32, CNDTR::Register>,
45    /// channel 3 peripheral address register
46    cpar3: ReadWrite<u32, CPAR::Register>,
47    /// channel 3 memory address register
48    cmar3: ReadWrite<u32, CMAR::Register>,
49
50    _reserved2: [u8; 4],
51
52    /// channel 4 configuration register
53    ccr4: ReadWrite<u32, CCR::Register>,
54    /// channel 4 number of data register
55    cndtr4: ReadWrite<u32, CNDTR::Register>,
56    /// channel 4 peripheral address register
57    cpar4: ReadWrite<u32, CPAR::Register>,
58    /// channel 4 memory address register
59    cmar4: ReadWrite<u32, CMAR::Register>,
60
61    _reserved3: [u8; 4],
62
63    /// channel 5 configuration register
64    ccr5: ReadWrite<u32, CCR::Register>,
65    /// channel 5 number of data register
66    cndtr5: ReadWrite<u32, CNDTR::Register>,
67    /// channel 5 peripheral address register
68    cpar5: ReadWrite<u32, CPAR::Register>,
69    /// channel 5 memory address register
70    cmar5: ReadWrite<u32, CMAR::Register>,
71
72    _reserved4: [u8; 4],
73
74    /// channel 6 configuration register
75    ccr6: ReadWrite<u32, CCR::Register>,
76    /// channel 6 number of data register
77    cndtr6: ReadWrite<u32, CNDTR::Register>,
78    /// channel 6 peripheral address register
79    cpar6: ReadWrite<u32, CPAR::Register>,
80    /// channel 6 memory address register
81    cmar6: ReadWrite<u32, CMAR::Register>,
82
83    _reserved5: [u8; 4],
84
85    /// channel 7 configuration register
86    ccr7: ReadWrite<u32, CCR::Register>,
87    /// channel 7 number of data register
88    cndtr7: ReadWrite<u32, CNDTR::Register>,
89    /// channel 7 peripheral address register
90    cpar7: ReadWrite<u32, CPAR::Register>,
91    /// channel 7 memory address register
92    cmar7: ReadWrite<u32, CMAR::Register>,
93}
94
95register_bitfields![u32,
96    ISR [
97        /// Channel 7 transfer error flag
98        TEIF7 OFFSET(27) NUMBITS(1) [],
99        /// Channel 7 half transfer flag
100        HTIF7 OFFSET(26) NUMBITS(1) [],
101        /// Channel 7 transfer complete flag
102        TCIF7 OFFSET(25) NUMBITS(1) [],
103        /// Channel 7 global interrupt flag
104        GIF7 OFFSET(24) NUMBITS(1) [],
105
106        /// Channel 6 transfer error flag
107        TEIF6 OFFSET(23) NUMBITS(1) [],
108        /// Channel 6 half transfer flag
109        HTIF6 OFFSET(22) NUMBITS(1) [],
110        /// Channel 6 transfer complete flag
111        TCIF6 OFFSET(21) NUMBITS(1) [],
112        /// Channel 6 global interrupt flag
113        GIF6 OFFSET(20) NUMBITS(1) [],
114
115        /// Channel 5 transfer error flag
116        TEIF5 OFFSET(19) NUMBITS(1) [],
117        /// Channel 5 half transfer flag
118        HTIF5 OFFSET(18) NUMBITS(1) [],
119        /// Channel 5 transfer complete flag
120        TCIF5 OFFSET(17) NUMBITS(1) [],
121        /// Channel 5 global interrupt flag
122        GIF5 OFFSET(16) NUMBITS(1) [],
123
124        /// Channel 4 transfer error flag
125        TEIF4 OFFSET(15) NUMBITS(1) [],
126        /// Channel 4 half transfer flag
127        HTIF4 OFFSET(14) NUMBITS(1) [],
128        /// Channel 4 transfer complete flag
129        TCIF4 OFFSET(13) NUMBITS(1) [],
130        /// Channel 4 global interrupt flag
131        GIF4 OFFSET(12) NUMBITS(1) [],
132
133        /// Channel 3 transfer error flag
134        TEIF3 OFFSET(11) NUMBITS(1) [],
135        /// Channel 3 half transfer flag
136        HTIF3 OFFSET(10) NUMBITS(1) [],
137        /// Channel 3 transfer complete flag
138        TCIF3 OFFSET(9) NUMBITS(1) [],
139        /// Channel 3 global interrupt flag
140        GIF3 OFFSET(8) NUMBITS(1) [],
141
142        /// Channel 2 transfer error flag
143        TEIF2 OFFSET(7) NUMBITS(1) [],
144        /// Channel 2 half transfer flag
145        HTIF2 OFFSET(6) NUMBITS(1) [],
146        /// Channel 2 transfer complete flag
147        TCIF2 OFFSET(5) NUMBITS(1) [],
148        /// Channel 2 global interrupt flag
149        GIF2 OFFSET(4) NUMBITS(1) [],
150
151        /// Channel 1 transfer error flag
152        TEIF1 OFFSET(3) NUMBITS(1) [],
153        /// Channel 1 half transfer flag
154        HTIF1 OFFSET(2) NUMBITS(1) [],
155        /// Channel 1 transfer complete flag
156        TCIF1 OFFSET(1) NUMBITS(1) [],
157        /// Channel 1 global interrupt flag
158        GIF1 OFFSET(0) NUMBITS(1) []
159    ],
160    IFCR [
161        /// Channel 7 transfer error clear
162        CTEIF7 OFFSET(27) NUMBITS(1) [],
163        /// Channel 7 half transfer clear
164        CHTIF7 OFFSET(26) NUMBITS(1) [],
165        /// Channel 7 transfer complete clear
166        CTCIF7 OFFSET(25) NUMBITS(1) [],
167        /// Channel 7 global interrupt clear
168        CGIF7 OFFSET(24) NUMBITS(1) [],
169
170        /// Channel 6 transfer error clear
171        CTEIF6 OFFSET(23) NUMBITS(1) [],
172        /// Channel 6 half transfer clear
173        CHTIF6 OFFSET(22) NUMBITS(1) [],
174        /// Channel 6 transfer complete clear
175        CTCIF6 OFFSET(21) NUMBITS(1) [],
176        /// Channel 6 global interrupt clear
177        CGIF6 OFFSET(20) NUMBITS(1) [],
178
179        /// Channel 5 transfer error clear
180        CTEIF5 OFFSET(19) NUMBITS(1) [],
181        /// Channel 5 half transfer clear
182        CHTIF5 OFFSET(18) NUMBITS(1) [],
183        /// Channel 5 transfer complete clear
184        CTCIF5 OFFSET(17) NUMBITS(1) [],
185        /// Channel 5 global interrupt clear
186        CGIF5 OFFSET(16) NUMBITS(1) [],
187
188        /// Channel 4 transfer error clear
189        CTEIF4 OFFSET(15) NUMBITS(1) [],
190        /// Channel 4 half transfer clear
191        CHTIF4 OFFSET(14) NUMBITS(1) [],
192        /// Channel 4 transfer complete clear
193        CTCIF4 OFFSET(13) NUMBITS(1) [],
194        /// Channel 4 global interrupt clear
195        CGIF4 OFFSET(12) NUMBITS(1) [],
196
197        /// Channel 3 transfer error clear
198        CTEIF3 OFFSET(11) NUMBITS(1) [],
199        /// Channel 3 half transfer clear
200        CHTIF3 OFFSET(10) NUMBITS(1) [],
201        /// Channel 3 transfer complete clear
202        CTCIF3 OFFSET(9) NUMBITS(1) [],
203        /// Channel 3 global interrupt clear
204        CGIF3 OFFSET(8) NUMBITS(1) [],
205
206        /// Channel 2 transfer error clear
207        CTEIF2 OFFSET(7) NUMBITS(1) [],
208        /// Channel 2 half transfer clear
209        CHTIF2 OFFSET(6) NUMBITS(1) [],
210        /// Channel 2 transfer complete clear
211        CTCIF2 OFFSET(5) NUMBITS(1) [],
212        /// Channel 2 global interrupt clear
213        CGIF2 OFFSET(4) NUMBITS(1) [],
214
215        /// Channel 1 transfer error clear
216        CTEIF1 OFFSET(3) NUMBITS(1) [],
217        /// Channel 1 half transfer clear
218        CHTIF1 OFFSET(2) NUMBITS(1) [],
219        /// Channel 1 transfer complete clear
220        CTCIF1 OFFSET(1) NUMBITS(1) [],
221        /// Channel 1 global interrupt clear
222        CGIF1 OFFSET(0) NUMBITS(1) []
223    ],
224    CCR [
225        /// Memory to memory mode
226        MEM2MEM OFFSET(14) NUMBITS(1) [],
227        /// Channel priority level
228        PL OFFSET(12) NUMBITS(2) [],
229        /// Memory size
230        MSIZE OFFSET(10) NUMBITS(2) [],
231        /// Peripheral size
232        PSIZE OFFSET(8) NUMBITS(2) [],
233        /// Memory increment mode
234        MINC OFFSET(7) NUMBITS(1) [],
235        /// Peripheral increment mode
236        PINC OFFSET(6) NUMBITS(1) [],
237        /// Circular mode
238        CIRC OFFSET(5) NUMBITS(1) [],
239        /// Data transfer direction
240        DIR OFFSET(4) NUMBITS(1) [],
241        /// Transfer error interrupt enable
242        TEIE OFFSET(3) NUMBITS(1) [],
243        /// Half transfer interrupt enable
244        HTIE OFFSET(2) NUMBITS(1) [],
245        /// Transfer complete interrupt enable
246        TCIE OFFSET(1) NUMBITS(1) [],
247        /// Channel enable
248        EN OFFSET(0) NUMBITS(1) []
249    ],
250    CNDTR [
251        /// Number of data to transfer
252        NDT OFFSET(0) NUMBITS(16) []
253    ],
254    CPAR [
255        /// Peripheral address
256        PA OFFSET(0) NUMBITS(32) []
257    ],
258    CMAR [
259        /// Memory address
260        MA OFFSET(0) NUMBITS(32) []
261    ]
262];
263
264const DMA1_BASE: StaticRef<Dma1Registers> =
265    unsafe { StaticRef::new(0x4002_0000 as *const Dma1Registers) };
266
267#[allow(dead_code)]
268#[repr(u32)]
269enum ChannelId {
270    Channel1 = 0b000,
271    Channel2 = 0b001,
272    Channel3 = 0b010,
273    Channel4 = 0b011,
274    Channel5 = 0b100,
275    Channel6 = 0b101,
276    Channel7 = 0b110,
277}
278
279/// DMA transfer priority. Section 13.5.3
280#[allow(dead_code)]
281#[repr(u32)]
282enum Priority {
283    Low = 0b00,
284    Medium = 0b01,
285    High = 0b10,
286    VeryHigh = 0b11,
287}
288
289/// DMA data size. Section 13.5.3
290#[allow(dead_code)]
291#[repr(u32)]
292enum Size {
293    Byte = 0b00,
294    HalfWord = 0b01,
295    Word = 0b10,
296}
297
298#[allow(unused)]
299struct Msize(Size);
300#[allow(unused)]
301struct Psize(Size);
302
303/// List of peripherals managed by DMA1
304/// not complete yet
305#[allow(non_camel_case_types, non_snake_case)]
306#[derive(Copy, Clone, PartialEq)]
307pub enum Dma1Peripheral {
308    USART1_TX,
309    USART1_RX,
310}
311
312pub struct Dma1<'a> {
313    _registers: StaticRef<Dma1Registers>,
314    clock: Dma1Clock<'a>,
315}
316
317impl<'a> Dma1<'a> {
318    pub const fn new(rcc: &'a rcc::Rcc) -> Self {
319        Self {
320            _registers: DMA1_BASE,
321            clock: Dma1Clock(rcc::PeripheralClock::new(
322                rcc::PeripheralClockType::AHB(rcc::HCLK::DMA1),
323                rcc,
324            )),
325        }
326    }
327
328    pub fn is_enabled_clock(&self) -> bool {
329        self.clock.is_enabled()
330    }
331
332    pub fn enable_clock(&self) {
333        self.clock.enable();
334    }
335
336    pub fn disable_clock(&self) {
337        self.clock.disable();
338    }
339}
340
341struct Dma1Clock<'a>(rcc::PeripheralClock<'a>);
342
343impl ClockInterface for Dma1Clock<'_> {
344    fn is_enabled(&self) -> bool {
345        self.0.is_enabled()
346    }
347
348    fn enable(&self) {
349        self.0.enable();
350    }
351
352    fn disable(&self) {
353        self.0.disable();
354    }
355}