Thank you for that. There is the gpio_dump_io_configuration() but unnfortunately is is designed to stream to stdio which is a concept hat does not exist on the Arduino so I couldn't use that. I hadn't considered using gpio_io_config_t. I added your function to my test sketch.
So at the start when pins are set to input_pullup it returns:
--------------
pin 32:
input 1
output 0
output open drain 0
pullup 1
pulldown 0
--------------
So far that looks as might be expected. The pin is in input mode with pull-up enabled. Next, when the pins are switched to output using pinMode() I get:
--------------
pin 32:
input 1
output 1
output open drain 0
pullup 0
pulldown 0
--------------
That is starting to look a little strange. The pin is in BOTH input and output mode at the same time.
For the final test switching using registers the result is:
--------------
pin 32:
input 0
output 1
output open drain 0
pullup 0
pulldown 0
--------------
Writing to the register switches on output as expected but this time input is disabled. Also to note is that regardless of whether pinMode() or writing to registers is used for switching to output mode, the pull-ups evidently do get disabled.
I am showing the result for just one pin here, but all 8 switched pins behaved exactly the same.
So does this mean that pinMode() is actually switching to input_output mode? I reversed the order of the two output tests and got the same result, so its not just a case of pinMode() not clearing the input setting. It is actively setting both input and output modes on.
I am unsure at this point but it doesn't seem possible to turn on input_output mode by writing to GPIO_ENABLE_W1TS_REG or GPIO_ENABLE_W1TC_REG because either a bit is set or its cleared. However, it can be done using the gpio_io_config_t object.
I added another couple of tests doing just that the result can then be correctly read with digitalRead(). It now shows the output pin bits turned on rather than all zeroes.