La gestione diretta delle porte e' abbastanza semplice. Il registro DDR indica la direzione della porta (0 input, 1 output).
Il registro PORT indica lo stato della porta (se di input, 1 attiva il pullup. Se di output 1 porta l'output alto, 0 basso).
PIN contiene lo stato della porta (1 se alto, 0 se basso).
Quindi SCALE_CLK_DDR |= _BV(CLK_PIN_BIT);
va a fare un or tra lo stato del registro DDRD e 100 (1<<2==_BV(2)). Imposta il pin 2 di arduino come output.
E' la stessa cosa che scrivere pinMode(2, OUTPUT) oppure pinMode(CLK_PIN_BIT, OUTPUT);
SCALE_CLK_OUTPUT_PORT &= ~_BV(CLK_PIN_BIT);
va a fare un and tra il registro PORTD e 011 (0<<2==~_BV(2)), quindi mette il pin 2 allo stato basso.
Stessa cosa che scrivere digitalWrite (CLK_PIN_BIT, LOW);
Cose che, penso, gia' sai ma gia' che c'ero ho fatto un ripasso personale.
Per quanto riguarda l'invertire clock e dati, tutto e' possibile ma non 5 volte, di cui l'ultima accertandomi di tutto (anche perche' la riga era in prestito
).
Stavo ripensando al fatto che, per qualche motivo, in fase di boot gli i/o dell'atmega vengano messi come output. Se anche dovesse succedere, sarebbe per frazioni di secondo (esagerando diciamo 5 secondi).
Quando ho provato con la riga in prestito (sana), l'ho collegata, letto l'assorbimento sull'amperometro e staccato l'alimentazione. Sicuramente sono passati piu' di 5 secondi e la riga e' rimasta sana (ricollegandola al display assorbiva i canonici 15uA).
Quindi hanno un minimo di resistenza agli stress e, immagino, anche se tirate a bassa impedenza per alcuni secondi non dovrebbero soffrire.