]> sigrok.org Git - libsigrok.git/blame_incremental - src/hardware/sysclk-lwla/protocol.c
Drop unneeded std_session_send_df_header() comments.
[libsigrok.git] / src / hardware / sysclk-lwla / protocol.c
... / ...
CommitLineData
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2014 Daniel Elstner <daniel.kitta@gmail.com>
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 <string.h>
22#include "protocol.h"
23#include "lwla.h"
24
25/* Submit an already filled-in USB transfer.
26 */
27static int submit_transfer(struct dev_context *devc,
28 struct libusb_transfer *xfer)
29{
30 int ret;
31
32 ret = libusb_submit_transfer(xfer);
33
34 if (ret != 0) {
35 sr_err("Submit transfer failed: %s.", libusb_error_name(ret));
36 devc->transfer_error = TRUE;
37 return SR_ERR;
38 }
39
40 return SR_OK;
41}
42
43/* Set up transfer for the next register in a write sequence.
44 */
45static void next_reg_write(struct acquisition_state *acq)
46{
47 struct regval *regval;
48
49 regval = &acq->reg_sequence[acq->reg_seq_pos];
50
51 acq->xfer_buf_out[0] = LWLA_WORD(CMD_WRITE_REG);
52 acq->xfer_buf_out[1] = LWLA_WORD(regval->reg);
53 acq->xfer_buf_out[2] = LWLA_WORD_0(regval->val);
54 acq->xfer_buf_out[3] = LWLA_WORD_1(regval->val);
55
56 acq->xfer_out->length = 4 * sizeof(acq->xfer_buf_out[0]);
57}
58
59/* Set up transfer for the next register in a read sequence.
60 */
61static void next_reg_read(struct acquisition_state *acq)
62{
63 unsigned int addr;
64
65 addr = acq->reg_sequence[acq->reg_seq_pos].reg;
66
67 acq->xfer_buf_out[0] = LWLA_WORD(CMD_READ_REG);
68 acq->xfer_buf_out[1] = LWLA_WORD(addr);
69
70 acq->xfer_out->length = 2 * sizeof(acq->xfer_buf_out[0]);
71}
72
73/* Decode the response to a register read request.
74 */
75static int read_reg_response(struct acquisition_state *acq)
76{
77 uint32_t value;
78
79 if (acq->xfer_in->actual_length != 4) {
80 sr_err("Received size %d doesn't match expected size 4.",
81 acq->xfer_in->actual_length);
82 return SR_ERR;
83 }
84 value = LWLA_TO_UINT32(acq->xfer_buf_in[0]);
85 acq->reg_sequence[acq->reg_seq_pos].val = value;
86
87 return SR_OK;
88}
89
90/* Enter a new state and submit the corresponding request to the device.
91 */
92static int submit_request(const struct sr_dev_inst *sdi,
93 enum protocol_state state)
94{
95 struct dev_context *devc;
96 struct acquisition_state *acq;
97 int ret;
98
99 devc = sdi->priv;
100 acq = devc->acquisition;
101
102 devc->state = state;
103
104 acq->xfer_out->length = 0;
105 acq->reg_seq_pos = 0;
106 acq->reg_seq_len = 0;
107
108 /* Perform the model-specific action for the new state. */
109 ret = (*devc->model->prepare_request)(sdi);
110
111 if (ret != SR_OK) {
112 devc->transfer_error = TRUE;
113 return ret;
114 }
115
116 if (acq->reg_seq_pos < acq->reg_seq_len) {
117 if ((state & STATE_EXPECT_RESPONSE) != 0)
118 next_reg_read(acq);
119 else
120 next_reg_write(acq);
121 }
122
123 return submit_transfer(devc, acq->xfer_out);
124}
125
126/* Evaluate and act on the response to a capture status request.
127 */
128static void handle_status_response(const struct sr_dev_inst *sdi)
129{
130 struct dev_context *devc;
131 struct acquisition_state *acq;
132 unsigned int old_status;
133
134 devc = sdi->priv;
135 acq = devc->acquisition;
136 old_status = acq->status;
137
138 if ((*devc->model->handle_response)(sdi) != SR_OK) {
139 devc->transfer_error = TRUE;
140 return;
141 }
142 devc->state = STATE_STATUS_WAIT;
143
144 sr_spew("Captured %u words, %" PRIu64 " ms, status 0x%02X.",
145 acq->mem_addr_fill, acq->duration_now, acq->status);
146
147 if ((~old_status & acq->status & STATUS_TRIGGERED) != 0)
148 sr_info("Capture triggered.");
149
150 if (acq->duration_now >= acq->duration_max) {
151 sr_dbg("Time limit reached, stopping capture.");
152 submit_request(sdi, STATE_STOP_CAPTURE);
153 } else if ((acq->status & STATUS_TRIGGERED) == 0) {
154 sr_spew("Waiting for trigger.");
155 } else if ((acq->status & STATUS_MEM_AVAIL) == 0) {
156 sr_dbg("Capture memory filled.");
157 submit_request(sdi, STATE_LENGTH_REQUEST);
158 } else if ((acq->status & STATUS_CAPTURING) != 0) {
159 sr_spew("Sampling in progress.");
160 }
161}
162
163/* Evaluate and act on the response to a capture length request.
164 */
165static void handle_length_response(const struct sr_dev_inst *sdi)
166{
167 struct dev_context *devc;
168 struct acquisition_state *acq;
169
170 devc = sdi->priv;
171 acq = devc->acquisition;
172
173 if ((*devc->model->handle_response)(sdi) != SR_OK) {
174 devc->transfer_error = TRUE;
175 return;
176 }
177 acq->rle = RLE_STATE_DATA;
178 acq->sample = 0;
179 acq->run_len = 0;
180 acq->samples_done = 0;
181 acq->mem_addr_done = acq->mem_addr_next;
182 acq->out_index = 0;
183
184 if (acq->mem_addr_next >= acq->mem_addr_stop) {
185 submit_request(sdi, STATE_READ_FINISH);
186 return;
187 }
188 sr_dbg("%u words in capture buffer.",
189 acq->mem_addr_stop - acq->mem_addr_next);
190
191 submit_request(sdi, STATE_READ_PREPARE);
192}
193
194/* Evaluate and act on the response to a capture memory read request.
195 */
196static void handle_read_response(const struct sr_dev_inst *sdi)
197{
198 struct dev_context *devc;
199 struct acquisition_state *acq;
200 struct sr_datafeed_packet packet;
201 struct sr_datafeed_logic logic;
202 unsigned int end_addr;
203
204 devc = sdi->priv;
205 acq = devc->acquisition;
206
207 /* Prepare session packet. */
208 packet.type = SR_DF_LOGIC;
209 packet.payload = &logic;
210 logic.unitsize = (devc->model->num_channels + 7) / 8;
211 logic.data = acq->out_packet;
212
213 end_addr = MIN(acq->mem_addr_next, acq->mem_addr_stop);
214 acq->in_index = 0;
215
216 /*
217 * Repeatedly call the model-specific read response handler until
218 * all data received in the transfer has been accounted for.
219 */
220 while (!devc->cancel_requested
221 && (acq->run_len > 0 || acq->mem_addr_done < end_addr)
222 && acq->samples_done < acq->samples_max) {
223
224 if ((*devc->model->handle_response)(sdi) != SR_OK) {
225 devc->transfer_error = TRUE;
226 return;
227 }
228 if (acq->out_index * logic.unitsize >= PACKET_SIZE) {
229 /* Send off full logic packet. */
230 logic.length = acq->out_index * logic.unitsize;
231 sr_session_send(sdi, &packet);
232 acq->out_index = 0;
233 }
234 }
235
236 if (!devc->cancel_requested
237 && acq->samples_done < acq->samples_max
238 && acq->mem_addr_next < acq->mem_addr_stop) {
239 /* Request the next block. */
240 submit_request(sdi, STATE_READ_REQUEST);
241 return;
242 }
243
244 /* Send partially filled packet as it is the last one. */
245 if (!devc->cancel_requested && acq->out_index > 0) {
246 logic.length = acq->out_index * logic.unitsize;
247 sr_session_send(sdi, &packet);
248 acq->out_index = 0;
249 }
250 submit_request(sdi, STATE_READ_FINISH);
251}
252
253/* Destroy and unset the acquisition state record.
254 */
255static void clear_acquisition_state(const struct sr_dev_inst *sdi)
256{
257 struct dev_context *devc;
258 struct acquisition_state *acq;
259
260 devc = sdi->priv;
261 acq = devc->acquisition;
262
263 devc->acquisition = NULL;
264
265 if (acq) {
266 libusb_free_transfer(acq->xfer_out);
267 libusb_free_transfer(acq->xfer_in);
268 g_free(acq);
269 }
270}
271
272/* USB I/O source callback.
273 */
274static int transfer_event(int fd, int revents, void *cb_data)
275{
276 const struct sr_dev_inst *sdi;
277 struct dev_context *devc;
278 struct drv_context *drvc;
279 struct timeval tv;
280 int ret;
281
282 (void)fd;
283
284 sdi = cb_data;
285 devc = sdi->priv;
286 drvc = sdi->driver->context;
287
288 if (!devc || !drvc)
289 return G_SOURCE_REMOVE;
290
291 /* Handle pending USB events without blocking. */
292 tv.tv_sec = 0;
293 tv.tv_usec = 0;
294 ret = libusb_handle_events_timeout_completed(drvc->sr_ctx->libusb_ctx,
295 &tv, NULL);
296 if (ret != 0) {
297 sr_err("Event handling failed: %s.", libusb_error_name(ret));
298 devc->transfer_error = TRUE;
299 }
300
301 if (!devc->transfer_error && devc->state == STATE_STATUS_WAIT) {
302 if (devc->cancel_requested)
303 submit_request(sdi, STATE_STOP_CAPTURE);
304 else if (revents == 0) /* status poll timeout */
305 submit_request(sdi, STATE_STATUS_REQUEST);
306 }
307
308 /* Stop processing events if an error occurred on a transfer. */
309 if (devc->transfer_error)
310 devc->state = STATE_IDLE;
311
312 if (devc->state != STATE_IDLE)
313 return G_SOURCE_CONTINUE;
314
315 sr_info("Acquisition stopped.");
316
317 /* We are done, clean up and send end packet to session bus. */
318 clear_acquisition_state(sdi);
319 std_session_send_df_end(sdi, LOG_PREFIX);
320
321 return G_SOURCE_REMOVE;
322}
323
324/* USB output transfer completion callback.
325 */
326static void LIBUSB_CALL transfer_out_completed(struct libusb_transfer *transfer)
327{
328 const struct sr_dev_inst *sdi;
329 struct dev_context *devc;
330 struct acquisition_state *acq;
331
332 sdi = transfer->user_data;
333 devc = sdi->priv;
334 acq = devc->acquisition;
335
336 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
337 sr_err("Transfer to device failed (state %d): %s.",
338 devc->state, libusb_error_name(transfer->status));
339 devc->transfer_error = TRUE;
340 return;
341 }
342
343 /* If this was a read request, wait for the response. */
344 if ((devc->state & STATE_EXPECT_RESPONSE) != 0) {
345 submit_transfer(devc, acq->xfer_in);
346 return;
347 }
348 if (acq->reg_seq_pos < acq->reg_seq_len)
349 acq->reg_seq_pos++; /* register write completed */
350
351 /* Repeat until all queued registers have been written. */
352 if (acq->reg_seq_pos < acq->reg_seq_len && !devc->cancel_requested) {
353 next_reg_write(acq);
354 submit_transfer(devc, acq->xfer_out);
355 return;
356 }
357
358 switch (devc->state) {
359 case STATE_START_CAPTURE:
360 sr_info("Acquisition started.");
361
362 if (!devc->cancel_requested)
363 devc->state = STATE_STATUS_WAIT;
364 else
365 submit_request(sdi, STATE_STOP_CAPTURE);
366 break;
367 case STATE_STOP_CAPTURE:
368 if (!devc->cancel_requested)
369 submit_request(sdi, STATE_LENGTH_REQUEST);
370 else
371 devc->state = STATE_IDLE;
372 break;
373 case STATE_READ_PREPARE:
374 if (acq->mem_addr_next < acq->mem_addr_stop && !devc->cancel_requested)
375 submit_request(sdi, STATE_READ_REQUEST);
376 else
377 submit_request(sdi, STATE_READ_FINISH);
378 break;
379 case STATE_READ_FINISH:
380 devc->state = STATE_IDLE;
381 break;
382 default:
383 sr_err("Unexpected device state %d.", devc->state);
384 devc->transfer_error = TRUE;
385 break;
386 }
387}
388
389/* USB input transfer completion callback.
390 */
391static void LIBUSB_CALL transfer_in_completed(struct libusb_transfer *transfer)
392{
393 const struct sr_dev_inst *sdi;
394 struct dev_context *devc;
395 struct acquisition_state *acq;
396
397 sdi = transfer->user_data;
398 devc = sdi->priv;
399 acq = devc->acquisition;
400
401 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
402 sr_err("Transfer from device failed (state %d): %s.",
403 devc->state, libusb_error_name(transfer->status));
404 devc->transfer_error = TRUE;
405 return;
406 }
407 if ((devc->state & STATE_EXPECT_RESPONSE) == 0) {
408 sr_err("Unexpected completion of input transfer (state %d).",
409 devc->state);
410 devc->transfer_error = TRUE;
411 return;
412 }
413
414 if (acq->reg_seq_pos < acq->reg_seq_len && !devc->cancel_requested) {
415 /* Complete register read sequence. */
416 if (read_reg_response(acq) != SR_OK) {
417 devc->transfer_error = TRUE;
418 return;
419 }
420 /* Repeat until all queued registers have been read. */
421 if (++acq->reg_seq_pos < acq->reg_seq_len) {
422 next_reg_read(acq);
423 submit_transfer(devc, acq->xfer_out);
424 return;
425 }
426 }
427
428 switch (devc->state) {
429 case STATE_STATUS_REQUEST:
430 if (devc->cancel_requested)
431 submit_request(sdi, STATE_STOP_CAPTURE);
432 else
433 handle_status_response(sdi);
434 break;
435 case STATE_LENGTH_REQUEST:
436 if (devc->cancel_requested)
437 submit_request(sdi, STATE_READ_FINISH);
438 else
439 handle_length_response(sdi);
440 break;
441 case STATE_READ_REQUEST:
442 handle_read_response(sdi);
443 break;
444 default:
445 sr_err("Unexpected device state %d.", devc->state);
446 devc->transfer_error = TRUE;
447 break;
448 }
449}
450
451/* Set up the acquisition state record.
452 */
453static int init_acquisition_state(const struct sr_dev_inst *sdi)
454{
455 struct dev_context *devc;
456 struct sr_usb_dev_inst *usb;
457 struct acquisition_state *acq;
458
459 devc = sdi->priv;
460 usb = sdi->conn;
461
462 if (devc->acquisition) {
463 sr_err("Acquisition still in progress?");
464 return SR_ERR;
465 }
466 if (devc->cfg_clock_source == CLOCK_INTERNAL && devc->samplerate == 0) {
467 sr_err("Samplerate not set.");
468 return SR_ERR;
469 }
470
471 acq = g_try_malloc0(sizeof(struct acquisition_state));
472 if (!acq)
473 return SR_ERR_MALLOC;
474
475 acq->xfer_in = libusb_alloc_transfer(0);
476 if (!acq->xfer_in) {
477 g_free(acq);
478 return SR_ERR_MALLOC;
479 }
480 acq->xfer_out = libusb_alloc_transfer(0);
481 if (!acq->xfer_out) {
482 libusb_free_transfer(acq->xfer_in);
483 g_free(acq);
484 return SR_ERR_MALLOC;
485 }
486
487 libusb_fill_bulk_transfer(acq->xfer_out, usb->devhdl, EP_COMMAND,
488 (unsigned char *)acq->xfer_buf_out, 0,
489 &transfer_out_completed,
490 (struct sr_dev_inst *)sdi, USB_TIMEOUT_MS);
491
492 libusb_fill_bulk_transfer(acq->xfer_in, usb->devhdl, EP_REPLY,
493 (unsigned char *)acq->xfer_buf_in,
494 sizeof(acq->xfer_buf_in),
495 &transfer_in_completed,
496 (struct sr_dev_inst *)sdi, USB_TIMEOUT_MS);
497
498 if (devc->limit_msec > 0) {
499 acq->duration_max = devc->limit_msec;
500 sr_info("Acquisition time limit %" PRIu64 " ms.",
501 devc->limit_msec);
502 } else
503 acq->duration_max = MAX_LIMIT_MSEC;
504
505 if (devc->limit_samples > 0) {
506 acq->samples_max = devc->limit_samples;
507 sr_info("Acquisition sample count limit %" PRIu64 ".",
508 devc->limit_samples);
509 } else
510 acq->samples_max = MAX_LIMIT_SAMPLES;
511
512 if (devc->cfg_clock_source == CLOCK_INTERNAL) {
513 sr_info("Internal clock, samplerate %" PRIu64 ".",
514 devc->samplerate);
515 /* Ramp up clock speed to enable samplerates above 100 MS/s. */
516 acq->clock_boost = (devc->samplerate > SR_MHZ(100));
517
518 /* If only one of the limits is set, derive the other one. */
519 if (devc->limit_msec == 0 && devc->limit_samples > 0)
520 acq->duration_max = devc->limit_samples
521 * 1000 / devc->samplerate + 1;
522 else if (devc->limit_samples == 0 && devc->limit_msec > 0)
523 acq->samples_max = devc->limit_msec
524 * devc->samplerate / 1000;
525 } else {
526 acq->clock_boost = TRUE;
527
528 if (devc->cfg_clock_edge == EDGE_POSITIVE)
529 sr_info("External clock, rising edge.");
530 else
531 sr_info("External clock, falling edge.");
532 }
533
534 acq->rle_enabled = devc->cfg_rle;
535 devc->acquisition = acq;
536
537 return SR_OK;
538}
539
540SR_PRIV int lwla_start_acquisition(const struct sr_dev_inst *sdi)
541{
542 struct drv_context *drvc;
543 struct dev_context *devc;
544 int ret;
545 const int poll_interval_ms = 100;
546
547 drvc = sdi->driver->context;
548 devc = sdi->priv;
549
550 if (devc->state != STATE_IDLE) {
551 sr_err("Not in idle state, cannot start acquisition.");
552 return SR_ERR;
553 }
554 devc->cancel_requested = FALSE;
555 devc->transfer_error = FALSE;
556
557 ret = init_acquisition_state(sdi);
558 if (ret != SR_OK)
559 return ret;
560
561 ret = (*devc->model->setup_acquisition)(sdi);
562 if (ret != SR_OK) {
563 sr_err("Failed to set up device for acquisition.");
564 clear_acquisition_state(sdi);
565 return ret;
566 }
567 /* Register event source for asynchronous USB I/O. */
568 ret = usb_source_add(sdi->session, drvc->sr_ctx, poll_interval_ms,
569 &transfer_event, (struct sr_dev_inst *)sdi);
570 if (ret != SR_OK) {
571 clear_acquisition_state(sdi);
572 return ret;
573 }
574 ret = submit_request(sdi, STATE_START_CAPTURE);
575
576 if (ret == SR_OK)
577 ret = std_session_send_df_header(sdi, LOG_PREFIX);
578
579 if (ret != SR_OK) {
580 usb_source_remove(sdi->session, drvc->sr_ctx);
581 clear_acquisition_state(sdi);
582 }
583
584 return ret;
585}