[Tinyos-beta-commits] CVS: tinyos-1.x/beta/chips/AD524X/v2 AD524X.h, NONE, 1.1 AD524X.nc, NONE, 1.1 AD524XC.nc, NONE, 1.1 AD524XM.nc, NONE, 1.1

Joe Polastre jpolastre at users.sourceforge.net
Wed Aug 3 16:43:07 PDT 2005


Update of /cvsroot/tinyos/tinyos-1.x/beta/chips/AD524X/v2
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23907

Added Files:
	AD524X.h AD524X.nc AD524XC.nc AD524XM.nc 
Log Message:
New implementation of the AD524X driver that supports all of the AD524X
series of devices instead of just the AD5241 and AD5242.

New interface defined; works in less code space that the previous implementation, especially when multiple potentiometers are located on the same board (ahem, prabal)


located in v2/ directory since NEST FE is using the first version
Ideally the first version will go away and eventually v2 will move to the
main tree once mica* platforms implement new I2CPacket interface


--- NEW FILE: AD524X.h ---
/*
 * Copyright (c) 2005 Moteiv Corporation
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached MOTEIV-LICENSE     
 * file. If you do not find these files, copies can be found at
 * http://www.moteiv.com/MOTEIV-LICENSE.txt and by emailing info at moteiv.com.
 *
 * @author Joe Polastre <info at moteiv.com>
 */
#ifndef _H_AD524X_H
#define _H_AD524X_H

typedef enum {
  TYPE_AD5241 = 0,
  TYPE_AD5242,
  TYPE_AD5243,
  TYPE_AD5245,
  TYPE_AD5246,
  TYPE_AD5247,
  TYPE_AD5248,
} ad524x_type_t;

#endif

--- NEW FILE: AD524X.nc ---
// $Id: AD524X.nc,v 1.1 2005/08/03 23:43:05 jpolastre Exp $
/*
 * "Copyright (c) 2000-2005 The Regents of the University  of California.
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 * Copyright (c) 2005 Moteiv Corporation
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached MOTEIV-LICENSE     
 * file. If you do not find these files, copies can be found at
 * http://www.moteiv.com/MOTEIV-LICENSE.txt and by emailing info at moteiv.com.
 *
 */

/**
 * @author Joe Polastre <info at moteiv.com>
 * Revision:  $Revision: 1.1 $
 *
 * The AD524X interface provides commands for using the
 * Analog Devices AD524X family of potentiometers.
 *
 * The lower 2 bits (AD1 and AD0) must be provided as the address.
 * The full address may be provided as well, but all other bits will be
 * stripped (addr = addr & 0x03)
 */

includes AD524X;

interface AD524X {
  /**
   * Start the AD5242 device.  This sets the SD bit to enable the device
   * via the I2C bus.  This command does not alter the physical shutdown
   * pin of the device.  The StdControl interface is responsible for
   * the physical shutdown of the device.
   *
   * @param addr Lower 2 bits (AD1,AD0) of the device I2C address
   * @param type Type of address -- only some AD524X devices can be started
   * @return SUCCESS if the request was accepted
   */
  command result_t start(uint8_t addr, ad524x_type_t type);
  /**
   * Notification that there was an attempt to set the SD bit.
   *
   * @param addr Lower 2 bits (AD1,AD0) of the device I2C address
   * @param result SUCCESS if the bit was actually set, FAIL if the
   *               device could not be reached or the operation failed
   * @param type Type of device
   */
  event void startDone(uint8_t addr, result_t result, ad524x_type_t type);

  /**
   * Stop the AD5242 device.  This clears the SD bit to enable the device
   * via the I2C bus.  This command does not alter the physical shutdown
   * pin of the device.  The StdControl interface is responsible for
   * the physical shutdown of the device.
   *
   * @param addr Lower 2 bits (AD1,AD0) of the device I2C address
   * @param type Type of address -- only some AD524X devices can be stopped
   * @return SUCCESS if the request was accepted
   */
  command result_t stop(uint8_t addr, ad524x_type_t type);
  /**
   * Notification that there was an attempt to clear the SD bit.
   *
   * @param addr Lower 2 bits (AD1,AD0) of the device I2C address
   * @param result SUCCESS if the bit was actually cleared, FAIL if the
   *               device could not be reached or the operation failed
   * @param type Type of device
   */
  event void stopDone(uint8_t addr, result_t result, ad524x_type_t type);

  /**
   * Set the value of one of the output pins.
   *
   * @param addr Lower 2 bits (AD1,AD0) of the device I2C address
   * @param high TRUE if O should be set, FALSE if it should be cleared
   * @param output FALSE if O1 should be used, TRUE for 02
   * @param Type of device -- only some AD524X devices have outputs
   * @return SUCCESS if the request was accepted
   */
  command result_t setOutput(uint8_t addr, bool output, bool high, ad524x_type_t type);

