First off, this is a very preliminary performance test. I had a gut feeling that I wouldn’t need my 800Ms/s logic analyzer; so I plugged in my 100Ms/s unit instead. I wrote a very simple sketch using DigitalOut that did a led =1, followed by a led =0 inside loop() for the m7 and m4.
Performance was the same for both processors, but pulses were anywhere from 170 to 250ns. I even observed a sequence down to the 100ns width, but only on m7. But, here’s the bad news. Both processors would stop processing randomly from ~3.5 to >10us. The >10us dropouts would occur on both processors at about the same time. These are huge dead zones.
I repeat, this is a first try test and is not intended for precise measurements — yet.
But, I thought it would be of interest to publish this first test.
There is a configurable mode for this mcu where it goes into low power mode so may be that, or something with mbed os.
Overall these high level functions don’t tend to be very optimized though.
I don’t think low power mode is the issue. I’m pulsing the outputs as fast as possible using the high level DigitalOut command. I’m thinking that the HAL and MBED layers aren’t well optimized yet. My next attempt is going to be using the HAL gpio commands. This should decrease output pulse width, but I’d be surprised if it reduces the drop outs.
Hmm I am not sure if that may be the case though to be honest, because I managed to achieve reading and writing down analog values at really high sample rates which I wouldn’t expect to be possible otherwise (12msps at smaller resolution)
Thanks. By the way, if you want to find out how much time in microseconds passed, you can do micros() at beginning and end of the code to find out. Though this is not fully accurate, and with fast functions, you’ll need to use a loop and repeat them multiple times, to get any useful numbers.
I really wish I could count cpu cycles. I use this technique with my other development boards and at 600Mhz, I have a 1.7ns cycle time. Very useful. Using an LA to measure the time between an output set and output clear should be useful, but for the Giga, I’m beginning to question the validity of LA timing measurements.
I’ve been measuring how long your “CatchADCValue()” functions take to process, and yes they seem to taking about 200ns, which is incredibly fast. I’m very impressed with the results and with your code, BUT, there’s still that pesky dead zone. It’s more than I was expecting.
More testing is required!
I really do enjoy this stuff
The catch adc value only catches it if it’s ready by the way, so it depends on the adc speed mainly, and due to physical limitations it’s not possible to push the clock speed much further without loosing range. If you want to test just reading the register, would have to remove the while loop.
You can get the adc to double the speed too, but that really starts compromising the range
To get more consistency I recommend going down to 14/12 bit resolution.
But I also made a library called gigascope which can be combined with this one, it can both plot data, and calculate frequency and duty cycle.
You should be able to. Systick (24bit down counter) counts at CPU frequency (usually.)
(24 bits is a bit too few in many cases, for fast CPUs.)
And most M4/M7 ARM implementations will have the "Data Watchpoint and Trace" unit that includes a 32bit CPU tick counter. (sample usage, for an M4-only chip: https://github.com/WestfW/Duino-hacks/blob/master/systick_delay/systick_delay.ino )
westfw, thanks for pointing this out me. Very useful indeed. On the other micro-controller that I’m very familiar with, ARM_DWT_CYCCNT gets the current cpu cycle count.
Millisecond tick interrupts we’re expected. Most of the timing blocks I saw were about 1us that I assumed were tick interrupt processing. What surprised me were the blocks in the 10us range. I wasn’t expecting that.
I am new to this forum and just bought the Giga and the Due board. I am now 80 years old and long retired. I mainly developed hardware in the 1980s. That was still TTL. I also used this to do tests with the Atmega 328P, which was still all assembler. Later I mainly used the Altera EDLDs and then the FPGAs. Now I still use the DE0-nano-Soc module to control Fischertechnik and lego. That is with verilog as the programming language.
I have now also done some testing with the UNO, DUE and Giga boards to measure timing and interrupts and to see how fast they are. I use the PicoScope 2406B, a 4ch 50 Mhz scope and sampling time up to 1ns. The scope has a very large buffer that allows me to monitor the interrupts for longer periods of time. My first observation, all 3 boards have an interrupt of 1 msec. The Uno is 1024ns but this does not matter much. I use a simple program to record the digitalWrite. This is the same program for all 3 boards.
/*
Arduino Giga Burst output on D11
note: every 1ms there is an interrupt duration ~4.1 us followed by 2 smaller interrupts ~2.2us and ~0.7us
*/
void setup() {
pinMode(11, OUTPUT);
digitalWrite(11, LOW);
}
void loop() { // peiode 245.7 ns 4.069 Mhz
while (1) {
digitalWrite(11, HIGH); // high time: Giga 129.2 ns
digitalWrite(11, LOW); // low time: Giga 116.5 ns
}
}
The Giga has an interupt every 1ms and it takes 4.1us. But there is a 2nd interupt that comes 88us later and takes 700ns. The distance between these two interrupts is always the same. However, there is a third interrupt and it takes 2.1us but it does not set a fixed distance relative to the 2 others. If you are unlucky, this 3rd interrupt can coincide with one of the others. This may explain why you would exceptionally measure a higher interrupt time. I can selectively trigger on a window boundary so I always have perfect triggering relative to the desired interrupt type 1, 2 or 3
Two digitawrites (1,0) have a period of 245.7 ns where one is 116.5 ns the other is 129.2 ns.
I have more cyclus times but have yet to summarize them.
Results will still be comme on my Flick web: fotoopa
I have only just started with these new Arduino boards and also have to learn the C language.... and yes at my age of 80 this is going to be a little slower.
I suspect that the second ~1ms interrupt is the USB keepalive?
That could be, at least it is repetitive. I have no experience with this hardware yet.
I would like to use a fast IO write on the Giga. I've seen that you've already done this for the SAMD. Due to my lack of C++ knowledge I fail to execute register writes directly instead of the digitalWrite function on the Giga. If you could convert it for me I would be very thankful to you. I have been searching for this syntax for a few days but my not succeeding. With the Arduino Due there is the difference in speed is very large.
it looks like a lot of the pin-mapping stuff is abstracted behind MBed, and then the ST libraries, so code similar to what I did for SAMD will be difficult and annoying