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