  /**
   * Notification that the state of an output pin may have changed.
   *
   * @param addr Lower 2 bits (AD1,AD0) of the device I2C address
   * @param output FALSE for O1, TRUE for O2
   * @param result SUCCESS if the output O was successfully changed
   * @param Type of device -- only some AD524X devices have outputs
   */
  event void setOutputDone(uint8_t addr, bool output, result_t result, ad524x_type_t type);

  /**
   * Get the value of an output pin.
   *
   * @param addr Lower 2 bits (AD1,AD0) of the device I2C address
   * @param output FALSE for O1, TRUE for 02
   * @param type of device -- only some AD524X devices have outputs
   * @return TRUE if the bit is set, FALSE otherwise
   */
  command bool getOutput(uint8_t addr, bool output, ad524x_type_t type);

  /**
   * Set the value of an RDAC
   *
   * @param addr Lower 2 bits (AD1,AD0) of the device I2C address
   * @param rdac FALSE for RDAC1, TRUE for RDAC2 if exits
   *             parameter ignored if type != AD5242
   * @param value A 256-bit value corresponding to the wiper position
   *              For 128-bit pots, the value must be *left* justified
   *              (the LSB will be discarded)
   * @return SUCCESS if the request was accepted
   */
  command result_t setPot(uint8_t addr, bool rdac, uint8_t value, ad524x_type_t type);

  /**
   * Notification that RDAC may be set to a new value
   *
   * @param addr Lower 2 bits (AD1,AD0) of the device I2C address
   * @param SUCCESS if the value of RDAC was changed
   */
  event void setPotDone(uint8_t addr, bool rdac, result_t result, ad524x_type_t type);

  /**
   * Get the value of an RDAC
   *
   * @param addr Lower 2 bits (AD1,AD0) of the device I2C address
   * @param rdac FALSE for RDAC1, TRUE for RDAC2
   * @param type The device type
   * @return SUCCESS if the request was accepted
   */
  command result_t getPot(uint8_t addr, bool rdac, ad524x_type_t type);

  /**
   * Result of the get operation with the value of the RDAC potentiometer.
   *
   * @param addr Lower 2 bits (AD1,AD0) of the device I2C address
   * @param rdac The potentiometer that qas requested
   * @param value A 256-bit value corresponding to the wiper position
   *              For 128-bit potentiometers, value is left-justified
   *              (shifted left by 1 bit)
   * @param result SUCCESS if the value was correctly obtained from the
   *               device.  If FAIL is returned, the value is not valid.
   * @param type The type of the device
   */
  event void getPotDone(uint8_t addr, bool rdac, uint8_t value, result_t result, ad524x_type_t type);

}

--- NEW FILE: AD524XC.nc ---
// $Id: AD524XC.nc,v 1.1 2005/08/03 23:43:05 jpolastre Exp $
/*
 * "Copyright (c) 2000-2005 The Regents of the University  of California.
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 */

/**
 * @author Joe Polastre <info at moteiv.com>
 * Revision:  $Revision: 1.1 $
 *
 * AD524XC provides access to primitives for the AD524X family of
 * potentiometers. StdControl sets the physical hardware pin to turn
 * the device on or off via the shutdown pin (if supported by the
 * underlying platform).
 *
 * You *must* define the "AD524X_SD" pin in an included file, presumably
 * your sensorboard.h file.  The AD524X_SD pin is used to put the device
 * into and out of shutdown when StdControl start() and stop() are called.
 * These functions:
 *   TOSH_MAKE_AD524X_SD_OUTPUT()
 *   TOSH_MAKE_AD524X_SD_INPUT()
 *   TOSH_SET_AD524X_SD_PIN()
 *   TOSH_CLR_AD524X_SD_PIN()
 * May be defined as empty functions for platforms that do not support the
 * AD524X shutdown pin.
 *
 * The AD524X driver counts the number of users for systems with multiple
 * pots and only causes the physical pin to initiate a shutdown when all
 * users of the pot have called stop (in other words #start() == #stop())
 *
 * It is recommended that you use the SD bit in the AD524X by calling
 * AD524X.start() and AD524X.stop() rather than toggling the actual
 * shutdown pin.  By setting the pin in the particular device, you can
 * ensure that device has been shutdown.
 */

configuration AD524XC {
  provides {
    interface StdControl;
    interface AD524X;
  }
}
implementation
{
  components I2CPacketC, AD524XM;

  AD524X = AD524XM;
  StdControl = AD524XM;

  AD524XM.LowerControl -> I2CPacketC;
  AD524XM.I2CPacket -> I2CPacketC;
}

