-
-
Notifications
You must be signed in to change notification settings - Fork 120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding digitalToggle to core? #130
Comments
Sounds like a good additoin. I think it belongs to the ArduinoCore-API repo, though, so I'm moving it there. As for AVR, IIRC you can also toggle a pin by writing a 1 to the |
Implementation for ESP32For ESP32 platform I have not yet tested code. esp32-hal-gpio.h int digitalToggle(uint8_t pin); esp32-hal-gpio.c extern int IRAM_ATTR __digitalToggle(uint8_t pin)
{
uint32_t val = 0;
uint32_t mask = 0x01;
if (pin < 32)
{
mask = (0x01 << pin);
val = (GPIO.in & mask) != 0;
if (val) GPIO.out_w1tc = ((uint32_t) mask);
else GPIO.out_w1ts = ((uint32_t) mask);
return (val == 0);
}
if( pin < 34)
{
mask = (0x01 << (pin - 32));
val = (GPIO.in1.val & mask) != 0;
if (val) GPIO.out1_w1tc.val = ((uint32_t) mask);
else GPIO.out1_w1ts.val = ((uint32_t) mask);
return (val == 0);
}
return 0;
}
extern int digitalToggle(uint8_t pin) __attribute__ ((weak, alias("__digitalToggle"))); |
Nice idea. Here is a small optimization opportunity: return ((*out & bit) != 0); The compiler should issue a “load” instruction for uint8_t state = *out;
state ^= bit; // invert bit
*out = state;
SREG = oldSREG;
return ((state & bit) != 0); I would expect this to save two CPU cycles, although I did not test. The compiler cannot perform this optimization itself because the |
That was my first contribution here on github, as I just had the same idea others have had. I came here from the Arduino forums. My only contribution is to make it a void return so it operates otherwise like digitalWrite(). There is an AVR specific version that would write a 1 to the portInputRegister(port) as per Atmel, writing a 1 to PINx will toggle that pin, but the XOR operation is portable to other microcontrollers.
|
Description
The Arduino core has a digitalWrite() and a digitalRead() function.
In many sketches there is a need to toggle a pin, either for a blinking LED or a clock pin for swSPI etc.
There are two typical ways to invert a pin - see code below
The latter one is slower as it redo a lot of "pin math", so I implemented a version of digitalToggle() for AVR.
Attached test sketch shows the gain compared to the two methods.
Results test on UNO
The gain of toggle returning state is 46% resp 16%
The gain of toggle returning NO state is 52% resp 26%
Imho these gains are interesting, esp for clocking data
Implementation for AVR
Arduino.h
wiring_digital.c
Note: a no state returning version is straightforward given the above code.
Test sketch
digitalToggle.zip
The text was updated successfully, but these errors were encountered: