]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * This file is part of the libsigrok project. | |
3 | * | |
4 | * Copyright (C) 2015 Daniel Glöckner <daniel-gl@gmx.net> | |
5 | * | |
6 | * This program is free software: you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation, either version 3 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | */ | |
19 | ||
20 | #include <config.h> | |
21 | #include <math.h> | |
22 | #include <ieee1284.h> | |
23 | #include "protocol.h" | |
24 | ||
25 | /* The firmware can be in the following states: | |
26 | * 0x00 Temporary state during initialization | |
27 | * Automatically transitions to state 0x01 | |
28 | * 0x01 Idle, this state updates calibration caps | |
29 | * Send 0x02 to go to state 0x21 | |
30 | * Send 0x03 to go to state 0x03 | |
31 | * Send 0x04 to go to state 0x14 | |
32 | * 0x21 Trigger is armed, caps are _not_ updated | |
33 | * Send 0x99 to check if trigger event occured | |
34 | * if triggered, goes to state 0x03 | |
35 | * else stays in state 0x21 | |
36 | * Send 0xFE to generate artificial trigger event | |
37 | * returns to state 0x21 | |
38 | * but next 0x99 will succeed | |
39 | * Send 0xFF to go to state 0x03 (abort capture) | |
40 | * 0x03 Extracts two 500 sample subsets from the 5000 | |
41 | * sample capture buffer for readout | |
42 | * When reading samples, the FPGA starts at the | |
43 | * first of the 1000 samples and automatically | |
44 | * advances to the next. | |
45 | * Send 0x04 to go to state 0x0F | |
46 | * 0x14 Scroll acquisition mode, update calib caps | |
47 | * When reading samples, the FPGA provides the | |
48 | * current value of the ADCs | |
49 | * Send 0xFF to go to state 0x0F | |
50 | * 0x0F Send channel number (1 or 2) to go to next state | |
51 | * There are actually two 0x0F states in series | |
52 | * which both expect the channel number. | |
53 | * If the values don't match, they are discarded. | |
54 | * The next state 0x05 is entered anyway | |
55 | * 0x05 Same as state 0x0F but expects sample rate index. | |
56 | * The next state is 0x08 | |
57 | * 0x08 Same as state 0x0F but expects step size + 1 for | |
58 | * the second 500 sample subset | |
59 | * The next state is 0x09 | |
60 | * 0x09 Same as state 0x0F but expects step size + 1 for | |
61 | * the first 500 sample subset | |
62 | * The next state is 0x06 | |
63 | * 0x06 Same as state 0x0F but expects vdiv and coupling | |
64 | * configuration for the first channel and trigger | |
65 | * source selection. | |
66 | * (U46 in the schematics) | |
67 | * The next state is 0x07 | |
68 | * 0x07 Same as state 0x0F but expects vdiv and coupling | |
69 | * configuration for the first channel and trigger | |
70 | * type (edge, TV hsync, TV vsync). | |
71 | * (U47 in the schematics) | |
72 | * The next state is 0x0A | |
73 | * 0x0A Same as state 0x0F but expects a parameter X + 1 | |
74 | * that determines the offset of the second 500 sample | |
75 | * subset | |
76 | * Offset = 5 * X * step size for first subset | |
77 | * The next state is 0x0B | |
78 | * 0x0B Same as state 0x0F but expects the type of edge to | |
79 | * trigger on (rising or falling) | |
80 | * The next state is 0x0C | |
81 | * 0x0C Same as state 0x0F but expects the calibration | |
82 | * value for the first channel's position | |
83 | * (POS1 in the schematics) | |
84 | * The next state is 0x0D | |
85 | * 0x0D Same as state 0x0F but expects the calibration | |
86 | * value for the second channel's position | |
87 | * (POS2 in the schematics) | |
88 | * The next state is 0x0E | |
89 | * 0x0E Same as state 0x0F but expects the trigger level | |
90 | * (TRIGLEVEL in the schematics) | |
91 | * Keep in mind that trigger sources are AC coupled | |
92 | * The next state is 0x10 | |
93 | * 0x10 Same as state 0x0F but expects the calibration | |
94 | * value for the first channel's offset | |
95 | * (OFFSET1 in the schematics) | |
96 | * The next state is 0x11 | |
97 | * 0x11 Same as state 0x0F but expects the calibration | |
98 | * value for the first channel's gain | |
99 | * (GAIN1 in the schematics) | |
100 | * The next state is 0x12 | |
101 | * 0x12 Same as state 0x0F but expects the calibration | |
102 | * value for the second channel's offset | |
103 | * (OFFSET2 in the schematics) | |
104 | * The next state is 0x13 | |
105 | * 0x13 Same as state 0x0F but expects the calibration | |
106 | * value for the second channel's gain | |
107 | * (GAIN2 in the schematics) | |
108 | * The next state is 0x01 | |
109 | * | |
110 | * The Mailbox appears to be half duplex. | |
111 | * If one side writes a byte into the mailbox, it | |
112 | * reads 0 until the other side has written a byte. | |
113 | * So you can't transfer 0. | |
114 | * | |
115 | * As the status signals are unconnected, the device is not | |
116 | * IEEE1284 compliant and can't make use of EPP or ECP transfers. | |
117 | * It drives the data lines when control is set to: | |
118 | * 0 => Channel A data | |
119 | * C1284_NAUTOFD => Channel B data | |
120 | * C1284_NSELECTIN => Mailbox | |
121 | * C1284_NSELECTIN | C1284_NAUTOFD => 0x55 | |
122 | * | |
123 | * It takes about 200ns for the data lines to become stable after | |
124 | * the control lines have been changed. This driver assumes that | |
125 | * parallel port access is slow enough to not require additional | |
126 | * delays. | |
127 | * | |
128 | * Channel values in state 0x14 and the mailbox can change their | |
129 | * value while they are selected, the latter of course only from | |
130 | * 0 to a valid state. Beware of intermediate values. | |
131 | * | |
132 | * SRAM N layout (N = 1 or 2): | |
133 | * 0x0000-0x13ff samples captured from ADC N | |
134 | * 0x4000-0x41f3 bytes extracted from 0x6000 with step1 | |
135 | * (both ADCs but only channel N) | |
136 | * 0x41f4-0x43e7 bytes extracted from 0x6000+5*step1*shift | |
137 | * with step2 (both ADCs but only channel N) | |
138 | * 0x43e8-0x43ea {0x01, 0xfe, 0x80} | |
139 | * 0x43eb-0x444e copy of bytes from 0x4320 | |
140 | * 0x6000-0x7387 interleaved SRAM 1 and SRAM 2 bytes from | |
141 | * 0x0001 to 0x09c5 after channel N was captured | |
142 | * | |
143 | * On a trigger event the FPGA directs the ADC samples to the region | |
144 | * at 0x0000. The microcontroller then copies 5000 samples from 0x0001 | |
145 | * to 0x6000. Each time state 0x03 is entered, the bytes from 0x4000 | |
146 | * to 0x444e are filled and the start address for readout is reset to | |
147 | * 0x4000. Readout will wrap around back to 0x4000 after reaching 0x7fff. | |
148 | * | |
149 | * As you can see from the layout, it was probably intended to capture | |
150 | * 5000 samples for both probes before they are read out. We don't do that | |
151 | * to be able to read the full 10k samples captured by the FPGA. It would | |
152 | * be useless anyway if you don't capture repetitive signals. We're also | |
153 | * not reading the two samples at 0x0000 to save a few milliseconds. | |
154 | */ | |
155 | ||
156 | static const struct { | |
157 | uint16_t num; | |
158 | uint8_t step1; | |
159 | uint8_t shift; | |
160 | uint8_t interleave; | |
161 | } readout_steps[] = { | |
162 | { 1000, 1, 100, 0 }, | |
163 | { 500, 100, 2, 0 }, | |
164 | { 500, 100, 3, 0 }, | |
165 | { 500, 100, 4, 0 }, | |
166 | { 500, 100, 5, 0 }, | |
167 | { 500, 100, 6, 0 }, | |
168 | { 500, 100, 7, 0 }, | |
169 | { 500, 100, 8, 0 }, | |
170 | { 500, 100, 9, 0 }, | |
171 | { 499, 212, 41, 1 }, | |
172 | { 500, 157, 56, 1 }, | |
173 | { 500, 247, 36, 1 }, | |
174 | { 500, 232, 180, 1 }, | |
175 | { 500, 230, 182, 1 }, | |
176 | { 120, 212, 43, 1 } | |
177 | }; | |
178 | ||
179 | SR_PRIV void hung_chang_dso_2100_reset_port(struct parport *port) | |
180 | { | |
181 | ieee1284_write_control(port, | |
182 | C1284_NSTROBE | C1284_NAUTOFD | C1284_NSELECTIN); | |
183 | ieee1284_data_dir(port, 0); | |
184 | } | |
185 | ||
186 | SR_PRIV gboolean hung_chang_dso_2100_check_id(struct parport *port) | |
187 | { | |
188 | gboolean ret = FALSE; | |
189 | ||
190 | if (ieee1284_data_dir(port, 1) != E1284_OK) | |
191 | goto fail; | |
192 | ||
193 | ieee1284_write_control(port, C1284_NSTROBE | C1284_NAUTOFD | C1284_NSELECTIN); | |
194 | ieee1284_write_control(port, C1284_NAUTOFD | C1284_NSELECTIN); | |
195 | ||
196 | if (ieee1284_read_data(port) != 0x55) | |
197 | goto fail; | |
198 | ||
199 | ret = TRUE; | |
200 | fail: | |
201 | hung_chang_dso_2100_reset_port(port); | |
202 | ||
203 | return ret; | |
204 | } | |
205 | ||
206 | SR_PRIV void hung_chang_dso_2100_write_mbox(struct parport *port, uint8_t val) | |
207 | { | |
208 | sr_dbg("mbox <= %X", val); | |
209 | ieee1284_write_control(port, | |
210 | C1284_NSTROBE | C1284_NINIT | C1284_NSELECTIN); | |
211 | ieee1284_data_dir(port, 0); | |
212 | ieee1284_write_data(port, val); | |
213 | ieee1284_write_control(port, C1284_NINIT | C1284_NSELECTIN); | |
214 | ieee1284_write_control(port, | |
215 | C1284_NSTROBE | C1284_NINIT | C1284_NSELECTIN); | |
216 | ieee1284_data_dir(port, 1); | |
217 | ieee1284_write_control(port, | |
218 | C1284_NSTROBE | C1284_NAUTOFD | C1284_NINIT | C1284_NSELECTIN); | |
219 | } | |
220 | ||
221 | SR_PRIV uint8_t hung_chang_dso_2100_read_mbox(struct parport *port, float timeout) | |
222 | { | |
223 | GTimer *timer = NULL; | |
224 | uint8_t val; | |
225 | ||
226 | ieee1284_write_control(port, C1284_NSTROBE | C1284_NSELECTIN); | |
227 | ieee1284_write_control(port, C1284_NSELECTIN); | |
228 | ||
229 | for (;;) { | |
230 | if (ieee1284_read_data(port)) { | |
231 | /* Always read the value a second time. | |
232 | * The first one may be unstable. */ | |
233 | val = ieee1284_read_data(port); | |
234 | break; | |
235 | } | |
236 | if (!timer) { | |
237 | timer = g_timer_new(); | |
238 | } else if (g_timer_elapsed(timer, NULL) > timeout) { | |
239 | val = 0; | |
240 | break; | |
241 | } | |
242 | } | |
243 | ||
244 | ieee1284_write_control(port, C1284_NSTROBE | C1284_NSELECTIN); | |
245 | ieee1284_write_control(port, | |
246 | C1284_NSTROBE | C1284_NAUTOFD | C1284_NINIT | C1284_NSELECTIN); | |
247 | ||
248 | if (timer) | |
249 | g_timer_destroy(timer); | |
250 | sr_dbg("mbox == %X", val); | |
251 | return val; | |
252 | } | |
253 | ||
254 | SR_PRIV int hung_chang_dso_2100_move_to(const struct sr_dev_inst *sdi, uint8_t target) | |
255 | { | |
256 | struct dev_context *devc = sdi->priv; | |
257 | int timeout = 40; | |
258 | uint8_t c; | |
259 | ||
260 | while (timeout--) { | |
261 | c = hung_chang_dso_2100_read_mbox(sdi->conn, 0.1); | |
262 | if (c == target) | |
263 | return SR_OK; | |
264 | ||
265 | switch (c) { | |
266 | case 0x00: | |
267 | /* Can happen if someone wrote something into | |
268 | * the mbox that was not expected by the uC. | |
269 | * Alternating between 0xff and 4 helps in | |
270 | * all states. */ | |
271 | c = (timeout & 1) ? 0xFF : 0x04; | |
272 | break; | |
273 | case 0x01: | |
274 | switch (target) { | |
275 | case 0x21: c = 2; break; | |
276 | case 0x03: c = 3; break; | |
277 | default: c = 4; | |
278 | } | |
279 | break; | |
280 | case 0x03: c = 4; break; | |
281 | case 0x05: c = devc->rate + 1; break; | |
282 | case 0x06: c = devc->cctl[0]; break; | |
283 | case 0x07: c = devc->cctl[1]; break; | |
284 | case 0x08: c = 1 /* step 2 */ + 1 ; break; | |
285 | case 0x09: c = readout_steps[devc->step].step1 + 1; break; | |
286 | case 0x0A: c = readout_steps[devc->step].shift + 1; break; | |
287 | case 0x0B: c = devc->edge + 1; break; | |
288 | case 0x0C: c = devc->pos[0]; break; | |
289 | case 0x0D: c = devc->pos[1]; break; | |
290 | case 0x0E: c = devc->tlevel; break; | |
291 | case 0x0F: | |
292 | if (!devc->channel) | |
293 | c = 1; | |
294 | else if (readout_steps[devc->step].interleave) | |
295 | c = devc->adc2 ? 2 : 1; | |
296 | else | |
297 | c = devc->channel; | |
298 | break; | |
299 | case 0x10: c = devc->offset[0]; break; | |
300 | case 0x11: c = devc->gain[0]; break; | |
301 | case 0x12: c = devc->offset[1]; break; | |
302 | case 0x13: c = devc->gain[1]; break; | |
303 | case 0x14: | |
304 | case 0x21: c = 0xFF; break; | |
305 | default: | |
306 | return SR_ERR_DATA; | |
307 | } | |
308 | hung_chang_dso_2100_write_mbox(sdi->conn, c); | |
309 | } | |
310 | return SR_ERR_TIMEOUT; | |
311 | } | |
312 | ||
313 | static void skip_samples(struct parport *port, uint8_t ctrl, size_t num) | |
314 | { | |
315 | while (num--) { | |
316 | ieee1284_write_control(port, ctrl & ~C1284_NSTROBE); | |
317 | ieee1284_write_control(port, ctrl); | |
318 | } | |
319 | } | |
320 | ||
321 | static void read_samples(struct parport *port, uint8_t ctrl, uint8_t *buf, size_t num, size_t stride) | |
322 | { | |
323 | while (num--) { | |
324 | ieee1284_write_control(port, ctrl & ~C1284_NSTROBE); | |
325 | *buf = ieee1284_read_data(port); | |
326 | buf += stride; | |
327 | ieee1284_write_control(port, ctrl); | |
328 | } | |
329 | } | |
330 | ||
331 | static void push_samples(const struct sr_dev_inst *sdi, uint8_t *buf, size_t num) | |
332 | { | |
333 | struct dev_context *devc = sdi->priv; | |
334 | float *data = devc->samples; | |
335 | struct sr_datafeed_analog analog; | |
336 | struct sr_analog_encoding encoding; | |
337 | struct sr_analog_meaning meaning; | |
338 | struct sr_analog_spec spec; | |
339 | struct sr_datafeed_packet packet = { | |
340 | .type = SR_DF_ANALOG, | |
341 | .payload = &analog, | |
342 | }; | |
343 | float factor = devc->factor; | |
344 | ||
345 | while (num--) | |
346 | data[num] = (buf[num] - 0x80) * factor; | |
347 | ||
348 | float vdivlog = log10f(factor); | |
349 | int digits = -(int)vdivlog + (vdivlog < 0.0); | |
350 | ||
351 | sr_analog_init(&analog, &encoding, &meaning, &spec, digits); | |
352 | analog.meaning->channels = devc->enabled_channel; | |
353 | analog.meaning->mq = SR_MQ_VOLTAGE; | |
354 | analog.meaning->unit = SR_UNIT_VOLT; | |
355 | analog.meaning->mqflags = 0; | |
356 | analog.num_samples = num; | |
357 | analog.data = data; | |
358 | ||
359 | sr_session_send(sdi, &packet); | |
360 | } | |
361 | ||
362 | static int read_subframe(const struct sr_dev_inst *sdi, uint8_t *buf) | |
363 | { | |
364 | struct dev_context *devc = sdi->priv; | |
365 | uint8_t sig[3], ctrl; | |
366 | unsigned int num; | |
367 | gboolean interleave; | |
368 | ||
369 | interleave = readout_steps[devc->step].interleave; | |
370 | ctrl = C1284_NSTROBE; | |
371 | if ((interleave && devc->adc2) || (!interleave && devc->channel == 2)) | |
372 | ctrl |= C1284_NAUTOFD; | |
373 | ||
374 | ieee1284_write_control(sdi->conn, ctrl); | |
375 | num = readout_steps[devc->step].num; | |
376 | if (num < 1000) | |
377 | skip_samples(sdi->conn, ctrl, 1000 - num); | |
378 | read_samples(sdi->conn, ctrl, buf + (devc->adc2 ? 1 : 0), num, | |
379 | interleave ? 2 : 1); | |
380 | read_samples(sdi->conn, ctrl, sig, 3, 1); | |
381 | if (sig[0] != 0x01 || sig[1] != 0xfe || sig[2] != 0x80) { | |
382 | if (--devc->retries) { | |
383 | sr_dbg("Missing signature at end of buffer, %i tries remaining", | |
384 | devc->retries); | |
385 | return TRUE; | |
386 | } else { | |
387 | sr_err("Failed to read frame without transfer errors"); | |
388 | devc->step = 0; | |
389 | } | |
390 | } else { | |
391 | if (interleave && !devc->adc2) { | |
392 | devc->adc2 = TRUE; | |
393 | devc->retries = MAX_RETRIES; | |
394 | return TRUE; | |
395 | } else { | |
396 | if (interleave) | |
397 | num *= 2; | |
398 | if (!devc->step) { | |
399 | struct sr_datafeed_packet packet = { | |
400 | .type = SR_DF_TRIGGER | |
401 | }; | |
402 | ||
403 | push_samples(sdi, buf, 6); | |
404 | sr_session_send(sdi, &packet); | |
405 | buf += 6; | |
406 | num -= 6; | |
407 | } | |
408 | push_samples(sdi, buf, num); | |
409 | if (++devc->step > devc->last_step) | |
410 | devc->step = 0; | |
411 | } | |
412 | } | |
413 | ||
414 | devc->adc2 = FALSE; | |
415 | devc->retries = MAX_RETRIES; | |
416 | ||
417 | return devc->step > 0; | |
418 | } | |
419 | ||
420 | SR_PRIV int hung_chang_dso_2100_poll(int fd, int revents, void *cb_data) | |
421 | { | |
422 | struct sr_datafeed_packet packet = { .type = SR_DF_FRAME_BEGIN }; | |
423 | const struct sr_dev_inst *sdi; | |
424 | struct dev_context *devc; | |
425 | uint8_t state, buf[1000]; | |
426 | ||
427 | (void)fd; | |
428 | (void)revents; | |
429 | ||
430 | if (!(sdi = cb_data)) | |
431 | return TRUE; | |
432 | ||
433 | if (!(devc = sdi->priv)) | |
434 | return TRUE; | |
435 | ||
436 | if (devc->state_known) | |
437 | hung_chang_dso_2100_write_mbox(sdi->conn, 0x99); | |
438 | ||
439 | state = hung_chang_dso_2100_read_mbox(sdi->conn, 0.00025); | |
440 | devc->state_known = (state != 0x00); | |
441 | ||
442 | if (!devc->state_known || state == 0x21) | |
443 | return TRUE; | |
444 | ||
445 | if (state != 0x03) { | |
446 | sr_err("Unexpected state 0x%X while checking for trigger", state); | |
447 | return FALSE; | |
448 | } | |
449 | ||
450 | sr_session_send(sdi, &packet); | |
451 | ||
452 | if (devc->channel) { | |
453 | while (read_subframe(sdi, buf)) { | |
454 | if (hung_chang_dso_2100_move_to(sdi, 1) != SR_OK) | |
455 | break; | |
456 | hung_chang_dso_2100_write_mbox(sdi->conn, 3); | |
457 | g_usleep(1700); | |
458 | if (hung_chang_dso_2100_read_mbox(sdi->conn, 0.02) != 0x03) | |
459 | break; | |
460 | } | |
461 | } | |
462 | ||
463 | packet.type = SR_DF_FRAME_END; | |
464 | sr_session_send(sdi, &packet); | |
465 | ||
466 | if (++devc->frame >= devc->frame_limit) | |
467 | hung_chang_dso_2100_dev_acquisition_stop(sdi); | |
468 | else | |
469 | hung_chang_dso_2100_move_to(sdi, 0x21); | |
470 | ||
471 | return TRUE; | |
472 | } |