@@ -18,7 +18,7 @@ extern crate stm32l4xx_hal as hal;
18
18
// #[macro_use(block)]
19
19
// extern crate nb;
20
20
21
- use crate :: hal:: dma:: { CircReadDma , Half } ;
21
+ use crate :: hal:: dma:: CircReadDma ;
22
22
use crate :: hal:: prelude:: * ;
23
23
use crate :: hal:: serial:: { Config , Serial } ;
24
24
use crate :: rt:: ExceptionFrame ;
@@ -59,34 +59,66 @@ fn main() -> ! {
59
59
) ;
60
60
let ( mut tx, rx) = serial. split ( ) ;
61
61
62
- let sent = b'X' ;
63
-
64
- // The `block!` macro makes an operation block until it finishes
65
- // NOTE the error type is `!`
66
-
67
- block ! ( tx. write( sent) ) . ok ( ) ;
68
-
69
- let buf = singleton ! ( : [ [ u8 ; 8 ] ; 2 ] = [ [ 0 ; 8 ] ; 2 ] ) . unwrap ( ) ;
70
-
62
+ let buf = singleton ! ( : [ u8 ; 9 ] = [ 0 ; 9 ] ) . unwrap ( ) ;
71
63
let mut circ_buffer = rx. with_dma ( channels. 5 ) . circ_read ( buf) ;
64
+ let mut rx_buf = [ 0 ; 9 ] ;
65
+
66
+ // single byte send/receive
67
+ send ( & mut tx, b"x" ) ;
68
+ let rx_len = circ_buffer. read ( & mut rx_buf) . unwrap ( ) ;
69
+ assert_eq ! ( rx_len, 1 ) ;
70
+ assert_eq ! ( & rx_buf[ ..1 ] , b"x" ) ;
71
+
72
+ // multi byte send/receive
73
+ send ( & mut tx, b"12345678" ) ;
74
+ let rx_len = circ_buffer. read ( & mut rx_buf) . unwrap ( ) ;
75
+ assert_eq ! ( rx_len, 8 ) ;
76
+ assert_eq ! ( & rx_buf[ ..8 ] , b"12345678" ) ;
77
+
78
+ // Checking three types of overflow detection
79
+ // 1. write pointer passes read pointer
80
+ send ( & mut tx, b"12345678" ) ; // write-pointer -> 8
81
+ let rx_len = circ_buffer. read ( & mut rx_buf[ ..1 ] ) . unwrap ( ) ; // read-pointer -> 1
82
+ assert_eq ! ( rx_len, 1 ) ;
83
+ send ( & mut tx, b"12" ) ; // write-pointer -> 1 (catches up with read-pointer)
84
+ let rx_res = circ_buffer. read ( & mut rx_buf[ ..1 ] ) ;
85
+ if let Err ( hal:: dma:: Error :: Overrun ) = rx_res {
86
+ } else {
87
+ panic ! ( "An overrun should have been detected" ) ;
88
+ }
72
89
73
- for _ in 0 ..2 {
74
- while circ_buffer. readable_half ( ) . unwrap ( ) != Half :: First { }
75
-
76
- let _first_half = circ_buffer. peek ( |_buf, half| half) . unwrap ( ) ;
77
-
78
- // asm::bkpt();
79
-
80
- while circ_buffer. readable_half ( ) . unwrap ( ) != Half :: Second { }
81
-
82
- // asm::bkpt();
83
-
84
- let _second_half = circ_buffer. peek ( |_buf, half| half) . unwrap ( ) ;
90
+ // 2. transfer complete flag set but it looks like the write-pointer did not pass 0
91
+ send ( & mut tx, b"123456789" ) ; // write-pointer stays 1, transfer complete flag set
92
+ send ( & mut tx, b"1234" ) ; // write-pointer -> 5
93
+ let rx_res = circ_buffer. read ( & mut rx_buf[ ..] ) ;
94
+ if let Err ( hal:: dma:: Error :: Overrun ) = rx_res {
95
+ } else {
96
+ panic ! ( "An overrun should have been detected" ) ;
85
97
}
86
98
87
- // let received = block!(rx.read()).unwrap();
99
+ // 3a. half complete flag set but it looks like the write-ptr did not pass ceil(capacity/2) = 5
100
+ send ( & mut tx, b"123456789" ) ; // write-pointer stays 5, all flags set
101
+ send ( & mut tx, b"12345678" ) ; // write-pointer -> 4
102
+ let rx_res = circ_buffer. read ( & mut rx_buf[ ..] ) ;
103
+ if let Err ( hal:: dma:: Error :: Overrun ) = rx_res {
104
+ } else {
105
+ panic ! ( "An overrun should have been detected" ) ;
106
+ }
88
107
89
- // assert_eq!(received, sent);
108
+ // 3b. check that the half complete flag is not yet set at write-pointer = floor(capacity/2) = 4
109
+ send ( & mut tx, b"1234" ) ; // write-pointer -> 0
110
+ circ_buffer. read ( & mut rx_buf[ ..] ) . unwrap ( ) ; // read something to prevent overrun
111
+ send ( & mut tx, b"12345" ) ; // write-pointer -> 4
112
+ circ_buffer
113
+ . read ( & mut rx_buf[ ..] )
114
+ . expect ( "No overrun should be detected here" ) ;
115
+
116
+ // Undetectable overrun
117
+ send ( & mut tx, b"123456789" ) ;
118
+ send ( & mut tx, b"abcdefgh" ) ; // overrun but it looks like only 8 bytes have been written
119
+ let rx_len = circ_buffer. read ( & mut rx_buf[ ..] ) . unwrap ( ) ;
120
+ assert_eq ! ( rx_len, 8 ) ;
121
+ assert_eq ! ( & rx_buf[ ..8 ] , b"abcdefgh" ) ;
90
122
91
123
// if all goes well you should reach this breakpoint
92
124
asm:: bkpt ( ) ;
@@ -96,6 +128,19 @@ fn main() -> ! {
96
128
}
97
129
}
98
130
131
+ fn send ( tx : & mut impl embedded_hal:: serial:: Write < u8 > , data : & [ u8 ] ) {
132
+ for byte in data {
133
+ if let Err ( _) = block ! ( tx. write( * byte) ) {
134
+ panic ! ( "serial tx failed" ) ;
135
+ }
136
+ }
137
+
138
+ // waste some time so that the data will be received completely
139
+ for i in 0 ..10000 {
140
+ cortex_m:: asm:: nop ( ) ;
141
+ }
142
+ }
143
+
99
144
#[ exception]
100
145
fn HardFault ( ef : & ExceptionFrame ) -> ! {
101
146
panic ! ( "{:#?}" , ef) ;
0 commit comments