  * continuous turn servos. It also has an ADC input for checking
  * the battery level.
  *
- * To test on Linux:
- *
- * # # Assume that the ATtiny85's I2C pins are connected to the
- * # # host's I2C bus 1
- * # i2cdetect -y 1
+ * To test on Raspian:
+ *
+ * Connect the ATtiny85's I2C pins to the I2C pins on the
+ * Raspberry Pi's GPIO connector
+ *
+ * # sudo apt-get install i2c-tools
+ * # sudo raspi-config
+ * In raspi-config, enable I2C through the advanced menu.
+ *
+ * # sudo modprobe i2c-dev
+ * # sudo i2cdetect -y 1
  *      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
  * 00:          -- 04 -- -- -- -- -- -- -- -- -- -- --
  * 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

    while (howMany) {
       byte value = TinyWireS.receive();
       howMany--;
      switch (reg_position) {
      case 0:
         if (value >= 17 && value <= 28)
            OCR1A = value;
         break;
      case 1:
         if (value >= 17 && value <= 28)
            OCR1B = value;
         break;
      default:
         break;
      }
      reg_position++;
      if (reg_position >= reg_count)
         reg_position = 0;
    }
}


void setup()
{
    // Servos like PWM durations around 1.5 ms with periods of 15-20 ms
    //
    // Set Timer/Counter 1 to increment at 15625 Hz (8 MHz/512) and
    // count to 255. This gives a PWM period of ~16 ms (256/15625)
    // See ATtiny25/45/85 datasheet
    // OCR1C = value to count up to (period for PWM)
    // COM1A1,COM1A0 = 1,0  # set output low when counter matches OCR1A value (See Table 13-1)
    OCR1C = 255; // Count to 255, then reset counter
    OCR1A = 22; // servo idle (~1.5 ms)
    OCR1B = 22; // servo idle (~1.5 ms)
    TCCR1 = _BV(PWM1A) | _BV(COM1A1) | 0xa; // Enable PWM1A; CK/512 (Table 12-5) NOTE: Table 12-5 not for PWM Mode???
    GTCCR = _BV(PWM1B) | _BV(COM1B1);       // Enable PWM1B

    pinMode(1, OUTPUT); // PWM1A
    pinMode(4, OUTPUT); // PWM1B
    pinMode(3, INPUT);  // Battery level

    /**
     * Reminder: taking care of pull-ups is the masters job
     */

    TinyWireS.begin(I2C_SLAVE_ADDRESS);
    TinyWireS.onReceive(receiveEvent);
    TinyWireS.onRequest(requestEvent);
}

void loop()
{
    /**
     * This is the only way we can detect stop condition (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=984716&sid=82e9dc7299a8243b86cf7969dd41b5b5#984716)
     * it needs to be called in a very tight loop in order not to miss any (REMINDER: Do *not* use delay() anywhere, use tws_delay() instead).
     * It will call the function registered via TinyWireS.onReceive(); if there is data in the buffer on stop.
     */
    TinyWireS_stop_check();
}


#define I2C_SLAVE_ADDRESS 0x4
#include <TinyWireS.h>

enum I2cRegisters {
  I2cRegLeftServoLo = 0,
  I2cRegLeftServoHi,
  I2cRegRightServoLo,
  I2cRegRightServoHi,
  I2cRegBatteryLo,
  I2cRegBatteryHi,
  I2cRegCount
};

volatile uint8_t currentRegister = 0;

uint16_t leftServoMicros = 1500;
uint16_t rightServoMicros = 1500;
uint16_t batteryMicroVolts = 0;

#if F_CPU == 8000000L
    // Divide FCLK by 64 -> 8 MHz/64 = 125 KHz (each tick is 8 uS)
    #define TCCR1_CS_BITS 0x7
#else
    #error Unexpected CPU speed
#endif

/*
 * Handle a 'get' request from the I2C master.
 */
void requestEvent()
{
    byte value = 0;
    switch (currentRegister) {
    case I2cRegLeftServoLo:
       value = lowByte(leftServoMicros);
       break;
    case I2cRegLeftServoHi:
       value = highByte(leftServoMicros);
       break;
    case I2cRegRightServoLo:
       value = lowByte(rightServoMicros);
       break;
    case I2cRegRightServoHi:
       value = highByte(rightServoMicros);
       break;
    case I2cRegBatteryLo:
       value = lowByte(batteryMicroVolts);
       break;
    case I2cRegBatteryHi:
       value = highByte(batteryMicroVolts);
       break;
    }
    TinyWireS.send(value);
    currentRegister++;
    if (currentRegister >= I2cRegCount)
       currentRegister = 0;
}

/*
 * Handle a 'set' request from the I2C master.
 */
void receiveEvent(uint8_t howMany)
{
   static uint16_t nextLeftServoMicros = 0;
   static uint16_t nextRightServoMicros = 0;

    // Sanity check
    if (howMany < 1 || howMany > I2cRegCount)
      return;

    // Read register position
    currentRegister = TinyWireS.receive();
    howMany--;

    if (currentRegister >= I2cRegCount) {
       // If invalid register, ignore the request
       currentRegister = 0;
       return;
    }
    
