Currently, I am working on a very speed-constrained application using the Arduino Due to send data to my PC from a high-ish speed ADC (24-bit, 128kHz). Unfortunately, using the built-in libraries I was only able to sample from the ADC at ~44kHz, and it looks like there's a lot of dead time that isn't SPI or USB transactions. I was curious how much of that dead time was due to the overhead of the built-in Arduino libraries, so I did a test.
Here's the result on pin 53 using a digitalWrite (see code below) using nothing but HIGH and LOW digitalWrites to the pin involved:
As you can see from the scope trace, it takes about 2.24us to complete a digitalWrite (high or low). That's a LOT of time in real-time digital land (about 188 cycles with the Due's 84MHz clock).
And here's the result using a direct write to the port:
This takes about 23ns to complete a write (high or low), or 2 clock cycles. This is exactly what is specified in the SAM3X datasheet in Section 31.1 (it should take 2 clock cycles to do a register read or write). It's so fast my poor 50MHz scope can barely keep up.
In other words, I got a speedup of ~100x using direct writing to registers over using the Arduino's built-in libraries. I was actually so surprised by this I decided to post it here.
[EDIT: code]
void setup() {
// put your setup code here, to run once:
pinMode(53, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
/*
PIOB -> PIO_SODR = 1 << 14;
PIOB -> PIO_CODR = 1 << 14;
PIOB -> PIO_SODR = 1 << 14;
PIOB -> PIO_CODR = 1 << 14;
PIOB -> PIO_SODR = 1 << 14;
PIOB -> PIO_CODR = 1 << 14;
PIOB -> PIO_SODR = 1 << 14;
PIOB -> PIO_CODR = 1 << 14;
PIOB -> PIO_SODR = 1 << 14;
PIOB -> PIO_CODR = 1 << 14;
*/
digitalWrite(53, HIGH);
digitalWrite(53, LOW);
digitalWrite(53, HIGH);
digitalWrite(53, LOW);
digitalWrite(53, HIGH);
digitalWrite(53, LOW);
digitalWrite(53, HIGH);
digitalWrite(53, LOW);
digitalWrite(53, HIGH);
digitalWrite(53, LOW);
}