You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current implementation of digitalWrite() in the SAMD core incorrectly uses the DIRSET register to determine if a pin is configured as an output, which could lead to inconsistent behavior.
Technical Details
In wiring_digital.c, the function uses the following condition to check if a pin is configured as an output:
if ((PORT->Group[port].DIRSET.reg&pinMask) ==0)
{
// the pin is not an output, disable pull-up if val is LOW, otherwise enable pull-upPORT->Group[port].PINCFG[pin].bit.PULLEN= ((ulVal==LOW) ? 0 : 1);
}
However, according to the SAMD21 datasheet (section 23.8.3), DIRSET is designed to be a write-only register and does not guarantee it matches actual pin direction state. This will cause the function to sometimes incorrectly attempt configuring pull-up resistors even on pins configured as outputs.
Proposed Fix
Replace the DIRSET check with a DIR check, which correctly reflects the current pin direction state:
if ((PORT->Group[port].DIR.reg&pinMask) ==0)
{
// [rest of the code unchanged]
}
Impact Assessment
This bug has likely been present for some time without causing major functional issues, because
setting pull-up configuration on output pins has minimal effect (output drivers override pull-ups).
modifying DIRCLR and DIRTGL registers updates DIRSET so it aligns with DIR.
Testing shows DIRSET tracks DIR even under circumstances not guaranteed by the datasheet
While not a high impact issue, it's technically incorrect and could potentially cause subtle issues in certain edge cases or confuse developers examining the behavior of the function.
The text was updated successfully, but these errors were encountered:
jacoblgit
added a commit
to jacoblgit/ArduinoCore-samd
that referenced
this issue
Mar 2, 2025
Replace DIRSET with DIR register when checking if a pin is
configured as output in digitalWrite(). DIR is the designated
register for reading current pin direction state.
According to the SAMD21 datasheet, DIRSET is designed as a
write-only register without guaranteed read behavior, while
DIR explicitly represents the current direction state.
Fixesarduino#727
Bug Description
The current implementation of
digitalWrite()
in the SAMD core incorrectly uses the DIRSET register to determine if a pin is configured as an output, which could lead to inconsistent behavior.Technical Details
In
wiring_digital.c
, the function uses the following condition to check if a pin is configured as an output:However, according to the SAMD21 datasheet (section 23.8.3), DIRSET is designed to be a write-only register and does not guarantee it matches actual pin direction state. This will cause the function to sometimes incorrectly attempt configuring pull-up resistors even on pins configured as outputs.
Proposed Fix
Replace the DIRSET check with a DIR check, which correctly reflects the current pin direction state:
Impact Assessment
This bug has likely been present for some time without causing major functional issues, because
DIRCLR
andDIRTGL
registers updatesDIRSET
so it aligns withDIR
.DIRSET
tracksDIR
even under circumstances not guaranteed by the datasheetWhile not a high impact issue, it's technically incorrect and could potentially cause subtle issues in certain edge cases or confuse developers examining the behavior of the function.
The text was updated successfully, but these errors were encountered: