// Magical TodBot incantation to set
// analog three to power and analog 2 to ground, from
// his (awesome) Bionic Arduino course at
// http://todbot.com/blog/bionicarduino/
// BEGIN QUOTE
// Uses port C (analog in) pins as power & ground for Nunchuck
static void nunchuck_setpowerpins()
{
#define pwrpin PORTC3
#define gndpin PORTC2
DDRC |= _BV(pwrpin) | _BV(gndpin);
PORTC &=~ _BV(gndpin);
PORTC |= _BV(pwrpin);
delay(100); // wait for things to stabilize
}
// END QUOTE
//
// You can use this code to make things really convenient for
// just plugging I2C widgets (or other stuff) into the analog pins without
// having to mess around with any wiring at all: you can just plug and
// go. As a result the code shows up on the internet a lot, either copied verbatum
// or in slightly mutated forms.
//
// It was also *completely* incomprehensible to me at first glance.
//
// I imagine this is the case for a lot of folks, since
// it's written in the native idiom of AVR-C rather than
// in the nice Arduino interface we're familiar with.
//
// As such, I figured I'd annotate it while trying to
// convince myself it wouldn't fry my brand new MotionPlus :)
//
// All of the annotations below are based on a *very* brief
// scan of the AVR headers that came with my Arduino software
// distribution and some quick follow-up googling, and may very well be incorrect.
//
// Anyhow, here goes:
static void todbot_power_pins()
{
// Turns out, each AVR pin (or at least each of the two
// we'll be messing with) has three bits associated with it.
//
// a DDR bit, that tells us whether the pin is input (0) or output (1)
// a BIT bit, that lets us READ a pin if it's configured for input,
// a PORT bit, that apparently has a few different intepretations:
// When a pin's DDR bit is set to 1, we can write the state of the
// pin by setting or clearing the associated PORT bit.
// This means different (and from the look of things, important)
// stuff when the DDR bit is clear, whic we'll be ignoring here :)
//
// Since we have eight bit registers, and more than 8 pins we can
// address in this way, the bits are arranged into a number of registers.
// It happens that arduino pins A2 and A3 (which we'll be using
// as ground and power, respectively) are part of group C
// (C2 and C3, in fact)
// Moving right along...
// PORTC2 and PORTC3 are bit offsets of our interesting pins
// So I2C ground -> arduino pin A2 -> AVR Port C pin 3
// So I2C power -> arduino pin A3 -> AVR Port C pin 3
#define gndpin PORTC2
#define pwrpin PORTC3
// _BV(N) is "Bit N", where _BV(0) is the LSB.
// So since PORTC2 is a bit offset, we can find the bits relevant
// to pin C2 in DDRC, PORTC, and BITC with _BV(PORTC2)
// So, set our pins into write mode
DDRC |= _BV(pwrpin) | _BV(gndpin);
// Set our ground pin to write low
PORTC &=~ _BV(gndpin);
// Set our power pin to write high
PORTC |= _BV(pwrpin);
// then give the Microcontroller time to stabilize
delay(100);
}
// Voila! Error reports would be appreciated, you can reach me
// by typing joerbowers, and then typing the little @ thingy and then
// typing gmail.com