Data acquisition/Logic Analyzer

The quickest dynamic loop I was able to come up with does take 8 clock cycles per read (of 10000 reads!):

// C.23 = D7
Pio *p = digitalPinToPort(7);

void setup() {
  uint32_t i,A[10000],t0,t1;

  Serial.begin(57600);
  while(!Serial){}
  
  pinMode(7, INPUT);

  t0=SysTick->VAL;
  for(i=0; i<sizeof(A)/sizeof(A[0]); ) {
    A[i++] = p->PIO_PDSR; 
  }
  // 80012 => 8 clock cycles per read
  t1=SysTick->VAL;
  
  Serial.println( ((t0<t1)?84000+t0:t0)-t1 );
  Serial.println();
}

void loop() {}

Copying in the 10000 statements does take only 3 clock cycles per read (30008 for 10000):

// C.23 = D7
Pio *p = digitalPinToPort(7);

#define T(stmt) stmt; stmt; stmt; stmt; stmt; stmt; stmt; stmt; stmt; stmt;

void setup() {
  uint32_t i,A[10000],t0,t1,*a=&A[0];

  Serial.begin(57600);
  while(!Serial){}
  
  pinMode(7, INPUT);

  t0=SysTick->VAL; 
  T(T(T(*a++ = p->PIO_PDSR)))
  T(T(T(*a++ = p->PIO_PDSR)))
  T(T(T(*a++ = p->PIO_PDSR)))
  T(T(T(*a++ = p->PIO_PDSR)))
  T(T(T(*a++ = p->PIO_PDSR)))
  T(T(T(*a++ = p->PIO_PDSR)))
  T(T(T(*a++ = p->PIO_PDSR)))
  T(T(T(*a++ = p->PIO_PDSR)))
  T(T(T(*a++ = p->PIO_PDSR)))
  T(T(T(*a++ = p->PIO_PDSR)))
  // 34(10), 304(100), 3008(1000), 30008(10000) => 3 clock cycles per read
  t1=SysTick->VAL;
  
  Serial.println( ((t0<t1)?84000+t0:t0)-t1 );
  Serial.println();
}

void loop() {}

The Arduino IDE compiler gave up on compiling single line "T(T(T(T(*a++ = p->PIO_PDSR))))", so I just copied 10 lines generating 1000 reads.

10000 32bit values is 40000 bytes, so you could read slightly more than double of that into Arduino 96KB memory, eg. 20000 values in 60000 clock cycles (of 11.9ns) or 714μs in total. So Arduino Due can be a short time span (less than a millisecond) 84/3=28MHz, 32 channel logic analyzer. That is even better than the 100MHz logic analyzer mentioned above, that can do 16CH@16M MAX Sample Rate while Due can (for less than a millisecond) 32CH@28M ...

This definition

unsigned char *a = (unsigned char *)&A[0];

does need 3 clock cylces per read

*a++ = p->PIO_PDSR

as well, and

a[0] = 0x01234567;
a[1] = 0x89ABCDEF;

results in a[0]=0x67 and a[1]=0xEF. With that change you can read 3ms with 8CH@28M into Arduino Due ram.

Hermann.