As I wondered in the thread:
Adafruit_ILI9341 and SPI library issues on GIGA board - Hardware / GIGA R1 - Arduino Forum
Is there a faster version of digitalWrite for these boards.
Does anyone have a version that works well?
So I thought I would try a quick and dirty experiment, along the line I did for the UNO R4.
First attempt: I put the function directly into the sketch for ease of trying.
#include "pinDefinitions.h"
#define PIN 2
static inline void digitalWriteFast(uint8_t pin, PinStatus val) __attribute__((always_inline, unused));
//#include "digitalFast.h"
void setup() {
Serial.begin(115200);
Serial.println("\n\nTest");
while (!Serial && millis() < 5000)
;
pinMode(PIN, OUTPUT);
}
void do_digitalWrite() {
uint32_t start_time = micros();
for (int i = 0; i < 1000; i++) {
digitalWrite(PIN, HIGH);
digitalWrite(PIN, LOW);
}
uint32_t delta_time = micros() - start_time;
Serial.print("digitalWrite: ");
Serial.println(delta_time, DEC);
}
void do_digitalWriteFast() {
uint32_t start_time = micros();
for (int i = 0; i < 1000; i++) {
digitalWriteFast(PIN, HIGH);
digitalWriteFast(PIN, LOW);
}
uint32_t delta_time = micros() - start_time;
Serial.print("digitalWriteFast: ");
Serial.println(delta_time, DEC);
}
void loop() {
do_digitalWrite();
do_digitalWriteFast();
delay(1000);
}
static GPIO_TypeDef * const port_table[] = { GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOE, GPIOF, GPIOG, GPIOH, GPIOI, GPIOJ, GPIOK };
static const uint16_t mask_table[] = { 1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7,
1 << 8, 1 << 9, 1 << 10, 1 << 11, 1 << 12, 1 << 13, 1 << 14, 1 << 15 };
static inline void digitalWriteFast(pin_size_t pin, PinStatus val) {
PinName hardware_port_pin = g_APinDescription[pin].name;
//uint16_t mask = 1 << (hardware_port_pin & 0xf);
uint16_t mask = mask_table[hardware_port_pin & 0xf];
GPIO_TypeDef * const port = port_table[hardware_port_pin >> 8];
if (val) port->BSRR = mask;
else port->BSRR = (uint32_t)(mask << 16);
}
It appears to be working and reasonably faster:
digitalWrite: 253
digitalWriteFast: 54
digitalWrite: 250
digitalWriteFast: 51
digitalWrite: 252
digitalWriteFast: 52
Or more zoomed in:
vs
I am not great on assembly language on these boards, but:
08040390 <_Z19do_digitalWriteFastv>:
8040390: b510 push {r4, lr}
8040392: f001 fe61 bl 8042058 <micros>
8040396: 4b11 ldr r3, [pc, #68] ; (80403dc <_Z19do_digitalWriteFastv+0x4c>)
8040398: 4a11 ldr r2, [pc, #68] ; (80403e0 <_Z19do_digitalWriteFastv+0x50>)
804039a: 4604 mov r4, r0
804039c: f9b3 3020 ldrsh.w r3, [r3, #32]
80403a0: f003 010f and.w r1, r3, #15
80403a4: 121b asrs r3, r3, #8
80403a6: f832 1011 ldrh.w r1, [r2, r1, lsl #1]
80403aa: 4a0e ldr r2, [pc, #56] ; (80403e4 <_Z19do_digitalWriteFastv+0x54>)
80403ac: 0408 lsls r0, r1, #16
80403ae: f852 2023 ldr.w r2, [r2, r3, lsl #2]
80403b2: f44f 737a mov.w r3, #1000 ; 0x3e8
80403b6: 3b01 subs r3, #1
80403b8: 6191 str r1, [r2, #24]
80403ba: 6190 str r0, [r2, #24]
80403bc: d1fb bne.n 80403b6 <_Z19do_digitalWriteFastv+0x26>
80403be: f001 fe4b bl 8042058 <micros>
80403c2: 1b04 subs r4, r0, r4
80403c4: 4908 ldr r1, [pc, #32] ; (80403e8 <_Z19do_digitalWriteFastv+0x58>)
80403c6: 4809 ldr r0, [pc, #36] ; (80403ec <_Z19do_digitalWriteFastv+0x5c>)
80403c8: f001 fdb1 bl 8041f2e <_ZN7arduino5Print5printEPKc>
80403cc: 4621 mov r1, r4
80403ce: 220a movs r2, #10
80403d0: 4806 ldr r0, [pc, #24] ; (80403ec <_Z19do_digitalWriteFastv+0x5c>)
80403d2: e8bd 4010 ldmia.w sp!, {r4, lr}
80403d6: f001 bded b.w 8041fb4 <_ZN7arduino5Print7printlnEmi>
80403da: bf00 nop
80403dc: 24000004 strcs r0, [r0], #-4
80403e0: 080576c6 stmdaeq r5, {r1, r2, r6, r7, r9, sl, ip, sp, lr}
80403e4: 080576e8 stmdaeq r5, {r3, r5, r6, r7, r9, sl, ip, sp, lr}
80403e8: 080576b3 stmdaeq r5, {r0, r1, r4, r5, r7, r9, sl, ip, sp, lr}
80403ec: 24001780 strcs r1, [r0], #-1920 ; 0xfffff880
Not sure if this will go anywhere but does show some promise.