]> sigrok.org Git - libsigrok.git/blame - hardware/zeroplus-logic-cube/analyzer.c
Start of code base layout restructuring.
[libsigrok.git] / hardware / zeroplus-logic-cube / analyzer.c
CommitLineData
a1bb33af
UH
1/*
2 Copyright (c) 2010 Sven Peter <sven@fail0verflow.com>
3 Copyright (c) 2010 Haxx Enterprises <bushing@gmail.com>
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or
7 without modification, are permitted provided that the following
8 conditions are met:
9
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12
13 * Redistributions in binary form must reproduce the above copyright notice,
14 this list of conditions and the following disclaimer in the documentation
15 and/or other materials provided with the distribution.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 THE POSSIBILITY OF SUCH DAMAGE.
28
29*/
30#include <assert.h>
31
32#include "analyzer.h"
33#include "gl_usb.h"
34
35enum {
36 HARD_DATA_CHECK_SUM = 0x00,
37 PASS_WORD,
38
39 DEVICE_ID0 = 0x10,
40 DEVICE_ID1,
41
42 START_STATUS = 0x20,
43 DEVICE_STATUS = 0x21,
44 FREQUENCY_REG0 = 0x30,
45 FREQUENCY_REG1,
46 FREQUENCY_REG2,
47 FREQUENCY_REG3,
48 FREQUENCY_REG4,
49 MEMORY_LENGTH,
50 CLOCK_SOURCE,
51
52 TRIGGER_STATUS0 = 0x40,
53 TRIGGER_STATUS1,
54 TRIGGER_STATUS2,
55 TRIGGER_STATUS3,
56 TRIGGER_STATUS4,
57 TRIGGER_STATUS5,
58 TRIGGER_STATUS6,
59 TRIGGER_STATUS7,
60 TRIGGER_STATUS8,
61
62 TRIGGER_COUNT0 = 0x50,
63 TRIGGER_COUNT1,
64
65 TRIGGER_LEVEL0 = 0x55,
66 TRIGGER_LEVEL1,
67 TRIGGER_LEVEL2,
68 TRIGGER_LEVEL3,
69
70 RAMSIZE_TRIGGERBAR_ADDRESS0 = 0x60,
71 RAMSIZE_TRIGGERBAR_ADDRESS1,
72 RAMSIZE_TRIGGERBAR_ADDRESS2,
73 TRIGGERBAR_ADDRESS0,
74 TRIGGERBAR_ADDRESS1,
75 TRIGGERBAR_ADDRESS2,
76 DONT_CARE_TRIGGERBAR,
77
78 FILTER_ENABLE = 0x70,
79 FILTER_STATUS,
80
81 ENABLE_DELAY_TIME0 = 0x7A,
82 ENABLE_DELAY_TIME1,
83
84 ENABLE_INSERT_DATA0 = 0x80,
85 ENABLE_INSERT_DATA1,
86 ENABLE_INSERT_DATA2,
87 ENABLE_INSERT_DATA3,
88 COMPRESSION_TYPE0,
89 COMPRESSION_TYPE1,
90
91 TRIGGER_ADDRESS0 = 0x90,
92 TRIGGER_ADDRESS1,
93 TRIGGER_ADDRESS2,
94
95 NOW_ADDRESS0 = 0x96,
96 NOW_ADDRESS1,
97 NOW_ADDRESS2,
98
99 STOP_ADDRESS0 = 0x9B,
100 STOP_ADDRESS1,
101 STOP_ADDRESS2,
102
103 READ_RAM_STATUS = 0xA0
104};
105
106static int g_trigger_status[9] = {0};
107static int g_trigger_count = 1;
108
109static int g_filter_status[8] = {0};
110static int g_filter_enable = 0;
111
112static int g_freq_value = 100;
113static int g_freq_scale = FREQ_SCALE_MHZ;
114static int g_memory_size = MEMORY_SIZE_512K;
115static int g_ramsize_triggerbar_addr = 0x80000>>2;
116static int g_triggerbar_addr = 0x3fe;
117static int g_compression = COMPRESSION_NONE;
118
119// maybe unk specifies an "endpoint" or "register" of sorts
120static int analyzer_write_status(libusb_device_handle *devh, unsigned char unk, unsigned char flags)
121{
122 assert(unk <= 3);
123 return gl_reg_write(devh, START_STATUS, unk << 6 | flags);
124}
125
126static int __analyzer_set_freq(libusb_device_handle *devh, int freq, int scale)
127{
128 int reg0=0, divisor=0, reg2=0;
129 switch (scale) {
130 case FREQ_SCALE_MHZ: // MHz
131 if (freq >= 100 && freq <= 200) {
132 reg0 = freq * 0.1;
133 divisor = 1;
134 reg2 = 0;
135 break;
136 }
137 if (freq >= 50 && freq < 100) {
138 reg0 = freq * 0.2;
139 divisor = 2;
140 reg2 = 0;
141 break;
142 }
143 if (freq >= 10 && freq < 50) {
144 if (freq == 25) {
145 reg0 = 25;
146 divisor = 5;
147 reg2 = 1;
148 break;
149 } else {
150 reg0 = freq * 0.5;
151 divisor = 5;
152 reg2 = 1;
153 break;
154 }
155 }
156 if (freq >= 2 && freq < 10) {
157 divisor = 5;
158 reg0 = freq * 2;
159 reg2 = 2;
160 break;
161 }
162 if (freq == 1) {
163 divisor = 5;
164 reg2 = 16;
165 reg0 = 5;
166 break;
167 }
168 divisor = 5;
169 reg0 = 5;
170 reg2 = 64;
171 break;
172 case FREQ_SCALE_HZ: // Hz
173 if (freq >= 500 && freq < 1000) {
174 reg0 = freq * 0.01;
175 divisor = 10;
176 reg2 = 64;
177 break;
178 }
179 if (freq >= 300 && freq < 500) {
180 reg0 = freq * 0.005 * 8;
181 divisor = 5;
182 reg2 = 67;
183 break;
184 }
185 if (freq >= 100 && freq < 300) {
186 reg0 = freq * 0.005 * 16;
187 divisor = 5;
188 reg2 = 68;
189 break;
190 }
191 divisor = 5;
192 reg0 = 5;
193 reg2 = 64;
194 break;
195 case FREQ_SCALE_KHZ: // KHz
196 if (freq >= 500 && freq < 1000) {
197 reg0 = freq * 0.01;
198 divisor = 5;
199 reg2 = 17;
200 break;
201 }
202 if (freq >= 100 && freq < 500) {
203 reg0 = freq * 0.05;
204 divisor = 5;
205 reg2 = 32;
206 break;
207 }
208 if (freq >= 50 && freq < 100) {
209 reg0 = freq * 0.1;
210 divisor = 5;
211 reg2 = 33;
212 break;
213 }
214 if (freq >= 10 && freq < 50) {
215 if (freq == 25) {
216 reg0 = 25;
217 divisor = 5;
218 reg2 = 49;
219 break;
220 }
221 reg0 = freq * 0.5;
222 divisor = 5;
223 reg2 = 48;
224 break;
225 }
226 if (freq >= 2 && freq < 10) {
227 divisor = 5;
228 reg0 = freq * 2;
229 reg2 = 50;
230 break;
231 }
232 divisor = 5;
233 reg0 = 5;
234 reg2 = 64;
235 break;
236 default:
237 divisor = 5;
238 reg0 = 5;
239 reg2 = 64;
240 break;
241 }
242 if (gl_reg_write(devh, FREQUENCY_REG0, divisor) < 0)
243 return -1; // divisor maybe?
244
245 if (gl_reg_write(devh, FREQUENCY_REG1, reg0) < 0)
246 return -1; // 10 / 0.2
247
248 if (gl_reg_write(devh, FREQUENCY_REG2, 0x02) < 0)
249 return -1; // always 2
250
251 if (gl_reg_write(devh, FREQUENCY_REG4, reg2) < 0)
252 return -1;
253
254 return 0;
255}
256
257static void __analyzer_set_ramsize_trigger_address(libusb_device_handle *devh, unsigned int address)
258{
259 gl_reg_write(devh, RAMSIZE_TRIGGERBAR_ADDRESS0, (address >> 0) & 0xFF);
260 gl_reg_write(devh, RAMSIZE_TRIGGERBAR_ADDRESS1, (address >> 8) & 0xFF);
261 gl_reg_write(devh, RAMSIZE_TRIGGERBAR_ADDRESS2, (address >> 16) & 0xFF);
262}
263
264static void __analyzer_set_triggerbar_address(libusb_device_handle *devh, unsigned int address)
265{
266 gl_reg_write(devh, TRIGGERBAR_ADDRESS0, (address >> 0) & 0xFF);
267 gl_reg_write(devh, TRIGGERBAR_ADDRESS1, (address >> 8) & 0xFF);
268 gl_reg_write(devh, TRIGGERBAR_ADDRESS2, (address >> 16) & 0xFF);
269}
270
271static void __analyzer_set_compression(libusb_device_handle *devh, unsigned int type)
272{
273 gl_reg_write(devh, COMPRESSION_TYPE0, (type >> 0) & 0xFF);
274 gl_reg_write(devh, COMPRESSION_TYPE1, (type >> 8) & 0xFF);
275}
276
277static void __analyzer_set_trigger_count(libusb_device_handle *devh, unsigned int count)
278{
279 gl_reg_write(devh, TRIGGER_COUNT0, (count >> 0) & 0xFF);
280 gl_reg_write(devh, TRIGGER_COUNT1, (count >> 8) & 0xFF);
281}
282
283static void analyzer_write_enable_insert_data(libusb_device_handle *devh)
284{
285 gl_reg_write(devh, ENABLE_INSERT_DATA0, 0x12);
286 gl_reg_write(devh, ENABLE_INSERT_DATA1, 0x34);
287 gl_reg_write(devh, ENABLE_INSERT_DATA2, 0x56);
288 gl_reg_write(devh, ENABLE_INSERT_DATA3, 0x78);
289}
290
291static void analyzer_set_filter(libusb_device_handle *devh)
292{
293 int i;
294 gl_reg_write(devh, FILTER_ENABLE, g_filter_enable);
295 for (i = 0; i < 8; i++)
296 gl_reg_write(devh, FILTER_STATUS + i, g_filter_status[i]);
297}
298
299void analyzer_reset(libusb_device_handle *devh)
300{
301 analyzer_write_status(devh, 3, STATUS_FLAG_NONE); // reset device
302 analyzer_write_status(devh, 3, STATUS_FLAG_RESET); // reset device
303}
304
305void analyzer_initialize(libusb_device_handle *devh)
306{
307 analyzer_write_status(devh, 1, STATUS_FLAG_NONE);
308 analyzer_write_status(devh, 1, STATUS_FLAG_INIT);
309 analyzer_write_status(devh, 1, STATUS_FLAG_NONE);
310}
311
312void analyzer_wait(libusb_device_handle *devh, int set, int unset)
313{
314 int status;
315 while(1) {
316 status = gl_reg_read(devh, DEVICE_STATUS);
317 if ((status & set) && ((status & unset) == 0))
318 return;
319 }
320}
321
322void analyzer_read_start(libusb_device_handle *devh)
323{
324 int i;
325
326 analyzer_write_status(devh, 3, STATUS_FLAG_20 | STATUS_FLAG_READ);
327
328 for (i = 0; i < 8; i++)
329 (void)gl_reg_read(devh, READ_RAM_STATUS);
330}
331
332int analyzer_read_data(libusb_device_handle *devh, void *buffer, unsigned int size)
333{
334 return gl_read_bulk(devh, buffer, size);
335}
336
337void analyzer_read_stop(libusb_device_handle *devh)
338{
339 analyzer_write_status(devh, 3, STATUS_FLAG_20);
340 analyzer_write_status(devh, 3, STATUS_FLAG_NONE);
341}
342
343void analyzer_start(libusb_device_handle *devh)
344{
345 analyzer_write_status(devh, 1, STATUS_FLAG_NONE);
346 analyzer_write_status(devh, 1, STATUS_FLAG_INIT);
347 analyzer_write_status(devh, 1, STATUS_FLAG_NONE);
348 analyzer_write_status(devh, 1, STATUS_FLAG_GO);
349}
350
351void analyzer_configure(libusb_device_handle *devh)
352{
353 // Write_Start_Status
354 analyzer_write_status(devh, 1, STATUS_FLAG_RESET);
355 analyzer_write_status(devh, 1, STATUS_FLAG_NONE);
356
357 // Start_Config_Outside_Device ?
358 analyzer_write_status(devh, 1, STATUS_FLAG_INIT);
359 analyzer_write_status(devh, 1, STATUS_FLAG_NONE);
360
361 //SetData_To_Frequence_Reg
362 __analyzer_set_freq(devh, g_freq_value, g_freq_scale);
363
364 //SetMemory_Length
365 gl_reg_write(devh, MEMORY_LENGTH, g_memory_size);
366
367 //Sele_Inside_Outside_Clock
368 gl_reg_write(devh, CLOCK_SOURCE, 0x03);
369
370 //Set_Trigger_Status
371 int i;
372 for (i = 0; i < 9; i++)
373 gl_reg_write(devh, TRIGGER_STATUS0 + i, g_trigger_status[i]);
374
375 __analyzer_set_trigger_count(devh, g_trigger_count);
376
377 //Set_Trigger_Level
378 gl_reg_write(devh, TRIGGER_LEVEL0, 0x31);
379 gl_reg_write(devh, TRIGGER_LEVEL1, 0x31);
380 gl_reg_write(devh, TRIGGER_LEVEL2, 0x31);
381 gl_reg_write(devh, TRIGGER_LEVEL3, 0x31);
382
383 __analyzer_set_ramsize_trigger_address(devh, g_ramsize_triggerbar_addr); // size of actual memory >> 2
384 __analyzer_set_triggerbar_address(devh, g_triggerbar_addr);
385
386 //Set_Dont_Care_TriggerBar
387 gl_reg_write(devh, DONT_CARE_TRIGGERBAR, 0x01);
388
389 //Enable_Status
390 analyzer_set_filter(devh);
391
392 //Set_Enable_Delay_Time
393 gl_reg_write(devh, 0x7a, 0x00);
394 gl_reg_write(devh, 0x7b, 0x00);
395 analyzer_write_enable_insert_data(devh);
396 __analyzer_set_compression(devh,g_compression);
397}
398
399void analyzer_add_trigger(int channel, int type)
400{
401 if ((channel & 0xf) >= 8)
402 return;
403
404 if (type == TRIGGER_HIGH || type == TRIGGER_LOW) {
405 int i;
406 if (channel & CHANNEL_A)
407 i = 0;
408 else if (channel & CHANNEL_B)
409 i = 2;
410 else if (channel & CHANNEL_C)
411 i = 4;
412 else if (channel & CHANNEL_D)
413 i = 6;
414 else
415 return;
416 if ((channel & 0xf) >= 4) {
417 i++;
418 channel -= 4;
419 }
420 g_trigger_status[i] |= 1 << ((2 * channel) + (type == TRIGGER_LOW ? 1 : 0));
421 } else {
422 if (type == TRIGGER_POSEDGE)
423 g_trigger_status[8] = 0x40;
424 else if(type == TRIGGER_NEGEDGE)
425 g_trigger_status[8] = 0x80;
426 else
427 g_trigger_status[8] = 0xc0;
428
429 // FIXME: just guessed the index; need to verify
430 if (channel & CHANNEL_B)
431 g_trigger_status[8] += 8;
432 else if (channel & CHANNEL_C)
433 g_trigger_status[8] += 16;
434 else if (channel & CHANNEL_D)
435 g_trigger_status[8] += 24;
436 g_trigger_status[8] += channel % 8;
437 }
438}
439
440void analyzer_add_filter(int channel, int type)
441{
442 if (type != FILTER_HIGH && type != FILTER_LOW)
443 return;
444 if ((channel & 0xf) >= 8)
445 return;
446
447 int i;
448 if (channel & CHANNEL_A)
449 i = 0;
450 else if (channel & CHANNEL_B)
451 i = 2;
452 else if (channel & CHANNEL_C)
453 i = 4;
454 else if (channel & CHANNEL_D)
455 i = 6;
456 else
457 return;
458 if ((channel & 0xf) >= 4) {
459 i++;
460 channel -= 4;
461 }
462 g_filter_status[i] |= 1 << ((2 * channel) + (type == FILTER_LOW ? 1 : 0));
463 g_filter_enable = 1;
464}
465
466void analyzer_set_trigger_count(int count)
467{
468 g_trigger_count = count;
469}
470
471void analyzer_set_freq(int freq, int scale)
472{
473 g_freq_value = freq;
474 g_freq_scale = scale;
475}
476
477void analyzer_set_memory_size(unsigned int size)
478{
479 g_memory_size = size;
480}
481
482
483void analyzer_set_ramsize_trigger_address(unsigned int address)
484{
485 g_ramsize_triggerbar_addr = address;
486}
487
488void analyzer_set_triggerbar_address(unsigned int address)
489{
490 g_triggerbar_addr = address;
491}
492
493unsigned int analyzer_read_id(libusb_device_handle *devh)
494{
495 return gl_reg_read(devh, DEVICE_ID1) << 8 | gl_reg_read(devh, DEVICE_ID0);
496}
497
498unsigned int analyzer_get_stop_address(libusb_device_handle *devh)
499{
500 return gl_reg_read(devh, STOP_ADDRESS2) << 16 | gl_reg_read(devh, STOP_ADDRESS1) << 8 | gl_reg_read(devh, STOP_ADDRESS0);
501}
502
503unsigned int analyzer_get_now_address(libusb_device_handle *devh)
504{
505 return gl_reg_read(devh, NOW_ADDRESS2) << 16 | gl_reg_read(devh, NOW_ADDRESS1) << 8 | gl_reg_read(devh, NOW_ADDRESS0);
506}
507
508unsigned int analyzer_get_trigger_address(libusb_device_handle *devh)
509{
510 return gl_reg_read(devh, TRIGGER_ADDRESS2) << 16 | gl_reg_read(devh, TRIGGER_ADDRESS1) << 8 | gl_reg_read(devh, TRIGGER_ADDRESS0);
511}
512
513void analyzer_set_compression(unsigned int type)
514{
515 g_compression = type;
516}
517
518void analyzer_wait_button(libusb_device_handle *devh)
519{
520 analyzer_wait(devh, STATUS_BUTTON_PRESSED, 0);
521}
522
523void analyzer_wait_data(libusb_device_handle *devh)
524{
525 analyzer_wait(devh, STATUS_READY | 8, STATUS_BUSY);
526}
527
528int analyzer_decompress(void *input, unsigned int input_len, void *output, unsigned int output_len)
529{
530 unsigned char *in = input;
531 unsigned char *out = output;
532 unsigned int A, B, C, count;
533 unsigned int written = 0;
534
535 while (input_len > 0) {
536 A = *in++;
537 B = *in++;
538 C = *in++;
539 count = (*in++) + 1;
540
541 if (count > output_len)
542 count = output_len;
543 output_len -= count;
544 written += count;
545
546 while (count--) {
547 *out++ = A;
548 *out++ = B;
549 *out++ = C;
550 *out++ = 0; // channel D
551 }
552
553 input_len -= 4;
554 if (output_len == 0)
555 break;
556 }
557
558 return written;
559}