digitalWriteFast, digitalReadFast, pinModeFast etc

This talk about "PWM disable" in digitalWrite isn't about actually disabling the timers. It is merely about clearing a bit which causes the timer's PWM generation to essentially "take over" a pin, if it's configured as an output.

Obviously analogWrite() sets that bit, and it also make the pin an output. Until that bit is cleared, it doesn't matter if the pin is configured as high or low the normal way (writing to the PORTx register), because it's being controlled by the PWM waveform generator in the timer.

Currently, digitalWrite() clears that bit. This is nice, because if a pin were previously "written" using analogWrite(), without clearing this bit, digitalWrite() would have no effect. That might be pretty confusing. Of course, the clearing of that bit is pretty expensive in terms of speed, as it takes extra time, and it even burdens the non-PWM-capable pins with a check to know if the pin is PWM capable.

If digitalWrite() didn't clear that bit, then some other way would be needed, and every discussion I've heard on this issue seems to suggest using pinMode(). That ends up raising a lot more questions, like if a separate mode for PWM would be defined, or if the user would just configure it to OUTPUT mode again, even though they already had previously configured it to OUTPUT mode?

Ultimately, there are at least 2 important issues:

1: Is the digitalWrite, analogWrite, pinMode API a "thin" layer that is designed for performance, yet exposes hardware details? Or is it more "opaque", providing novices with conceptual simplicity and fully insulating them from painful hardware quirks? It's a classic performance vs usability trade-off.

2: Either way, what should the API really be? If that's anything other than what it currently is, would short term pain of breaking compatibility be worthwhile for long term performance or usability gains?

Today, regarding #1, I believe the API somewhere in between, achieving neither great performance nor excellent usability. We've all heard about the performance issues, and removing the PWM disable is intended to improve speed.

Usability-wise, even though digitalWrite handles this PWM disable, it fails to insulate users from other hardware quirks, mainly the pullup resistors (which I believe is pretty horrible for novices, since they get tricked into thinking they have a "hardware problem" when their code seems to be working, but the pin isn't able to do much more than drive a multimeter, where correct voltage checks further reinforce the notion their hardware is damaged, all because they forgot pinMode OUTPUT). digitalWrite() also doesn't do a bounds check on the pin number, so novices aren't protected from mistakes like a loop clearing all pins being "off by one" or "way off". You might also wonder why analogWrite switches the pin to OUTPUT mode automatically, but digitalWrite doesn't? There's also bug #146, which is rare, but extremely difficult when it does strike. digitalWrite() seems simple and easy to use, but it leaves plenty of "gotchas" for unsuspecting users.

People who teach classes and workshops have a great interest in the simplicity of the API, and having a coherent model free of low-level hardware quirks. People who built robots and other more complex projects care deeply about performance.

So this all gets into a lot of talk about the conceptual model this API is supposed to provide for users. Unfortunately, it's probably far too late to really throughly consider that model, because many thousands of people have written mountains of code that depends on the current behavior.

But anyway, that's what's meant by this "PWM disable" stuff. It's not about actually reconfiguring the timer (and each timer generates PWM for 2 or 3 pins, so you wouldn't do that anyway for a single pin). These issues about the API, conceptual/teaching models, performance and backwards compatibility are quite difficult. So far, the only easy answer has been to put off making any decisions.