[2.0.x] AVR: Atomic bit set and clear of upper pin ports without critical section#10502
[2.0.x] AVR: Atomic bit set and clear of upper pin ports without critical section#10502thinkyhead merged 2 commits intoMarlinFirmware:bugfix-2.0.xfrom ejtagle:bugfix-2.0.x
Conversation
|
Bueller? Bueller? I'm serious about the shorter commit messages. |
Marlin/src/HAL/HAL_AVR/fastio_AVR.h
Outdated
There was a problem hiding this comment.
I guess this change will only affect platforms that have a Port H and above. Is that correct?
Which AVR platforms have that many ports?
Marlin/src/HAL/HAL_AVR/fastio_AVR.h
Outdated
There was a problem hiding this comment.
Ah, so this actually toggles the bit? That's interesting!
There was a problem hiding this comment.
Does this work ok for all port addresses, both over and under 0x100?
|
@thinkyhead : This time i tried to make commit messages shorter. Sometimes i just don´t know how to resume them even more... :( Exactly as you said, this will only be used for PORTH onwards. I assume AVR mega 1280 / 2560 Yes, the pin toggle, according to the datasheet, works for all ports (http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf , section 13.2.2) And as a matter of fact, the TOGGLE macro was buggy, as it was reading from the INPUT (_RPORT) register, and writing to the INPUT (_RPORT) register. If you want to use a XOR to toggle a bit, you must use the OUTPUT (_WPORT) register.... 😮 |
Well, every genius has a blind spot…
And I modded
Looks like we dodged a bullet, then! |
Based on #10502 Co-Authored-By: ejtagle <ejtagle@hotmail.com>
The critical section can be dropped, saving 3 cycles per access. Also simplified pin toggling for all ports.
|
We may have a small issue with this... Please check out: #10512 |
|
That, unfortunately, is a avr-gcc bug. It is not being C99 compliant. I can reproduce the error with the following minimalistic example: #define DIO4_DDR a
#define DIO4_PIN 10
#undef _BV
#define _BV(b) (1<<(b))
#define SBI(n,b) n |= _BV(b)
#define _SET_OUTPUT(IO) SBI(DIO##IO##_DDR, DIO##IO##_PIN)
#define SET_OUTPUT(IO) _SET_OUTPUT( IO )
#define CONTROLLER_FAN_PIN 4 //hello
uint8_t a = 0;
SET_OUTPUT(CONTROLLER_FAN_PIN); /*Set pin used for driver cooling fan */ |
|
if it is an avr-gcc bug and not Arduino IDE how does it compile on PlatformIO (Travis)? |
|
Maybe is dependant on the Arduino AVR-GCC version ? ... To be honest, i had no problems compiling on Arduino, but... Let´s check
And all of them are disabled on most configurations, so they don´t trigger the problem. |
|
And i tried, and the only one that creates problems seems to be |
Commit MarlinFirmware#10502 has an upper case V as the macro parameter, and thus must have one where it is used.
Based on #10502 Co-Authored-By: ejtagle <ejtagle@hotmail.com>
On AVR, writing to the read register of a port allows to perform an atomic pin toggling without using a critical section.
This saves 3 cycles per access to those upper ports and reduces interrupt processing latency, improves speed and reduces program size.
Also simplified pin toggling for all ports (no need to read before writing as it was done before)
Quoting AVR datasheet:
The following was the code that was generated before this PR, and after applying it:
Clear port bit
Set Port bit