src/hp34comm.cpp~

changeset 8
55021f3f1929
parent 7
5cf4034ba4e0
child 9
e5254c6aa0c8
equal deleted inserted replaced
7:5cf4034ba4e0 8:55021f3f1929
1
2 #include "hp34comm.h"
3
4 /***** HP 34970A communication class ***/
5
6
7
8
9 HPSerial::HPSerial():
10 ncmd(0),
11 serial_tx(NC, HP_SERIAL_TX), serial_rx(NC, HP_SERIAL_RX) {
12
13 //pc.printf("HPSerial init\n");
14
15 for(uint8_t i=0; i<MAX_ERRS; i++)
16 errs[i] = 0;
17 reset();
18
19 serial_tx.baud(187500);
20 serial_tx.attach(this, &HPSerial::txIrq, Serial::RxIrq); //sic!
21
22 serial_rx.baud(187500);
23 serial_rx.attach(this, &HPSerial::rxIrq, Serial::RxIrq);
24 }
25
26 bool HPSerial::cmd_available(void) {
27 return !cmdbuf.empty();
28 }
29
30 bool HPSerial::pop(CMD& cmd) {
31 return cmdbuf.pop(cmd);
32 }
33
34 bool HPSerial::cmd_buf_full(void) {
35 return cmdbuf.full();
36 }
37
38 unsigned int HPSerial::nerrors(uint8_t errorno) {
39 return errs[errorno];
40 }
41
42
43
44 void HPSerial::reset(uint8_t errorno=0xFF) {
45 timeouter.detach();
46 head = 0;
47 tx_state = Idle;
48 setstatedbg();
49 tx_cmd = 0xFF;
50 tx_ack = false;
51 tx_len = 0xFF;
52 memset(buf, 0, BUF_SIZE);
53 if (errorno != 0xFF){
54 errs[errorno]++;
55 pulse(errorno+1);
56 }
57
58 }
59
60 void HPSerial::handleAck(uint8_t val) {
61 if ((tx_state == Rx) & (tx_cmd == 0xFF) & (tx_ack == false) & (val == 0x66)) {
62 // special case: keypad does not acknwledge and takes precedence
63 // on the "bus"
64 tx_state = Tx;
65 setstatedbg();
66 } else
67
68 if (tx_ack == true)
69 reset(0);
70
71 else
72 if (tx_cmd == 0xFF) // still at the beginning of a packet, expect 0x99 as ack
73 if (val == 0x99)
74 {
75 tx_ack = true;
76 #ifdef DEBUG
77 ack = 1;
78 wait_us(2);
79 ack = 0;
80 #endif
81 }
82 else
83 reset(1);
84
85 else // expect 0x00 as ack
86 if (val == 0x00)
87 {
88 tx_ack = true;
89 #ifdef DEBUG
90 ack = 1;
91 wait_us(2);
92 ack = 0;
93 wait_us(2);
94 ack = 1;
95 wait_us(2);
96 ack = 0;
97 #endif
98 }
99 else
100 reset(2);
101 }
102
103 void HPSerial::pushCmd(TrState direction, uint8_t cmd, uint8_t size, char *payload) {
104 CMD val;
105 uint8_t i;
106 val.id = ncmd++;
107 val.direction = direction;
108 val.cmd = cmd;
109 val.size = size;
110 for(i=0; i<size; i++)
111 val.value[i] = payload[i];
112 val.value[i] = 0x00;
113 cmdbuf.push(val);
114 }
115
116 void HPSerial::handleChar(uint8_t val) {
117 if (tx_ack == false)
118 reset(3);
119 else // remaining of the state machine
120 if (tx_cmd == 0xFF) {
121 // begin of transmission, expect a cmd
122 tx_cmd = val;
123 tx_ack = false;
124 if (tx_state == Rx)
125 tx_len = 0xFF;
126 else
127 tx_len = 0x00; // no payload: tx_cmd is the key stroke
128 }
129 else if (tx_len == 0xFF) {
130 // got a cmd, expect a payload size
131 tx_len = val;
132 tx_ack = false;
133 }
134 else if (tx_len > 0) {
135 // a payload char
136 buf[head++] = val;
137 tx_len--;
138 tx_ack = false;
139 }
140 else { // end of payload, manage sent content
141 uint8_t cur_state = tx_state;
142 pushCmd(tx_state, tx_cmd, head, buf);
143
144 switch(val) {
145 case 0x66: // a new transmisson
146 reset();
147 tx_state = cur_state;
148 setstatedbg();
149 break;
150 case 0x55:
151 reset();
152 break;
153 default:
154 reset(6);
155 break;
156 }
157 }
158 }
159
160
161
162 void HPSerial::setstatedbg(void) {
163 /*
164 if (tx_state == Rx)
165 staterx = 1;
166 else
167 staterx = 0;
168 if (tx_state == Tx)
169 statetx = 1;
170 else
171 statetx = 0;
172 */
173 }
174
175 void HPSerial::rxIrq(void) {
176 uint8_t val;
177 if(serial_rx.readable()) { // no reason why we would end here without this condition, but hey
178 #ifdef DEBUG
179 inrx=1;
180 #endif
181 val = serial_rx.getc();
182
183 timeouter.attach(this, &HPSerial::timeout, 0.001); // if nothing else happen in the next ms, reset
184
185 if (tx_state == Idle)
186 if (val == 0x66) {
187 // no transmission in progress, expect a start of transmission
188 tx_state = Rx;
189 tx_ack = false;
190 setstatedbg();
191 }
192 else
193 reset(4);
194
195 else if (tx_state == Tx) // manage the acks
196 handleAck(val);
197
198 else
199 handleChar(val);
200 #ifdef DEBUG
201 inrx=0;
202 #endif
203 }
204 }
205
206 void HPSerial::txIrq(void) {
207 uint8_t val;
208 if(serial_tx.readable()) { // no reason why we would end here without this condition, but hey
209 #ifdef DEBUG
210 intx=1;
211 #endif
212 val = serial_tx.getc();
213
214 timeouter.attach(this, &HPSerial::timeout, 0.001); // if nothing else happen in the next ms, reset
215
216 if (tx_state == Idle)
217 if (val == 0x66) {
218 // no transmission in progress, expect a start of transmission
219 tx_state = Tx;
220 tx_ack = false;
221 setstatedbg();
222 }
223 else
224 reset(5);
225
226 else if (tx_state == Rx) // manage the acks
227 handleAck(val);
228
229 else
230 handleChar(val);
231 }
232 #ifdef DEBUG
233 intx=0;
234 #endif
235 }
236
237 void HPSerial::timeout(void) {
238 if (tx_state != Idle) {
239 reset(7);
240 }
241 }

mercurial