Skip to content

Commit 7861a33

Browse files
committed
gpdma + spi: move generic DMA structs to gpdma::periph
1 parent 6f6b18f commit 7861a33

File tree

1 file changed

+9
-180
lines changed

1 file changed

+9
-180
lines changed

src/spi/dma.rs

Lines changed: 9 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,14 @@
1-
use core::{
2-
marker::PhantomData,
3-
ops::{Deref, DerefMut},
4-
};
1+
use core::ops::{Deref, DerefMut};
52

6-
use embedded_dma::{ReadBuffer, WriteBuffer};
73
use embedded_hal::spi::ErrorType;
84
use embedded_hal_async::spi::SpiBus;
95

106
use crate::gpdma::{
11-
config::{DmaConfig, MemoryToPeripheral, PeripheralToMemory, TransferType},
12-
ChannelRegs, DmaChannel, DmaTransfer, Error as DmaError, Word as DmaWord,
7+
config::DmaConfig, periph::{DmaDuplex, DmaRx, DmaTx, Rx, RxAddr, Tx, TxAddr}, ChannelRegs, DmaChannel, DmaTransfer, Error as DmaError, Word as DmaWord
138
};
149

1510
use super::{Error, Instance, Spi, Word};
1611

17-
pub trait TxAddr<W: DmaWord> {
18-
/// Returns a pointer to the peripheral's transmit data register.
19-
///
20-
/// # Safety
21-
///
22-
/// The caller must ensure that the returned pointer is only used when it is valid to access
23-
/// the peripheral's transmit data register, and that no data races or invalid memory accesses
24-
/// occur.
25-
unsafe fn tx_addr() -> *mut W;
26-
}
27-
28-
pub trait RxAddr<W: DmaWord> {
29-
/// Returns a pointer to the peripheral's receive data register.
30-
///
31-
/// # Safety
32-
///
33-
/// The caller must ensure that the returned pointer is only used when it is valid to access
34-
/// the peripheral's receive data register, and that no data races or invalid memory accesses
35-
/// occur.
36-
unsafe fn rx_addr() -> *const W;
37-
}
38-
3912
impl<SPI: Instance, W: DmaWord> TxAddr<W> for SPI {
4013
unsafe fn tx_addr() -> *mut W {
4114
(*SPI::ptr()).txdr().as_ptr() as *mut W
@@ -86,151 +59,6 @@ where
8659
}
8760
}
8861

