15#ifndef LOG_BUFFER_SIZE
16#define LOG_BUFFER_SIZE 80
20#ifndef DUMP_RECORD_SIZE
21#define DUMP_RECORD_SIZE 1024*1
25#define SUMP_RESET 0x00
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
39namespace logic_analyzer {
49enum Status : uint8_t {STOPPED, ARMED, TRIGGERED};
52enum Event : uint8_t {RESET, STATUS, CAPUTRE_SIZE, CAPTURE_FREQUNCY,TRIGGER_VALUES,TRIGGER_MASK, READ_DLEAY_COUNT, FLAGS};
53typedef void (*EventHandler)(Event event);
55PinReader *pin_reader_ptr =
nullptr;
69 uint32_t tmp = (uint32_t) bits;
70 stream_ptr->write((
const uint8_t*)&tmp,
sizeof(tmp));
74void write(uint32_t *buff,
size_t n_samples) {
76 int open = n_samples *
sizeof(uint32_t);
78 size_t result = stream_ptr->write((
const char*)buff + written, open);
85void write(PinBitArray *buff,
size_t n_samples) {
88 uint32_t tmp[DUMP_RECORD_SIZE];
90 for (
int j=0;j<n_samples;j++){
91 tmp[idx++] = (uint32_t) buff[j];
92 if (idx==DUMP_RECORD_SIZE){
104inline void log(
const char* fmt, ...) {
106 char serial_printf_buffer[LOG_BUFFER_SIZE] = {0};
109 vsnprintf(serial_printf_buffer,LOG_BUFFER_SIZE, fmt, args);
131 return uint16Values[idx];
136 return uint32Value[0];
140 uint8_t uint8Values[4];
141 uint16_t* uint16Values = (uint16_t*) &uint8Values[0];
142 uint32_t* uint32Value = (uint32_t*) &uint8Values[0];
154 this->size_count =
size + 10;
155 data =
new PinBitArray[this->size_count];
157 log(
"Requested capture size is too big");
158 this->size_count = 0;
170 if (ignore_count > 0) {
174 data[write_pos++] = value;
175 if (write_pos>=size_count){
178 if (available_count<size_count){
181 read_pos = write_pos+1;
187 PinBitArray result = 0;
188 if (available_count>0){
189 if (read_pos>=size_count){
192 result = data[read_pos++];
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++){
224 if (count>available_count){
226 ignore_count = count - available_count;
229 for (
int j=0;j<count &&
available()>0;j++){
236 return available_count;
241 available_count = avail;
249 PinBitArray *data_ptr(){
254 size_t available_count = 0;
255 size_t size_count = 0;
256 size_t write_pos = 0;
258 size_t ignore_count = 0;
276 log(
"setStatus %d", status);
277 status_value = status;
286 volatile Status status_value;
287 bool is_continuous_capture =
false;
288 uint32_t max_capture_size = 1000;
289 int trigger_pos = -1;
294 uint64_t frequecy_value;
295 uint64_t delay_time_us;
296 PinBitArray trigger_mask = 0;
297 PinBitArray trigger_values = 0;
298 Sump4ByteComandArg cmd4;
299 EventHandler eventHandler =
nullptr;
304 if (eventHandler!=
nullptr) eventHandler(event);
330 return *logic_analyzer_ptr;
335 return *(pin_reader_ptr);
354 logic_analyzer_ptr = &la;
368 max_frequecy_value = maxCaptureFreq;
369 max_frequecy_threshold = maxCaptureFreqThreshold;
376 if (la_state.frequecy_value > max_frequecy_value + (max_frequecy_value/2)){
380 log(
"The frequency %u is not supported!", la_state.frequecy_value );
385 capture(la_state.frequecy_value >= max_frequecy_threshold);
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);
401 log(
"captureAllMaxSpeed %ld entries",la_state.read_count);
402 while(la_state.status_value == TRIGGERED &&
buffer_ptr->
available() < la_state.read_count ){
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);
419 log(
"captureAllContinousMaxSpeed");
420 while(la_state.status_value == TRIGGERED){
438 PinBitArray actual = pin_reader_ptr->
readAll();
441 if (la_state.is_continuous_capture) {
443 }
else if (la_state.status_value==TRIGGERED) {
451 uint64_t max_frequecy_value;
452 uint64_t max_frequecy_threshold;
456 log(
"capture is_max_speed: %s", is_max_speed ?
"true":
"false");
458 if (la_state.trigger_mask) {
459 log(
"waiting for trigger");
460 while ((la_state.trigger_values ^
captureSample()) & la_state.trigger_mask)
467 long keep = la_state.read_count - la_state.delay_count;
469 log(
"keeping last %ld entries",keep);
471 }
else if (keep < 0) {
472 log(
"ignoring first %ld entries",abs(keep));
474 }
else if (keep==0l){
475 log(
"starting with clean buffer");
481 if (la_state.is_continuous_capture){
490 if (la_state.is_continuous_capture){
511 uint32_t tmp[DUMP_RECORD_SIZE];
536 log(
"LogicAnalyzer");
541 log(
"~LogicAnalyzer");
546 if (pin_reader_ptr!=
nullptr){
547 delete pin_reader_ptr;
548 pin_reader_ptr =
nullptr;
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;
576 if (pin_reader_ptr==
nullptr){
577 pin_reader_ptr =
new PinReader(pinStart);
580 if (do_allocate_buffer &&
buffer_ptr==
nullptr) {
586 capture->setLogicAnalyzer(*
this);
593 pinMode(pinStart+j, INPUT);
602 return la_state.pin_start;
607 return la_state.pin_numbers;
617 return la_state.status_value;
634 log(
"processCommand %d", cmd);
641 return la_state.trigger_values;
646 la_state.trigger_values = values;
647 log(
"--> setTriggerValues: %u", (uint32_t) values);
653 return la_state.trigger_mask;
658 la_state.trigger_mask = values;
659 log(
"--> setTriggerValues: %u", (uint32_t) values);
665 return la_state.read_count;
670 la_state.read_count = count;
675 return la_state.delay_count;
680 log(
"--> setDelayCount: %d", count);
681 la_state.delay_count = count;
686 return la_state.frequecy_value;
691 return la_state.delay_time_us;
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);
705 return la_state.is_continuous_capture;
710 la_state.is_continuous_capture = cont;
715 la_state.eventHandler = eh;
723 memset(
buffer_ptr->data_ptr(),0x00, la_state.max_capture_size*
sizeof(PinBitArray));
756 do_allocate_buffer = do_allocate;
761 if (capture_ptr!=
nullptr)
767 bool is_capture_on_arm =
true;
768 bool do_allocate_buffer =
true;
769 uint64_t sump_reset_igorne_timeout=0;
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";
797 return la_state.cmd4;
801 void write(uint8_t cmd, uint32_t number){
803 uint32_t toSend = htonl(number);
804 stream().write((
byte*)&toSend,
sizeof(uint32_t));
809 void write(uint8_t cmd,
const char* str){
812 stream().write(
"\x000",1);
819 switch(
sizeof(PinBitArray)) {
821 return (PinBitArray) cmd.
getPtr()[0];
823 return (PinBitArray) cmd.
get16(0);
825 return (PinBitArray) cmd.
get32();
860 write(0x01, description);
861 write(0x02, firmware_version);
863 write(0x20, la_state.pin_numbers);
865 write(0x21, la_state.max_capture_size);
869 stream().write(protocol_version, strlen(protocol_version)+1);
884 if (millis()>sump_reset_igorne_timeout){
888 sump_reset_igorne_timeout = millis()+ 500;
898 stream().write(device_id, 4);
906 case SUMP_GET_METADATA:
907 log(
"=>SUMP_GET_METADATA");
919 if (is_capture_on_arm){
928 case SUMP_TRIGGER_MASK:
929 log(
"=>SUMP_TRIGGER_MASK");
937 case SUMP_TRIGGER_VALUES:
938 log(
"=>SUMP_TRIGGER_VALUES");
944 case SUMP_TRIGGER_CONFIG:
945 log(
"=>SUMP_TRIGGER_CONFIG");
953 case SUMP_SET_DIVIDER: {
954 log(
"=>SUMP_SET_DIVIDER");
956 uint32_t divider = cmd.
get32();
957 log(
"-divider: %lu\n", divider);
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);
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);
996 log(
"=>UNHANDLED command: %d", cmd);
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