]>
Commit | Line | Data |
---|---|---|
be64f90b DE |
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_LEN32 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; | |
7ed80817 DE |
105 | unsigned int words_left, num_words; |
106 | unsigned int max_samples, run_samples; | |
107 | unsigned int i; | |
be64f90b DE |
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; | |
7ed80817 DE |
145 | unsigned int words_left; |
146 | unsigned int max_samples, run_samples; | |
147 | unsigned int wi, ri; | |
be64f90b DE |
148 | uint32_t word; |
149 | uint16_t sample; | |
150 | ||
151 | words_left = MIN(acq->mem_addr_next, acq->mem_addr_stop) | |
152 | - acq->mem_addr_done; | |
153 | in_p = &acq->xfer_buf_in[acq->in_index]; | |
154 | ||
155 | for (wi = 0;; wi++) { | |
156 | /* Calculate number of samples to write into packet. */ | |
157 | max_samples = MIN(acq->samples_max - acq->samples_done, | |
158 | PACKET_SIZE / UNIT_SIZE - acq->out_index); | |
159 | run_samples = MIN(max_samples, acq->run_len); | |
160 | ||
161 | /* Expand run-length samples into session packet. */ | |
7ed80817 | 162 | sample = GUINT16_TO_LE(acq->sample); |
be64f90b DE |
163 | out_p = &((uint16_t *)acq->out_packet)[acq->out_index]; |
164 | ||
165 | for (ri = 0; ri < run_samples; ri++) | |
7ed80817 | 166 | out_p[ri] = sample; |
be64f90b DE |
167 | |
168 | acq->run_len -= run_samples; | |
169 | acq->out_index += run_samples; | |
170 | acq->samples_done += run_samples; | |
171 | ||
172 | if (run_samples == max_samples) | |
173 | break; /* packet full or sample limit reached */ | |
174 | if (wi >= words_left) | |
175 | break; /* done with current transfer */ | |
176 | ||
177 | word = GUINT32_FROM_LE(in_p[wi]); | |
178 | acq->sample = word >> 16; | |
179 | acq->run_len = (word & 0xFFFF) + 1; | |
180 | } | |
181 | acq->in_index += wi; | |
182 | acq->mem_addr_done += wi; | |
183 | } | |
184 | ||
185 | /* Select and transfer FPGA bitstream for the current configuration. | |
186 | */ | |
187 | static int apply_fpga_config(const struct sr_dev_inst *sdi) | |
188 | { | |
189 | struct dev_context *devc; | |
190 | struct drv_context *drvc; | |
191 | int config; | |
192 | int ret; | |
193 | ||
194 | devc = sdi->priv; | |
195 | drvc = sdi->driver->context; | |
196 | ||
197 | if (sdi->status == SR_ST_INACTIVE) | |
198 | return SR_OK; /* the LWLA1016 has no off state */ | |
199 | ||
200 | config = (devc->cfg_rle) ? FPGA_100_TS : FPGA_100; | |
201 | ||
202 | if (config == devc->active_fpga_config) | |
203 | return SR_OK; /* no change */ | |
204 | ||
205 | ret = lwla_send_bitstream(drvc->sr_ctx, sdi->conn, | |
206 | bitstream_map[config]); | |
207 | devc->active_fpga_config = (ret == SR_OK) ? config : FPGA_NOCONF; | |
208 | ||
209 | return ret; | |
210 | } | |
211 | ||
212 | /* Perform initialization self test. | |
213 | */ | |
214 | static int device_init_check(const struct sr_dev_inst *sdi) | |
215 | { | |
216 | uint32_t value; | |
217 | int ret; | |
218 | ||
219 | ret = lwla_read_reg(sdi->conn, REG_TEST_ID, &value); | |
220 | if (ret != SR_OK) | |
221 | return ret; | |
222 | ||
223 | /* Ignore the value returned by the first read. */ | |
224 | ret = lwla_read_reg(sdi->conn, REG_TEST_ID, &value); | |
225 | if (ret != SR_OK) | |
226 | return ret; | |
227 | ||
228 | if (value != 0x12345678) { | |
229 | sr_err("Received invalid test word 0x%08X.", value); | |
230 | return SR_ERR; | |
231 | } | |
232 | return SR_OK; | |
233 | } | |
234 | ||
235 | static int setup_acquisition(const struct sr_dev_inst *sdi) | |
236 | { | |
237 | struct dev_context *devc; | |
238 | struct sr_usb_dev_inst *usb; | |
239 | struct acquisition_state *acq; | |
240 | uint32_t divider_count; | |
241 | int ret; | |
242 | ||
243 | devc = sdi->priv; | |
244 | usb = sdi->conn; | |
245 | acq = devc->acquisition; | |
246 | ||
247 | acq->reg_seq_pos = 0; | |
248 | acq->reg_seq_len = 0; | |
249 | ||
250 | lwla_queue_regval(acq, REG_CHAN_MASK, devc->channel_mask); | |
251 | ||
252 | if (devc->samplerate > 0 && devc->samplerate < SR_MHZ(100)) | |
253 | divider_count = SR_MHZ(100) / devc->samplerate - 1; | |
254 | else | |
255 | divider_count = 0; | |
256 | ||
257 | lwla_queue_regval(acq, REG_DIV_COUNT, divider_count); | |
258 | ||
259 | lwla_queue_regval(acq, REG_CAP_CTRL, 0); | |
260 | lwla_queue_regval(acq, REG_DURATION, 0); | |
261 | ||
262 | lwla_queue_regval(acq, REG_MEM_CTRL, MEM_CTRL_RESET); | |
263 | lwla_queue_regval(acq, REG_MEM_CTRL, 0); | |
264 | lwla_queue_regval(acq, REG_MEM_CTRL, MEM_CTRL_WRITE); | |
265 | ||
266 | lwla_queue_regval(acq, REG_CAP_CTRL, | |
267 | CAP_CTRL_FIFO32_FULL | CAP_CTRL_FIFO64_FULL); | |
268 | ||
269 | lwla_queue_regval(acq, REG_CAP_CTRL, CAP_CTRL_FIFO_EMPTY); | |
270 | lwla_queue_regval(acq, REG_CAP_CTRL, 0); | |
271 | ||
272 | lwla_queue_regval(acq, REG_CAP_COUNT, MEMORY_DEPTH - 5); | |
273 | ||
274 | lwla_queue_regval(acq, REG_TRG_SEL, | |
275 | ((devc->trigger_edge_mask & 0xFFFF) << 16) | |
276 | | (devc->trigger_values & 0xFFFF)); | |
277 | ||
278 | ret = lwla_write_regs(usb, acq->reg_sequence, acq->reg_seq_len); | |
279 | acq->reg_seq_len = 0; | |
280 | ||
281 | return ret; | |
282 | } | |
283 | ||
284 | static int prepare_request(const struct sr_dev_inst *sdi) | |
285 | { | |
286 | struct dev_context *devc; | |
287 | struct acquisition_state *acq; | |
7ed80817 | 288 | unsigned int count; |
be64f90b DE |
289 | |
290 | devc = sdi->priv; | |
291 | acq = devc->acquisition; | |
292 | ||
293 | acq->xfer_out->length = 0; | |
294 | acq->reg_seq_pos = 0; | |
295 | acq->reg_seq_len = 0; | |
296 | ||
297 | switch (devc->state) { | |
298 | case STATE_START_CAPTURE: | |
299 | lwla_queue_regval(acq, REG_CAP_CTRL, CAP_CTRL_TRG_EN | |
300 | | ((devc->trigger_mask & 0xFFFF) << 16)); | |
301 | break; | |
302 | case STATE_STOP_CAPTURE: | |
303 | lwla_queue_regval(acq, REG_CAP_CTRL, 0); | |
304 | lwla_queue_regval(acq, REG_DIV_COUNT, 0); | |
305 | break; | |
306 | case STATE_READ_PREPARE: | |
307 | lwla_queue_regval(acq, REG_MEM_CTRL, 0); | |
308 | break; | |
309 | case STATE_READ_FINISH: | |
310 | lwla_queue_regval(acq, REG_MEM_CTRL, MEM_CTRL_RESET); | |
311 | lwla_queue_regval(acq, REG_MEM_CTRL, 0); | |
312 | break; | |
313 | case STATE_STATUS_REQUEST: | |
314 | lwla_queue_regval(acq, REG_CAP_CTRL, 0); | |
315 | lwla_queue_regval(acq, REG_MEM_WR_PTR, 0); | |
316 | lwla_queue_regval(acq, REG_DURATION, 0); | |
317 | break; | |
318 | case STATE_LENGTH_REQUEST: | |
319 | lwla_queue_regval(acq, REG_CAP_COUNT, 0); | |
320 | break; | |
321 | case STATE_READ_REQUEST: | |
be64f90b DE |
322 | count = MIN(READ_CHUNK_LEN32, |
323 | acq->mem_addr_stop - acq->mem_addr_next); | |
324 | ||
325 | acq->xfer_buf_out[0] = LWLA_WORD(CMD_READ_MEM32); | |
326 | acq->xfer_buf_out[1] = LWLA_WORD_0(acq->mem_addr_next); | |
327 | acq->xfer_buf_out[2] = LWLA_WORD_1(acq->mem_addr_next); | |
328 | acq->xfer_buf_out[3] = LWLA_WORD_0(count); | |
329 | acq->xfer_buf_out[4] = LWLA_WORD_1(count); | |
330 | acq->xfer_out->length = 5 * sizeof(acq->xfer_buf_out[0]); | |
331 | ||
332 | acq->mem_addr_next += count; | |
333 | break; | |
334 | default: | |
335 | sr_err("BUG: unhandled request state %d.", devc->state); | |
336 | return SR_ERR_BUG; | |
337 | } | |
338 | ||
339 | return SR_OK; | |
340 | } | |
341 | ||
342 | static int handle_response(const struct sr_dev_inst *sdi) | |
343 | { | |
344 | struct dev_context *devc; | |
345 | struct acquisition_state *acq; | |
346 | int expect_len; | |
347 | ||
348 | devc = sdi->priv; | |
349 | acq = devc->acquisition; | |
350 | ||
351 | switch (devc->state) { | |
352 | case STATE_STATUS_REQUEST: | |
353 | acq->status = acq->reg_sequence[0].val & 0x7F; | |
354 | acq->mem_addr_fill = acq->reg_sequence[1].val; | |
355 | acq->duration_now = acq->reg_sequence[2].val; | |
356 | break; | |
357 | case STATE_LENGTH_REQUEST: | |
358 | acq->mem_addr_next = READ_START_ADDR; | |
359 | acq->mem_addr_stop = acq->reg_sequence[0].val + READ_START_ADDR - 1; | |
360 | break; | |
361 | case STATE_READ_REQUEST: | |
362 | expect_len = (acq->mem_addr_next - acq->mem_addr_done | |
363 | + acq->in_index) * sizeof(acq->xfer_buf_in[0]); | |
364 | if (acq->xfer_in->actual_length != expect_len) { | |
365 | sr_err("Received size %d does not match expected size %d.", | |
366 | acq->xfer_in->actual_length, expect_len); | |
367 | devc->transfer_error = TRUE; | |
368 | return SR_ERR; | |
369 | } | |
370 | if (acq->rle_enabled) | |
371 | read_response_rle(acq); | |
372 | else | |
373 | read_response(acq); | |
374 | break; | |
375 | default: | |
376 | sr_err("BUG: unhandled response state %d.", devc->state); | |
377 | return SR_ERR_BUG; | |
378 | } | |
379 | ||
380 | return SR_OK; | |
381 | } | |
382 | ||
383 | /* Model descriptor for the LWLA1016. | |
384 | */ | |
385 | SR_PRIV const struct model_info lwla1016_info = { | |
386 | .name = "LWLA1016", | |
387 | .num_channels = NUM_CHANNELS, | |
388 | ||
389 | .num_devopts = 5, | |
390 | .devopts = { | |
391 | SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET, | |
392 | SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET, | |
393 | SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, | |
394 | SR_CONF_TRIGGER_MATCH | SR_CONF_LIST, | |
395 | SR_CONF_RLE | SR_CONF_GET | SR_CONF_SET, | |
396 | }, | |
397 | .num_samplerates = 19, | |
398 | .samplerates = { | |
399 | SR_MHZ(100), | |
400 | SR_MHZ(50), SR_MHZ(20), SR_MHZ(10), | |
401 | SR_MHZ(5), SR_MHZ(2), SR_MHZ(1), | |
402 | SR_KHZ(500), SR_KHZ(200), SR_KHZ(100), | |
403 | SR_KHZ(50), SR_KHZ(20), SR_KHZ(10), | |
404 | SR_KHZ(5), SR_KHZ(2), SR_KHZ(1), | |
405 | SR_HZ(500), SR_HZ(200), SR_HZ(100), | |
406 | }, | |
407 | ||
408 | .apply_fpga_config = &apply_fpga_config, | |
409 | .device_init_check = &device_init_check, | |
410 | .setup_acquisition = &setup_acquisition, | |
411 | ||
412 | .prepare_request = &prepare_request, | |
413 | .handle_response = &handle_response, | |
414 | }; |