Mon, 09 Nov 2020 23:05:24 +0100
Refactor HPSerial to get rid of packet collision misbehavior
completely split the key sending code from the irq-based receiveing logic.
When sending keycodes, disable the RxIrq callback and handle send and recv
of bytes synchronously.
The keycode sending routine rus in a dedicated thread.
5 | 1 | #include "hp34comm.h" |
28
424d792fea4f
compile for nucleo f446re & f303re with mbed 6
David Douard <david.douard@sdfa3.org>
parents:
21
diff
changeset
|
2 | |
424d792fea4f
compile for nucleo f446re & f303re with mbed 6
David Douard <david.douard@sdfa3.org>
parents:
21
diff
changeset
|
3 | #include <mbed.h> |
424d792fea4f
compile for nucleo f446re & f303re with mbed 6
David Douard <david.douard@sdfa3.org>
parents:
21
diff
changeset
|
4 | #include <CircularBuffer.h> |
5 | 5 | |
6 | /***** HP 34970A communication class ***/ | |
7 | ||
37
07e8ca2bdf6d
Extracted the display related functions in a Display class
David Douard <david.douard@sdf3.org>
parents:
28
diff
changeset
|
8 | #define RXTIMEOUT 50ms |
19 | 9 | #define STARTUPRETRY 0.5 |
21 | 10 | |
39
63c6a720cb97
hp34comm: add support for boot keycode
David Douard <david.douard@sdf3.org>
parents:
37
diff
changeset
|
11 | uint8_t startup_seq[] = { |
19 | 12 | 0x33, |
44 | 13 | 0x02, // 0x02? |
19 | 14 | 0x00, |
44 | 15 | 0x00, |
19 | 16 | }; |
17 | ||
18 | HPSerial::statemethod HPSerial::state_table[NUM_STATES] = { | |
44 | 19 | &HPSerial::do_state_initial, // STATE_IDLE |
20 | &HPSerial::do_state_command, // STATE_COMMAND | |
21 | &HPSerial::do_state_payload_size, // STATE_PAYLOAD_SIZE | |
22 | &HPSerial::do_state_payload, // STATE_PAYLOAD | |
23 | &HPSerial::do_state_sending, // STATE_SENDING | |
19 | 24 | }; |
5 | 25 | |
37
07e8ca2bdf6d
Extracted the display related functions in a Display class
David Douard <david.douard@sdf3.org>
parents:
28
diff
changeset
|
26 | |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
27 | HPSerial::HPSerial(PinName tx, PinName rx): |
19 | 28 | serial(tx, rx), |
37
07e8ca2bdf6d
Extracted the display related functions in a Display class
David Douard <david.douard@sdf3.org>
parents:
28
diff
changeset
|
29 | ncmd(0), |
07e8ca2bdf6d
Extracted the display related functions in a Display class
David Douard <david.douard@sdf3.org>
parents:
28
diff
changeset
|
30 | cur_gstate(GSTATE_IDLE) |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
31 | { |
21 | 32 | serial.baud(187500); |
44 | 33 | serial.format(8, BufferedSerial::Even, 1); |
19 | 34 | cur_state = STATE_IDLE; |
49
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
35 | send_thread.start(callback(this, &HPSerial::send_pending_key)); |
44 | 36 | serial.attach(callback(this, &HPSerial::rx_irq), SerialBase::RxIrq); |
19 | 37 | } |
38 | ||
39
63c6a720cb97
hp34comm: add support for boot keycode
David Douard <david.douard@sdf3.org>
parents:
37
diff
changeset
|
39 | void HPSerial::startup(uint8_t keycode) { |
44 | 40 | cur_gstate = GSTATE_STARTING; |
41 | ||
39
63c6a720cb97
hp34comm: add support for boot keycode
David Douard <david.douard@sdf3.org>
parents:
37
diff
changeset
|
42 | if (keycode != 0xFF) { |
44 | 43 | printf("Set startup keycode to %X\n", keycode); |
44 | startup_seq[2] = 0xFF; | |
45 | startup_seq[3] = keycode; | |
39
63c6a720cb97
hp34comm: add support for boot keycode
David Douard <david.douard@sdf3.org>
parents:
37
diff
changeset
|
46 | } |
44 | 47 | else |
48 | startup_seq[2] = 0x00; | |
37
07e8ca2bdf6d
Extracted the display related functions in a Display class
David Douard <david.douard@sdf3.org>
parents:
28
diff
changeset
|
49 | set_timer(10ms); // launch the startup in 10ms |
19 | 50 | } |
51 | ||
52 | void HPSerial::_startup(void) | |
53 | { | |
54 | cur_gstate = GSTATE_STARTING; | |
55 | tr_data.cmd = 0xFF; | |
56 | tr_data.pos = 0; | |
39
63c6a720cb97
hp34comm: add support for boot keycode
David Douard <david.douard@sdf3.org>
parents:
37
diff
changeset
|
57 | |
63c6a720cb97
hp34comm: add support for boot keycode
David Douard <david.douard@sdf3.org>
parents:
37
diff
changeset
|
58 | if (startup_seq[2] == 0xFF) |
63c6a720cb97
hp34comm: add support for boot keycode
David Douard <david.douard@sdf3.org>
parents:
37
diff
changeset
|
59 | tr_data.size = 4; |
63c6a720cb97
hp34comm: add support for boot keycode
David Douard <david.douard@sdf3.org>
parents:
37
diff
changeset
|
60 | else |
63c6a720cb97
hp34comm: add support for boot keycode
David Douard <david.douard@sdf3.org>
parents:
37
diff
changeset
|
61 | tr_data.size = 3; // sizeof(startup_seq); |
19 | 62 | for(uint8_t i=0; i<tr_data.size; i++) |
63 | tr_data.payload[i] = startup_seq[i]; | |
64 | cur_state = do_state_sending(); | |
5 | 65 | } |
66 | ||
19 | 67 | void HPSerial::sendkey(uint8_t keycode) |
68 | { | |
44 | 69 | if (!sendbuf.full()) |
70 | sendbuf.push(keycode); | |
71 | } | |
72 | ||
49
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
73 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
74 | bool HPSerial::wait_for(uint8_t value) |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
75 | { |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
76 | char c; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
77 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
78 | for(uint8_t i=0; i<2; i++) |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
79 | { |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
80 | while(!serial.readable()) |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
81 | wait_us(10); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
82 | //ThisThread::sleep_for(0.1ms); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
83 | serial.read(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
84 | if (value == c) |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
85 | return true; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
86 | } |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
87 | return false; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
88 | } |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
89 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
90 | void HPSerial::send_pending_key() { |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
91 | uint8_t c; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
92 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
93 | while(true) |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
94 | { |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
95 | if (!sendbuf.empty()) |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
96 | { |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
97 | if (cur_gstate == GSTATE_IDLE) |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
98 | { |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
99 | serial.attach(0, SerialBase::RxIrq); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
100 | cur_gstate = GSTATE_TX; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
101 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
102 | c = 0x66; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
103 | serial.write(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
104 | if (!wait_for(0x99)) {} |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
105 | // break; // XXX what to do? |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
106 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
107 | sendbuf.pop(c); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
108 | serial.write(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
109 | if (!wait_for(0x00)) {} |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
110 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
111 | c = 0x55; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
112 | serial.write(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
113 | cur_gstate = GSTATE_IDLE; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
114 | serial.attach(callback(this, &HPSerial::rx_irq), SerialBase::RxIrq); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
115 | } |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
116 | } |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
117 | //else // prevent from flooding the main unit |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
118 | ThisThread::sleep_for(5ms); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
119 | } |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
120 | } |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
121 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
122 | void HPSerial::send_startup_seq(uint8_t keycode) { |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
123 | uint8_t c; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
124 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
125 | while (cur_gstate != GSTATE_IDLE) { |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
126 | ThisThread::sleep_for(1ms); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
127 | } |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
128 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
129 | serial.attach(0, SerialBase::RxIrq); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
130 | cur_gstate = GSTATE_TX; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
131 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
132 | // Send the init seq 0x33 0x02 0xFF <keycode> 0x55 |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
133 | c = 0x33; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
134 | serial.write(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
135 | if (!wait_for(0xCC)) {} |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
136 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
137 | c = 0x02; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
138 | serial.write(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
139 | if (!wait_for(0x00)) {} |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
140 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
141 | c = 0xFF; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
142 | serial.write(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
143 | if (!wait_for(0x00)) {} |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
144 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
145 | c = keycode; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
146 | serial.write(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
147 | if (!wait_for(0x00)) {} |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
148 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
149 | c = 0x55; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
150 | serial.write(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
151 | cur_gstate = GSTATE_IDLE; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
152 | serial.attach(callback(this, &HPSerial::rx_irq), SerialBase::RxIrq); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
153 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
154 | } |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
155 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
156 | void HPSerial::send_startup_seq() { |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
157 | uint8_t c; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
158 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
159 | while (cur_gstate != GSTATE_IDLE) { |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
160 | ThisThread::sleep_for(1ms); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
161 | } |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
162 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
163 | serial.attach(0, SerialBase::RxIrq); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
164 | cur_gstate = GSTATE_TX; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
165 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
166 | // Send the init seq 0x33 0x02 0x00 0x55 |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
167 | c = 0x33; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
168 | serial.write(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
169 | if (!wait_for(0xCC)) {} |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
170 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
171 | c = 0x02; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
172 | serial.write(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
173 | if (!wait_for(0x00)) {} |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
174 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
175 | c = 0x00; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
176 | serial.write(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
177 | if (!wait_for(0x00)) {} |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
178 | |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
179 | c = 0x55; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
180 | serial.write(&c, 1); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
181 | cur_gstate = GSTATE_IDLE; |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
182 | serial.attach(callback(this, &HPSerial::rx_irq), SerialBase::RxIrq); |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
183 | } |
c146d19101a3
Refactor HPSerial to get rid of packet collision misbehavior
David Douard <david.douard@sdf3.org>
parents:
47
diff
changeset
|
184 | |
44 | 185 | void HPSerial::send_key_when_idle() { |
186 | if (!sendbuf.empty() && cur_gstate == GSTATE_IDLE) | |
187 | { | |
188 | uint8_t keycode; | |
189 | cur_gstate = GSTATE_TX; | |
190 | sendbuf.pop(keycode); | |
191 | tr_data.size = 2; | |
192 | tr_data.cmd = 0xFF; | |
193 | tr_data.pos = 0; | |
194 | tr_data.payload[0] = 0x66; | |
195 | tr_data.payload[1] = keycode; | |
196 | cur_state = do_state_sending(); | |
197 | } | |
19 | 198 | } |
199 | ||
200 | bool HPSerial::cmd_available(void) | |
201 | { | |
5 | 202 | return !cmdbuf.empty(); |
203 | } | |
204 | ||
19 | 205 | bool HPSerial::pop(CMD& cmd) |
206 | { | |
5 | 207 | return cmdbuf.pop(cmd); |
208 | } | |
209 | ||
19 | 210 | bool HPSerial::cmd_buf_full(void) |
211 | { | |
5 | 212 | return cmdbuf.full(); |
213 | } | |
214 | ||
19 | 215 | unsigned int HPSerial::nerrors(uint8_t errorno) |
21 | 216 | { |
5 | 217 | return errs[errorno]; |
218 | } | |
219 | ||
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
220 | void HPSerial::pushCmd(uint8_t cmd, uint8_t size, char *payload) { |
5 | 221 | CMD val; |
222 | uint8_t i; | |
223 | val.id = ncmd++; | |
224 | val.cmd = cmd; | |
225 | val.size = size; | |
226 | for(i=0; i<size; i++) | |
227 | val.value[i] = payload[i]; | |
228 | val.value[i] = 0x00; | |
229 | cmdbuf.push(val); | |
230 | } | |
231 | ||
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
232 | void HPSerial::send_ack(uint8_t c) { |
44 | 233 | serial.write(&c, 1); |
234 | set_timer(RXTIMEOUT); // if nothing else happen in the next RXTIMEOUT ms, reset | |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
235 | } |
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
236 | |
19 | 237 | HPSerial::state_t HPSerial::do_state_initial(uint8_t c) |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
238 | { |
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
239 | // we are idle, incoming char is a handcheck |
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
240 | // knwon handcheck values are 0x66 and 0x33 |
19 | 241 | set_timer(RXTIMEOUT); // reset the watchdog |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
242 | switch (c) { |
44 | 243 | case 0x33: // XXX? when are we expecting a 0x33 here? |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
244 | send_ack(0xCC); |
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
245 | return HPSerial::STATE_PAYLOAD_SIZE; |
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
246 | break; |
19 | 247 | case 0x55: // EoT |
248 | return HPSerial::STATE_IDLE; | |
249 | break; | |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
250 | case 0x66: |
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
251 | send_ack(0x99); |
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
252 | return HPSerial::STATE_COMMAND; |
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
253 | break; |
19 | 254 | case 0xFF: |
255 | return HPSerial::STATE_IDLE; | |
256 | default: // unknown value | |
257 | send_ack(0xFF); | |
258 | return HPSerial::STATE_IDLE; | |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
259 | } |
5 | 260 | } |
261 | ||
19 | 262 | HPSerial::state_t HPSerial::do_state_command(uint8_t c) |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
263 | { |
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
264 | if (c == 0x55) { // EoT |
19 | 265 | return STATE_IDLE; |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
266 | } |
5 | 267 | |
19 | 268 | tr_data.cmd = c; |
269 | tr_data.size = 0; | |
270 | tr_data.pos = 0; | |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
271 | send_ack(0x00); |
19 | 272 | |
273 | if (c == 0x86) { // shutdown | |
274 | pushCmd(tr_data.cmd, tr_data.size, tr_data.payload); | |
275 | return HPSerial::STATE_IDLE; | |
21 | 276 | } |
19 | 277 | return STATE_PAYLOAD_SIZE; |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
278 | } |
5 | 279 | |
19 | 280 | HPSerial::state_t HPSerial::do_state_payload_size(uint8_t c) |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
281 | { |
19 | 282 | tr_data.size = c; |
283 | tr_data.pos = 0; | |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
284 | send_ack(0x00); |
19 | 285 | return STATE_PAYLOAD; |
5 | 286 | } |
287 | ||
19 | 288 | HPSerial::state_t HPSerial::do_state_payload(uint8_t c) |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
289 | { |
19 | 290 | tr_data.payload[tr_data.pos++] = c; |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
291 | send_ack(0x00); |
19 | 292 | if (tr_data.pos >= tr_data.size) { |
293 | pushCmd(tr_data.cmd, tr_data.size, tr_data.payload); | |
44 | 294 | return STATE_IDLE; |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
295 | } |
44 | 296 | return STATE_PAYLOAD; |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
297 | } |
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
298 | |
19 | 299 | HPSerial::state_t HPSerial::do_state_sending(uint8_t c) |
300 | { | |
47
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
301 | // check the ack value returned by the main unit |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
302 | |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
303 | if ((tr_data.pos == 1) && (tr_data.payload[0] == 0x66)) |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
304 | { |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
305 | if (c != 0x99) |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
306 | { |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
307 | //::printf("ACK ERROR %X [exp. %X]\n", c, ~(tr_data.payload[0])); |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
308 | // did not received the expected ack |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
309 | if (c == 0x66) |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
310 | { |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
311 | // we received a start of transmission while trying to emit something, |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
312 | // ignore it, the correct ack should be sent but the main unit just behind... |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
313 | set_timer(RXTIMEOUT); |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
314 | return cur_state; |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
315 | } |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
316 | else |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
317 | { |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
318 | // not sure how this may happen, in doubt, try again |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
319 | tr_data.pos--; |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
320 | } |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
321 | } |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
322 | } |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
323 | /* |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
324 | else if (c != 0x00) |
21 | 325 | { // resend current char |
47
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
326 | tr_data.pos--; |
21 | 327 | } |
47
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
328 | */ |
11c57010e4f9
Attempt to improve the detection of packet collisions (not fixed yet)
David Douard <david.douard@sdf3.org>
parents:
44
diff
changeset
|
329 | |
19 | 330 | // TODO: check ACK values (c is the received ack) |
331 | if (tr_data.pos >= tr_data.size) | |
21 | 332 | { |
44 | 333 | c = 0x55; |
334 | serial.write(&c, 1); // EoT | |
335 | cur_gstate = GSTATE_IDLE; | |
336 | set_timer(); // We are IDLE, detach the timeouter | |
337 | return STATE_IDLE; | |
21 | 338 | } |
44 | 339 | else |
340 | { | |
341 | serial.write(&tr_data.payload[tr_data.pos++], 1); | |
342 | set_timer(RXTIMEOUT); | |
343 | return STATE_SENDING; | |
344 | } | |
19 | 345 | } |
346 | ||
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
347 | HPSerial::state_t HPSerial::run_state(HPSerial::state_t cur_state, |
44 | 348 | uint8_t c) |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
349 | { |
19 | 350 | return (this->*(HPSerial::state_table[cur_state]))(c); |
18
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
351 | }; |
4fd621551d55
[full replacement] implement a state machine for Rx
David Douard <david.douard@logilab.fr>
parents:
16
diff
changeset
|
352 | |
44 | 353 | void HPSerial::rx_irq(void) { |
5 | 354 | uint8_t val; |
21 | 355 | if(serial.readable()) |
356 | { // no reason why we would end here without | |
357 | // this condition, but hey | |
44 | 358 | if (cur_gstate == GSTATE_IDLE) |
359 | // occurs when the CPU starts a new transmission | |
360 | // at this point, cur_state should be STATE_IDLE also (TODO add a check?) | |
361 | cur_gstate = GSTATE_RX; | |
28
424d792fea4f
compile for nucleo f446re & f303re with mbed 6
David Douard <david.douard@sdfa3.org>
parents:
21
diff
changeset
|
362 | serial.read(&val, 1); |
19 | 363 | cur_state = run_state(cur_state, val); |
5 | 364 | } |
365 | } | |
366 | ||
367 | ||
368 | void HPSerial::timeout(void) { | |
19 | 369 | set_timer(); // detach the timeouter |
370 | if (cur_gstate == GSTATE_STARTING) | |
371 | _startup(); | |
44 | 372 | else // CPU took too long to reply, reset |
19 | 373 | { |
374 | cur_gstate = GSTATE_IDLE; | |
375 | cur_state = STATE_IDLE; | |
376 | } | |
5 | 377 | } |