Fast digital I/O and software SPI with C++ templates

pYro_65:
I was initially trying to re-create the fastDigitalWrite macros as a template library so I could add in extra features. But I hit a wall as no matter how much I can write, I really don't know that much about arduinos internals, that's where your code comes in.

This is the only thread that i found mentioning templated digitalwritefasts .. so posting here.

There is already a very cool templated fastPins header here USB_Host_Shield_2.0/avrpins.h at master · felis/USB_Host_Shield_2.0 · GitHub

However, by default its syntax is different/object oriented, so a blink example would look like this:

#include <avrpins.h>

void setup() {
  P13::SetDirWrite();
}

void loop() {
  P13::Set();
  delay(1000);
  P13::Clear();
  delay(1000);
}

With a bit of preprocessor help, and partial template class specialization its easy to translate digitalWrite syntax to this syntax without creating any runtime overhead. Call this header digitalWriteFast3.h :

#include <avrpins.h>

template <class T, int N>
struct fast3_wrap_impl
{
    static T setmode() {
		T::SetDirWrite();
	} 
	static T write() {
		T::Set();
	}
};

template <class T>
struct fast3_wrap_impl<T, 0>
{
    static T setmode() { 
		T::SetDirInput();
	}
	static T write() {
		T::Clear();
	}
};

template <class T, int N>
void fast3_wrap_setmode()
{
    fast3_wrap_impl<T, N>::setmode();
}

template <class T, int N>
void fast3_wrap_write() { 
	fast3_wrap_impl<T, N>::write();
}

template <class T>
int fast3_wrap_read() { 
	return T::IsSet();
}

#define pinModeFast3(a, b) fast3_wrap_setmode< P##a , b>();
#define digitalWriteFast3(a,b) fast3_wrap_write< P##a , b >();
#define digitalReadFast3(a,b) fast3_wrap_read< P##a >();

After that, rewriting the loop example:

#include <digitalWriteFast3.h>

void setup() {
  pinModeFast3(13, OUTPUT);
}

void loop() {
  digitalWriteFast3( 13, HIGH );
  delay(1000);
  digitalWriteFast3( 13 , LOW ) ;
  delay(1000);
}

Feel free to modify and improve. I have not tested this beyond the simple blink, but i trust that as long avrpins.h does things correctly, it should be fairly safe to use.

I have verified that these digitalWriteFast3 calls resolve into single cbi/sbi instructions.

Maybe the author of the avrpins.h could add this template stuff in, as a user you would be able to use either syntax without thinking about it, and still get the same result.