I think it is simpler that I initially thought, it was a good idea to look at arduino/wiring_digital.c where I found the definition of pinMode():
void pinMode(uint8_t pin, uint8_t mode)
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *reg, *out;
if (port == NOT_A_PIN) return;
// JWS: can I let the optimizer do this?
reg = portModeRegister(port);
out = portOutputRegister(port);
if (mode == INPUT) {
uint8_t oldSREG = SREG;
cli();
*reg &= ~bit;
*out &= ~bit;
SREG = oldSREG;
} else if (mode == INPUT_PULLUP) {
uint8_t oldSREG = SREG;
cli();
*reg &= ~bit;
*out |= bit;
SREG = oldSREG;
} else {
uint8_t oldSREG = SREG;
cli();
*reg |= bit;
SREG = oldSREG;
}
}
that was easily reversed to a "getter":
uint8_t getPinMode(uint8_t pin)
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *reg = portModeRegister(port);
if (*reg & bit) {
return OUTPUT;
} else {
volatile uint8_t *out = portOutputRegister(port);
if (*out & bit) {
return INPUT_PULLUP;
} else {
return INPUT;
}
}
}
this compiles but I can't test it now. I'm still not sure about the "oldSREG = SREG" trick and the CLI that are used in pinMode()