]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * This file is part of the libsigrok project. | |
3 | * | |
4 | * Copyright (C) 2015 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 "lwla.h" | |
22 | #include "protocol.h" | |
23 | ||
24 | /* Number of logic channels. | |
25 | */ | |
26 | #define NUM_CHANNELS 16 | |
27 | ||
28 | /* Unit size for the sigrok logic datafeed. | |
29 | */ | |
30 | #define UNIT_SIZE ((NUM_CHANNELS + 7) / 8) | |
31 | ||
32 | /* Size of the acquisition buffer in device memory units. | |
33 | */ | |
34 | #define MEMORY_DEPTH (256 * 1024) /* 256k x 32 bit */ | |
35 | ||
36 | /* Capture memory read start address. | |
37 | */ | |
38 | #define READ_START_ADDR 2 | |
39 | ||
40 | /* Number of device memory units (32 bit) to read at a time. | |
41 | */ | |
42 | #define READ_CHUNK_LEN 250 | |
43 | ||
44 | /** LWLA1016 register addresses. | |
45 | */ | |
46 | enum reg_addr { | |
47 | REG_CHAN_MASK = 0x1000, /* bit mask of enabled channels */ | |
48 | ||
49 | REG_DURATION = 0x1010, /* capture duration in ms */ | |
50 | ||
51 | REG_MEM_WR_PTR = 0x1070, | |
52 | REG_MEM_RD_PTR = 0x1074, | |
53 | REG_MEM_DATA = 0x1078, | |
54 | REG_MEM_CTRL = 0x107C, | |
55 | ||
56 | REG_CAP_COUNT = 0x10B0, | |
57 | ||
58 | REG_TEST_ID = 0x10B4, /* read */ | |
59 | REG_TRG_SEL = 0x10B4, /* write */ | |
60 | ||
61 | REG_CAP_CTRL = 0x10B8, | |
62 | ||
63 | REG_CAP_TOTAL = 0x10BC, /* read */ | |
64 | REG_DIV_COUNT = 0x10BC, /* write */ | |
65 | }; | |
66 | ||
67 | /** Flag bits for REG_MEM_CTRL. | |
68 | */ | |
69 | enum mem_ctrl_flag { | |
70 | MEM_CTRL_RESET = 1 << 0, | |
71 | MEM_CTRL_WRITE = 1 << 1, | |
72 | }; | |
73 | ||
74 | /** Flag bits for REG_CAP_CTRL. | |
75 | */ | |
76 | enum cap_ctrl_flag { | |
77 | CAP_CTRL_FIFO32_FULL = 1 << 0, /* "fifo32_ful" bit */ | |
78 | CAP_CTRL_FIFO64_FULL = 1 << 1, /* "fifo64_ful" bit */ | |
79 | CAP_CTRL_TRG_EN = 1 << 2, /* "trg_en" bit */ | |
80 | CAP_CTRL_CLR_TIMEBASE = 1 << 3, /* "do_clr_timebase" bit */ | |
81 | CAP_CTRL_FIFO_EMPTY = 1 << 4, /* "fifo_empty" bit */ | |
82 | CAP_CTRL_SAMPLE_EN = 1 << 5, /* "sample_en" bit */ | |
83 | CAP_CTRL_CNTR_NOT_ENDR = 1 << 6, /* "cntr_not_endr" bit */ | |
84 | }; | |
85 | ||
86 | /* Available FPGA configurations. | |
87 | */ | |
88 | enum fpga_config { | |
89 | FPGA_100 = 0, /* 100 MS/s, no compression */ | |
90 | FPGA_100_TS, /* 100 MS/s, timing-state mode */ | |
91 | }; | |
92 | ||
93 | /* FPGA bitstream resource filenames. | |
94 | */ | |
95 | static const char bitstream_map[][32] = { | |
96 | [FPGA_100] = "sysclk-lwla1016-100.rbf", | |
97 | [FPGA_100_TS] = "sysclk-lwla1016-100-ts.rbf", | |
98 | }; | |
99 | ||
100 | /* Demangle incoming sample data from the transfer buffer. | |
101 | */ | |
102 | static void read_response(struct acquisition_state *acq) | |
103 | { | |
104 | uint32_t *in_p, *out_p; | |
105 | unsigned int words_left, num_words; | |
106 | unsigned int max_samples, run_samples; | |
107 | unsigned int i; | |
108 | ||
109 | words_left = MIN(acq->mem_addr_next, acq->mem_addr_stop) | |
110 | - acq->mem_addr_done; | |
111 | /* Calculate number of samples to write into packet. */ | |
112 | max_samples = MIN(acq->samples_max - acq->samples_done, | |
113 | PACKET_SIZE / UNIT_SIZE - acq->out_index); | |
114 | run_samples = MIN(max_samples, 2 * words_left); | |
115 | ||
116 | /* Round up in case the samples limit is an odd number. */ | |
117 | num_words = (run_samples + 1) / 2; | |
118 | /* | |
119 | * Without RLE the output index will always be a multiple of two | |
120 | * samples (at least before reaching the samples limit), thus 32-bit | |
121 | * alignment is guaranteed. | |
122 | */ | |
123 | out_p = (uint32_t *)&acq->out_packet[acq->out_index * UNIT_SIZE]; | |
124 | in_p = &acq->xfer_buf_in[acq->in_index]; | |
125 | /* | |
126 | * Transfer two samples at a time, taking care to swap the 16-bit | |
127 | * halves of each input word but keeping the samples themselves in | |
128 | * the original Little Endian order. | |
129 | */ | |
130 | for (i = 0; i < num_words; i++) | |
131 | out_p[i] = LROTATE(in_p[i], 16); | |
132 | ||
133 | acq->in_index += num_words; | |
134 | acq->mem_addr_done += num_words; | |
135 | acq->out_index += run_samples; | |
136 | acq->samples_done += run_samples; | |
137 | } | |
138 | ||
139 | /* Demangle and decompress incoming sample data from the transfer buffer. | |
140 | */ | |
141 | static void read_response_rle(struct acquisition_state *acq) | |
142 | { | |
143 | uint32_t *in_p; | |
144 | uint16_t *out_p; | |
145 | unsigned int words_left, max_samples, run_samples, wi, ri; | |
146 | uint32_t word; | |
147 | uint16_t sample; | |
148 | ||
149 | words_left = MIN(acq->mem_addr_next, acq->mem_addr_stop) | |
150 | - acq->mem_addr_done; | |
151 | in_p = &acq->xfer_buf_in[acq->in_index]; | |
152 | ||
153 | for (wi = 0;; wi++) { | |
154 | /* Calculate number of samples to write into packet. */ | |
155 | max_samples = MIN(acq->samples_max - acq->samples_done, | |
156 | PACKET_SIZE / UNIT_SIZE - acq->out_index); | |
157 | run_samples = MIN(max_samples, acq->run_len); | |
158 | ||
159 | /* Expand run-length samples into session packet. */ | |
160 | sample = GUINT16_TO_LE(acq->sample); | |
161 | out_p = &((uint16_t *)acq->out_packet)[acq->out_index]; | |
162 | ||
163 | for (ri = 0; ri < run_samples; ri++) | |
164 | out_p[ri] = sample; | |
165 | ||
166 | acq->run_len -= run_samples; | |
167 | acq->out_index += run_samples; | |
168 | acq->samples_done += run_samples; | |
169 | ||
170 | if (run_samples == max_samples) | |
171 | break; /* Packet full or sample limit reached. */ | |
172 | if (wi >= words_left) | |
173 | break; /* Done with current transfer. */ | |
174 | ||
175 | word = GUINT32_FROM_LE(in_p[wi]); | |
176 | acq->sample = word >> 16; | |
177 | acq->run_len = (word & 0xFFFF) + 1; | |
178 | } | |
179 | ||
180 | acq->in_index += wi; | |
181 | acq->mem_addr_done += wi; | |
182 | } | |
183 | ||
184 | /* Check whether we can receive responses of more than 64 bytes. | |
185 | * The FX2 firmware of the LWLA1016 has a bug in the reset logic which | |
186 | * sometimes causes the response endpoint to be limited to transfers of | |
187 | * 64 bytes at a time, instead of the expected 2*512 bytes. The problem | |
188 | * can be worked around by never requesting more than 64 bytes. | |
189 | * This quirk manifests itself only under certain conditions, and some | |
190 | * users seem to see it more frequently than others. Detect it here in | |
191 | * order to avoid paying the penalty unnecessarily. | |
192 | */ | |
193 | static int test_read_memory(const struct sr_dev_inst *sdi, | |
194 | unsigned int start, unsigned int count) | |
195 | { | |
196 | struct dev_context *devc; | |
197 | struct sr_usb_dev_inst *usb; | |
198 | unsigned int i; | |
199 | int xfer_len, ret; | |
200 | uint16_t command[5]; | |
201 | unsigned char reply[512]; | |
202 | ||
203 | devc = sdi->priv; | |
204 | usb = sdi->conn; | |
205 | ||
206 | command[0] = LWLA_WORD(CMD_READ_MEM32); | |
207 | command[1] = LWLA_WORD_0(start); | |
208 | command[2] = LWLA_WORD_1(start); | |
209 | command[3] = LWLA_WORD_0(count); | |
210 | command[4] = LWLA_WORD_1(count); | |
211 | ||
212 | ret = lwla_send_command(usb, command, ARRAY_SIZE(command)); | |
213 | if (ret != SR_OK) | |
214 | return ret; | |
215 | ||
216 | ret = lwla_receive_reply(usb, reply, sizeof(reply), &xfer_len); | |
217 | if (ret != SR_OK) | |
218 | return ret; | |
219 | ||
220 | devc->short_transfer_quirk = (xfer_len == 64); | |
221 | ||
222 | for (i = xfer_len; i < 4 * count && xfer_len == 64; i += xfer_len) { | |
223 | ret = lwla_receive_reply(usb, reply, sizeof(reply), &xfer_len); | |
224 | if (ret != SR_OK) | |
225 | return ret; | |
226 | } | |
227 | if (i != 4 * count) { | |
228 | sr_err("Invalid read response of unexpected length %d.", | |
229 | xfer_len); | |
230 | return SR_ERR; | |
231 | } | |
232 | ||
233 | return SR_OK; | |
234 | } | |
235 | ||
236 | /* Select and transfer FPGA bitstream for the current configuration. | |
237 | */ | |
238 | static int apply_fpga_config(const struct sr_dev_inst *sdi) | |
239 | { | |
240 | struct dev_context *devc; | |
241 | struct drv_context *drvc; | |
242 | int config, ret; | |
243 | ||
244 | devc = sdi->priv; | |
245 | drvc = sdi->driver->context; | |
246 | ||
247 | if (sdi->status == SR_ST_INACTIVE) | |
248 | return SR_OK; /* The LWLA1016 has no off state. */ | |
249 | ||
250 | config = (devc->cfg_rle) ? FPGA_100_TS : FPGA_100; | |
251 | ||
252 | if (config == devc->active_fpga_config) | |
253 | return SR_OK; /* No change. */ | |
254 | ||
255 | ret = lwla_send_bitstream(drvc->sr_ctx, sdi->conn, | |
256 | bitstream_map[config]); | |
257 | devc->active_fpga_config = (ret == SR_OK) ? config : FPGA_NOCONF; | |
258 | ||
259 | return ret; | |
260 | } | |
261 | ||
262 | /* Perform initialization self test. | |
263 | */ | |
264 | static int device_init_check(const struct sr_dev_inst *sdi) | |
265 | { | |
266 | static const struct regval mem_reset[] = { | |
267 | {REG_MEM_CTRL, MEM_CTRL_RESET}, | |
268 | {REG_MEM_CTRL, 0}, | |
269 | }; | |
270 | uint32_t value; | |
271 | int ret; | |
272 | const unsigned int test_count = 24; | |
273 | ||
274 | lwla_read_reg(sdi->conn, REG_TEST_ID, &value); | |
275 | ||
276 | /* Ignore the value returned by the first read. */ | |
277 | ret = lwla_read_reg(sdi->conn, REG_TEST_ID, &value); | |
278 | if (ret != SR_OK) | |
279 | return ret; | |
280 | ||
281 | if (value != 0x12345678) { | |
282 | sr_err("Received invalid test word 0x%08X.", value); | |
283 | return SR_ERR; | |
284 | } | |
285 | ||
286 | ret = lwla_write_regs(sdi->conn, mem_reset, ARRAY_SIZE(mem_reset)); | |
287 | if (ret != SR_OK) | |
288 | return ret; | |
289 | ||
290 | ret = test_read_memory(sdi, 0, test_count); | |
291 | if (ret != SR_OK) | |
292 | return ret; | |
293 | ||
294 | /* | |
295 | * Issue another read request or the device will stall, for whatever | |
296 | * reason. This happens both with and without the short transfer quirk. | |
297 | */ | |
298 | return test_read_memory(sdi, test_count, test_count); | |
299 | } | |
300 | ||
301 | static int setup_acquisition(const struct sr_dev_inst *sdi) | |
302 | { | |
303 | static const struct regval capture_init[] = { | |
304 | {REG_CAP_CTRL, 0}, | |
305 | {REG_DURATION, 0}, | |
306 | {REG_MEM_CTRL, MEM_CTRL_RESET}, | |
307 | {REG_MEM_CTRL, 0}, | |
308 | {REG_MEM_CTRL, MEM_CTRL_WRITE}, | |
309 | {REG_CAP_CTRL, CAP_CTRL_FIFO32_FULL | CAP_CTRL_FIFO64_FULL}, | |
310 | {REG_CAP_CTRL, CAP_CTRL_FIFO_EMPTY}, | |
311 | {REG_CAP_CTRL, 0}, | |
312 | {REG_CAP_COUNT, MEMORY_DEPTH - 5}, | |
313 | }; | |
314 | struct dev_context *devc; | |
315 | struct sr_usb_dev_inst *usb; | |
316 | uint32_t divider_count, trigger_setup; | |
317 | int ret; | |
318 | ||
319 | devc = sdi->priv; | |
320 | usb = sdi->conn; | |
321 | ||
322 | ret = lwla_write_reg(usb, REG_CHAN_MASK, devc->channel_mask); | |
323 | if (ret != SR_OK) | |
324 | return ret; | |
325 | ||
326 | if (devc->samplerate > 0 && devc->samplerate < SR_MHZ(100)) | |
327 | divider_count = SR_MHZ(100) / devc->samplerate - 1; | |
328 | else | |
329 | divider_count = 0; | |
330 | ||
331 | ret = lwla_write_reg(usb, REG_DIV_COUNT, divider_count); | |
332 | if (ret != SR_OK) | |
333 | return ret; | |
334 | ||
335 | ret = lwla_write_regs(usb, capture_init, ARRAY_SIZE(capture_init)); | |
336 | if (ret != SR_OK) | |
337 | return ret; | |
338 | ||
339 | trigger_setup = ((devc->trigger_edge_mask & 0xFFFF) << 16) | |
340 | | (devc->trigger_values & 0xFFFF); | |
341 | ||
342 | return lwla_write_reg(usb, REG_TRG_SEL, trigger_setup); | |
343 | } | |
344 | ||
345 | static int prepare_request(const struct sr_dev_inst *sdi) | |
346 | { | |
347 | struct dev_context *devc; | |
348 | struct acquisition_state *acq; | |
349 | unsigned int chunk_len, count; | |
350 | ||
351 | devc = sdi->priv; | |
352 | acq = devc->acquisition; | |
353 | ||
354 | acq->xfer_out->length = 0; | |
355 | acq->reg_seq_pos = 0; | |
356 | acq->reg_seq_len = 0; | |
357 | ||
358 | switch (devc->state) { | |
359 | case STATE_START_CAPTURE: | |
360 | lwla_queue_regval(acq, REG_CAP_CTRL, CAP_CTRL_TRG_EN | |
361 | | ((devc->trigger_mask & 0xFFFF) << 16)); | |
362 | break; | |
363 | case STATE_STOP_CAPTURE: | |
364 | lwla_queue_regval(acq, REG_CAP_CTRL, 0); | |
365 | lwla_queue_regval(acq, REG_DIV_COUNT, 0); | |
366 | break; | |
367 | case STATE_READ_PREPARE: | |
368 | lwla_queue_regval(acq, REG_MEM_CTRL, 0); | |
369 | break; | |
370 | case STATE_READ_FINISH: | |
371 | lwla_queue_regval(acq, REG_MEM_CTRL, MEM_CTRL_RESET); | |
372 | lwla_queue_regval(acq, REG_MEM_CTRL, 0); | |
373 | break; | |
374 | case STATE_STATUS_REQUEST: | |
375 | lwla_queue_regval(acq, REG_CAP_CTRL, 0); | |
376 | lwla_queue_regval(acq, REG_MEM_WR_PTR, 0); | |
377 | lwla_queue_regval(acq, REG_DURATION, 0); | |
378 | break; | |
379 | case STATE_LENGTH_REQUEST: | |
380 | lwla_queue_regval(acq, REG_CAP_COUNT, 0); | |
381 | break; | |
382 | case STATE_READ_REQUEST: | |
383 | /* Limit reads to 16 device words (64 bytes) at a time if the | |
384 | * device firmware has the short transfer quirk. */ | |
385 | chunk_len = (devc->short_transfer_quirk) ? 16 : READ_CHUNK_LEN; | |
386 | count = MIN(chunk_len, acq->mem_addr_stop - acq->mem_addr_next); | |
387 | ||
388 | acq->xfer_buf_out[0] = LWLA_WORD(CMD_READ_MEM32); | |
389 | acq->xfer_buf_out[1] = LWLA_WORD_0(acq->mem_addr_next); | |
390 | acq->xfer_buf_out[2] = LWLA_WORD_1(acq->mem_addr_next); | |
391 | acq->xfer_buf_out[3] = LWLA_WORD_0(count); | |
392 | acq->xfer_buf_out[4] = LWLA_WORD_1(count); | |
393 | acq->xfer_out->length = 5 * sizeof(acq->xfer_buf_out[0]); | |
394 | ||
395 | acq->mem_addr_next += count; | |
396 | break; | |
397 | default: | |
398 | sr_err("BUG: unhandled request state %d.", devc->state); | |
399 | return SR_ERR_BUG; | |
400 | } | |
401 | ||
402 | return SR_OK; | |
403 | } | |
404 | ||
405 | static int handle_response(const struct sr_dev_inst *sdi) | |
406 | { | |
407 | struct dev_context *devc; | |
408 | struct acquisition_state *acq; | |
409 | int expect_len; | |
410 | ||
411 | devc = sdi->priv; | |
412 | acq = devc->acquisition; | |
413 | ||
414 | switch (devc->state) { | |
415 | case STATE_STATUS_REQUEST: | |
416 | acq->status = acq->reg_sequence[0].val & 0x7F; | |
417 | acq->mem_addr_fill = acq->reg_sequence[1].val; | |
418 | acq->duration_now = acq->reg_sequence[2].val; | |
419 | break; | |
420 | case STATE_LENGTH_REQUEST: | |
421 | acq->mem_addr_next = READ_START_ADDR; | |
422 | acq->mem_addr_stop = acq->reg_sequence[0].val + READ_START_ADDR - 1; | |
423 | break; | |
424 | case STATE_READ_REQUEST: | |
425 | expect_len = (acq->mem_addr_next - acq->mem_addr_done | |
426 | + acq->in_index) * sizeof(acq->xfer_buf_in[0]); | |
427 | if (acq->xfer_in->actual_length != expect_len) { | |
428 | sr_err("Received size %d does not match expected size %d.", | |
429 | acq->xfer_in->actual_length, expect_len); | |
430 | devc->transfer_error = TRUE; | |
431 | return SR_ERR; | |
432 | } | |
433 | if (acq->rle_enabled) | |
434 | read_response_rle(acq); | |
435 | else | |
436 | read_response(acq); | |
437 | break; | |
438 | default: | |
439 | sr_err("BUG: unhandled response state %d.", devc->state); | |
440 | return SR_ERR_BUG; | |
441 | } | |
442 | ||
443 | return SR_OK; | |
444 | } | |
445 | ||
446 | /* Model descriptor for the LWLA1016. | |
447 | */ | |
448 | SR_PRIV const struct model_info lwla1016_info = { | |
449 | .name = "LWLA1016", | |
450 | .num_channels = NUM_CHANNELS, | |
451 | ||
452 | .num_devopts = 5, | |
453 | .devopts = { | |
454 | SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET, | |
455 | SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET, | |
456 | SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, | |
457 | SR_CONF_TRIGGER_MATCH | SR_CONF_LIST, | |
458 | SR_CONF_RLE | SR_CONF_GET | SR_CONF_SET, | |
459 | }, | |
460 | .num_samplerates = 19, | |
461 | .samplerates = { | |
462 | SR_MHZ(100), | |
463 | SR_MHZ(50), SR_MHZ(20), SR_MHZ(10), | |
464 | SR_MHZ(5), SR_MHZ(2), SR_MHZ(1), | |
465 | SR_KHZ(500), SR_KHZ(200), SR_KHZ(100), | |
466 | SR_KHZ(50), SR_KHZ(20), SR_KHZ(10), | |
467 | SR_KHZ(5), SR_KHZ(2), SR_KHZ(1), | |
468 | SR_HZ(500), SR_HZ(200), SR_HZ(100), | |
469 | }, | |
470 | ||
471 | .apply_fpga_config = &apply_fpga_config, | |
472 | .device_init_check = &device_init_check, | |
473 | .setup_acquisition = &setup_acquisition, | |
474 | ||
475 | .prepare_request = &prepare_request, | |
476 | .handle_response = &handle_response, | |
477 | }; |