//------------------------------------------------------------------
// qfixSlaveBoard.h
//
// This file contains the class SlaveBoard which represents a kind
// of remote control of a BobbyBoard via the I2C bus. The SlaveBoard
// can be used like a local BobbyBoard with all its inputs and outputs.
//
// Copyright 2005 by KTB mechatronics GmbH
// Author: Stefan Enderle
//------------------------------------------------------------------


#ifndef qfixSlaveBoard_h
#define qfixSlaveBoard_h

#include "qfixI2CMaster.h"
#include "qfixI2CDefs.h"


const uint8_t CMD_LEDON    = 0;
const uint8_t CMD_LEDOFF   = 1;
const uint8_t CMD_LEDSOFF  = 2;
const uint8_t CMD_POWERON  = 3;
const uint8_t CMD_POWEROFF = 4;
const uint8_t CMD_MOTOR    = 5;
const uint8_t CMD_BUTTON   = 6;
const uint8_t CMD_ANALOG   = 7;
const uint8_t CMD_DIGITAL  = 8;


//----------------------------------------



class SlaveBoard : I2CMaster
{
public:
  SlaveBoard();
  SlaveBoard(uint8_t logicalID);

  /** Puts on LED i 
  */
  void ledOn(uint8_t i);

  /** Puts off LED i
  */
  void ledOff(uint8_t i);

  /** Puts off all LEDs
  */
  void ledsOff();

  /** Puts the power output i on
  */
  void powerOn(uint8_t i);

  /** Puts the power output i off
  */
  void powerOff(uint8_t i);

  /** Sets motor i to the given speed. -255 <= speed <= 255
  */
  void motor(uint8_t i, int speed);

  /** Checks the state of button i. If it is pressed, true is returned,
   *  else false.
  */
  bool button(uint8_t i);

  /** returns the value of the analog port i. 0 <= value <= 255
  */
  int analog(uint8_t i);

  /** returns true if the digital port is logical high, else false.
  */
  bool digital(uint8_t i);
};


SlaveBoard::SlaveBoard() : I2CMaster(I2C_ADDR_BOBBYBOARD)
{
}


SlaveBoard::SlaveBoard(uint8_t logicalID) 
: I2CMaster(I2C_ADDR_BOBBYBOARD, logicalID)
{
}


void SlaveBoard::ledOn(uint8_t i)
{
  if  (i>3) return;
  command(CMD_LEDON, i);
}


void SlaveBoard::ledOff(uint8_t i)
{
  if  (i>3) return;
  command(CMD_LEDOFF, i);
}


void SlaveBoard::ledsOff()
{
  command(CMD_LEDSOFF);
}


void SlaveBoard::powerOn(uint8_t i)
{
  if  (i>7) return;
  command(CMD_POWERON, i);
}


void SlaveBoard::powerOff(uint8_t i)
{
  if  (i>7) return;
  command(CMD_POWEROFF, i);
}


void SlaveBoard::motor(uint8_t i, int speed)
{
  if (i>1) return;
  uint8_t neg=(speed<0)?1:0;
  uint8_t s;
  if (speed>=0) s=uint8_t(speed); else s=-uint8_t(speed);
  command(CMD_MOTOR, i, neg, s);
}


bool SlaveBoard::button(uint8_t i)
{
  if  (i>3) return false;    // better error handling!
  return (request(CMD_BUTTON, i) == 1);
}


int SlaveBoard::analog(uint8_t i)
{
  if  (i>3) return -1;    // better error handling!
  return (request(CMD_ANALOG, i));
}


bool SlaveBoard::digital(uint8_t i)
{
  if  (i>3) return false;    // better error handling!
  return (request(CMD_DIGITAL, i) == 1);
}


#endif

