I found out that the libraries of the ATmega4809 allow the statement: digitalWrite(pin, CHANGE);
I can't really remember what Arduino Reference has to say about it, so I went looking. And now I have the question: Where to find it? And directly behind that: Where does Arduino expect any user to search for things like this? (Especially users using something else than ATmega328.)
Sidenote: if this exists in the 4809, and the 328 also has hardware that enables digitalWrite(pin, CHANGE); why has it NOT been implemented in the 328?
Another sidenote: some documentation uses the term TOGGLE. This gives an impression of two discrete states. This would give a better representation of the function of the statement.
Maybe a user manual for Arduino Reference is needed?
4809 datasheet and the board package
From wiring_digital.c
void digitalWrite(uint8_t pin, PinStatus val)
{
/* Get bit mask for pin */
uint8_t bit_mask = digitalPinToBitMask(pin);
if(bit_mask == NOT_A_PIN || isDoubleBondedActive(pin)) return;
/* Turn off PWM if applicable */
// If the pin that support PWM output, we need to turn it off
// before doing a digital write.
turnOffPWM(pin);
/* Assuming the direction is already output !! */
/* Get port */
PORT_t *port = digitalPinToPortStruct(pin);
/* Output direction */
if(port->DIR & bit_mask){
/* Set output to value */
if (val == LOW) { /* If LOW */
port->OUTCLR = bit_mask;
} else if (val == CHANGE) { /* If TOGGLE */
port->OUTTGL = bit_mask;
/* If HIGH OR > TOGGLE */
} else {
port->OUTSET = bit_mask;
}
/* 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;
}
}
Note:
I do not know which documentation you have found.
I make a distinction between technical documentation and user manuals. Are the .h file technical documentation? It doesn’t feel like that to me, they are the inner guts of the system. Manuals explain, that is to say, good manuals do.
digitalWrite() is defined with a second parameter PinStatus which is really designed for attachInterrupt(). So it has HIGH and LOW as you expect, but also CHANGE which makes sense for attachInterrupt(), less so for write and read. And FALLING and RISING are just not applicable to read or write.
I can see that they wanted to re-use existing definitions and avoid creating new ones, but it leaves a bit of a mess.
I browsed a bit through that ArduinoCore-API on GitHub. Apparently it is the source of the files I found on my computer, but it doesn't give more info.
I’ve used my Nano Every for some time without knowing that digitalWrite(pin, CHANGE) was a possibility. Now I wonder: what more info do I miss out on because of the quality of the documentation? Is every user expected to browse through all the .h files to find out things that could have been in the Arduino Reference pages?
The quality of the documentation is discussed at least since 2009. You have a point about there is lacking a lot but documentation has improved over the years.
A quote of one of my professors was "in case of conflict between documentation and code, code always wins", and it is still true. If you want to know the details, the code is leading.
Furthermore there are thousands of libraries around, so studying the .h files is not an option. Better start high level, what do I need (requirements) and how can these things be implemented, are there libraries (and do they meet my needs) or tutorials that are close.
And if questions remain, there is always the forum to ask .
Besides missing documentation, there is also a missing functionality. That is why libraries are made. E.g. the digitalToggle() mentioned before. I combined a number of digitalWrite() related in my OUTPIN library, (performance optimized for AVR).
The documentation of libraries differ, as do maintenance, I have good, bad and ugly libraries myself
Writing a 1 to the PIN register is used to toggle an output in the 328. I'm not certain it is any better documented by Arduino in basic pin i/o documentation than digitalWrite(pin,CHANGE) is for the Nano Every.
The way I understand the intentions of Arduino, the elements of the Arduino language (digitalWrite, analogRead, etc) are meant to work in all supported boards, and work the same in these boards, producing both flexibility and portability. At the same time Arduino wants to make hardware properties accessible through it's language. Ideally, the user doesn't need to know the specifics of the board to use the Arduino language.
The Arduino language is a layer over C++. The user is free to use C or C++ to achieve more on the software side.
To achieve more on the hardware side the user needs to acquire knowledge of the board and it's processor (interrupts, analog peripherials etc). But using this knowledge immediately negates the flexibility and the portability.
Yes I'm able to write a 1 to the Input Register using direct register access, but I think it's in line with the intentions of Arduino to offer this possibility within it's language.
This is sort-of the result of the creation of the PinStatus enum, which merges some of the states from possible output states and possible interrupt states, as part of the implementation of the "avr api" (common application programmer interface; device independent.)
It has problems, but it doesn't look like it will be changed. See:
Note that the avr core was never converted over to the new api definitions.