--- NEW FILE: AD524XM.nc ---
// $Id: AD524XM.nc,v 1.1 2005/08/03 23:43:05 jpolastre Exp $
/*
 * Copyright (c) 2005 Moteiv Corporation
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached MOTEIV-LICENSE     
 * file. If you do not find these files, copies can be found at
 * http://www.moteiv.com/MOTEIV-LICENSE.txt and by emailing info at moteiv.com.
 *
 * "Copyright (c) 2000-2005 The Regents of the University  of California.
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 */

/**
 * @author Joe Polastre <info at moteiv.com>
 * Revision:  $Revision: 1.1 $
 *
 */
includes AD524X;

module AD524XM
{
  provides {
    interface StdControl;
    interface AD524X;
  }
  uses {
    interface StdControl as LowerControl;
    interface MSP430I2CPacket as I2CPacket;
  }
}

implementation
{
  enum {
    AD524X_RDAC   = 1 << 7,
    AD524X_RS     = 1 << 6,
    AD524X_SD     = 1 << 5,
    AD524X_3_8_SD = 1 << 6, /* the AD5243 and AD5248 use a different bit */
    AD524X_O1     = 1 << 4,
    AD524X_O2     = 1 << 3
  };

  enum {
    IDLE = 0,
    AD524X_START,
    AD524X_STOP,
    AD524X_OUTPUT ,
    AD524X_RPOT,
    AD524X_WPOT,
  };
    
  uint8_t data[2];
  uint8_t device[4];
  uint8_t state;
  uint8_t type;
  bool rdac;
  int8_t usercount;

  result_t startWriteCommand(uint8_t _addr, uint8_t _length, uint16_t _data, uint8_t _newstate, bool _rdac, ad524x_type_t _type) {
    uint8_t _state = 0;

    atomic {
      _state = state;
      if (_state == IDLE) {
	state = _newstate;
	type = _type;
	rdac = _rdac;
      }
    }

    if (_state == IDLE) {
      data[0] = _data & 0xFF;
      data[1] = (_data >> 8) & 0xFF;
      if (!call I2CPacket.writePacket((_addr & 0x03) | 0x2C, _length, data)) {
	state = IDLE;
	return FAIL;
      }
      return SUCCESS;
    }
    return FAIL;
  }

  result_t startReadCommand(uint8_t _addr, uint8_t _length, uint8_t _newstate, bool _rdac, ad524x_type_t _type) {
    uint8_t _state = 0;

    atomic {
      _state = state;
      if (_state == IDLE) {
	state = _newstate;
	type = _type;
	rdac = _rdac;
      }
    }

    if (_state == IDLE) {
      if (!call I2CPacket.readPacket((_addr & 0x03) | 0x2C, _length, data)) {
	state = IDLE;
	return FAIL;
      }
      return SUCCESS;
    }
    return FAIL;
  }

  command result_t StdControl.init() {
    atomic {
      usercount = 0;
      state = 0;
    }
    return call LowerControl.init();
  }

  command result_t StdControl.start() {
    int8_t _localcount;
    atomic {
      if (usercount <= 0) {
	TOSH_MAKE_AD524X_SD_OUTPUT();
	TOSH_SET_AD524X_SD_PIN();
	usercount = 0;
      }
      _localcount = usercount;
      usercount++;
    }
    if (_localcount == 0)
      return call LowerControl.start();
    else
      return SUCCESS;
  }

  command result_t StdControl.stop() {
    int8_t _localcount;
    atomic {
      usercount--;
      if (usercount <= 0) {
	TOSH_CLR_AD524X_SD_PIN();
	TOSH_MAKE_AD524X_SD_INPUT();
	usercount = 0;
      }
      _localcount = usercount;
    }
    if (_localcount == 0)
      return call LowerControl.stop();
    else
      return SUCCESS;
  }

  command result_t AD524X.start(uint8_t addr, ad524x_type_t _type) {
    if ((_type == TYPE_AD5241) || (_type == TYPE_AD5242) || (_type == TYPE_AD5245)) {
      atomic device[(int)(addr & 0x03)] &= ~AD524X_SD;
      return startWriteCommand(addr, 1, device[(int)(addr & 0x03)], AD524X_START, 0, _type);
    }
    else if ((_type == TYPE_AD5243) || (_type == TYPE_AD5248)) {
      atomic device[(int)(addr & 0x03)] &= ~AD524X_3_8_SD;
      return startWriteCommand(addr, 1, device[(int)(addr & 0x03)], AD524X_START, 0, _type);
    }
    return FAIL;
  }

  command result_t AD524X.stop(uint8_t addr, ad524x_type_t _type) {
    if ((_type == TYPE_AD5241) || (_type == TYPE_AD5242) || (_type == TYPE_AD5245)) {
      atomic device[(int)(addr & 0x03)] |= AD524X_SD;
      return startWriteCommand(addr, 1, device[(int)(addr & 0x03)], AD524X_STOP, 0, _type);
    }
    else if ((_type == TYPE_AD5243) || (_type == TYPE_AD5248)) {
      atomic device[(int)(addr & 0x03)] |= AD524X_3_8_SD;
      return startWriteCommand(addr, 1, device[(int)(addr & 0x03)], AD524X_STOP, 0, _type);
    }
    return FAIL;
  }

  command result_t AD524X.setOutput(uint8_t addr, bool output, bool high, ad524x_type_t _type) {
    if ((_type == TYPE_AD5241) || (_type == TYPE_AD5242)) {
      atomic {
	if (!output)
	  if (high)
	    device[(int)(addr & 0x03)] |= AD524X_O1;
	  else
	    device[(int)(addr & 0x03)] &= ~AD524X_O1;
	else
	  if (high)
	    device[(int)(addr & 0x03)] |= AD524X_O2;
	  else
	    device[(int)(addr & 0x03)] &= ~AD524X_O2;
      }
      return startWriteCommand(addr, 1, device[(int)addr & 0x03], AD524X_OUTPUT, output, _type);
    }
    return FAIL;
  }

  command bool AD524X.getOutput(uint8_t addr, bool output, ad524x_type_t _type) {
    if ((_type == TYPE_AD5241) || (_type == TYPE_AD5242)) {
      bool _high;
      if (!output)
	atomic _high = (device[(int)(addr & 0x03)] & AD524X_O1) >> AD524X_O1;
      else
	atomic _high = (device[(int)(addr & 0x03)] & AD524X_O2) >> AD524X_O2;
      return _high;
    }
    return FALSE;
  }
  
  command result_t AD524X.setPot(uint8_t addr, bool _rdac, 
				 uint8_t value, ad524x_type_t _type) {
    uint16_t _temp;
    if ((_type == TYPE_AD5241) || (_type == TYPE_AD5242)) {
      atomic _temp = (device[(int)addr & 0x03] & ~AD524X_RDAC) | (value << 8);
      if ((_type == TYPE_AD5242) && (_rdac)) {
	_temp |= AD524X_RDAC;
      }
      return startWriteCommand(addr, 2, _temp, AD524X_WPOT, _rdac, _type);
    }
    else {
      value = value >> 1; // turn 256-pos value to 128-pos value
      return startWriteCommand(addr, 1, value, AD524X_WPOT, 0, _type);
    } 
  }

  command result_t AD524X.getPot(uint8_t addr, bool _rdac, 
				 ad524x_type_t _type) {
    uint8_t _temp;
    if (_type == TYPE_AD5242) {
      atomic _temp = (device[(int)addr & 0x03] & ~AD524X_RDAC);
      return startWriteCommand(addr, 1, _temp, AD524X_RPOT, _rdac, _type);
    }
    else {
      return startReadCommand(addr, 1, AD524X_RPOT, 0, _type);
    }
  }

  event void I2CPacket.readPacketDone(uint16_t _addr, uint8_t _length, uint8_t* _data, result_t _success) { 
    uint8_t _state;
    bool _rdac;
    uint8_t _type;

    atomic {
      _state = state;
      _rdac = rdac;
      _type = type;
    }

    // check if the buffer is ours
    if (data != _data)
      return;

    switch (_state) {
    case AD524X_RPOT:
      state = IDLE;
      signal AD524X.getPotDone(_addr & 0x03, _rdac, data[0], _success, _type);
      break;
    }
  }

  event void I2CPacket.writePacketDone(uint16_t _addr, uint8_t _length, uint8_t* _data, result_t _success) { 
    uint8_t _state;
    uint8_t _type;
    bool _rdac;

    atomic {
      _state = state;
      _type = type;
      _rdac = rdac;
    }

    // check if the buffer is ours
    if (data != _data)
      return;

    switch (_state) {
    case AD524X_START:
      state = IDLE;
      signal AD524X.startDone(_addr & 0x03, _success, _type);
      break;
    case AD524X_STOP:
      state = IDLE;
      signal AD524X.stopDone(_addr & 0x03, _success, _type);
      break;
    case AD524X_OUTPUT:
      state = IDLE;
      signal AD524X.setOutputDone(_addr & 0x03, _rdac, _success, _type);
      break;
    case AD524X_WPOT:
      state = IDLE;
      if (_length == 1)
	signal AD524X.setPotDone(_addr & 0x03, 0, _success, _type);
      else
	signal AD524X.setPotDone(_addr & 0x03, _rdac, _success, _type);
      break;
    case AD524X_RPOT:
      state = IDLE;
      startReadCommand(_addr, 1, AD524X_RPOT, rdac, type);
      break;
    }
  }

}




More information about the Tinyos-beta-commits mailing list