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