89-
trait Tx<W> {
90-
fn init_tx_transfer<'a>(
91-
&'a self,
92-
config: DmaConfig<MemoryToPeripheral, W, W>,
93-
words: &'a [W],
94-
) -> DmaTransfer<'a, impl ChannelRegs>;
95-
}
96-
97-
trait Rx<W> {
98-
fn init_rx_transfer<'a>(
99-
&'a self,
100-
config: DmaConfig<PeripheralToMemory, W, W>,
101-
words: &'a mut [W],
102-
) -> DmaTransfer<'a, impl ChannelRegs>;
103-
}
104-
105-
pub struct DmaRx<PERIPH, W, CH> {
106-
_periph: PhantomData<PERIPH>,
107-
_word: PhantomData<W>,
108-
channel: DmaChannel<CH>,
109-
}
110-
111-
impl<PERIPH, W, CH: ChannelRegs> DmaRx<PERIPH, W, CH> {
112-
fn new(channel: DmaChannel<CH>) -> Self {
113-
Self {
114-
_periph: PhantomData,
115-
_word: PhantomData,
116-
channel,
117-
}
118-
}
119-
}
120-
121-
unsafe impl<PERIPH: RxAddr<W>, W: DmaWord, CH> ReadBuffer for &DmaRx<PERIPH, W, CH> {
122-
type Word = W;
123-
124-
unsafe fn read_buffer(&self) -> (*const Self::Word, usize) {
125-
(PERIPH::rx_addr(), 1)
126-
}
127-
}
128-
129-
impl<PERIPH, W, CH> Rx<W> for DmaRx<PERIPH, W, CH>
130-
where
131-
PERIPH: RxAddr<W>,
132-
CH: ChannelRegs,
133-
W: DmaWord,
134-
{
135-
fn init_rx_transfer<'a>(
136-
&'a self,
137-
config: DmaConfig<PeripheralToMemory, W, W>,
138-
words: &'a mut [W],
139-
) -> DmaTransfer<'a, impl ChannelRegs> {
140-
DmaTransfer::peripheral_to_memory(config, &self.channel, self, words)
141-
}
142-
}
143-
144-
pub struct DmaTx<PERIPH, W, CH> {
145-
_periph: PhantomData<PERIPH>,
146-
_word: PhantomData<W>,
147-
channel: DmaChannel<CH>,
148-
}
149-
150-
impl<PERIPH, W, CH: ChannelRegs> DmaTx<PERIPH, W, CH> {
151-
fn new(channel: DmaChannel<CH>) -> Self {
152-
Self {
153-
_periph: PhantomData,
154-
_word: PhantomData,
155-
channel,
156-
}
157-
}
158-
}
159-
160-
unsafe impl<PERIPH: TxAddr<W>, W: DmaWord, CH> WriteBuffer for &DmaTx<PERIPH, W, CH> {
161-
type Word = W;
162-
163-
unsafe fn write_buffer(&mut self) -> (*mut Self::Word, usize) {
164-
(PERIPH::tx_addr(), 1)
165-
}
166-
}
167-
168-
impl<PERIPH, W, CH> Tx<W> for DmaTx<PERIPH, W, CH>
169-
where
170-
PERIPH: TxAddr<W>,
171-
CH: ChannelRegs,
172-
W: DmaWord,
173-
{
174-
fn init_tx_transfer<'a>(
175-
&'a self,
176-
config: DmaConfig<MemoryToPeripheral, W, W>,
177-
words: &'a [W],
178-
) -> DmaTransfer<'a, impl ChannelRegs> {
179-
DmaTransfer::memory_to_peripheral(config, &self.channel, words, self)
180-
}
181-
}
182-
183-
pub struct DmaDuplex<PERIPH, W, TX, RX> {
184-
tx: DmaTx<PERIPH, W, TX>,
185-
rx: DmaRx<PERIPH, W, RX>,
186-
}
187-
188-
impl<PERIPH, W, TX, RX> DmaDuplex<PERIPH, W, TX, RX>
189-
where
190-
PERIPH: TxAddr<W> + RxAddr<W>,
191-
W: DmaWord,
192-
TX: ChannelRegs,
193-
RX: ChannelRegs,
194-
{
195-
fn new(tx: DmaChannel<TX>, rx: DmaChannel<RX>) -> Self {
196-
Self {
197-
tx: DmaTx::new(tx),
198-
rx: DmaRx::new(rx),
199-
}
200-
}
201-
}
202-
203-
impl<PERIPH, W, TX, RX> Tx<W> for DmaDuplex<PERIPH, W, TX, RX>
204-
where
205-
PERIPH: TxAddr<W> + RxAddr<W>,
206-
W: DmaWord,
207-
TX: ChannelRegs,
208-
RX: ChannelRegs,
209-
{
210-
fn init_tx_transfer<'a>(
211-
&'a self,
212-
config: DmaConfig<MemoryToPeripheral, W, W>,
213-
words: &'a [W],
214-
) -> DmaTransfer<'a, impl ChannelRegs> {
215-
self.tx.init_tx_transfer(config, words)
216-
}
217-
}
218-
219-
impl<PERIPH, W, TX, RX> Rx<W> for DmaDuplex<PERIPH, W, TX, RX>
220-
where
221-
PERIPH: TxAddr<W> + RxAddr<W>,
222-
W: Word + DmaWord,
223-
TX: ChannelRegs,
224-
RX: ChannelRegs,
225-
{
226-
fn init_rx_transfer<'a>(
227-
&'a self,
228-
config: DmaConfig<PeripheralToMemory, W, W>,
229-
words: &'a mut [W],
230-
) -> DmaTransfer<'a, impl ChannelRegs> {
231-
self.rx.init_rx_transfer(config, words)
232-
}
233-
}
23462

23563
pub struct SpiDma<SPI, W: Word, MODE> {
23664
spi: Spi<SPI, W>,
@@ -277,12 +105,12 @@ where
277105
) -> Self {
278106
Self {
279107
spi,
280-
mode: DmaTx::new(channel),
108+
mode: DmaTx::from(channel),
281109
}
282110
}
283111

284112
pub fn free(self) -> (Spi<SPI, W>, DmaChannel<CH>) {
285-
(self.spi, self.mode.channel)
113+
(self.spi, self.mode.into())
286114
}
287115
}
288116

@@ -298,18 +126,18 @@ where
298126
) -> Self {
299127
Self {
300128
spi,
301-
mode: DmaRx::new(channel),
129+
mode: DmaRx::from(channel),
302130
}
303131
}
304132

305133
pub fn free(self) -> (Spi<SPI, W>, DmaChannel<CH>) {
306-
(self.spi, self.mode.channel)
134+
(self.spi, self.mode.into())
307135
}
308136
}
309137

310138
impl<SPI, W, TX, RX> SpiDma<SPI, W, DmaDuplex<SPI, W, TX, RX>>
311139
where
312-
SPI: Instance,
140+
SPI: Instance + TxAddr<W> + RxAddr<W>,
313141
W: Word + DmaWord,
314142
TX: ChannelRegs,
315143
RX: ChannelRegs,
@@ -326,7 +154,8 @@ where
326154
}
327155

328156
pub fn free(self) -> (Spi<SPI, W>, DmaChannel<TX>, DmaChannel<RX>) {
329-
(self.spi, self.mode.tx.channel, self.mode.rx.channel)
157+
let (tx, rx) = self.mode.free();
158+
(self.spi, tx, rx)
330159
}
331160
}
332161

0 commit comments

Comments
 (0)