1
1
use arduino_hal:: { hal:: Atmega , usart:: UsartOps , Usart } ;
2
2
use embedded_hal:: serial:: { Read , Write } ;
3
+ use void:: ResultVoidExt ;
3
4
4
5
use crate :: millis:: millis;
5
6
6
- /// Note: all arguments are big-endian
7
+ /// The types of sendable messages.
8
+ /// Keep up to date with /src/serial.rs
9
+ ///
10
+ /// Note: all messages are big-endian
7
11
pub enum SerialMsg {
8
12
/// Just send HandshakeResponse back if you get this.
9
13
///
10
- /// 0x00
11
- Handshake ,
14
+ /// Parameter: mode
15
+ /// 0x0000 - let the other party decide
16
+ /// 0x0001 - sync
17
+ /// 0x0002 - other party is slave
18
+ /// 0x0003 - other party is master
19
+ ///
20
+ /// 0xc0
21
+ Handshake { mode : u32 } ,
12
22
/// Yay, Handshake was successful!
13
23
///
14
- /// 0x01
15
- HandshakeResponse ,
16
- /// P1 is now counting down, and P2 has the specified # of ms. This will
17
- /// wrap after about an hour.
24
+ /// Parameter: selected_mode
25
+ /// 0x0000 - mode not supported
26
+ /// 0x0001 - sync
27
+ /// 0x0002 - we're slave
28
+ /// 0x0003 - we're master
29
+ ///
30
+ /// 0xc1
31
+ HandshakeResponse { selected_mode : u32 } ,
32
+ /// P1 is now counting down, and P2 has the specified # of ms.
18
33
///
19
- /// 0x02
20
- StartP1 { p2_time : u16 } ,
21
- /// P2 is now counting down, and P1 has the specified # of ms. This will
22
- /// wrap after about an hour.
34
+ /// 0xc2
35
+ StartP1 { p2_time : u32 } ,
36
+ /// P2 is now counting down, and P1 has the specified # of ms.
23
37
///
24
- /// 0x03
25
- StartP2 { p1_time : u16 } ,
38
+ /// 0xc3
39
+ StartP2 { p1_time : u32 } ,
26
40
/// Syncing time. P1 first, then P2, in ms.
27
41
///
28
- /// 0x04
29
- Sync { p1_time : u16 , p2_time : u16 } ,
42
+ /// 0xc4
43
+ Sync { p1_time : u32 , p2_time : u32 } ,
30
44
/// Pause both times. The currently running clock finished at the specified
31
45
/// ms.
32
46
///
33
- /// 0x05
34
- Pause { time : u16 } ,
47
+ /// 0xc5
48
+ Pause { time : u32 } ,
49
+ /// P1 won by time.
50
+ ///
51
+ /// 0xc6
52
+ P1Finish ,
53
+ /// P2 won by time.
54
+ ///
55
+ /// 0xc7
56
+ P2Finish ,
35
57
}
36
58
37
59
impl SerialMsg {
38
60
fn to_u8 ( & self ) -> u8 {
39
61
match * self {
40
- SerialMsg :: Handshake => 0x00 ,
41
- SerialMsg :: HandshakeResponse => 0x01 ,
42
- SerialMsg :: StartP1 { p2_time : _ } => 0x02 ,
43
- SerialMsg :: StartP2 { p1_time : _ } => 0x03 ,
62
+ SerialMsg :: Handshake { mode : _ } => 0xc0 ,
63
+ SerialMsg :: HandshakeResponse { selected_mode : _ } => 0xc1 ,
64
+ SerialMsg :: StartP1 { p2_time : _ } => 0xc2 ,
65
+ SerialMsg :: StartP2 { p1_time : _ } => 0xc3 ,
44
66
SerialMsg :: Sync {
45
67
p1_time : _,
46
68
p2_time : _,
47
- } => 0x04 ,
48
- SerialMsg :: Pause { time : _ } => 0x05 ,
69
+ } => 0xc4 ,
70
+ SerialMsg :: Pause { time : _ } => 0xc5 ,
71
+ SerialMsg :: P1Finish => 0xc6 ,
72
+ SerialMsg :: P2Finish => 0xc7 ,
49
73
}
50
74
}
51
75
}
@@ -56,59 +80,72 @@ pub struct SerialHandler<USART: UsartOps<Atmega, RX, TX>, RX, TX> {
56
80
pub connected : bool ,
57
81
}
58
82
83
+ /// Handles serial communication between the firmware and website.
84
+ /// Keep up to date with /www/src/serial.ts
59
85
impl < USART : UsartOps < Atmega , RX , TX > , RX , TX > SerialHandler < USART , RX , TX > {
60
- fn write_u16 ( & mut self , v : u16 ) -> nb :: Result < ( ) , void :: Void > {
86
+ fn write_u32 ( & mut self , v : u32 ) {
61
87
let bytes = v. to_be_bytes ( ) ;
62
- self . serial . write ( bytes[ 0 ] ) ? ;
63
- self . serial . write ( bytes [ 1 ] ) ? ;
64
- Ok ( ( ) )
88
+ for byte in bytes {
89
+ nb :: block! ( self . serial. write( byte ) ) . void_unwrap ( ) ;
90
+ }
65
91
}
66
92
67
- pub fn write ( & mut self , msg : SerialMsg ) -> nb :: Result < ( ) , void :: Void > {
68
- self . serial . write ( msg. to_u8 ( ) ) ? ;
93
+ pub fn write ( & mut self , msg : SerialMsg ) {
94
+ self . serial . write_byte ( msg. to_u8 ( ) ) ;
69
95
match msg {
70
- SerialMsg :: Handshake => { }
71
- SerialMsg :: HandshakeResponse => { }
96
+ SerialMsg :: Handshake { mode } => {
97
+ self . write_u32 ( mode) ;
98
+ }
99
+ SerialMsg :: HandshakeResponse { selected_mode } => {
100
+ self . write_u32 ( selected_mode) ;
101
+ }
72
102
SerialMsg :: StartP1 { p2_time } => {
73
- self . write_u16 ( p2_time) ? ;
103
+ self . write_u32 ( p2_time) ;
74
104
}
75
105
SerialMsg :: StartP2 { p1_time } => {
76
- self . write_u16 ( p1_time) ? ;
106
+ self . write_u32 ( p1_time) ;
77
107
}
78
108
SerialMsg :: Sync { p1_time, p2_time } => {
79
- self . write_u16 ( p1_time) ? ;
80
- self . write_u16 ( p2_time) ? ;
109
+ self . write_u32 ( p1_time) ;
110
+ self . write_u32 ( p2_time) ;
81
111
}
82
112
SerialMsg :: Pause { time } => {
83
- self . write_u16 ( time) ? ;
113
+ self . write_u32 ( time) ;
84
114
}
115
+ SerialMsg :: P1Finish => { }
116
+ SerialMsg :: P2Finish => { }
85
117
}
86
- Ok ( ( ) )
118
+ }
119
+
120
+ fn read_u32 ( & mut self ) -> u32 {
121
+ ( ( nb:: block!( self . serial. read( ) ) . void_unwrap ( ) as u32 ) << 24 )
122
+ | ( ( nb:: block!( self . serial. read( ) ) . void_unwrap ( ) as u32 ) << 16 )
123
+ | ( ( nb:: block!( self . serial. read( ) ) . void_unwrap ( ) as u32 ) << 8 )
124
+ | nb:: block!( self . serial. read( ) ) . void_unwrap ( ) as u32
87
125
}
88
126
89
127
/// Reads a raw message from the wire and blocks until it's completely received.
90
128
fn raw_read ( & mut self ) -> nb:: Result < SerialMsg , void:: Void > {
91
129
let msg = self . serial . read ( ) ?;
92
130
match msg {
93
- 0x00 => Ok ( SerialMsg :: Handshake ) ,
94
- 0x01 => Ok ( SerialMsg :: HandshakeResponse ) ,
95
- 0x02 => Ok ( SerialMsg :: StartP1 {
96
- p2_time : ( ( nb:: block!( self . serial. read( ) ) ? as u16 ) << 8 )
97
- | nb:: block!( self . serial. read( ) ) ? as u16 ,
131
+ 0xc0 => Ok ( SerialMsg :: Handshake {
132
+ mode : self . read_u32 ( ) ,
133
+ } ) ,
134
+ 0xc1 => Ok ( SerialMsg :: HandshakeResponse {
135
+ selected_mode : self . read_u32 ( ) ,
136
+ } ) ,
137
+ 0xc2 => Ok ( SerialMsg :: StartP1 {
138
+ p2_time : self . read_u32 ( ) ,
98
139
} ) ,
99
- 0x03 => Ok ( SerialMsg :: StartP2 {
100
- p1_time : ( ( nb:: block!( self . serial. read( ) ) ? as u16 ) << 8 )
101
- | nb:: block!( self . serial. read( ) ) ? as u16 ,
140
+ 0xc3 => Ok ( SerialMsg :: StartP2 {
141
+ p1_time : self . read_u32 ( ) ,
102
142
} ) ,
103
- 0x04 => Ok ( SerialMsg :: Sync {
104
- p1_time : ( ( nb:: block!( self . serial. read( ) ) ? as u16 ) << 8 )
105
- | nb:: block!( self . serial. read( ) ) ? as u16 ,
106
- p2_time : ( ( nb:: block!( self . serial. read( ) ) ? as u16 ) << 8 )
107
- | nb:: block!( self . serial. read( ) ) ? as u16 ,
143
+ 0xc4 => Ok ( SerialMsg :: Sync {
144
+ p1_time : self . read_u32 ( ) ,
145
+ p2_time : self . read_u32 ( ) ,
108
146
} ) ,
109
- 0x05 => Ok ( SerialMsg :: Pause {
110
- time : ( ( nb:: block!( self . serial. read( ) ) ? as u16 ) << 8 )
111
- | nb:: block!( self . serial. read( ) ) ? as u16 ,
147
+ 0xc5 => Ok ( SerialMsg :: Pause {
148
+ time : self . read_u32 ( ) ,
112
149
} ) ,
113
150
_ => {
114
151
// Huh? Malformed message, this isn't good, ignore the message
@@ -120,12 +157,20 @@ impl<USART: UsartOps<Atmega, RX, TX>, RX, TX> SerialHandler<USART, RX, TX> {
120
157
pub fn read ( & mut self ) -> nb:: Result < SerialMsg , void:: Void > {
121
158
let msg = self . raw_read ( ) ?;
122
159
match msg {
123
- SerialMsg :: Handshake => {
160
+ SerialMsg :: Handshake { mode } => {
124
161
self . connected = true ;
125
- self . write ( SerialMsg :: HandshakeResponse ) ?;
162
+ let selected_mode = match mode {
163
+ 0x0000 => 0x0002 , // if we decide, make them a slave
164
+ 0x0001 => 0x0001 , // syncing
165
+ 0x0002 => 0x0000 , // if we're a slave, it's not supported
166
+ 0x0003 => 0x0003 , // we're master
167
+ _ => 0x0000 , // unsupported value
168
+ } ;
169
+ self . write ( SerialMsg :: HandshakeResponse { selected_mode } ) ;
126
170
Err ( nb:: Error :: WouldBlock )
127
171
}
128
- SerialMsg :: HandshakeResponse => {
172
+ SerialMsg :: HandshakeResponse { selected_mode : _ } => {
173
+ // hopefully selected_mode is ok. we don't have the resources to check
129
174
self . connected = true ;
130
175
Err ( nb:: Error :: WouldBlock )
131
176
}
@@ -137,7 +182,7 @@ impl<USART: UsartOps<Atmega, RX, TX>, RX, TX> SerialHandler<USART, RX, TX> {
137
182
if let None = self . wait_start {
138
183
self . connected = false ;
139
184
self . wait_start = Some ( millis ( ) ) ;
140
- self . write ( SerialMsg :: Handshake ) ? ;
185
+ self . write ( SerialMsg :: Handshake { mode : 0x0002 } ) ;
141
186
}
142
187
let wait_start = self . wait_start . unwrap ( ) ;
143
188
match self . read ( ) {
0 commit comments