/*
 * $Id: srf08.c,v 1.1 2010/10/19 05:18:47 bsd Exp $
 *
 */

#include <util/twi.h>

#include <inttypes.h>

#include "i2c.h"
#include "srf08.h"


/*
 * srf08_ping - initiate a ping to the SRF08 module.  Returns
 * immidiately, the caller must then wait the appropriate amount of
 * time before reading the echo results.  Use 'srf08_range()' to read
 * the echo results.  'device' is the 7 bit I2C address of the SRF08
 * module.  'cmd' is the command to execute.
 *
 * Returns 0 on success, or -1 if an I2C error occured.  */
int8_t srf08_ping(uint8_t device, uint8_t cmd)
{
  /* start condition */
  if (i2c_start(0x08, 1))
    return -1;

  /* address slave device, write */
  if (i2c_sla_rw(device, 0, TW_MT_SLA_ACK, 1))
    return -2;

  /* write address */
  if (i2c_data_tx(0x00, TW_MT_DATA_ACK, 1))
    return -3;

  /* write command */
  if (i2c_data_tx(cmd, TW_MT_DATA_ACK, 1))
    return -4;

  if (i2c_stop())
    return -5;

  return 0;
}


/*
 * srf08_range - Read echo results from the SRF08 module.
 *
 * 'device' should be the 7 bit I2C address of the unit.  'echo'
 * should contain which echo to read, 0=first echo, 1=second echo,
 * etc.  'range' should point to a 2 byte location to hold the 16 bit
 * echo result.
 *
 * Returns 0 on success, or -1 if an I2C error occured.
 */
int8_t srf08_range(uint8_t device, uint8_t echo, uint16_t * range)
{
  uint8_t vh, vl;
  uint8_t addr;

  /* start condition */
  if (i2c_start(0x08, 1))
    return -1;

  /* address slave device, write */
  if (i2c_sla_rw(device, 0, TW_MT_SLA_ACK, 1))
    return -2;

  addr = echo*2 + 2;

  /* write address */
  if (i2c_data_tx(addr, TW_MT_DATA_ACK, 1))
    return -3;

  /* repeated start condition */
  if (i2c_start(0x10, 1))
    return -4;

   /* address slave device, read */
  if (i2c_sla_rw(device, 1, TW_MR_SLA_ACK, 1))
    return -5;

  /* read high byte */
  if (i2c_data_rx(&vh, I2C_ACK, TW_MR_DATA_ACK, 1))
    return -6;

  /* read low byte */
  if (i2c_data_rx(&vl, I2C_NACK, TW_MR_DATA_NACK, 1))
    return -7;

  if (i2c_stop())
    return -8;

  *range = (vh << 8) | vl;

  return 0;
}


