Encouraged by the previous post, I started writing a bit more code based on C++ features such as templates and namespaces, in the form of an Arduino library (compatible with it, not depending on it):
Things to point out:
Less #defines (none so far), I turned bitRead() and bitWrite() into template functions (getBit and setBit), so that they can be used with 1..4 byte ints, just as the macros.
The Port class is inside a new “Jee” namespace, so there is no conflict with the existing Ports library.
Atomic access hasn’t been solved. Some of this won’t work if I/O pins get changed by interrupt code. I’m hoping to solve that at a higher level.
There are compatibility definitions for pinMode(), digitalRead(), and digitalWrite() using the normal Arduino pin numbering conventions (only Duemilanove so far). These are in their own namespace, but can also be used without any qualifiers by adding “using namespace Jee::Arduino;” to the sketch.
Totally incomplete stuff, untested, and not 100% compatible with Arduino in fact.
The other thing I want to explore, is to treat the choice of what a pin does as a pin initialization mode. Hence the enum with Mode_IN .. Mode_PWM definitions. The underlying code is PortBase::modeSetter(), but it hasn’t been written yet. It’s all steamy hot vapor for now.
Update – I’ve placed the code in subversion, but the API is going to be in flux for a long time.
Update #2 – Atomic access is actually better than I thought. With constant pin numbers, setBit() will use the cbi/sbi instructions, which are atomic.
Does the compiler optimize away the right-shift operation in the body of getBit()? If not, this should be more efficient with constant bit numbers and especially in AVRs that don’t have a barrel shifter:
return (byte) ((v & 1<<bit) != 0);
Or even only guarantee a non-zero result for set bits and leave the comparison to the caller, if it needs it:
return (byte) (v & 1<<bit);
Good point. I haven’t checked the generated code. I considered this – wanted to get a 0/1 result out of getBit(). Perhaps adding a testBit() which uses that last simplest expression would be an idea.
I’ve seen people use “!!” (not-not) to get a 0/1 response out of some expression. I don’t know how it compares to != 0, though — I need to check out the generated code.