]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * This file is part of the libsigrok project. | |
3 | * | |
4 | * Copyright (C) 2017 Jan Luebbe <jluebbe@lasnet.de> | |
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 | ||
24 | #define COMMAND_START_CAPTURE 0x01 | |
25 | #define COMMAND_STOP_CAPTURE 0x02 | |
26 | #define COMMAND_READ_EEPROM 0x07 | |
27 | #define COMMAND_INIT_BITSTREAM 0x7e | |
28 | #define COMMAND_SEND_BITSTREAM 0x7f | |
29 | #define COMMAND_WRITE_REG 0x80 | |
30 | #define COMMAND_READ_REG 0x81 | |
31 | #define COMMAND_READ_TEMP 0x86 | |
32 | #define COMMAND_WRITE_I2C 0x87 | |
33 | #define COMMAND_READ_I2C 0x88 | |
34 | #define COMMAND_WAKE_I2C 0x89 | |
35 | #define COMMAND_READ_FW_VER 0x8b | |
36 | ||
37 | #define REG_ADC_IDX 0x03 | |
38 | #define REG_ADC_VAL_LSB 0x04 | |
39 | #define REG_ADC_VAL_MSB 0x05 | |
40 | #define REG_LED_RED 0x0f | |
41 | #define REG_LED_GREEN 0x10 | |
42 | #define REG_LED_BLUE 0x11 | |
43 | #define REG_STATUS 0x40 | |
44 | ||
45 | static void iterate_lfsr(const struct sr_dev_inst *sdi) | |
46 | { | |
47 | struct dev_context *devc = sdi->priv; | |
48 | uint32_t lfsr = devc->lfsr; | |
49 | int i, max; | |
50 | ||
51 | max = (lfsr & 0x1f) + 34; | |
52 | for (i = 0; i <= max; i++) { | |
53 | lfsr = (lfsr >> 1) | \ | |
54 | ((lfsr ^ \ | |
55 | (lfsr >> 1) ^ \ | |
56 | (lfsr >> 21) ^ \ | |
57 | (lfsr >> 31) \ | |
58 | ) << 31); | |
59 | } | |
60 | sr_spew("Iterate 0x%08x -> 0x%08x", devc->lfsr, lfsr); | |
61 | devc->lfsr = lfsr; | |
62 | } | |
63 | ||
64 | static void encrypt(const struct sr_dev_inst *sdi, const uint8_t *in, uint8_t *out, uint16_t len) | |
65 | { | |
66 | struct dev_context *devc = sdi->priv; | |
67 | uint32_t lfsr = devc->lfsr; | |
68 | uint8_t value, mask; | |
69 | int i; | |
70 | ||
71 | for (i = 0; i < len; i++) { | |
72 | value = in[i]; | |
73 | mask = lfsr >> (i % 4 * 8); | |
74 | if (i == 0) | |
75 | value = (value & 0x28) | ((value ^ mask) & ~0x28); | |
76 | else | |
77 | value = value ^ mask; | |
78 | out[i] = value; | |
79 | } | |
80 | iterate_lfsr(sdi); | |
81 | } | |
82 | ||
83 | static void decrypt(const struct sr_dev_inst *sdi, uint8_t *data, uint16_t len) | |
84 | { | |
85 | struct dev_context *devc = sdi->priv; | |
86 | uint32_t lfsr = devc->lfsr; | |
87 | int i; | |
88 | ||
89 | for (i = 0; i < len; i++) | |
90 | data[i] ^= (lfsr >> (i % 4 * 8)); | |
91 | iterate_lfsr(sdi); | |
92 | } | |
93 | ||
94 | static int transact(const struct sr_dev_inst *sdi, | |
95 | const uint8_t *req, uint16_t req_len, | |
96 | uint8_t *rsp, uint16_t rsp_len) | |
97 | { | |
98 | struct sr_usb_dev_inst *usb = sdi->conn; | |
99 | uint8_t *req_enc; | |
100 | uint8_t rsp_dummy[1] = {}; | |
101 | int ret, xfer; | |
102 | ||
103 | if (req_len < 2 || req_len > 1024 || rsp_len > 128 || | |
104 | !req || (rsp_len > 0 && !rsp)) | |
105 | return SR_ERR_ARG; | |
106 | ||
107 | req_enc = g_malloc(req_len); | |
108 | encrypt(sdi, req, req_enc, req_len); | |
109 | ||
110 | ret = libusb_bulk_transfer(usb->devhdl, 1, req_enc, req_len, &xfer, 1000); | |
111 | if (ret != 0) { | |
112 | sr_dbg("Failed to send request 0x%02x: %s.", | |
113 | req[1], libusb_error_name(ret)); | |
114 | return SR_ERR; | |
115 | } | |
116 | if (xfer != req_len) { | |
117 | sr_dbg("Failed to send request 0x%02x: incorrect length " | |
118 | "%d != %d.", req[1], xfer, req_len); | |
119 | return SR_ERR; | |
120 | } | |
121 | ||
122 | if (req[0] == 0x20) { /* Reseed. */ | |
123 | return SR_OK; | |
124 | } else if (rsp_len == 0) { | |
125 | rsp = rsp_dummy; | |
126 | rsp_len = sizeof(rsp_dummy); | |
127 | } | |
128 | ||
129 | ret = libusb_bulk_transfer(usb->devhdl, 0x80 | 1, rsp, rsp_len, | |
130 | &xfer, 1000); | |
131 | if (ret != 0) { | |
132 | sr_dbg("Failed to receive response to request 0x%02x: %s.", | |
133 | req[1], libusb_error_name(ret)); | |
134 | return SR_ERR; | |
135 | } | |
136 | if (xfer != rsp_len) { | |
137 | sr_dbg("Failed to receive response to request 0x%02x: " | |
138 | "incorrect length %d != %d.", req[1], xfer, rsp_len); | |
139 | return SR_ERR; | |
140 | } | |
141 | ||
142 | decrypt(sdi, rsp, rsp_len); | |
143 | ||
144 | return SR_OK; | |
145 | } | |
146 | ||
147 | static int reseed(const struct sr_dev_inst *sdi) | |
148 | { | |
149 | struct dev_context *devc = sdi->priv; | |
150 | uint8_t req[] = {0x20, 0x24, 0x4b, 0x35, 0x8e}; | |
151 | ||
152 | devc->lfsr = 0; | |
153 | return transact(sdi, req, sizeof(req), NULL, 0); | |
154 | } | |
155 | ||
156 | static int write_regs(const struct sr_dev_inst *sdi, uint8_t (*regs)[2], uint8_t cnt) | |
157 | { | |
158 | uint8_t req[64]; | |
159 | int i; | |
160 | ||
161 | if (cnt < 1 || cnt > 30) | |
162 | return SR_ERR_ARG; | |
163 | ||
164 | req[0] = 0x00; | |
165 | req[1] = COMMAND_WRITE_REG; | |
166 | req[2] = cnt; | |
167 | ||
168 | for (i = 0; i < cnt; i++) { | |
169 | req[3 + 2 * i] = regs[i][0]; | |
170 | req[4 + 2 * i] = regs[i][1]; | |
171 | } | |
172 | ||
173 | return transact(sdi, req, 3 + (2 * cnt), NULL, 0); | |
174 | } | |
175 | ||
176 | static int write_reg(const struct sr_dev_inst *sdi, | |
177 | uint8_t address, uint8_t value) | |
178 | { | |
179 | uint8_t regs[2] = {address, value}; | |
180 | ||
181 | return write_regs(sdi, ®s, 1); | |
182 | } | |
183 | ||
184 | static int read_regs(const struct sr_dev_inst *sdi, | |
185 | const uint8_t *regs, uint8_t *values, | |
186 | uint8_t cnt) | |
187 | { | |
188 | uint8_t req[33]; | |
189 | ||
190 | if (cnt < 1 || cnt > 30) | |
191 | return SR_ERR_ARG; | |
192 | ||
193 | req[0] = 0x00; | |
194 | req[1] = COMMAND_READ_REG; | |
195 | req[2] = cnt; | |
196 | if (cnt) | |
197 | memcpy(&req[3], regs, cnt); | |
198 | ||
199 | return transact(sdi, req, 3 + cnt, values, cnt); | |
200 | } | |
201 | ||
202 | static int read_reg(const struct sr_dev_inst *sdi, | |
203 | uint8_t address, uint8_t *value) | |
204 | { | |
205 | return read_regs(sdi, &address, value, 1); | |
206 | } | |
207 | ||
208 | static int write_adc(const struct sr_dev_inst *sdi, | |
209 | uint8_t address, uint16_t value) | |
210 | { | |
211 | uint8_t regs[][2] = { | |
212 | {REG_ADC_IDX, address}, | |
213 | {REG_ADC_VAL_LSB, value}, | |
214 | {REG_ADC_VAL_MSB, value >> 8}, | |
215 | }; | |
216 | ||
217 | return write_regs(sdi, ARRAY_AND_SIZE(regs)); | |
218 | } | |
219 | ||
220 | static int read_eeprom(const struct sr_dev_inst *sdi, | |
221 | uint16_t address, uint8_t *data, uint16_t len) | |
222 | { | |
223 | uint8_t req[8] = { | |
224 | 0x00, COMMAND_READ_EEPROM, | |
225 | 0x33, 0x81, /* Unknown values */ | |
226 | address, address >> 8, | |
227 | len, len >> 8 | |
228 | }; | |
229 | ||
230 | return transact(sdi, req, sizeof(req), data, len); | |
231 | } | |
232 | ||
233 | static int read_eeprom_serial(const struct sr_dev_inst *sdi, | |
234 | uint8_t data[8]) | |
235 | { | |
236 | return read_eeprom(sdi, 0x08, data, 0x8); | |
237 | } | |
238 | ||
239 | static int read_eeprom_magic(const struct sr_dev_inst *sdi, | |
240 | uint8_t data[16]) | |
241 | { | |
242 | return read_eeprom(sdi, 0x10, data, 0x10); | |
243 | } | |
244 | ||
245 | static int read_temperature(const struct sr_dev_inst *sdi, int8_t *temp) | |
246 | { | |
247 | uint8_t req[2] = {0x00, COMMAND_READ_TEMP}; | |
248 | ||
249 | return transact(sdi, req, sizeof(req), (uint8_t*)temp, 1); | |
250 | } | |
251 | ||
252 | static int get_firmware_version(const struct sr_dev_inst *sdi) | |
253 | { | |
254 | uint8_t req[2] = {0x00, COMMAND_READ_FW_VER}; | |
255 | uint8_t rsp[128] = {}; | |
256 | int ret; | |
257 | ||
258 | ret = transact(sdi, req, sizeof(req), rsp, sizeof(rsp)); | |
259 | if (ret == SR_OK) { | |
260 | rsp[63] = 0; | |
261 | sr_dbg("fw-version: %s", rsp); | |
262 | } | |
263 | ||
264 | return ret; | |
265 | } | |
266 | ||
267 | static int read_i2c(const struct sr_dev_inst *sdi, uint8_t *data, uint8_t len) | |
268 | { | |
269 | uint8_t req[5]; | |
270 | uint8_t rsp[1 + 128]; | |
271 | int ret; | |
272 | ||
273 | if (len < 1 || len > 128 || !data) | |
274 | return SR_ERR_ARG; | |
275 | ||
276 | req[0] = 0x00; | |
277 | req[1] = COMMAND_READ_I2C; | |
278 | req[2] = 0xc0; /* Fixed address */ | |
279 | req[3] = len; | |
280 | req[4] = 0; /* Len MSB? */ | |
281 | ||
282 | ret = transact(sdi, req, sizeof(req), rsp, 1 + len); | |
283 | if (ret != SR_OK) | |
284 | return ret; | |
285 | if (rsp[0] != 0x02) { | |
286 | sr_dbg("Failed to do I2C read (0x%02x).", rsp[0]); | |
287 | return SR_ERR; | |
288 | } | |
289 | ||
290 | memcpy(data, rsp + 1, len); | |
291 | return SR_OK; | |
292 | } | |
293 | ||
294 | static int write_i2c(const struct sr_dev_inst *sdi, const uint8_t *data, uint8_t len) | |
295 | { | |
296 | uint8_t req[5 + 128]; | |
297 | uint8_t rsp[1]; | |
298 | int ret; | |
299 | ||
300 | if (len < 1 || len > 128 || !data) | |
301 | return SR_ERR_ARG; | |
302 | ||
303 | req[0] = 0x00; | |
304 | req[1] = COMMAND_WRITE_I2C; | |
305 | req[2] = 0xc0; /* Fixed address */ | |
306 | req[3] = len; | |
307 | req[4] = 0; /* Len MSB? */ | |
308 | memcpy(req + 5, data, len); | |
309 | ||
310 | ret = transact(sdi, req, 5 + len, rsp, sizeof(rsp)); | |
311 | if (ret != SR_OK) | |
312 | return ret; | |
313 | if (rsp[0] != 0x02) { | |
314 | sr_dbg("Failed to do I2C write (0x%02x).", rsp[0]); | |
315 | return SR_ERR; | |
316 | } | |
317 | ||
318 | return SR_OK; | |
319 | } | |
320 | ||
321 | static int wake_i2c(const struct sr_dev_inst *sdi) | |
322 | { | |
323 | uint8_t req[] = {0x00, COMMAND_WAKE_I2C}; | |
324 | uint8_t rsp[1] = {}; | |
325 | uint8_t i2c_rsp[1 + 1 + 2] = {}; | |
326 | int ret; | |
327 | ||
328 | ret = transact(sdi, req, sizeof(req), rsp, sizeof(rsp)); | |
329 | if (ret != SR_OK) | |
330 | return ret; | |
331 | if (rsp[0] != 0x00) { | |
332 | sr_dbg("Failed to do I2C wake trigger (0x%02x).", rsp[0]); | |
333 | return SR_ERR; | |
334 | } | |
335 | ||
336 | ret = read_i2c(sdi, i2c_rsp, sizeof(i2c_rsp)); | |
337 | if (ret != SR_OK) { | |
338 | return ret; | |
339 | } | |
340 | if (i2c_rsp[1] != 0x11) { | |
341 | sr_dbg("Failed to do I2C wake read (0x%02x).", i2c_rsp[0]); | |
342 | return SR_ERR; | |
343 | } | |
344 | ||
345 | return SR_OK; | |
346 | } | |
347 | ||
348 | static int crypto_random(const struct sr_dev_inst *sdi, uint8_t *data) | |
349 | { | |
350 | uint8_t i2c_req[8] = {0x03, 0x07, 0x1b, 0x00, 0x00, 0x00, 0x24, 0xcd}; | |
351 | uint8_t i2c_rsp[1 + 32 + 2] = {}; | |
352 | int ret; | |
353 | ||
354 | ret = write_i2c(sdi, i2c_req, sizeof(i2c_req)); | |
355 | if (ret != SR_OK) | |
356 | return ret; | |
357 | ||
358 | g_usleep(100000); /* TODO: Poll instead. */ | |
359 | ||
360 | ret = read_i2c(sdi, i2c_rsp, sizeof(i2c_rsp)); | |
361 | if (ret != SR_OK) | |
362 | return ret; | |
363 | ||
364 | if (data) | |
365 | memcpy(data, i2c_rsp + 1, 32); | |
366 | ||
367 | return SR_OK; | |
368 | } | |
369 | ||
370 | static int crypto_nonce(const struct sr_dev_inst *sdi, uint8_t *data) | |
371 | { | |
372 | uint8_t i2c_req[6 + 20 + 2] = {0x03, 0x1b, 0x16, 0x00, 0x00, 0x00}; | |
373 | uint8_t i2c_rsp[1 + 32 + 2] = {}; | |
374 | int ret; | |
375 | ||
376 | /* CRC */ | |
377 | i2c_req[26] = 0x7d; | |
378 | i2c_req[27] = 0xe0; | |
379 | ||
380 | ret = write_i2c(sdi, i2c_req, sizeof(i2c_req)); | |
381 | if (ret != SR_OK) | |
382 | return ret; | |
383 | ||
384 | g_usleep(100000); /* TODO: Poll instead. */ | |
385 | ||
386 | ret = read_i2c(sdi, i2c_rsp, sizeof(i2c_rsp)); | |
387 | if (ret != SR_OK) | |
388 | return ret; | |
389 | ||
390 | if (data) | |
391 | memcpy(data, i2c_rsp + 1, 32); | |
392 | ||
393 | return SR_OK; | |
394 | } | |
395 | ||
396 | static int crypto_sign(const struct sr_dev_inst *sdi, uint8_t *data, uint8_t *crc) | |
397 | { | |
398 | uint8_t i2c_req[8] = {0x03, 0x07, 0x41, 0x80, 0x00, 0x00, 0x28, 0x05}; | |
399 | uint8_t i2c_rsp[1 + 64 + 2] = {}; | |
400 | int ret; | |
401 | ||
402 | ret = write_i2c(sdi, i2c_req, sizeof(i2c_req)); | |
403 | if (ret != SR_OK) | |
404 | return ret; | |
405 | ||
406 | g_usleep(100000); /* TODO: Poll instead. */ | |
407 | ||
408 | ret = read_i2c(sdi, i2c_rsp, sizeof(i2c_rsp)); | |
409 | if (ret != SR_OK) | |
410 | return ret; | |
411 | ||
412 | memcpy(data, i2c_rsp + 1, 64); | |
413 | memcpy(crc, i2c_rsp + 1 + 64, 2); | |
414 | ||
415 | return SR_OK; | |
416 | } | |
417 | ||
418 | static int authenticate(const struct sr_dev_inst *sdi) | |
419 | { | |
420 | struct dev_context *devc = sdi->priv; | |
421 | uint8_t random[32] = {}; | |
422 | uint8_t nonce[32] = {}; | |
423 | uint8_t sig[64] = {}; | |
424 | uint8_t sig_crc[64] = {}; | |
425 | uint32_t lfsr; | |
426 | int i, ret; | |
427 | ||
428 | ret = wake_i2c(sdi); | |
429 | if (ret != SR_OK) | |
430 | return ret; | |
431 | ||
432 | ret = crypto_random(sdi, random); | |
433 | if (ret != SR_OK) | |
434 | return ret; | |
435 | sr_dbg("random: 0x%02x 0x%02x 0x%02x 0x%02x", random[0], random[1], random[2], random[3]); | |
436 | ||
437 | ret = crypto_nonce(sdi, nonce); | |
438 | if (ret != SR_OK) | |
439 | return ret; | |
440 | sr_dbg("nonce: 0x%02x 0x%02x 0x%02x 0x%02x", nonce[0], nonce[1], nonce[2], nonce[3]); | |
441 | ||
442 | ret = crypto_nonce(sdi, nonce); | |
443 | if (ret != SR_OK) | |
444 | return ret; | |
445 | sr_dbg("nonce: 0x%02x 0x%02x 0x%02x 0x%02x", nonce[0], nonce[1], nonce[2], nonce[3]); | |
446 | ||
447 | ret = crypto_sign(sdi, sig, sig_crc); | |
448 | if (ret != SR_OK) | |
449 | return ret; | |
450 | sr_dbg("sig: 0x%02x 0x%02x 0x%02x 0x%02x", sig[0], sig[1], sig[2], sig[3]); | |
451 | sr_dbg("sig crc: 0x%02x 0x%02x", sig_crc[0], sig_crc[1]); | |
452 | ||
453 | lfsr = 0; | |
454 | for (i = 0; i < 28; i++) | |
455 | lfsr ^= nonce[i] << (8 * (i % 4)); | |
456 | lfsr ^= sig_crc[0] | sig_crc[1] << 8; | |
457 | ||
458 | sr_dbg("Authenticate 0x%08x -> 0x%08x", devc->lfsr, lfsr); | |
459 | devc->lfsr = lfsr; | |
460 | ||
461 | return SR_OK; | |
462 | } | |
463 | ||
464 | static int upload_bitstream_part(const struct sr_dev_inst *sdi, | |
465 | const uint8_t *data, uint16_t len) | |
466 | { | |
467 | uint8_t req[4 + 1020]; | |
468 | uint8_t rsp[1]; | |
469 | int ret; | |
470 | ||
471 | if (len < 1 || len > 1020 || !data) | |
472 | return SR_ERR_ARG; | |
473 | ||
474 | req[0] = 0x00; | |
475 | req[1] = COMMAND_SEND_BITSTREAM; | |
476 | req[2] = len; | |
477 | req[3] = len >> 8; | |
478 | memcpy(req + 4, data, len); | |
479 | ||
480 | ret = transact(sdi, req, 4 + len, rsp, sizeof(rsp)); | |
481 | if (ret != SR_OK) | |
482 | return ret; | |
483 | if (rsp[0] != 0x00) { | |
484 | sr_dbg("Failed to do bitstream upload (0x%02x).", rsp[0]); | |
485 | return SR_ERR; | |
486 | } | |
487 | ||
488 | return SR_OK; | |
489 | } | |
490 | ||
491 | static int upload_bitstream(const struct sr_dev_inst *sdi, | |
492 | const char *name) | |
493 | { | |
494 | struct drv_context *drvc = sdi->driver->context; | |
495 | unsigned char *bitstream = NULL; | |
496 | uint8_t req[2]; | |
497 | uint8_t rsp[1]; | |
498 | uint8_t reg_val; | |
499 | int ret = SR_ERR; | |
500 | size_t bs_size, bs_offset = 0, bs_part_size; | |
501 | ||
502 | bitstream = sr_resource_load(drvc->sr_ctx, SR_RESOURCE_FIRMWARE, | |
503 | name, &bs_size, 512 * 1024); | |
504 | if (!bitstream) | |
505 | goto out; | |
506 | ||
507 | sr_info("Uploading bitstream '%s'.", name); | |
508 | ||
509 | req[0] = 0x00; | |
510 | req[1] = COMMAND_INIT_BITSTREAM; | |
511 | ||
512 | ret = transact(sdi, req, sizeof(req), rsp, sizeof(rsp)); | |
513 | if (ret != SR_OK) | |
514 | return ret; | |
515 | if (rsp[0] != 0x00) { | |
516 | sr_err("Failed to start bitstream upload (0x%02x).", rsp[0]); | |
517 | ret = SR_ERR; | |
518 | goto out; | |
519 | } | |
520 | ||
521 | while (bs_offset < bs_size) { | |
522 | bs_part_size = MIN(bs_size - bs_offset, 1020); | |
523 | sr_spew("Uploading %zd bytes.", bs_part_size); | |
524 | ret = upload_bitstream_part(sdi, bitstream + bs_offset, bs_part_size); | |
525 | if (ret != SR_OK) | |
526 | goto out; | |
527 | bs_offset += bs_part_size; | |
528 | } | |
529 | ||
530 | sr_info("Bitstream upload done."); | |
531 | ||
532 | /* Check a scratch register? */ | |
533 | ret = write_reg(sdi, 0x7f, 0xaa); | |
534 | if (ret != SR_OK) | |
535 | goto out; | |
536 | ret = read_reg(sdi, 0x7f, ®_val); | |
537 | if (ret != SR_OK) | |
538 | goto out; | |
539 | if (reg_val != 0xaa) { | |
540 | sr_err("Failed FPGA register read-back (0x%02x != 0xaa).", rsp[0]); | |
541 | ret = SR_ERR; | |
542 | goto out; | |
543 | } | |
544 | ||
545 | out: | |
546 | g_free(bitstream); | |
547 | ||
548 | return ret; | |
549 | } | |
550 | ||
551 | #if 0 | |
552 | static int set_led(const struct sr_dev_inst *sdi, uint8_t r, uint8_t g, uint8_t b) | |
553 | { | |
554 | uint8_t regs[][2] = { | |
555 | {REG_LED_RED, r}, | |
556 | {REG_LED_GREEN, g}, | |
557 | {REG_LED_BLUE, b}, | |
558 | }; | |
559 | ||
560 | authenticate(sdi); | |
561 | ||
562 | return write_regs(sdi, ARRAY_AND_SIZE(regs)); | |
563 | } | |
564 | #endif | |
565 | ||
566 | static int configure_channels(const struct sr_dev_inst *sdi) | |
567 | { | |
568 | struct dev_context *devc = sdi->priv; | |
569 | const struct sr_channel *c; | |
570 | const GSList *l; | |
571 | uint16_t mask; | |
572 | ||
573 | devc->dig_channel_cnt = 0; | |
574 | devc->dig_channel_mask = 0; | |
575 | for (l = sdi->channels; l; l = l->next) { | |
576 | c = l->data; | |
577 | if (!c->enabled) | |
578 | continue; | |
579 | ||
580 | mask = 1 << c->index; | |
581 | devc->dig_channel_masks[devc->dig_channel_cnt++] = mask; | |
582 | devc->dig_channel_mask |= mask; | |
583 | ||
584 | } | |
585 | sr_dbg("%d channels enabled (0x%04x)", | |
586 | devc->dig_channel_cnt, devc->dig_channel_mask); | |
587 | ||
588 | return SR_OK; | |
589 | } | |
590 | ||
591 | SR_PRIV int saleae_logic_pro_init(const struct sr_dev_inst *sdi) | |
592 | { | |
593 | uint8_t reg_val; | |
594 | uint8_t dummy[8]; | |
595 | uint8_t serial[8]; | |
596 | uint8_t magic[16]; | |
597 | int8_t temperature; | |
598 | int ret, i; | |
599 | ||
600 | ret = reseed(sdi); | |
601 | if (ret != SR_OK) | |
602 | return ret; | |
603 | ||
604 | ret = get_firmware_version(sdi); | |
605 | if (ret != SR_OK) | |
606 | return ret; | |
607 | ||
608 | sr_dbg("read serial"); | |
609 | ret = read_eeprom_serial(sdi, serial); | |
610 | if (ret != SR_OK) | |
611 | return ret; | |
612 | ||
613 | /* Check if we need to upload the bitstream. */ | |
614 | ret = read_reg(sdi, 0x7f, ®_val); | |
615 | if (ret != SR_OK) | |
616 | return ret; | |
617 | if (reg_val == 0xaa) { | |
618 | sr_info("Skipping bitstream upload."); | |
619 | } else { | |
620 | ret = upload_bitstream(sdi, "saleae-logicpro16-fpga.bitstream"); | |
621 | if (ret != SR_OK) | |
622 | return ret; | |
623 | } | |
624 | ||
625 | /* Reset the ADC? */ | |
626 | sr_dbg("reset ADC"); | |
627 | ret = write_reg(sdi, 0x00, 0x00); | |
628 | if (ret != SR_OK) | |
629 | return ret; | |
630 | ret = write_reg(sdi, 0x00, 0x80); | |
631 | if (ret != SR_OK) | |
632 | return ret; | |
633 | ||
634 | sr_dbg("init ADC"); | |
635 | ret = write_adc(sdi, 0x11, 0x0444); | |
636 | if (ret != SR_OK) | |
637 | return ret; | |
638 | ret = write_adc(sdi, 0x12, 0x0777); | |
639 | if (ret != SR_OK) | |
640 | return ret; | |
641 | ret = write_adc(sdi, 0x25, 0x0000); | |
642 | if (ret != SR_OK) | |
643 | return ret; | |
644 | ret = write_adc(sdi, 0x45, 0x0000); | |
645 | if (ret != SR_OK) | |
646 | return ret; | |
647 | ret = write_adc(sdi, 0x2a, 0x1111); | |
648 | if (ret != SR_OK) | |
649 | return ret; | |
650 | ret = write_adc(sdi, 0x2b, 0x1111); | |
651 | if (ret != SR_OK) | |
652 | return ret; | |
653 | ret = write_adc(sdi, 0x46, 0x0004); | |
654 | if (ret != SR_OK) | |
655 | return ret; | |
656 | ret = write_adc(sdi, 0x50, 0x0000); | |
657 | if (ret != SR_OK) | |
658 | return ret; | |
659 | ret = write_adc(sdi, 0x55, 0x0020); | |
660 | if (ret != SR_OK) | |
661 | return ret; | |
662 | ret = write_adc(sdi, 0x56, 0x0000); | |
663 | if (ret != SR_OK) | |
664 | return ret; | |
665 | ||
666 | ret = write_reg(sdi, 0x15, 0x00); | |
667 | if (ret != SR_OK) | |
668 | return ret; | |
669 | ||
670 | ret = write_adc(sdi, 0x0f, 0x0100); | |
671 | if (ret != SR_OK) | |
672 | return ret; | |
673 | ||
674 | /* Resets? */ | |
675 | sr_dbg("resets"); | |
676 | ret = write_reg(sdi, 0x00, 0x02); /* bit 1 */ | |
677 | if (ret != SR_OK) | |
678 | return ret; | |
679 | ret = write_reg(sdi, 0x00, 0x00); | |
680 | if (ret != SR_OK) | |
681 | return ret; | |
682 | ret = write_reg(sdi, 0x00, 0x04); /* bit 2 */ | |
683 | if (ret != SR_OK) | |
684 | return ret; | |
685 | ret = write_reg(sdi, 0x00, 0x00); | |
686 | if (ret != SR_OK) | |
687 | return ret; | |
688 | ret = write_reg(sdi, 0x00, 0x08); /* bit 3 */ | |
689 | if (ret != SR_OK) | |
690 | return ret; | |
691 | ret = write_reg(sdi, 0x00, 0x00); | |
692 | if (ret != SR_OK) | |
693 | return ret; | |
694 | ||
695 | sr_dbg("read dummy"); | |
696 | for (i = 0; i < 8; i++) { | |
697 | ret = read_reg(sdi, 0x41 + i, &dummy[i]); | |
698 | if (ret != SR_OK) | |
699 | return ret; | |
700 | } | |
701 | ||
702 | /* Read and write back magic EEPROM value. */ | |
703 | sr_dbg("read/write magic"); | |
704 | ret = read_eeprom_magic(sdi, magic); | |
705 | if (ret != SR_OK) | |
706 | return ret; | |
707 | for (i = 0; i < 16; i++) { | |
708 | ret = write_reg(sdi, 0x17, magic[i]); | |
709 | if (ret != SR_OK) | |
710 | return ret; | |
711 | } | |
712 | ||
713 | ret = read_temperature(sdi, &temperature); | |
714 | if (ret != SR_OK) | |
715 | return ret; | |
716 | sr_dbg("temperature = %d", temperature); | |
717 | ||
718 | /* Setting the LED doesn't work yet. */ | |
719 | /* set_led(sdi, 0x00, 0x00, 0xff); */ | |
720 | ||
721 | return SR_OK; | |
722 | } | |
723 | ||
724 | SR_PRIV int saleae_logic_pro_prepare(const struct sr_dev_inst *sdi) | |
725 | { | |
726 | struct dev_context *devc = sdi->priv; | |
727 | uint8_t regs_unknown[][2] = { | |
728 | {0x03, 0x0f}, | |
729 | {0x04, 0x00}, | |
730 | {0x05, 0x00}, | |
731 | }; | |
732 | uint8_t regs_config[][2] = { | |
733 | {0x00, 0x00}, | |
734 | {0x08, 0x00}, /* Analog channel mask (LSB) */ | |
735 | {0x09, 0x00}, /* Analog channel mask (MSB) */ | |
736 | {0x06, 0x01}, /* Digital channel mask (LSB) */ | |
737 | {0x07, 0x00}, /* Digital channel mask (MSB) */ | |
738 | {0x0a, 0x00}, /* Analog sample rate? */ | |
739 | {0x0b, 0x64}, /* Digital sample rate? */ | |
740 | {0x0c, 0x00}, | |
741 | {0x0d, 0x00}, /* Analog mux rate? */ | |
742 | {0x0e, 0x01}, /* Digital mux rate? */ | |
743 | {0x12, 0x04}, | |
744 | {0x13, 0x00}, | |
745 | {0x14, 0xff}, /* Pre-divider? */ | |
746 | }; | |
747 | uint8_t start_req[] = {0x00, 0x01}; | |
748 | uint8_t start_rsp[2] = {}; | |
749 | ||
750 | configure_channels(sdi); | |
751 | ||
752 | /* Digital channel mask and muxing */ | |
753 | regs_config[3][1] = devc->dig_channel_mask; | |
754 | regs_config[4][1] = devc->dig_channel_mask >> 8; | |
755 | regs_config[9][1] = devc->dig_channel_cnt; | |
756 | ||
757 | /* Samplerate */ | |
758 | switch (devc->dig_samplerate) { | |
759 | case SR_MHZ(1): | |
760 | regs_config[6][1] = 0x64; | |
761 | break; | |
762 | case SR_MHZ(2): | |
763 | regs_config[6][1] = 0x32; | |
764 | break; | |
765 | case SR_KHZ(2500): | |
766 | regs_config[6][1] = 0x28; | |
767 | break; | |
768 | case SR_MHZ(10): | |
769 | regs_config[6][1] = 0x0a; | |
770 | break; | |
771 | case SR_MHZ(25): | |
772 | regs_config[6][1] = 0x04; | |
773 | regs_config[12][1] = 0x80; | |
774 | break; | |
775 | case SR_MHZ(50): | |
776 | regs_config[6][1] = 0x02; | |
777 | regs_config[12][1] = 0x40; | |
778 | break; | |
779 | default: | |
780 | return SR_ERR_ARG; | |
781 | } | |
782 | ||
783 | authenticate(sdi); | |
784 | ||
785 | write_reg(sdi, 0x15, 0x03); | |
786 | write_regs(sdi, ARRAY_AND_SIZE(regs_unknown)); | |
787 | write_regs(sdi, ARRAY_AND_SIZE(regs_config)); | |
788 | ||
789 | transact(sdi, start_req, sizeof(start_req), start_rsp, sizeof(start_rsp)); | |
790 | ||
791 | return SR_OK; | |
792 | } | |
793 | ||
794 | SR_PRIV int saleae_logic_pro_start(const struct sr_dev_inst *sdi) | |
795 | { | |
796 | struct dev_context *devc = sdi->priv; | |
797 | ||
798 | devc->conv_size = 0; | |
799 | devc->batch_index = 0; | |
800 | ||
801 | write_reg(sdi, 0x00, 0x01); | |
802 | ||
803 | return SR_OK; | |
804 | } | |
805 | ||
806 | SR_PRIV int saleae_logic_pro_stop(const struct sr_dev_inst *sdi) | |
807 | { | |
808 | uint8_t stop_req[] = {0x00, 0x02}; | |
809 | uint8_t stop_rsp[2] = {}; | |
810 | uint8_t status; | |
811 | int ret; | |
812 | ||
813 | write_reg(sdi, 0x00, 0x00); | |
814 | transact(sdi, stop_req, sizeof(stop_req), stop_rsp, sizeof(stop_rsp)); | |
815 | ||
816 | ret = read_reg(sdi, 0x40, &status); | |
817 | if (ret != SR_OK) | |
818 | return ret; | |
819 | if (status != 0x20) { | |
820 | sr_err("Capture error (status reg = 0x%02x).", status); | |
821 | return SR_ERR; | |
822 | } | |
823 | ||
824 | return SR_OK; | |
825 | } | |
826 | ||
827 | static void saleae_logic_pro_send_data(const struct sr_dev_inst *sdi, | |
828 | void *data, size_t length, size_t unitsize) | |
829 | { | |
830 | const struct sr_datafeed_logic logic = { | |
831 | .length = length, | |
832 | .unitsize = unitsize, | |
833 | .data = data | |
834 | }; | |
835 | ||
836 | const struct sr_datafeed_packet packet = { | |
837 | .type = SR_DF_LOGIC, | |
838 | .payload = &logic | |
839 | }; | |
840 | ||
841 | sr_session_send(sdi, &packet); | |
842 | } | |
843 | ||
844 | /* | |
845 | * One batch from the device consists of 32 samples per active digital channel. | |
846 | * This stream of batches is packed into USB packets with 16384 bytes each. | |
847 | */ | |
848 | static void saleae_logic_pro_convert_data(const struct sr_dev_inst *sdi, | |
849 | const uint32_t *src, size_t srccnt) | |
850 | { | |
851 | struct dev_context *devc = sdi->priv; | |
852 | uint8_t *dst = devc->conv_buffer; | |
853 | uint32_t samples; | |
854 | uint16_t channel_mask; | |
855 | unsigned int sample_index, batch_index; | |
856 | uint16_t *dst_batch; | |
857 | ||
858 | /* Copy partial batch to the beginning. */ | |
859 | memcpy(dst, dst + devc->conv_size, CONV_BATCH_SIZE); | |
860 | /* Reset converted size. */ | |
861 | devc->conv_size = 0; | |
862 | ||
863 | batch_index = devc->batch_index; | |
864 | while (srccnt--) { | |
865 | samples = *src++; | |
866 | dst_batch = (uint16_t*)dst; | |
867 | ||
868 | /* First index of the batch. */ | |
869 | if (batch_index == 0) | |
870 | memset(dst, 0, CONV_BATCH_SIZE); | |
871 | ||
872 | /* Convert one channel. */ | |
873 | channel_mask = devc->dig_channel_masks[batch_index]; | |
874 | for (sample_index = 0; sample_index <= 31; sample_index++) | |
875 | if ((samples >> (31 - sample_index)) & 1) | |
876 | dst_batch[sample_index] |= channel_mask; | |
877 | ||
878 | /* Last index of the batch. */ | |
879 | if (++batch_index == devc->dig_channel_cnt) { | |
880 | devc->conv_size += CONV_BATCH_SIZE; | |
881 | batch_index = 0; | |
882 | dst += CONV_BATCH_SIZE; | |
883 | } | |
884 | } | |
885 | devc->batch_index = batch_index; | |
886 | } | |
887 | ||
888 | SR_PRIV void LIBUSB_CALL saleae_logic_pro_receive_data(struct libusb_transfer *transfer) | |
889 | { | |
890 | const struct sr_dev_inst *sdi = transfer->user_data; | |
891 | struct dev_context *devc = sdi->priv; | |
892 | int ret; | |
893 | ||
894 | switch (transfer->status) { | |
895 | case LIBUSB_TRANSFER_NO_DEVICE: | |
896 | sr_dbg("FIXME no device"); | |
897 | return; | |
898 | case LIBUSB_TRANSFER_COMPLETED: | |
899 | case LIBUSB_TRANSFER_TIMED_OUT: /* We may have received some data though. */ | |
900 | break; | |
901 | default: | |
902 | /* FIXME */ | |
903 | return; | |
904 | } | |
905 | ||
906 | saleae_logic_pro_convert_data(sdi, (uint32_t*)transfer->buffer, 16 * 1024 / 4); | |
907 | saleae_logic_pro_send_data(sdi, devc->conv_buffer, devc->conv_size, 2); | |
908 | ||
909 | if ((ret = libusb_submit_transfer(transfer)) != LIBUSB_SUCCESS) | |
910 | sr_dbg("FIXME resubmit failed"); | |
911 | } |