Skip to content

The pinMode(pin,OUTPUT) can't initialize the pin in HIGH state on a Nano Every #143

Open
@drf5n

Description

@drf5n

void pinMode(uint8_t pin, PinMode mode)
{
uint8_t bit_mask = digitalPinToBitMask(pin);
if ((bit_mask == NOT_A_PIN) || (mode > INPUT_PULLUP) || isDoubleBondedActive(pin)) return;
PORT_t* port = digitalPinToPortStruct(pin);
if(port == NULL) return;
if(mode == OUTPUT){
/* Configure direction as output */
port->DIRSET = bit_mask;
} else { /* mode == INPUT or INPUT_PULLUP */

On an Uno, you can use these lines to switch directly from INPUT_PULLUP to HIGH:

digitalWrite(pin,HIGH); // enable pullup
pinMode(pin,OUTPUT); // switch to OUTPUT HIGH

On a Nano Every, those commands switch instead to an OUTPUT LOW

See the discussion at:

https://forum.arduino.cc/t/how-to-set-output-high-without-pulse/1364909

The documentation at https://docs.arduino.cc/learn/microcontrollers/digital-pins/ says it should switch directly to HIGH:

Consequently, a pin that is configured to have pullup resistors turned on when the pin is an INPUT, will have the pin configured as HIGH if the pin is then switched to an OUTPUT with pinMode().

Per this chunk of code, it looks like half of the issue was considered:

/* Input direction */
} else {
/* Old implementation has side effect when pin set as input -
pull up is enabled if this function is called.
Should we purposely implement this side effect?
*/
/* Get bit position for getting pin ctrl reg */
uint8_t bit_pos = digitalPinToBitPosition(pin);
/* Calculate where pin control register is */
volatile uint8_t* pin_ctrl_reg = getPINnCTRLregister(port, bit_pos);
/* Save system status and disable interrupts */
uint8_t status = SREG;
cli();
if(val == LOW){
/* Disable pullup */
*pin_ctrl_reg &= ~PORT_PULLUPEN_bm;
} else {
/* Enable pull-up */
*pin_ctrl_reg |= PORT_PULLUPEN_bm;
}
/* Restore system status */
SREG = status;
}
}

But the pinMode code is where the problem happens. Instead of always assuming LOW, it should use the state on the pullup to set the level before enabling the OUTPUT direction in order to match the documentation and the behavior on the '328 and '2560.

See also #86

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions