logic-analyzer
Loading...
Searching...
No Matches
logic_analyzer.h
Go to the documentation of this file.
1
8#pragma once
9
10#include "Arduino.h"
11#include "config.h"
12#include "network.h"
13
14// Max numbers of logged characters in a line
15#ifndef LOG_BUFFER_SIZE
16#define LOG_BUFFER_SIZE 80
17#endif
18
19// Max size of buffered print
20#ifndef DUMP_RECORD_SIZE
21#define DUMP_RECORD_SIZE 1024*1
22#endif
23
24// Supported Commands
25#define SUMP_RESET 0x00
26#define SUMP_ARM 0x01
27#define SUMP_ID 0x02
28#define SUMP_XON 0x11
29#define SUMP_XOFF 0x13
30#define SUMP_TRIGGER_MASK 0xC0
31#define SUMP_TRIGGER_VALUES 0xC1
32#define SUMP_TRIGGER_CONFIG 0xC2
33#define SUMP_SET_DIVIDER 0x80
34#define SUMP_SET_READ_DELAY_COUNT 0x81
35#define SUMP_SET_FLAGS 0x82
36#define SUMP_SET_RLE 0x0100
37#define SUMP_GET_METADATA 0x04
38
39namespace logic_analyzer {
40
42class AbstractCapture;
43class Capture;
44class LogicAnalyzer;
45class RingBuffer;
46
47
49enum Status : uint8_t {STOPPED, ARMED, TRIGGERED};
50
52enum Event : uint8_t {RESET, STATUS, CAPUTRE_SIZE, CAPTURE_FREQUNCY,TRIGGER_VALUES,TRIGGER_MASK, READ_DLEAY_COUNT, FLAGS};
53typedef void (*EventHandler)(Event event);
54
55PinReader *pin_reader_ptr = nullptr;
59Stream *logger_ptr = nullptr;
61Stream *stream_ptr = nullptr;
62
64void write(PinBitArray bits) {
65 // The SUMP/OLS protocol expects each 4 byte sample in the host's native
66 // (little endian) byte order - NOT network (big endian) order, so we must
67 // not apply htonl() here. Also Arduino's Print::write(unsigned long)
68 // truncates to a single byte, so we write the full 4 bytes explicitly.
69 uint32_t tmp = (uint32_t) bits;
70 stream_ptr->write((const uint8_t*)&tmp, sizeof(tmp));
71}
72
73// writes a buffer of uint32_t values
74void write(uint32_t *buff, size_t n_samples) {
75 int written = 0;
76 int open = n_samples * sizeof(uint32_t);
77 while(open > 0){
78 size_t result = stream_ptr->write((const char*)buff + written, open);
79 written += result;
80 open -= result;
81 }
82}
83
84// writes a buffer of PinBitArray
85void write(PinBitArray *buff, size_t n_samples) {
86 // convert to uint32_t - samples must stay in native (little endian) byte
87 // order to match what the SUMP/OLS protocol (and PulseView) expects.
88 uint32_t tmp[DUMP_RECORD_SIZE];
89 int idx = 0;
90 for (int j=0;j<n_samples;j++){
91 tmp[idx++] = (uint32_t) buff[j];
92 if (idx==DUMP_RECORD_SIZE){
93 write(tmp, idx);
94 idx = 0;
95 }
96 }
97 if (idx>0){
98 write(tmp, idx);
99 }
100}
101
102
104inline void log(const char* fmt, ...) {
105 if (logger_ptr!=nullptr) {
106 char serial_printf_buffer[LOG_BUFFER_SIZE] = {0};
107 va_list args;
108 va_start(args,fmt);
109 vsnprintf(serial_printf_buffer,LOG_BUFFER_SIZE, fmt, args);
110 logger_ptr->println(serial_printf_buffer);
111 va_end(args);
112 logger_ptr->flush();
113 }
114}
115
123 public:
125 uint8_t *getPtr() {
126 return uint8Values;
127 }
128
130 uint16_t get16(int idx) {
131 return uint16Values[idx];
132 }
133
135 uint32_t get32() {
136 return uint32Value[0];
137 }
138
139 protected:
140 uint8_t uint8Values[4];
141 uint16_t* uint16Values = (uint16_t*) &uint8Values[0];
142 uint32_t* uint32Value = (uint32_t*) &uint8Values[0];
143
144};
145
152 public:
153 RingBuffer(size_t size){
154 this->size_count = size + 10;
155 data = new PinBitArray[this->size_count];
156 if (data==nullptr){
157 log("Requested capture size is too big");
158 this->size_count = 0;
159 }
160 }
161
162 ~RingBuffer(){
163 if (data!=nullptr){
164 delete[] data;
165 }
166 }
167
169 void write(PinBitArray value){
170 if (ignore_count > 0) {
171 ignore_count--;
172 return;
173 }
174 data[write_pos++] = value;
175 if (write_pos>=size_count){
176 write_pos = 0;
177 }
178 if (available_count<size_count){
179 available_count++;
180 } else {
181 read_pos = write_pos+1;
182 }
183 }
184
186 PinBitArray read() {
187 PinBitArray result = 0;
188 if (available_count>0){
189 if (read_pos>=size_count){
190 read_pos = 0;
191 }
192 result = data[read_pos++];
193 available_count--;
194 }
195 return result;
196 }
197
199 size_t readBuffer(uint32_t *result, size_t read_len){
200 size_t result_len;
201 for (size_t j=0; j<read_len; j++){
202 PinBitArray *ptr = (PinBitArray *) (result+j);
203 for (int i=0;i < (4/sizeof(PinBitArray)); i++){
204 ptr[i] = read();
205 if (available()==0){
206 return j+1;
207 }
208 }
209 }
210 return read_len;
211 }
212
214 void clear() {
215 ignore_count = 0;
216 available_count = 0;
217 write_pos = 0;
218 read_pos = 0;
219 }
220
222 void clear(size_t count){
223 ignore_count = 0;
224 if (count>available_count){
225 // calculate number of future entries to ignore
226 ignore_count = count - available_count;
227 }
228 // remove count entries
229 for (int j=0;j<count && available()>0;j++){
230 read();
231 }
232 }
233
235 size_t available() {
236 return available_count;
237 }
238
240 void setAvailable(size_t avail){
241 available_count = avail;
242 }
243
245 size_t size() {
246 return size_count;
247 }
248
249 PinBitArray *data_ptr(){
250 return data;
251 }
252
253 private:
254 size_t available_count = 0;
255 size_t size_count = 0;
256 size_t write_pos = 0;
257 size_t read_pos = 0;
258 size_t ignore_count = 0;
259 PinBitArray *data;
260};
261
269 public:
270 friend class AbstractCapture;
271 friend class LogicAnalyzer;
272 friend class Capture;
273
275 void setStatus(Status status){
276 log("setStatus %d", status);
277 status_value = status;
278 raiseEvent(STATUS);
279 }
280
281 Stream &stream() {
282 return *stream_ptr;
283 }
284
285 protected:
286 volatile Status status_value;
287 bool is_continuous_capture = false; // => continous capture
288 uint32_t max_capture_size = 1000;
289 int trigger_pos = -1;
290 int read_count = 0;
291 int delay_count = 0;
292 int pin_start = 0;
293 int pin_numbers = 0;
294 uint64_t frequecy_value; // in hz
295 uint64_t delay_time_us;
296 PinBitArray trigger_mask = 0;
297 PinBitArray trigger_values = 0;
298 Sump4ByteComandArg cmd4;
299 EventHandler eventHandler = nullptr;
300
301
303 void raiseEvent(Event event){
304 if (eventHandler!=nullptr) eventHandler(event);
305 }
306} la_state;
307
308
309
317 public:
318 friend class LogicAnalyzer;
319
323
327
330 return *logic_analyzer_ptr;
331 }
332
334 virtual PinReader &pinReader() {
335 return *(pin_reader_ptr);
336 }
337
339 virtual void setStatus(Status status){
340 la_state.setStatus(status);
341 }
342
344 virtual void capture() = 0;
345
347 virtual void captureAll() = 0;
348
349
350 protected:
351 LogicAnalyzer *logic_analyzer_ptr = nullptr;
352
353 virtual void setLogicAnalyzer(LogicAnalyzer &la){
354 logic_analyzer_ptr = &la;
355 }
356
357};
358
364class Capture : public AbstractCapture {
365 public:
367 Capture(uint64_t maxCaptureFreq, uint64_t maxCaptureFreqThreshold ) : AbstractCapture(){
368 max_frequecy_value = maxCaptureFreq;
369 max_frequecy_threshold = maxCaptureFreqThreshold;
370 }
371
373 virtual void capture(){
374 log("capture");
375 // no capture if request is well above max rate
376 if (la_state.frequecy_value > max_frequecy_value + (max_frequecy_value/2)){
377 setStatus(STOPPED);
378 // Send some dummy data to stop pulseview
379 write(0);
380 log("The frequency %u is not supported!", la_state.frequecy_value );
381 return;
382 }
383
384 // if frequecy_value >= max_frequecy_value -> capture at max speed
385 capture(la_state.frequecy_value >= max_frequecy_threshold);
386 log("capture-end");
387 }
388
390 void captureAll() {
391 log("captureAll %ld entries", la_state.read_count);
392 unsigned long delay_time_us = la_state.delay_time_us;
393 while(la_state.status_value == TRIGGERED && buffer_ptr->available() < la_state.read_count ){
395 delayMicroseconds(delay_time_us);
396 }
397 }
398
401 log("captureAllMaxSpeed %ld entries",la_state.read_count);
402 while(la_state.status_value == TRIGGERED && buffer_ptr->available() < la_state.read_count ){
404 }
405 }
406
409 log("captureAllContinous");
410 unsigned long delay_time_us = la_state.delay_time_us;
411 while(la_state.status_value == TRIGGERED){
413 delayMicroseconds(delay_time_us);
414 }
415 }
416
419 log("captureAllContinousMaxSpeed");
420 while(la_state.status_value == TRIGGERED){
422 }
423 }
424
427 buffer_ptr->write(pin_reader_ptr->readAll());
428 }
429
432 write(pin_reader_ptr->readAll());
433 }
434
436 PinBitArray captureSample() {
437 // actual state
438 PinBitArray actual = pin_reader_ptr->readAll();
439
440 // buffer single capture cycle
441 if (la_state.is_continuous_capture) {
442 write(actual);
443 } else if (la_state.status_value==TRIGGERED) {
444 buffer_ptr->write(actual);
445 }
446 return actual;
447 }
448
449
450 protected:
451 uint64_t max_frequecy_value; // in hz
452 uint64_t max_frequecy_threshold; // in hz
453
455 void capture(bool is_max_speed) {
456 log("capture is_max_speed: %s", is_max_speed ? "true":"false");
457 // waiting for trigger
458 if (la_state.trigger_mask) {
459 log("waiting for trigger");
460 while ((la_state.trigger_values ^ captureSample()) & la_state.trigger_mask)
461 ;
462 }
463 la_state.setStatus(TRIGGERED);
464 log("triggered");
465
466 // remove unnecessary entries from buffer based on delayCount & readCount
467 long keep = la_state.read_count - la_state.delay_count;
468 if (keep > 0 && buffer_ptr->available()>keep) {
469 log("keeping last %ld entries",keep);
471 } else if (keep < 0) {
472 log("ignoring first %ld entries",abs(keep));
473 buffer_ptr->clear(buffer_ptr->available() + abs(keep));
474 } else if (keep==0l){
475 log("starting with clean buffer");
476 buffer_ptr->clear();
477 }
478
479 // Start Capture
480 if (is_max_speed){
481 if (la_state.is_continuous_capture){
483 } else {
485 dumpData();
486 log("capture-done: %lu",buffer_ptr->available());
487 setStatus(STOPPED);
488 }
489 } else {
490 if (la_state.is_continuous_capture){
492 } else {
493 captureAll();
494 dumpData();
495 log("capture-done: %lu",buffer_ptr->available());
496 setStatus(STOPPED);
497 }
498 }
499 }
500
502 virtual Stream &stream() {
503 return *stream_ptr;
504 }
505
506
508 void dumpData() {
509 log("dumpData: %lu",buffer_ptr->available());
510 // buffered write
511 uint32_t tmp[DUMP_RECORD_SIZE];
512 stream_ptr->setTimeout(10000);
513 while(buffer_ptr->available()){
514 size_t len = buffer_ptr->readBuffer(tmp, DUMP_RECORD_SIZE);
515 write(tmp, len);
516 }
517 // flush final records - for backward compatibility
518 stream_ptr->flush();
519 log("dumpData-end");
520 }
521};
522
533 public:
536 log("LogicAnalyzer");
537 }
538
541 log("~LogicAnalyzer");
542 if (buffer_ptr!=nullptr) {
543 delete buffer_ptr;
544 buffer_ptr = nullptr;
545 }
546 if (pin_reader_ptr!=nullptr){
547 delete pin_reader_ptr;
548 pin_reader_ptr = nullptr;
549 }
550 }
551
562 void begin(Stream &procesingStream, AbstractCapture *capture, uint32_t maxCaptureSize, uint8_t pinStart=0, uint8_t numberOfPins=8, bool setup_pins=false){
563 log("begin");
564 stream_ptr = &procesingStream;
565 this->capture_ptr = capture;
566
567 la_state.max_capture_size = maxCaptureSize;
568 la_state.read_count = maxCaptureSize;
569 la_state.delay_count = maxCaptureSize;
570 la_state.pin_start = pinStart;
571 la_state.pin_numbers = numberOfPins;
572
573 // set initial status
574 setStatus(STOPPED);
575
576 if (pin_reader_ptr==nullptr){
577 pin_reader_ptr = new PinReader(pinStart);
578 }
579
580 if (do_allocate_buffer && buffer_ptr==nullptr) {
581 buffer_ptr = new RingBuffer(maxCaptureSize);
582 }
583
584 // assign state to capture
585 if (capture!=nullptr) {
586 capture->setLogicAnalyzer(*this);
587 }
588
589 // by default the pins are in read mode - so it is usually not really necesarry to set the mode to input
590 if (setup_pins){
591 // pinmode imput for requested pins
592 for (int j=0;j<numberOfPins;j++){
593 pinMode(pinStart+j, INPUT);
594 }
595 }
596
597 log("begin-end");
598 }
599
601 uint16_t startPin() {
602 return la_state.pin_start;
603 }
604
606 uint16_t numberOfPins() {
607 return la_state.pin_numbers;
608 }
609
611 Stream &stream() {
612 return *(stream_ptr);
613 }
614
617 return la_state.status_value;
618 }
619
622 la_state.setStatus(status);
623 }
624
627 return *(buffer_ptr);
628 }
629
632 if (hasCommand()){
633 int cmd = command();
634 log("processCommand %d", cmd);
635 processCommand(cmd);
636 }
637 }
638
640 PinBitArray triggerValues() {
641 return la_state.trigger_values;
642 }
643
645 void setTriggerValues(PinBitArray values){
646 la_state.trigger_values = values;
647 log("--> setTriggerValues: %u", (uint32_t) values);
648 raiseEvent(TRIGGER_VALUES);
649 }
650
652 PinBitArray triggerMask() {
653 return la_state.trigger_mask;
654 }
655
657 void setTriggerMask(PinBitArray values){
658 la_state.trigger_mask = values;
659 log("--> setTriggerValues: %u", (uint32_t) values);
660 raiseEvent(TRIGGER_MASK);
661 }
662
664 int readCount() {
665 return la_state.read_count;
666 }
667
669 void setReadCount(int count){
670 la_state.read_count = count;
671 }
672
675 return la_state.delay_count;
676 }
677
679 void setDelayCount(int count){
680 log("--> setDelayCount: %d", count);
681 la_state.delay_count = count;
682 }
683
685 uint64_t captureFrequency() {
686 return la_state.frequecy_value;
687 }
688
690 uint64_t delayTimeUs() {
691 return la_state.delay_time_us;
692 }
693
695 void setCaptureFrequency(uint64_t value){
696 la_state.frequecy_value = value;
697 log("--> setCaptureFrequency: %lu", la_state.frequecy_value);
698 la_state.delay_time_us = (1000000.0 / value );
699 log("--> delay_time_us: %lu", la_state.delay_time_us);
700 raiseEvent(CAPTURE_FREQUNCY);
701 }
702
705 return la_state.is_continuous_capture;
706 }
707
709 void setContinuousCapture(bool cont){
710 la_state.is_continuous_capture = cont;
711 }
712
714 void setEventHandler(EventHandler eh){
715 la_state.eventHandler = eh;
716 }
717
719 void clear(){
720 log("clear");
721 setStatus(STOPPED);
722 if (buffer_ptr!=nullptr){
723 memset(buffer_ptr->data_ptr(),0x00, la_state.max_capture_size*sizeof(PinBitArray));
724 buffer_ptr->clear();
725 }
726 }
727
729 size_t size() {
730 return buffer_ptr == nullptr ? 0 : buffer_ptr->size();
731 }
732
734 size_t available() {
735 return buffer_ptr == nullptr ? 0 : buffer_ptr->available();
736 }
737
739 void setLogger(Stream &logger){
740 logger_ptr = &logger;
741 }
742
745 is_capture_on_arm = capture;
746 }
747
748
750 void setDescription(const char* name) {
751 description = name;
752 }
753
755 void setAllocateBuffer(bool do_allocate){
756 do_allocate_buffer = do_allocate;
757 }
758
760 void capture() {
761 if (capture_ptr!=nullptr)
762 capture_ptr->capture();
763 }
764
765
766 protected:
767 bool is_capture_on_arm = true;
768 bool do_allocate_buffer = true;
769 uint64_t sump_reset_igorne_timeout=0;
770 AbstractCapture *capture_ptr = nullptr;
771 const char* description = "ARDUINO";
772 const char* device_id = "1ALS";
773 const char* firmware_version = "01.0";
774 const char* protocol_version = "\x041\x002";
775
778 return la_state;
779 }
780
781
783 bool hasCommand() {
784 return stream_ptr->available() > 0;
785 }
786
788 uint8_t command() {
789 int command = stream().read();
790 return command;
791 }
792
795 delay(10);
796 stream().readBytes(la_state.cmd4.getPtr(), 4);
797 return la_state.cmd4;
798 }
799
801 void write(uint8_t cmd, uint32_t number){
802 stream().write(cmd);
803 uint32_t toSend = htonl(number);
804 stream().write((byte*)&toSend,sizeof(uint32_t));
805 stream().flush();
806 }
807
809 void write(uint8_t cmd, const char* str){
810 stream().write(cmd);
811 stream().print(str);
812 stream().write("\x000",1);
813 stream().flush();
814 }
815
817 PinBitArray commandExtPinBitArray() {
819 switch(sizeof(PinBitArray)) {
820 case 1:
821 return (PinBitArray) cmd.getPtr()[0];
822 case 2:
823 return (PinBitArray) cmd.get16(0);
824 default:
825 return (PinBitArray) cmd.get32();
826 }
827 }
828
830 void raiseEvent(Event event){
831 la_state.raiseEvent(event);
832 }
833
848 void setupDelay(uint32_t divider) {
849 // calculate frequency
850 setCaptureFrequency(100000000UL / (divider+1));
851 }
852
859 log("sendMetadata");
860 write(0x01, description);
861 write(0x02, firmware_version);
862 // number of probes
863 write(0x20, la_state.pin_numbers);
864 // sample memory
865 write(0x21, la_state.max_capture_size);
866 // sample rate - We do not provide the real max sample rate since this does not have any impact on the gui and provides wrong results!
867 //write(0x23, la_state.max_frequecy_value);
868 // protocol version & end
869 stream().write(protocol_version, strlen(protocol_version)+1);
870 stream().flush();
871 }
872
876 void processCommand(int cmd){
877
878 switch (cmd) {
882 case SUMP_RESET:
883 // debounce reset
884 if (millis()>sump_reset_igorne_timeout){
885 log("=>SUMP_RESET");
886 setStatus(STOPPED);
887 clear();
888 sump_reset_igorne_timeout = millis()+ 500;
889 raiseEvent(RESET);
890 }
891 break;
892
896 case SUMP_ID:
897 log("=>SUMP_ID");
898 stream().write(device_id, 4);
899 stream().flush();
900 break;
901
902 /*
903 * We return a description of our capabilities.
904 * Check the function's comments below.
905 */
906 case SUMP_GET_METADATA:
907 log("=>SUMP_GET_METADATA");
908 sendMetadata();
909 break;
910
911 /*
912 * Captures the data
913 */
914 case SUMP_ARM:
915 log("=>SUMP_ARM");
916 // clear current data
917 clear();
918 setStatus(ARMED);
919 if (is_capture_on_arm){
920 capture();
921 }
922 break;
923
924 /*
925 * the trigger mask byte has a '1' for each enabled trigger so
926 * we can just use it directly as our trigger mask.
927 */
928 case SUMP_TRIGGER_MASK:
929 log("=>SUMP_TRIGGER_MASK");
931 break;
932
933 /*
934 * trigger_values can be used directly as the value of each bit
935 * defines whether we're looking for it to be high or low.
936 */
937 case SUMP_TRIGGER_VALUES:
938 log("=>SUMP_TRIGGER_VALUES");
940 break;
941
942
943 /* read the rest of the command bytes but ignore them. */
944 case SUMP_TRIGGER_CONFIG:
945 log("=>SUMP_TRIGGER_CONFIG");
946 commandExt();
947 break;
948
949 /*
950 * the shifting needs to be done on the 32bit unsigned long variable
951 * so that << 16 doesn't end up as zero.
952 */
953 case SUMP_SET_DIVIDER: {
954 log("=>SUMP_SET_DIVIDER");
956 uint32_t divider = cmd.get32();
957 log("-divider: %lu\n", divider);
958 setupDelay(divider);
959 }
960 break;
961
962 /*
963 * this just sets up how many samples there should be before
964 * and after the trigger fires. The readCount is total samples
965 * to return and delayCount number of samples after the trigger.
966 * this sets the buffer splits like 0/100, 25/75, 50/50
967 * for example if readCount == delayCount then we should
968 * return all samples starting from the trigger point.
969 * if delayCount < readCount we return (readCount - delayCount) of
970 * samples from before the trigger fired.
971 */
972 case SUMP_SET_READ_DELAY_COUNT: {
974 log("=>SUMP_SET_READ_DELAY_COUNT %02X %02X",cmd.get16(0),cmd.get16(1));
975 la_state.read_count = (cmd.get16(0)+1) * 4;
976 la_state.delay_count = (cmd.get16(1)+1) * 4;
977 log("--> read_count: %d", la_state.read_count);
978 log("--> delay_count: %d", la_state.delay_count);
979 raiseEvent(READ_DLEAY_COUNT);
980 }
981 break;
982
983 /* read the rest of the command bytes and check if RLE is enabled. */
984 case SUMP_SET_FLAGS: {
985 log("=>SUMP_SET_FLAGS");
987 la_state.is_continuous_capture = ((cmd.getPtr()[1] & 0B1000000) != 0);
988 log("--> is_continuous_capture: %d\n", la_state.is_continuous_capture);
989 raiseEvent(FLAGS);
990
991 }
992 break;
993
994 /* ignore any unrecognized bytes. */
995 default:
996 log("=>UNHANDLED command: %d", cmd);
997 break;
998
999 };
1000 }
1001};
1002
1003} // namespace
1004
1005
Abstract Class for Capturing Logic. Create your own subclass if you want to implement your own optimi...
Definition logic_analyzer.h:316
LogicAnalyzer & logicAnalyzer()
Provides access to the LogicAnalyzer.
Definition logic_analyzer.h:329
~AbstractCapture()
Destructor.
Definition logic_analyzer.h:325
virtual void captureAll()=0
Used to masure the speed - capture into memory w/o dump!
virtual PinReader & pinReader()
Provides access to the PinReader.
Definition logic_analyzer.h:334
AbstractCapture()
Default Constructor.
Definition logic_analyzer.h:321
virtual void setStatus(Status status)
Sets the status.
Definition logic_analyzer.h:339
virtual void capture()=0
Captures the data and dumps the result.
Default Implementation for the Capturing Logic.
Definition logic_analyzer.h:364
void captureAll()
Generic Capturing of requested number of examples into the buffer.
Definition logic_analyzer.h:390
void captureAllContinous()
Continuous capturing at the requested speed.
Definition logic_analyzer.h:408
virtual Stream & stream()
Provides access to the SUMP command stream.
Definition logic_analyzer.h:502
void captureSampleFastContinuous()
captures one singe entry for all pins and writes it to output stream
Definition logic_analyzer.h:431
void captureAllMaxSpeed()
Capturing of requested number of examples into the buffer at maximum speed.
Definition logic_analyzer.h:400
void capture(bool is_max_speed)
starts the capturing of the data
Definition logic_analyzer.h:455
void dumpData()
dumps the caputred data to the recording device
Definition logic_analyzer.h:508
virtual void capture()
starts the capturing of the data
Definition logic_analyzer.h:373
Capture(uint64_t maxCaptureFreq, uint64_t maxCaptureFreqThreshold)
Default Constructor.
Definition logic_analyzer.h:367
void captureAllContinousMaxSpeed()
Continuous capturing at max speed.
Definition logic_analyzer.h:418
PinBitArray captureSample()
captures one single entry for all pins and provides the result - used by the trigger
Definition logic_analyzer.h:436
void captureSampleFast()
captures one singe entry for all pins and writes it to the buffer
Definition logic_analyzer.h:426
Main Logic Analyzer API using the SUMP Protocol. When you try to connect to the Logic Analzyer - SUMP...
Definition logic_analyzer.h:532
RingBuffer & buffer()
Provides access to the buffer.
Definition logic_analyzer.h:626
PinBitArray triggerValues()
provides the trigger values
Definition logic_analyzer.h:640
void setTriggerMask(PinBitArray values)
defines the trigger mask
Definition logic_analyzer.h:657
size_t available()
returns the avialable buffer entries
Definition logic_analyzer.h:734
void raiseEvent(Event event)
raises an event
Definition logic_analyzer.h:830
void setDelayCount(int count)
defines the delay count
Definition logic_analyzer.h:679
Stream & stream()
provides command output stream of capturing divice
Definition logic_analyzer.h:611
void setEventHandler(EventHandler eh)
defines a event handler that gets notified on some defined events
Definition logic_analyzer.h:714
uint64_t captureFrequency()
provides the caputring frequency
Definition logic_analyzer.h:685
uint8_t command()
gets the next 1 byte command
Definition logic_analyzer.h:788
PinBitArray commandExtPinBitArray()
Provides the command as PinBitArray.
Definition logic_analyzer.h:817
Status status()
provides the actual Status
Definition logic_analyzer.h:616
int delayCount()
provides the delay count
Definition logic_analyzer.h:674
void clear()
Resets the status and buffer.
Definition logic_analyzer.h:719
void setCaptureOnArm(bool capture)
Switch automatic capturing on ARMED status on/off.
Definition logic_analyzer.h:744
void processCommand(int cmd)
Definition logic_analyzer.h:876
void write(uint8_t cmd, uint32_t number)
writes a byte command with uint32_t number argument
Definition logic_analyzer.h:801
void setReadCount(int count)
defines the read count
Definition logic_analyzer.h:669
void setContinuousCapture(bool cont)
defines the caputring as continuous
Definition logic_analyzer.h:709
void setTriggerValues(PinBitArray values)
defines the trigger values
Definition logic_analyzer.h:645
void setCaptureFrequency(uint64_t value)
defines the caputring frequency
Definition logic_analyzer.h:695
uint16_t numberOfPins()
Provides the number of subsequent GPIO pins which will be used for capturing.
Definition logic_analyzer.h:606
void capture()
starts the capturing
Definition logic_analyzer.h:760
LogicAnalyzerState & state()
Provides a reference to the LogicAnalyzerState.
Definition logic_analyzer.h:777
void sendMetadata()
Definition logic_analyzer.h:858
uint16_t startPin()
Provides the GPIO number of the start pin which is used for capturing.
Definition logic_analyzer.h:601
void setAllocateBuffer(bool do_allocate)
Allows to switch of the automatic buffer allocation - call before begin!
Definition logic_analyzer.h:755
bool isContinuousCapture()
checks if the caputring is continuous
Definition logic_analyzer.h:704
void setStatus(Status status)
Defines the actual status.
Definition logic_analyzer.h:621
PinBitArray triggerMask()
provides the trigger mask
Definition logic_analyzer.h:652
size_t size()
returns the max buffer size
Definition logic_analyzer.h:729
LogicAnalyzer()
Default Constructor.
Definition logic_analyzer.h:535
void processCommand()
process the next available command - Call this function from your Arduino loop()!
Definition logic_analyzer.h:631
~LogicAnalyzer()
Destructor.
Definition logic_analyzer.h:540
void setupDelay(uint32_t divider)
Definition logic_analyzer.h:848
void begin(Stream &procesingStream, AbstractCapture *capture, uint32_t maxCaptureSize, uint8_t pinStart=0, uint8_t numberOfPins=8, bool setup_pins=false)
Starts the processing.
Definition logic_analyzer.h:562
void setDescription(const char *name)
Defines the Description.
Definition logic_analyzer.h:750
void write(uint8_t cmd, const char *str)
writes a byte command with char* argument
Definition logic_analyzer.h:809
Sump4ByteComandArg & commandExt()
gets the next 4 byte command
Definition logic_analyzer.h:794
uint64_t delayTimeUs()
Provides the delay time between measurements in microseconds.
Definition logic_analyzer.h:690
int readCount()
provides the read count
Definition logic_analyzer.h:664
void setLogger(Stream &logger)
Activate the logging by defining the logging output Stream.
Definition logic_analyzer.h:739
bool hasCommand()
checks if there is a command available
Definition logic_analyzer.h:783
Common State information for the Logic Analyzer - provides event handling on State change.
Definition logic_analyzer.h:268
void setStatus(Status status)
Defines the actual status.
Definition logic_analyzer.h:275
void raiseEvent(Event event)
raises an event
Definition logic_analyzer.h:303
Arduino Mega specific implementation Logic for the PinReader. The Mega GPIO numbers are not mapped to...
Definition config_avr.h:52
PinBitArray readAll()
reads all pins and provides the result as bitmask
Definition config_avr.h:69
Data is captured in a ring buffer. If the buffer is full we overwrite the oldest entries....
Definition logic_analyzer.h:151
PinBitArray read()
reads the next available entry from the buffer
Definition logic_analyzer.h:186
void setAvailable(size_t avail)
Usualy you must not use this function. However for the RP PIO it is quite usefull to indicated that t...
Definition logic_analyzer.h:240
size_t size()
returns the max buffer size
Definition logic_analyzer.h:245
void write(PinBitArray value)
adds an entry - if there is no more space we overwrite the oldest value
Definition logic_analyzer.h:169
void clear()
clears all entries
Definition logic_analyzer.h:214
size_t available()
returns the number of available entries
Definition logic_analyzer.h:235
size_t readBuffer(uint32_t *result, size_t read_len)
1 SUMP record has 4 bytes - We privide the requested number of buffered values in the output format
Definition logic_analyzer.h:199
void clear(size_t count)
clears n entries from the buffer - if the number is bigger then the available data we ignore some fut...
Definition logic_analyzer.h:222
4 Byte SUMP Protocol Command. The uint8Values data is provided in network format (big endian) while t...
Definition logic_analyzer.h:122
uint16_t get16(int idx)
Provides a uint16_t value.
Definition logic_analyzer.h:130
uint8_t * getPtr()
Provides a pointer to the memory.
Definition logic_analyzer.h:125
uint32_t get32()
Provides a uint32_t value.
Definition logic_analyzer.h:135
void write(PinBitArray bits)
writes the status of all activated pins to the capturing device
Definition logic_analyzer.h:64
RingBuffer * buffer_ptr
common access to buffer
Definition logic_analyzer.h:57
Event
Events.
Definition logic_analyzer.h:52
Stream * logger_ptr
Logger Stream.
Definition logic_analyzer.h:59
Status
Logic Analzyer Capturing Status.
Definition logic_analyzer.h:49
void log(const char *fmt,...)
Prints the content to the logger output stream.
Definition logic_analyzer.h:104
Stream * stream_ptr
Command stream.
Definition logic_analyzer.h:61