Thanks for correcting me on 1/, I did retest with 0x90 vs 0x80 and there was no difference in timing. I did measure from "adc_init()" until after the 1st block was converted "while(obufn==bufn);", 35822 clock cycles in both cases.
Let me clarify on 2/, I did not test with laser light yet, as said before I just have a connection from D7 to A0 for the sketch I used. I did work on this yesterday afternoon in a cafe where I had to wait for 2 hours
I realized that the German sentence "Wer mißt misst Mist" ("Who measures measures crap") partially applies to my reported measurements. D21 did consist of 21 "cnt++" statements, that is right. But that did not translate to 21 clock cycles, but 126 beacuse "cnt++" gets optimized compiler to this:
6 clock cycles
ldr r7, [r3]
adds r7, r7, #1
str r7, [r3]
I verified that by using 100 "t=SysTick->VAL" statements as D21, they had same effect and took 125 clock cycles:
1.25 clock cycles
ldr r3, [r2, #8]
I remembered that somebody said "nop" would take exactly 1 clock cycle, but even that is not true! A big sequence of 888 nops takes 1000 clock cycle:
9/8=1.125 clock cycles
nop
Because 5/4 seemed easier than 9/8 I did measurements based on 100 "t=SysTick->VAL"s in a D21, see bottom for diff to previous posted sketch (as said you can verify with only having a Due and a D7-A0 connector cable yourself) and the new sketch attached as well.
Summary from the new measurements (with clock timing control and generated assembler control [copy out IDE compile command that compiles sketch, remove the trailing "-o ..." and add "-S"], both is important) that a single "D21" being the time needed to get one full ADC conversion is 125/126 clock cycles. That is loooong for measuring speed of light at home.
Let me add some more measurments I did. While a ADC cycle takes 125 clock cycles, in a sketch with absolutely reproducible setup as with D7-A0 connector I was able to get a picture of the rising edge at 1.25 clock cycle or 15ns timing resolution!
I did that by adding a single 1.25 clock cycle statement D1 before setting D7 to HIGH until I found the rising edge. So I had to run many sketches, and I did run each several times to see that the reported values are reproducible and stable. This was a sample line reported:
4 2 2 2 1007 4095 4095 4095 4095 4095
So setting D7 to HIGH with a single port statement "p->PIO_SODR = b7;", the rising edge takes 15ns even if looking at the big step from 1007 to 3916 only.
I have created a small laser transmitter and sensor testbed to measure the effect of real laser instead of setting a pin to HIGH on the Due:
Last let me say that I have not investigated DMA SPI with 42MHz yet, the 2 clock cycle resolution of measurements for a single bit sound promising.
What I found is a very simple method to record all 32 bits of port b every 3 clock cycles, but only 6 times in total. While 6 timestamps that can be taken does not sound much, the timeframe of (6-1)311.9ns=178.5ns should be more than enough for measuring speed of light at home, because light travels 54m(!) in that time.
This is the simple script, no DMA, just storing port value into local(!) variables, and "-O3" compilation:
// C.23 = D7
Pio *p = digitalPinToPort(7);
void setup() {
uint32_t b,a1,a2,a3,a4,a5,a6,a7;
uint32_t t0,t1,b7 = digitalPinToBitMask(7);
Serial.begin(57600);
while(!Serial){}
pinMode(7, INPUT);
t0=SysTick->VAL; // 1
a1 = p->PIO_PDSR; // 7
a2 = p->PIO_PDSR; // 10
a3 = p->PIO_PDSR; // 13
a4 = p->PIO_PDSR; // 16
a5 = p->PIO_PDSR; // 19
a6 = p->PIO_PDSR; // 22
/*
a7 = p->PIO_PDSR; // 26
*/
t1=SysTick->VAL;
Serial.println( ((t0<t1)?84000+t0:t0)-t1 );
Serial.print(a1,HEX); Serial.print(",");
Serial.print(a2,HEX); Serial.print(",");
Serial.print(a3,HEX); Serial.print(",");
Serial.print(a4,HEX); Serial.print(",");
Serial.print(a5,HEX); Serial.print(",");
Serial.print(a6,HEX); Serial.print(",");
Serial.print(a7,HEX);
Serial.println();
}
void loop() {}
Just for demoing this program I connected D7 (now digital INPUT pin) with GND first, did run sketch, then connected it do 3.3V pin and ran sketch again. The bit flip can be seen in Serial Monitor output, 7F7... vs 7FF...:
22
7F7FFFFE,7F7FFFFE,7F7FFFFE,7F7FFFFE,7F7FFFFE,7F7FFFFE,0
22
7FFFFFFE,7FFFFFFE,7FFFFFFE,7FFFFFFE,7FFFFFFE,7FFFFFFE,0
So if one can arrange an experiment to happen inside the range of 15 clock cycles one gets all 32 digital bit settings for port b at 3 clock cycle resolution! I hope measurements with laser in testbed described above will allow to do exactly that, with 1 or 2 laser sensors.
Hermann.
$ diff sketch_jun11b.ino.posted sketch_jun11b/sketch_jun11b.ino
7a8
> uint32_t t;
10c11,17
< #define D21 D(D(D(D(cnt++)))) D(D(cnt++)) cnt++;
---
> #define D1 t=SysTick->VAL;
> #define D2 D(D1)
> #define D4 D(D2)
> #define D8 D(D4)
> #define D16 D(D8)
> #define D32 D(D16)
> #define D21 D(D32 D16 D2)
32a40
> uint32_t t0,t1;
55c63,64
< D21 D21 D21 D21
---
> t0=SysTick->VAL;
> D21 D21 D21 D21
56a66
> t1=SysTick->VAL;
66a77
> Serial.println( ((t0<t1)?84000+t0:t0)-t1 );
$
sketch_jun11b.ino (1.9 KB)