1
- use core:: { marker:: PhantomData , num :: NonZeroUsize } ;
1
+ use core:: marker:: PhantomData ;
2
2
3
3
use embedded_dma:: { ReadBuffer , WriteBuffer } ;
4
4
5
5
use crate :: gpdma:: {
6
6
config:: { Config as DmaConfig , MemoryToPeripheral , PeripheralToMemory } ,
7
- Channel , Transfer as DmaTransfer , Word ,
7
+ Channel , ChannelRegs , Transfer as DmaTransfer , Word as DmaWord ,
8
8
} ;
9
9
10
- use super :: { Error , FrameSize , Instance , Spi } ;
10
+ use super :: { Error , Instance , Spi , Word } ;
11
11
12
12
pub struct DmaRx < SPI , W > {
13
13
_spi : PhantomData < SPI > ,
@@ -23,7 +23,7 @@ impl<SPI, W> DmaRx<SPI, W> {
23
23
}
24
24
}
25
25
26
- unsafe impl < SPI : Instance , W : FrameSize > ReadBuffer for DmaRx < SPI , W > {
26
+ unsafe impl < SPI : Instance , W : Word > ReadBuffer for DmaRx < SPI , W > {
27
27
type Word = W ;
28
28
29
29
unsafe fn read_buffer ( & self ) -> ( * const Self :: Word , usize ) {
@@ -45,27 +45,32 @@ impl<SPI, W> DmaTx<SPI, W> {
45
45
}
46
46
}
47
47
48
- unsafe impl < SPI : Instance , W : FrameSize > WriteBuffer for DmaTx < SPI , W > {
48
+ unsafe impl < SPI : Instance , W : Word > WriteBuffer for DmaTx < SPI , W > {
49
49
type Word = W ;
50
50
51
51
unsafe fn write_buffer ( & mut self ) -> ( * mut Self :: Word , usize ) {
52
52
( ( * SPI :: ptr ( ) ) . txdr ( ) . as_ptr ( ) as * mut W , 1 )
53
53
}
54
54
}
55
55
56
- pub struct RxDmaTransfer < ' a , SPI , W : FrameSize , CH , D > {
56
+ pub struct RxDmaTransfer < ' a , SPI , W : Word , CH , D > {
57
57
spi : & ' a mut Spi < SPI , W > ,
58
58
transfer : DmaTransfer < CH , DmaRx < SPI , W > , D , PeripheralToMemory > ,
59
59
}
60
60
61
61
impl < ' a , SPI , W , CH , D > RxDmaTransfer < ' a , SPI , W , CH , D >
62
62
where
63
63
SPI : Instance ,
64
- W : FrameSize + Word ,
65
- CH : Channel ,
64
+ W : Word + DmaWord ,
65
+ CH : ChannelRegs ,
66
66
D : WriteBuffer < Word = W > ,
67
67
{
68
- pub fn new ( spi : & ' a mut Spi < SPI , W > , channel : CH , destination : D ) -> Self {
68
+ pub fn new (
69
+ spi : & ' a mut Spi < SPI , W > ,
70
+ channel : Channel < CH > ,
71
+ mut destination : D ,
72
+ ) -> Self {
73
+ let ( _, len) = unsafe { destination. write_buffer ( ) } ;
69
74
let config = DmaConfig :: new ( ) . with_request ( SPI :: rx_dma_request ( ) ) ;
70
75
let source = DmaRx :: new ( ) ;
71
76
let transfer = DmaTransfer :: peripheral_to_memory (
@@ -74,15 +79,17 @@ where
74
79
source,
75
80
destination,
76
81
) ;
82
+ spi. inner . set_transfer_word_count ( len as u16 ) ;
77
83
Self { spi, transfer }
78
84
}
79
85
80
- pub fn start ( & mut self ) -> Result < ( ) , crate :: gpdma:: Error > {
81
- self . spi . enable_rx_dma ( ) ;
86
+ pub fn start ( & mut self ) -> Result < ( ) , Error > {
87
+ self . spi . setup_read_mode ( ) ?;
88
+ self . spi . inner . enable_rx_dma ( ) ;
82
89
self . transfer . start_with ( |_, _| {
83
- self . spi . enable ( ) ;
84
- self . spi . start_transfer ( ) ;
85
- } )
90
+ self . spi . start_transaction ( ) ;
91
+ } ) ? ;
92
+ Ok ( ( ) )
86
93
}
87
94
88
95
pub fn is_dma_complete ( & self ) -> Result < bool , Error > {
@@ -93,28 +100,33 @@ where
93
100
94
101
pub fn end_transfer ( & mut self ) {
95
102
self . spi . end_transaction ( ) ;
96
- self . spi . disable_dma ( ) ;
103
+ self . spi . inner . disable_dma ( ) ;
97
104
}
98
105
99
- pub fn free ( self ) -> Result < ( CH , D ) , Error > {
106
+ pub fn free ( self ) -> Result < ( Channel < CH > , D ) , Error > {
100
107
let ( ch, _, d) = self . transfer . free ( ) ?;
101
108
Ok ( ( ch, d) )
102
109
}
103
110
}
104
111
105
- pub struct TxDmaTransfer < ' a , SPI , W : FrameSize , CH , S > {
112
+ pub struct TxDmaTransfer < ' a , SPI , W : Word , CH , S > {
106
113
spi : & ' a mut Spi < SPI , W > ,
107
114
transfer : DmaTransfer < CH , S , DmaTx < SPI , W > , MemoryToPeripheral > ,
108
115
}
109
116
110
117
impl < ' a , SPI , W , CH , S > TxDmaTransfer < ' a , SPI , W , CH , S >
111
118
where
112
119
SPI : Instance ,
113
- W : FrameSize + Word ,
114
- CH : Channel ,
120
+ W : DmaWord + Word ,
121
+ CH : ChannelRegs ,
115
122
S : ReadBuffer < Word = W > ,
116
123
{
117
- pub fn new ( spi : & ' a mut Spi < SPI , W > , channel : CH , source : S ) -> Self {
124
+ pub fn new (
125
+ spi : & ' a mut Spi < SPI , W > ,
126
+ channel : Channel < CH > ,
127
+ source : S ,
128
+ ) -> Self {
129
+ let ( _, len) = unsafe { source. read_buffer ( ) } ;
118
130
let config = DmaConfig :: new ( ) . with_request ( SPI :: tx_dma_request ( ) ) ;
119
131
let destination = DmaTx :: new ( ) ;
120
132
let transfer = DmaTransfer :: memory_to_peripheral (
@@ -123,15 +135,17 @@ where
123
135
source,
124
136
destination,
125
137
) ;
138
+ spi. inner . set_transfer_word_count ( len as u16 ) ;
126
139
Self { spi, transfer }
127
140
}
128
141
129
- pub fn start ( & mut self ) -> Result < ( ) , crate :: gpdma:: Error > {
142
+ pub fn start ( & mut self ) -> Result < ( ) , Error > {
143
+ self . spi . setup_write_mode ( ) ?;
130
144
self . transfer . start_with ( |_, _| {
131
- self . spi . enable_tx_dma ( ) ;
132
- self . spi . enable ( ) ;
133
- self . spi . start_transfer ( ) ;
134
- } )
145
+ self . spi . inner . enable_tx_dma ( ) ;
146
+ self . spi . start_transaction ( ) ;
147
+ } ) ? ;
148
+ Ok ( ( ) )
135
149
}
136
150
137
151
pub fn is_dma_complete ( & self ) -> Result < bool , Error > {
@@ -142,35 +156,34 @@ where
142
156
143
157
pub fn end_transfer ( & mut self ) {
144
158
self . spi . end_transaction ( ) ;
145
- self . spi . disable_dma ( ) ;
159
+ self . spi . inner . disable_dma ( ) ;
146
160
}
147
161
148
- pub fn free ( self ) -> Result < ( CH , S ) , Error > {
162
+ pub fn free ( self ) -> Result < ( Channel < CH > , S ) , Error > {
149
163
let ( ch, s, _) = self . transfer . free ( ) ?;
150
164
Ok ( ( ch, s) )
151
165
}
152
166
}
153
167
154
- pub struct DuplexDmaTransfer < ' a , SPI , W : FrameSize , TX , RX , S , D > {
168
+ pub struct DuplexDmaTransfer < ' a , SPI , W : Word , TX , RX , S , D > {
155
169
spi : & ' a mut Spi < SPI , W > ,
156
170
tx_transfer : DmaTransfer < TX , S , DmaTx < SPI , W > , MemoryToPeripheral > ,
157
171
rx_transfer : DmaTransfer < RX , DmaRx < SPI , W > , D , PeripheralToMemory > ,
158
- len : usize ,
159
172
}
160
173
161
174
impl < ' a , SPI , W , RX , TX , S , D > DuplexDmaTransfer < ' a , SPI , W , TX , RX , S , D >
162
175
where
163
176
SPI : Instance ,
164
- W : FrameSize + Word ,
165
- TX : Channel ,
166
- RX : Channel ,
177
+ W : Word + DmaWord ,
178
+ TX : ChannelRegs ,
179
+ RX : ChannelRegs ,
167
180
S : ReadBuffer < Word = W > ,
168
181
D : WriteBuffer < Word = W > ,
169
182
{
170
183
pub fn new (
171
184
spi : & ' a mut Spi < SPI , W > ,
172
- tx_channel : TX ,
173
- rx_channel : RX ,
185
+ tx_channel : Channel < TX > ,
186
+ rx_channel : Channel < RX > ,
174
187
source : S ,
175
188
mut destination : D ,
176
189
) -> Self {
@@ -192,11 +205,11 @@ where
192
205
rx_source,
193
206
destination,
194
207
) ;
208
+ spi. inner . set_transfer_word_count ( dest_len as u16 ) ;
195
209
Self {
196
210
spi,
197
211
tx_transfer,
198
212
rx_transfer,
199
- len : dest_len,
200
213
}
201
214
}
202
215
@@ -209,12 +222,12 @@ where
209
222
}
210
223
211
224
pub fn start ( & mut self ) -> Result < ( ) , Error > {
212
- self . spi . enable_rx_dma ( ) ;
213
- self . rx_transfer . start_nb ( ) ;
214
- self . tx_transfer . start_nb ( ) ;
215
- self . spi . enable_tx_dma ( ) ;
216
- self . spi
217
- . setup_transaction ( NonZeroUsize :: new ( self . len ) . unwrap ( ) ) ? ;
225
+ self . spi . check_transfer_mode ( ) ? ;
226
+ self . spi . inner . enable_rx_dma ( ) ;
227
+ self . rx_transfer . start_nonblocking ( ) ;
228
+ self . tx_transfer . start_nonblocking ( ) ;
229
+ self . spi . inner . enable_tx_dma ( ) ;
230
+ self . spi . start_transaction ( ) ;
218
231
Ok ( ( ) )
219
232
}
220
233
@@ -228,13 +241,13 @@ where
228
241
self . tx_transfer . wait_for_transfer_complete ( ) ?;
229
242
self . rx_transfer . wait_for_transfer_complete ( ) ?;
230
243
self . spi . end_transaction ( ) ;
231
- self . spi . disable_dma ( ) ;
244
+ self . spi . inner . disable_dma ( ) ;
232
245
Ok ( ( ) )
233
246
}
234
247
235
248
pub fn end_transfer ( & mut self ) {
236
249
self . spi . end_transaction ( ) ;
237
- self . spi . disable_dma ( ) ;
250
+ self . spi . inner . disable_dma ( ) ;
238
251
}
239
252
240
253
pub fn abort ( & mut self ) -> Result < ( ) , Error > {
@@ -244,7 +257,7 @@ where
244
257
Ok ( ( ) )
245
258
}
246
259
247
- pub fn free ( mut self ) -> Result < ( TX , RX , S , D ) , Error > {
260
+ pub fn free ( mut self ) -> Result < ( Channel < TX > , Channel < RX > , S , D ) , Error > {
248
261
self . end_transfer ( ) ;
249
262
let ( tx, s, _) = self . tx_transfer . free ( ) ?;
250
263
let ( rx, _, d) = self . rx_transfer . free ( ) ?;
0 commit comments