15 #endif |
15 #endif |
16 |
16 |
17 DigitalOut lled(LED1); |
17 DigitalOut lled(LED1); |
18 |
18 |
19 HPSerial::HPSerial(PinName rx, PinName tx): |
19 HPSerial::HPSerial(PinName rx, PinName tx): |
20 serial_tx(A7, tx), |
|
21 serial_rx(NC, rx), |
20 serial_rx(NC, rx), |
22 ncmd(0) { |
21 ncmd(0) { |
23 |
22 |
24 //pc.printf("HPSerial init\n"); |
23 //pc.printf("HPSerial init\n"); |
25 |
24 |
26 for(uint8_t i=0; i<MAX_ERRS; i++) |
25 for(uint8_t i=0; i<MAX_ERRS; i++) |
27 errs[i] = 0; |
26 errs[i] = 0; |
28 reset(); |
27 reset(); |
29 |
|
30 serial_tx.baud(187500); |
|
31 serial_tx.attach(this, &HPSerial::txIrq, Serial::RxIrq); //sic! |
|
32 |
28 |
33 serial_rx.baud(187500); |
29 serial_rx.baud(187500); |
34 serial_rx.attach(this, &HPSerial::rxIrq, Serial::RxIrq); |
30 serial_rx.attach(this, &HPSerial::rxIrq, Serial::RxIrq); |
35 } |
31 } |
36 |
32 |
72 // special case: keypad does not acknwledge and takes precedence |
68 // special case: keypad does not acknwledge and takes precedence |
73 // on the "bus" |
69 // on the "bus" |
74 tx_state = Tx; |
70 tx_state = Tx; |
75 setstatedbg(); |
71 setstatedbg(); |
76 } else |
72 } else |
77 |
73 if (tx_cmd == 0xFF) // beginning of a packet, expect 0x99 as ack |
78 if (tx_ack == true) |
74 if (val == 0x99) |
79 reset(0); |
75 { |
80 |
76 tx_ack = true; |
81 else |
77 #ifdef DEBUG2 |
82 if (tx_cmd == 0xFF) // still at the beginning of a packet, expect 0x99 as ack |
78 ack = 1; |
83 if (val == 0x99) |
79 wait_us(2); |
84 { |
80 ack = 0; |
85 tx_ack = true; |
81 #endif |
86 #ifdef DEBUG2 |
82 } |
87 ack = 1; |
83 else |
88 wait_us(2); |
84 reset(1); |
89 ack = 0; |
85 |
90 #endif |
86 else // expect 0x00 as ack |
91 } |
87 if (val == 0x00) |
92 else |
88 { |
93 reset(1); |
89 tx_ack = true; |
94 |
90 #ifdef DEBUG2 |
95 else // expect 0x00 as ack |
91 ack = 1; |
96 if (val == 0x00) |
92 wait_us(2); |
97 { |
93 ack = 0; |
98 tx_ack = true; |
94 wait_us(2); |
99 #ifdef DEBUG2 |
95 ack = 1; |
100 ack = 1; |
96 wait_us(2); |
101 wait_us(2); |
97 ack = 0; |
102 ack = 0; |
98 #endif |
103 wait_us(2); |
99 } |
104 ack = 1; |
100 else |
105 wait_us(2); |
101 reset(2); |
106 ack = 0; |
|
107 #endif |
|
108 } |
|
109 else |
|
110 reset(2); |
|
111 } |
102 } |
112 |
103 |
113 void HPSerial::pushCmd(TrState direction, uint8_t cmd, uint8_t size, char *payload) { |
104 void HPSerial::pushCmd(TrState direction, uint8_t cmd, uint8_t size, char *payload) { |
114 CMD val; |
105 CMD val; |
115 uint8_t i; |
106 uint8_t i; |
129 else // remaining of the state machine |
120 else // remaining of the state machine |
130 if (tx_cmd == 0xFF) { |
121 if (tx_cmd == 0xFF) { |
131 // begin of transmission, expect a cmd |
122 // begin of transmission, expect a cmd |
132 tx_cmd = val; |
123 tx_cmd = val; |
133 tx_ack = false; |
124 tx_ack = false; |
134 if (tx_state == Rx) |
125 tx_len = 0xFF; |
135 tx_len = 0xFF; |
|
136 else |
|
137 tx_len = 0x00; // no payload: tx_cmd is the key stroke |
|
138 } |
126 } |
139 else if (tx_len == 0xFF) { |
127 else if (tx_len == 0xFF) { |
140 // got a cmd, expect a payload size |
128 // got a cmd, expect a payload size |
141 tx_len = val; |
129 tx_len = val; |
142 tx_ack = false; |
130 tx_ack = false; |
|
131 } |
|
132 else if (tx_len == 0x55) { |
|
133 // packet was in fact a keystroke, tx_cmd is in fact the key |
|
134 // stroke and no payload is expected |
|
135 pushCmd((TrState)Tx, tx_cmd, 0, NULL); |
|
136 reset(); |
143 } |
137 } |
144 else if (tx_len > 0) { |
138 else if (tx_len > 0) { |
145 // a payload char |
139 // a payload char |
146 buf[head++] = val; |
140 buf[head++] = val; |
147 tx_len--; |
141 tx_len--; |
186 uint8_t val; |
180 uint8_t val; |
187 if(serial_rx.readable()) { // no reason why we would end here without this condition, but hey |
181 if(serial_rx.readable()) { // no reason why we would end here without this condition, but hey |
188 #ifdef DEBUG2 |
182 #ifdef DEBUG2 |
189 inrx=1; |
183 inrx=1; |
190 #endif |
184 #endif |
191 lled = 1; |
185 lled = 1; |
192 val = serial_rx.getc(); |
186 val = serial_rx.getc(); |
193 |
187 |
194 timeouter.attach(this, &HPSerial::timeout, 0.001); // if nothing else happen in the next ms, reset |
188 timeouter.attach(this, &HPSerial::timeout, 0.001); // if nothing else happen in the next ms, reset |
195 |
189 |
196 if (tx_state == Idle) |
190 if (tx_state == Idle) |
201 setstatedbg(); |
195 setstatedbg(); |
202 } |
196 } |
203 else { |
197 else { |
204 reset(4); |
198 reset(4); |
205 } |
199 } |
206 else if (tx_state == Tx) // manage the acks |
200 else if (tx_ack == false) // manage the acks |
207 handleAck(val); |
201 handleAck(val); |
208 |
|
209 else |
202 else |
210 handleChar(val); |
203 handleChar(val); |
211 lled = 0; |
204 lled = 0; |
212 #ifdef DEBUG2 |
205 #ifdef DEBUG2 |
213 inrx=0; |
206 inrx=0; |
214 #endif |
207 #endif |
215 } |
208 } |
216 } |
209 } |
217 |
210 |
218 void HPSerial::txIrq(void) { |
|
219 uint8_t val; |
|
220 if(serial_tx.readable()) { // no reason why we would end here without this condition, but hey |
|
221 #ifdef DEBUG2 |
|
222 intx=1; |
|
223 #endif |
|
224 val = serial_tx.getc(); |
|
225 |
|
226 timeouter.attach(this, &HPSerial::timeout, 0.001); // if nothing else happen in the next ms, reset |
|
227 |
|
228 if (tx_state == Idle) |
|
229 if (val == 0x66) { |
|
230 // no transmission in progress, expect a start of transmission |
|
231 tx_state = Tx; |
|
232 tx_ack = false; |
|
233 setstatedbg(); |
|
234 } |
|
235 else { |
|
236 reset(5); |
|
237 } |
|
238 |
|
239 else if (tx_state == Rx) // manage the acks |
|
240 handleAck(val); |
|
241 |
|
242 else |
|
243 handleChar(val); |
|
244 } |
|
245 #ifdef DEBUG2 |
|
246 intx=0; |
|
247 #endif |
|
248 } |
|
249 |
211 |
250 void HPSerial::timeout(void) { |
212 void HPSerial::timeout(void) { |
251 if (tx_state != Idle) { |
213 if (tx_state != Idle) { |
252 reset(7); |
214 reset(7); |
253 } |
215 } |