1
1
//! Serial
2
2
3
- use core:: convert:: Infallible ;
4
- use core:: marker:: PhantomData ;
5
- use core:: ptr;
6
-
7
- use crate :: hal:: blocking:: serial:: write:: Default ;
8
- use crate :: hal:: serial;
9
- use crate :: pac:: { USART1 , USART2 , USART3 } ;
3
+ use crate :: {
4
+ gpio:: { gpioa, gpiob, gpioc, AF7 } ,
5
+ hal:: { blocking, serial} ,
6
+ pac:: { USART1 , USART2 , USART3 } ,
7
+ rcc:: { Clocks , APB1 , APB2 } ,
8
+ time:: Bps ,
9
+ } ;
10
+ use core:: { convert:: Infallible , marker:: PhantomData , ptr} ;
10
11
use nb;
11
12
12
- use crate :: gpio:: gpioa:: { PA10 , PA2 , PA3 , PA9 } ;
13
- #[ cfg( any(
14
- feature = "stm32f301" ,
15
- feature = "stm32f318" ,
16
- feature = "stm32f302" ,
17
- feature = "stm32f303" ,
18
- feature = "stm32f334" ,
19
- feature = "stm32f328" ,
20
- feature = "stm32f358" ,
21
- feature = "stm32f398"
22
- ) ) ]
23
- use crate :: gpio:: gpiob:: PB11 ;
24
- use crate :: gpio:: gpiob:: { PB10 , PB6 , PB7 } ;
25
- use crate :: gpio:: gpioc:: { PC10 , PC11 , PC4 , PC5 } ;
26
13
#[ cfg( any(
27
14
feature = "stm32f302" ,
28
15
feature = "stm32f303xb" ,
@@ -36,24 +23,20 @@ use crate::gpio::gpioc::{PC10, PC11, PC4, PC5};
36
23
feature = "stm32f358" ,
37
24
feature = "stm32f398"
38
25
) ) ]
39
- use crate :: gpio:: gpiod:: { PD5 , PD6 , PD8 , PD9 } ;
40
- #[ cfg( any(
41
- feature = "stm32f302" ,
42
- feature = "stm32f303xb" ,
43
- feature = "stm32f303xc" ,
44
- feature = "stm32f303xd" ,
45
- feature = "stm32f303xe" ,
46
- feature = "stm32f373" ,
47
- feature = "stm32f378" ,
48
- feature = "stm32f328" ,
49
- feature = "stm32f358" ,
50
- feature = "stm32f398"
51
- ) ) ]
52
- use crate :: gpio:: gpioe:: { PE0 , PE1 , PE15 } ;
26
+ use crate :: gpio:: { gpiod, gpioe} ;
27
+
28
+ #[ cfg( feature = "stm32f303" ) ]
29
+ mod dma_imports {
30
+ pub use crate :: dma;
31
+ pub use as_slice:: { AsMutSlice , AsSlice } ;
32
+ pub use core:: {
33
+ ops:: { Deref , DerefMut } ,
34
+ pin:: Pin ,
35
+ } ;
36
+ }
53
37
54
- use crate :: gpio:: AF7 ;
55
- use crate :: rcc:: { Clocks , APB1 , APB2 } ;
56
- use crate :: time:: Bps ;
38
+ #[ cfg( feature = "stm32f303" ) ]
39
+ use dma_imports:: * ;
57
40
58
41
/// Interrupt event
59
42
pub enum Event {
@@ -85,9 +68,9 @@ pub unsafe trait TxPin<USART> {}
85
68
/// RX pin - DO NOT IMPLEMENT THIS TRAIT
86
69
pub unsafe trait RxPin < USART > { }
87
70
88
- unsafe impl TxPin < USART1 > for PA9 < AF7 > { }
89
- unsafe impl TxPin < USART1 > for PB6 < AF7 > { }
90
- unsafe impl TxPin < USART1 > for PC4 < AF7 > { }
71
+ unsafe impl TxPin < USART1 > for gpioa :: PA9 < AF7 > { }
72
+ unsafe impl TxPin < USART1 > for gpiob :: PB6 < AF7 > { }
73
+ unsafe impl TxPin < USART1 > for gpioc :: PC4 < AF7 > { }
91
74
#[ cfg( any(
92
75
feature = "stm32f302" ,
93
76
feature = "stm32f303xb" ,
@@ -100,11 +83,11 @@ unsafe impl TxPin<USART1> for PC4<AF7> {}
100
83
feature = "stm32f358" ,
101
84
feature = "stm32f398"
102
85
) ) ]
103
- unsafe impl TxPin < USART1 > for PE0 < AF7 > { }
86
+ unsafe impl TxPin < USART1 > for gpioe :: PE0 < AF7 > { }
104
87
105
- unsafe impl RxPin < USART1 > for PA10 < AF7 > { }
106
- unsafe impl RxPin < USART1 > for PB7 < AF7 > { }
107
- unsafe impl RxPin < USART1 > for PC5 < AF7 > { }
88
+ unsafe impl RxPin < USART1 > for gpioa :: PA10 < AF7 > { }
89
+ unsafe impl RxPin < USART1 > for gpiob :: PB7 < AF7 > { }
90
+ unsafe impl RxPin < USART1 > for gpioc :: PC5 < AF7 > { }
108
91
#[ cfg( any(
109
92
feature = "stm32f302" ,
110
93
feature = "stm32f303xb" ,
@@ -117,11 +100,11 @@ unsafe impl RxPin<USART1> for PC5<AF7> {}
117
100
feature = "stm32f358" ,
118
101
feature = "stm32f398"
119
102
) ) ]
120
- unsafe impl RxPin < USART1 > for PE1 < AF7 > { }
103
+ unsafe impl RxPin < USART1 > for gpioe :: PE1 < AF7 > { }
121
104
122
- unsafe impl TxPin < USART2 > for PA2 < AF7 > { }
123
- // unsafe impl TxPin<USART2> for PA14<AF7> {}
124
- // unsafe impl TxPin<USART2> for PB3<AF7> {}
105
+ unsafe impl TxPin < USART2 > for gpioa :: PA2 < AF7 > { }
106
+ // unsafe impl TxPin<USART2> for gpioa:: PA14<AF7> {}
107
+ // unsafe impl TxPin<USART2> for gpiob:: PB3<AF7> {}
125
108
#[ cfg( any(
126
109
feature = "stm32f302" ,
127
110
feature = "stm32f303xb" ,
@@ -135,11 +118,11 @@ unsafe impl TxPin<USART2> for PA2<AF7> {}
135
118
feature = "stm32f358" ,
136
119
feature = "stm32f398"
137
120
) ) ]
138
- unsafe impl TxPin < USART2 > for PD5 < AF7 > { }
121
+ unsafe impl TxPin < USART2 > for gpiod :: PD5 < AF7 > { }
139
122
140
- unsafe impl RxPin < USART2 > for PA3 < AF7 > { }
141
- // unsafe impl RxPin<USART2> for PA15<AF7> {}
142
- // unsafe impl RxPin<USART2> for PB4<AF7> {}
123
+ unsafe impl RxPin < USART2 > for gpioa :: PA3 < AF7 > { }
124
+ // unsafe impl RxPin<USART2> for gpioa:: PA15<AF7> {}
125
+ // unsafe impl RxPin<USART2> for gpiob:: PB4<AF7> {}
143
126
#[ cfg( any(
144
127
feature = "stm32f302" ,
145
128
feature = "stm32f303xb" ,
@@ -153,10 +136,10 @@ unsafe impl RxPin<USART2> for PA3<AF7> {}
153
136
feature = "stm32f358" ,
154
137
feature = "stm32f398"
155
138
) ) ]
156
- unsafe impl RxPin < USART2 > for PD6 < AF7 > { }
139
+ unsafe impl RxPin < USART2 > for gpiod :: PD6 < AF7 > { }
157
140
158
- unsafe impl TxPin < USART3 > for PB10 < AF7 > { }
159
- unsafe impl TxPin < USART3 > for PC10 < AF7 > { }
141
+ unsafe impl TxPin < USART3 > for gpiob :: PB10 < AF7 > { }
142
+ unsafe impl TxPin < USART3 > for gpioc :: PC10 < AF7 > { }
160
143
#[ cfg( any(
161
144
feature = "stm32f302" ,
162
145
feature = "stm32f303xb" ,
@@ -170,7 +153,7 @@ unsafe impl TxPin<USART3> for PC10<AF7> {}
170
153
feature = "stm32f358" ,
171
154
feature = "stm32f398"
172
155
) ) ]
173
- unsafe impl TxPin < USART3 > for PD8 < AF7 > { }
156
+ unsafe impl TxPin < USART3 > for gpiod :: PD8 < AF7 > { }
174
157
175
158
#[ cfg( any(
176
159
feature = "stm32f301" ,
@@ -182,8 +165,8 @@ unsafe impl TxPin<USART3> for PD8<AF7> {}
182
165
feature = "stm32f358" ,
183
166
feature = "stm32f398"
184
167
) ) ]
185
- unsafe impl RxPin < USART3 > for PB11 < AF7 > { }
186
- unsafe impl RxPin < USART3 > for PC11 < AF7 > { }
168
+ unsafe impl RxPin < USART3 > for gpiob :: PB11 < AF7 > { }
169
+ unsafe impl RxPin < USART3 > for gpioc :: PC11 < AF7 > { }
187
170
#[ cfg( any(
188
171
feature = "stm32f302" ,
189
172
feature = "stm32f303xb" ,
@@ -197,7 +180,7 @@ unsafe impl RxPin<USART3> for PC11<AF7> {}
197
180
feature = "stm32f358" ,
198
181
feature = "stm32f398"
199
182
) ) ]
200
- unsafe impl RxPin < USART3 > for PD9 < AF7 > { }
183
+ unsafe impl RxPin < USART3 > for gpiod :: PD9 < AF7 > { }
201
184
#[ cfg( any(
202
185
feature = "stm32f302" ,
203
186
feature = "stm32f303xb" ,
@@ -210,7 +193,7 @@ unsafe impl RxPin<USART3> for PD9<AF7> {}
210
193
feature = "stm32f358" ,
211
194
feature = "stm32f398"
212
195
) ) ]
213
- unsafe impl RxPin < USART3 > for PE15 < AF7 > { }
196
+ unsafe impl RxPin < USART3 > for gpioe :: PE15 < AF7 > { }
214
197
215
198
/// Serial abstraction
216
199
pub struct Serial < USART , PINS > {
@@ -251,21 +234,21 @@ macro_rules! hal {
251
234
apb. rstr( ) . modify( |_, w| w. $usartXrst( ) . set_bit( ) ) ;
252
235
apb. rstr( ) . modify( |_, w| w. $usartXrst( ) . clear_bit( ) ) ;
253
236
254
- // disable hardware flow control
255
- // TODO enable DMA
256
- // usart.cr3.write(|w| w.rtse().clear_bit().ctse().clear_bit());
257
-
258
237
let brr = clocks. $pclkX( ) . 0 / baud_rate. 0 ;
259
238
assert!( brr >= 16 , "impossible baud rate" ) ;
260
239
// NOTE(write): uses all bits of this register.
261
240
usart. brr. write( |w| unsafe { w. bits( brr) } ) ;
262
241
263
- // UE: enable USART
264
- // RE: enable receiver
265
- // TE: enable transceiver
266
- usart
267
- . cr1
268
- . modify( |_, w| w. ue( ) . set_bit( ) . re( ) . set_bit( ) . te( ) . set_bit( ) ) ;
242
+ usart. cr3. modify( |_, w| {
243
+ w. dmar( ) . enabled( ) ; // enable DMA for reception
244
+ w. dmat( ) . enabled( ) // enable DMA for transmission
245
+ } ) ;
246
+
247
+ usart. cr1. modify( |_, w| {
248
+ w. ue( ) . enabled( ) ; // enable USART
249
+ w. re( ) . enabled( ) ; // enable receiver
250
+ w. te( ) . enabled( ) // enable transmitter
251
+ } ) ;
269
252
270
253
Serial { usart, pins }
271
254
}
@@ -380,7 +363,67 @@ macro_rules! hal {
380
363
}
381
364
}
382
365
383
- impl Default <u8 > for Tx <$USARTX> { }
366
+ impl blocking:: serial:: write:: Default <u8 > for Tx <$USARTX> { }
367
+
368
+ #[ cfg( feature = "stm32f303" ) ]
369
+ impl Rx <$USARTX> {
370
+ /// Fill the buffer with received data using DMA.
371
+ pub fn read_all<B , C >(
372
+ self ,
373
+ mut buffer: Pin <B >,
374
+ mut channel: C
375
+ ) -> dma:: Transfer <B , C , Self >
376
+ where
377
+ Self : dma:: Target <C >,
378
+ B : DerefMut + ' static ,
379
+ B :: Target : AsMutSlice <Element = u8 > + Unpin ,
380
+ C : dma:: Channel ,
381
+ {
382
+ // NOTE(unsafe) taking the address of a register
383
+ let pa = unsafe { & ( * $USARTX:: ptr( ) ) . rdr } as * const _ as u32 ;
384
+ channel. set_peripheral_address( pa, dma:: Increment :: Disable ) ;
385
+
386
+ let slice = buffer. as_mut_slice( ) ;
387
+ let ( ma, len) = ( slice. as_mut_ptr( ) as u32 , slice. len( ) ) ;
388
+ channel. set_memory_address( ma, dma:: Increment :: Enable ) ;
389
+ channel. set_transfer_length( len) ;
390
+ channel. set_word_size( dma:: WordSize :: Bits8 ) ;
391
+
392
+ channel. set_direction( dma:: Direction :: FromPeripheral ) ;
393
+
394
+ unsafe { dma:: Transfer :: start( buffer, channel, self ) }
395
+ }
396
+ }
397
+
398
+ #[ cfg( feature = "stm32f303" ) ]
399
+ impl Tx <$USARTX> {
400
+ /// Transmit all data in the buffer using DMA.
401
+ pub fn write_all<B , C >(
402
+ self ,
403
+ buffer: Pin <B >,
404
+ mut channel: C
405
+ ) -> dma:: Transfer <B , C , Self >
406
+ where
407
+ Self : dma:: Target <C >,
408
+ B : Deref + ' static ,
409
+ B :: Target : AsSlice <Element = u8 >,
410
+ C : dma:: Channel ,
411
+ {
412
+ // NOTE(unsafe) taking the address of a register
413
+ let pa = unsafe { & ( * $USARTX:: ptr( ) ) . tdr } as * const _ as u32 ;
414
+ channel. set_peripheral_address( pa, dma:: Increment :: Disable ) ;
415
+
416
+ let slice = buffer. as_slice( ) ;
417
+ let ( ma, len) = ( slice. as_ptr( ) as u32 , slice. len( ) ) ;
418
+ channel. set_memory_address( ma, dma:: Increment :: Enable ) ;
419
+ channel. set_transfer_length( len) ;
420
+ channel. set_word_size( dma:: WordSize :: Bits8 ) ;
421
+
422
+ channel. set_direction( dma:: Direction :: FromMemory ) ;
423
+
424
+ unsafe { dma:: Transfer :: start( buffer, channel, self ) }
425
+ }
426
+ }
384
427
) +
385
428
}
386
429
}
0 commit comments