digitalWriteFast, digitalReadFast, pinModeFast etc

Paul Stoffregen pointed out that these macros are not currently safe from issue #146 on the Megas. Conceptually what I have to add is something like

void inline atomicWrite( uint16_t address, unint8_t p, unint8_t v) {
  if (address < 0x20)     bitWrite(*address, __digitalPinToBit(p),v);
  else  {
    uint8_t register saveSreg = SREG;     
        cli;                                  
        bitWrite(*address, __digitalPinToBit(p), v);  
        SREG=saveSreg;
  }
}

#define digitalWrite(P, V) \
do {
  if (__builtin_constant_p(P) && __builtin_constant_p(V))   atomicWrite(digitalPinToPortReg(P),P,V);
    else  __digitalWrite((P), (V));         \
 }while (0)

Last night the compiler and I couldn't agree on the exact syntax. the Xcode editor I was using wouldn't help balance the last few }'s.

Surprisingly, this morning the Arduino IDE editor agrees with how I thought the }'s balanced. I broke it up by splitting out atomicWrite this morning but it seems obvious a cast of some sort is missing and I won't test it now.

Handling issue 146 will further diverge performance on ports above F, which already required more code. It struck me overnight that this MIGHT be a reason for continued existence of digitalWriteFast beyond implementation of faster digitalWrite in the core. After all, the vast majority of code I write does not turn the interrupt on. Worth some thought.

It also strikes me that I should probably create test code for whether issue 146 is solved. Maybe I can just add Tone to my current test programs, or something like that. I need something that will generate interrupts 10-1000 times per second, I think. If anyone understands how to write that, or can point me to a forum item I would appreciate that.