[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/atm128/i2c Atm128I2C.nc, NONE, 1.1.2.1 Atm128I2CMasterImplP.nc, NONE, 1.1.2.1 Atm128I2CMasterPacketP.nc, NONE, 1.1.2.1 Atm128I2C.h, 1.1.2.4, 1.1.2.5 Atm128I2CMasterC.nc, 1.1.2.2, 1.1.2.3 Atm128I2CMasterP.nc, 1.1.2.2, 1.1.2.3 HplAtm128I2CBus.nc, 1.1.2.2, 1.1.2.3 HplAtm128I2CBusP.nc, 1.1.2.2, 1.1.2.3

Phil Levis scipio at users.sourceforge.net
Wed Jun 7 20:22:06 PDT 2006


Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv20682

Modified Files:
      Tag: tinyos-2_0_devel-BRANCH
	Atm128I2C.h Atm128I2CMasterC.nc Atm128I2CMasterP.nc 
	HplAtm128I2CBus.nc HplAtm128I2CBusP.nc 
Added Files:
      Tag: tinyos-2_0_devel-BRANCH
	Atm128I2C.nc Atm128I2CMasterImplP.nc Atm128I2CMasterPacketP.nc 
Log Message:
I2C stack for atmega 128.


--- NEW FILE: Atm128I2C.nc ---
/// $Id: Atm128I2C.nc,v 1.1.2.1 2006/06/08 03:22:03 scipio Exp $
/*
 * Copyright (c) 2006 Stanford University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of the Stanford University nor the names of
 *   its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
 * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "Atm128I2C.h"

/**
 * An interface for stopping the I2C bus. Needed by the resource
 * reservation system, so that when a client releases you're sure
 * there's a stop.
 *
 * @author Philip Levis
 *
 * @version  $Id: Atm128I2C.nc,v 1.1.2.1 2006/06/08 03:22:03 scipio Exp $
 */
interface Atm128I2C {

  async command void stop();
}

--- NEW FILE: Atm128I2CMasterImplP.nc ---
/*
 * Copyright (c) 2006 Stanford University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of the Stanford University nor the names of
 *   its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
 * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * The configuration that takes the underlying I2C driver on the 
 * Atmega128 and turns it into a shared abstraction.
 *
 * @date May 28 2006
 * @author Philip Levis
 */

generic module Atm128I2CMasterImplP() {
  provides interface Resource[uint8_t client];
  provides interface I2CPacket<TI2CBasicAddr>[uint8_t client];
  uses interface Resource as SubResource[uint8_t];
  uses interface I2CPacket<TI2CBasicAddr> as SubPacket;
  uses interface Atm128I2C;
}
implementation {

  enum {
    NO_CLIENT = 0xff
  };
  
  uint8_t currentClient = NO_CLIENT;

  async command error_t Resource.request[uint8_t id]() {
    return call SubResource.request[id]();
  }

  async command error_t Resource.immediateRequest[uint8_t id]() {
    error_t rval = call SubResource.request[id]();
    if (rval == SUCCESS) {
      atomic currentClient = id;
    }
    return rval;
  }

  event void SubResource.granted[uint8_t id]() {
    atomic currentClient = id;
    signal Resource.granted[id]();
  }

  async command void Resource.release[uint8_t id]() {
    call Atm128I2C.stop(); // Always stop if someone has released.
    call SubResource.release[id]();
  }

  async command bool Resource.isOwner[uint8_t id]() {
    return call SubResource.isOwner[id]();
  }
  
  async command error_t I2CPacket.write[uint8_t id](i2c_flags_t flags, uint16_t addr, uint8_t len, uint8_t* data) {
    atomic {
      if (currentClient != id) {
	return FAIL;
      }
    }
    return call SubPacket.write(flags, addr, len, data);
  }
  
  async command error_t I2CPacket.read[uint8_t id](i2c_flags_t flags, uint16_t addr, uint8_t len, uint8_t* data) {
    atomic {
      if (currentClient != id) {
	return FAIL;
      }
    }
    return call SubPacket.read(flags, addr, len, data);
  }

  async event void SubPacket.readDone(error_t error, uint16_t addr, uint8_t len, uint8_t* data) {
    signal I2CPacket.readDone[currentClient](error, addr, len, data);
  }
  async event void SubPacket.writeDone(error_t error, uint16_t addr, uint8_t len, uint8_t* data) {
    signal I2CPacket.writeDone[currentClient](error, addr, len, data);
  }
  
  default event void Resource.granted[uint8_t id]() {}
 default async event void I2CPacket.writeDone[uint8_t id](error_t error, uint16_t addr, uint8_t len, uint8_t* data) {}
 default async event void I2CPacket.readDone[uint8_t id](error_t error, uint16_t addr, uint8_t len, uint8_t* data) {}
}


--- NEW FILE: Atm128I2CMasterPacketP.nc ---
/*
 * Copyright (c) 2006 Stanford University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of the Stanford University nor the names of
 *   its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
 * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "Atm128I2C.h"

/**
 * This driver implements an interupt driven I2C Master controller 
 * Hardware Abstraction Layer (HAL) to the ATmega128 
 * two-wire-interface (TWI) hardware subsystem.
 *
 * @author Philip Levis
 *
 * @version $Id: Atm128I2CMasterPacketP.nc,v 1.1.2.1 2006/06/08 03:22:03 scipio Exp $
 */

generic module Atm128I2CMasterPacketP() {
  provides interface AsyncStdControl;
  provides interface I2CPacket<TI2CBasicAddr>;
  provides interface Atm128I2C;
  
  uses interface HplAtm128I2CBus as I2C;
  uses interface Leds as ReadDebugLeds;
  uses interface Leds as WriteDebugLeds;
}
implementation {

  enum {
    I2C_OFF          = 0,
    I2C_IDLE         = 1,
    I2C_BUSY         = 2,      
    I2C_ADDR         = 3,
    I2C_DATA         = 4,
    I2C_STARTING     = 5,
    I2C_STOPPING     = 6,
  } atm128_i2c_state_t;

  uint8_t state = I2C_OFF;
  i2c_flags_t packetFlags; 
  uint8_t* packetPtr;
  uint8_t packetLen;
  uint8_t index;
  uint16_t packetAddr;
  bool reading = FALSE;

  void i2c_abort(error_t err) {
    atomic {
      // Cycle the I2C
      call I2C.readCurrent();
      call I2C.enableInterrupt(FALSE);
      call I2C.enable(FALSE);
      call I2C.sendCommand();
      call I2C.readCurrent();
      call I2C.enable(TRUE);
      call I2C.sendCommand();
      state = I2C_IDLE;
      if (reading) {
	signal I2CPacket.readDone(err, packetAddr, packetLen, packetPtr);
      }
      else {
	signal I2CPacket.writeDone(err, packetAddr, packetLen, packetPtr);
      }
    }
  }
  
  async command error_t AsyncStdControl.start() {
    atomic {
      if (state == I2C_OFF) {
	call I2C.init(FALSE);
	call I2C.readCurrent();
	call I2C.enable(TRUE);
	call I2C.enableInterrupt(FALSE);
	call I2C.sendCommand();
	state = I2C_IDLE;
	return SUCCESS;
      }
      else {
	return FAIL;
      }
    }
  }

  async command error_t AsyncStdControl.stop() {
    atomic {
      if (state == I2C_IDLE) {
	call I2C.readCurrent();
	call I2C.enable(FALSE);
	call I2C.enableInterrupt(FALSE);
	call I2C.setInterruptPending(FALSE);
	call I2C.off();
	state = I2C_OFF;
	return SUCCESS;
      }
      else {
	return FAIL;
      }
    }
  }

  async command error_t I2CPacket.read(i2c_flags_t flags, uint16_t addr, uint8_t len, uint8_t* data) {
    atomic {
      if (state == I2C_IDLE) {
	state = I2C_BUSY;
      }
      else if (state == I2C_OFF) {
	return EOFF;
      }
      else {
	return EBUSY;
      }
    }
    /* This follows the procedure described on page 209 of the atmega128L
     * data sheet. It is synchronous (does not handle interrupts).*/
    atomic {
      packetAddr = addr;
      packetPtr = data;
      packetLen = len;
      packetFlags = flags;
      index = 0;
      reading = TRUE;
    }
    /* Clear interrupt pending, send the I2C start command and abort
       if we're not in the start state.*/
    call I2C.readCurrent();
    atomic {
      call I2C.enableInterrupt(TRUE);
      call I2C.setInterruptPending(TRUE);
      call I2C.enableAck(FALSE);
      
      if (flags & I2C_START) {
        call I2C.setStart(TRUE);
        state = I2C_STARTING;
      }
      else if (len > 1 || (len > 0 && flags & I2C_ACK_END)) {
        call I2C.enableAck(TRUE);
        state = I2C_DATA;
      }
      else if (len == 1) { // length is 1
        state = I2C_DATA;
      }
      else if (flags & I2C_STOP) {
        state = I2C_STOPPING;
        call I2C.enableAck(FALSE);
        call I2C.setStop(TRUE);
      }
      call I2C.sendCommand();
    }
    return SUCCESS;
  }

  async command error_t I2CPacket.write(i2c_flags_t flags, uint16_t addr, uint8_t len, uint8_t* data) {
    atomic {
      if (state == I2C_IDLE) {
	state = I2C_BUSY;
      }
      else if (state == I2C_OFF) {
	return EOFF;
      }
      else {
	return EBUSY;
      }
    }
    /* This follows the procedure described on page 209 of the atmega128L
     * data sheet. It is synchronous (does not handle interrupts).*/
    atomic {
      packetAddr = addr;
      packetPtr = data;
      packetLen = len;
      packetFlags = flags;
      index = 0;
      reading = FALSE;
    }
    call I2C.readCurrent();
    atomic {
      call I2C.setInterruptPending(TRUE);
      call I2C.enableAck(TRUE);
      call I2C.enableInterrupt(TRUE);
      
      if (flags & I2C_START) {
        call I2C.setStart(TRUE);
	//	call WriteDebugLeds.led0On();
        state = I2C_STARTING;
      }
      else if (len > 0) {
        state = I2C_DATA;
	call I2C.write(data[index]);
      }
      else if (flags & I2C_STOP) {
        state = I2C_STOPPING;
        call I2C.enableAck(FALSE);
        call I2C.setStop(TRUE);
      }
      else { // A 0-length packet with no start and no stop....
	state = I2C_IDLE;
	return FAIL;
      }
      call I2C.sendCommand();
    }
    return SUCCESS;
  }
  
  /**
   * A command has been sent over the I2C.
   * The diversity of I2C options and modes means that there are a
   * plethora of cases to consider. To simplify reading the code,
   * they're described here and the corresponding statements
   * are only labelled with identifying comments.
   *
   * When reading:
   *  R1) A start condition has been requested. This requires 
   *      sending the start signal. When the interrupt comes in,
   *      send the first byte of the packet. This driver
   *      detects this condition by the START flag being set. 
   *      A successful send of the start clears the local copy of
   *      the flag. The driver does not distinguish between start
   *      and repeated start.
   *  R2) Sending the address byte with the read bit set.
   *  R3) Sending the first byte of a two-byte address with the
   *      read bit set. 
   *  R4) Sending the second byte of a two-byte address.
   *  R5) Reading any byte except the last byte of a packet.
   *  R6) Reading the last byte of the packet, with ACK_END requested.
   *  R7) Reading the last byte of the packet, with ACK_END cleared.
   *  R8) Sending a stop condition.
   */
  async event void I2C.commandComplete() {
    call I2C.readCurrent();
    atomic {
      if (state == I2C_DATA) {
	if (reading == TRUE) {
	  if (index < packetLen) {
	    packetPtr[index] = call I2C.read();
	    if (index == packetLen - 1 &&
                !(packetFlags & I2C_ACK_END)) { 
              call I2C.enableAck(FALSE);
            }
          }
	  else {
	    call I2C.enableInterrupt(FALSE);
	    if (packetFlags & I2C_STOP) {
	      packetFlags &= ~I2C_STOP;
	      call I2C.setStop(TRUE);
	      call I2C.status();
	    }
	    else {
	      call I2C.setInterruptPending(FALSE);
	    }
	    call I2C.sendCommand();
	    state = I2C_IDLE;
	    signal I2CPacket.readDone(SUCCESS, packetAddr, packetLen, packetPtr);
	    return;
	  }
	  index++;
	  call I2C.sendCommand();
	  return;
        }
        else { // Writing
	  if (index < packetLen) {
	    call I2C.write(packetPtr[index]);
	    index++;
	    call I2C.sendCommand();
	  }
	  else {
	    call I2C.enableInterrupt(FALSE);
	    if (packetFlags & I2C_STOP) {
	      packetFlags &= ~I2C_STOP;
	      call I2C.setStop(TRUE);
	      call WriteDebugLeds.led1On();
	    }
	    else {
	      call I2C.setInterruptPending(FALSE);
	    }
	    call I2C.sendCommand();
	    state = I2C_IDLE;
	    call WriteDebugLeds.led2On();
	    signal I2CPacket.writeDone(SUCCESS, packetAddr, packetLen, packetPtr);
	    return;
	  }
	}
      }
      else if (state == I2C_STARTING) {
	packetFlags &= ~I2C_START;
	call I2C.setStart(FALSE);
	if (call I2C.status() != ATM128_I2C_START &&
	    call I2C.status() != ATM128_I2C_RSTART) {
	  if (reading) {
	    //call ReadDebugLeds.set(call I2C.status() >> 4);
	  }
	  //call ReadDebugLeds.led2On();
	  i2c_abort(FAIL);
	  return;
	}
	state = I2C_ADDR;
	call I2C.enableAck(TRUE);
      }
      if (state == I2C_ADDR) {
	if (reading == TRUE) {
	  call I2C.write((packetAddr & 0xff) | ATM128_I2C_SLA_READ);
	}
	else
	  call I2C.write((packetAddr & 0xff) | ATM128_I2C_SLA_WRITE);
	state = I2C_DATA;
	call I2C.sendCommand();
      }
    }
  }

  async command void Atm128I2C.stop() {
    atomic {
      call I2C.readCurrent();
      call I2C.enableInterrupt(FALSE);
      call I2C.setStop(TRUE);
      call I2C.setInterruptPending(TRUE);
      call I2C.sendCommand();
    }
  }
}

Index: Atm128I2C.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c/Attic/Atm128I2C.h,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -C2 -d -r1.1.2.4 -r1.1.2.5
*** Atm128I2C.h	1 May 2006 21:50:50 -0000	1.1.2.4
--- Atm128I2C.h	8 Jun 2006 03:22:03 -0000	1.1.2.5
***************
*** 31,91 ****
  #define ATM128_I2C_SLA_READ 0x01
  
! typedef uint8_t Atm128_TWBR_t;  //!< Two Wire Bit Rate Register
! typedef uint8_t Atm128_TWDR_t;  //!< Two Wire Data Register
! 
! /* I2C Control Register -- TWCR */
! typedef struct {
!     uint8_t twie  : 1;  //!< Two Wire Interrupt Enable
!     uint8_t rsvd  : 1;  //!< Reserved
!     uint8_t twen  : 1;  //!< Two Wire Enable
!     uint8_t twwc  : 1;  //!< Two Wire Write Collision Flag
!     uint8_t twsto : 1;  //!< Two Wire Stop Condition
!     uint8_t twsta : 1;  //!< Two Wire Start Condition
!     uint8_t twea  : 1;  //!< Two Wire Enable Acknowledge
!     uint8_t twint : 1;  //!< Two Wire Interrupt
! } Atm128I2CControl_s;
! typedef union {
!     Atm128I2CControl_s bits;
!     uint8_t flat;
! } Atm128I2CControl_t;
  
- /* I2C Status Codes */
  enum {
!     ATM128_I2C_BUSERROR	        = 0x00,
!     ATM128_I2C_START		= 0x08,
!     ATM128_I2C_RSTART		= 0x10,
!     ATM128_I2C_MW_SLA_ACK	= 0x18,
!     ATM128_I2C_MW_SLA_NACK	= 0x20,
!     ATM128_I2C_MW_DATA_ACK	= 0x28,
!     ATM128_I2C_MW_DATA_NACK	= 0x30,
!     ATM128_I2C_M_ARB_LOST	= 0x38,
!     ATM128_I2C_MR_SLA_ACK	= 0x40,
!     ATM128_I2C_MR_SLA_NACK	= 0x48,
!     ATM128_I2C_MR_DATA_ACK	= 0x50,
!     ATM128_I2C_MR_DATA_NACK	= 0x58
  };
  
- /* I2C Status Register -- TWSR */
- typedef union {
-   struct Atm128I2CStatus_s {
-     uint8_t twps  : 2;  //!< Two Wire Prescaler Bits
-     uint8_t rsvd  : 1;  //!< Reserved
-     uint8_t tws   : 5;  //!< Two Wire Status
-   } bits;
-   uint8_t flat;
- } Atm128I2CStatus_t;
- 
- /* I2C Slave Address Register -- TWAR */
- typedef union {
-   struct Atm128I2CSlaveAddr_s {
-     uint8_t twgce : 1;  //!< Two Wire General Call Enable
-     uint8_t twa   : 7;  //!< Two Wire Slave Address
-   } bits;
-   uint8_t flat;
- } Atm128I2CSlaveAddr_t;
- 
- #define avr_i2c_enable()           TWCR |= (1 << TWEN)
- #define avr_i2c_start()            TWCR |= (1 << TWSTA) | (1 << TWINT)
- #define avr_i2c_wait()	           while(!(TWCR & (1<<TWINT))) ;
- 
  #endif // _H_Atm128I2C_h
--- 31,50 ----
  #define ATM128_I2C_SLA_READ 0x01
  
! #define UQ_ATM128_I2CMASTER "Atm128I2CMasterC.I2CPacket"
  
  enum {
!     ATM128_I2C_BUSERROR         = 0x00,
!     ATM128_I2C_START            = 0x08,
!     ATM128_I2C_RSTART           = 0x10,
!     ATM128_I2C_MW_SLA_ACK       = 0x18,
!     ATM128_I2C_MW_SLA_NACK      = 0x20,
!     ATM128_I2C_MW_DATA_ACK      = 0x28,
!     ATM128_I2C_MW_DATA_NACK     = 0x30,
!     ATM128_I2C_M_ARB_LOST       = 0x38,
!     ATM128_I2C_MR_SLA_ACK       = 0x40,
!     ATM128_I2C_MR_SLA_NACK      = 0x48,
!     ATM128_I2C_MR_DATA_ACK      = 0x50,
!     ATM128_I2C_MR_DATA_NACK     = 0x58
  };
  
  #endif // _H_Atm128I2C_h

Index: Atm128I2CMasterC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c/Attic/Atm128I2CMasterC.nc,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -C2 -d -r1.1.2.2 -r1.1.2.3
*** Atm128I2CMasterC.nc	1 May 2006 21:50:50 -0000	1.1.2.2
--- Atm128I2CMasterC.nc	8 Jun 2006 03:22:03 -0000	1.1.2.3
***************
*** 1,43 ****
- /// $Id$
- 
  /*
!  * Copyright (c) 2004-2005 Crossbow Technology, Inc.  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 CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS 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 CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
!  * DAMAGE. 
   *
!  * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL 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 NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
!  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
!  * MODIFICATIONS.
   */
  
  /**
!  * @author Martin Turon <mturon at xbow.com>
   * @author Philip Levis
   */
  
! configuration Atm128I2CMasterC {
!   provides interface AsyncStdControl;
!   provides interface I2CPacket;
  }
  implementation {
!   components HplAtm128I2CBusC, new Atm128I2CMasterP();
!   components NoLedsC, LedsC;
    
!   AsyncStdControl = Atm128I2CMasterP;
!   I2CPacket = Atm128I2CMasterP;
!   Atm128I2CMasterP.I2C -> HplAtm128I2CBusC;
!   Atm128I2CMasterP.WriteLeds -> NoLedsC;
!   Atm128I2CMasterP.ReadLeds -> LedsC;
  }
--- 1,55 ----
  /*
!  * Copyright (c) 2006 Stanford University.
!  * All rights reserved.
   *
!  * Redistribution and use in source and binary forms, with or without
!  * modification, are permitted provided that the following conditions
!  * are met:
!  * - Redistributions of source code must retain the above copyright
!  *   notice, this list of conditions and the following disclaimer.
!  * - Redistributions in binary form must reproduce the above copyright
!  *   notice, this list of conditions and the following disclaimer in the
!  *   documentation and/or other materials provided with the
!  *   distribution.
!  * - Neither the name of the Stanford University nor the names of
!  *   its contributors may be used to endorse or promote products derived
!  *   from this software without specific prior written permission.
   *
!  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
!  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
!  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
!  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD 
!  * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
!  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
!  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
!  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
!  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
!  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
!  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
!  * OF THE POSSIBILITY OF SUCH DAMAGE.
   */
  
  /**
!  * The basic client abstraction of the I2C on the Atmega128. I2C
!  * device drivers should instantiate one of these to ensure
!  * exclusive access to the I2C bus.
!  *
   * @author Philip Levis
+  * @date   May 28, 2006
   */
  
! #include "Atm128I2C.h"
! 
! generic configuration Atm128I2CMasterC() {
!   provides interface Resource;
!   provides interface I2CPacket<TI2CBasicAddr>;
  }
  implementation {
!   enum {
!     CLIENT_ID = unique(UQ_ATM128_I2CMASTER),
!   };
    
!   components Atm128I2CMasterP as I2C; 
!   Resource = I2C.Resource[CLIENT_ID];
!   I2CPacket = I2C.I2CPacket[CLIENT_ID]; 
  }

Index: Atm128I2CMasterP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c/Attic/Atm128I2CMasterP.nc,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -C2 -d -r1.1.2.2 -r1.1.2.3
*** Atm128I2CMasterP.nc	1 May 2006 21:50:50 -0000	1.1.2.2
--- Atm128I2CMasterP.nc	8 Jun 2006 03:22:03 -0000	1.1.2.3
***************
*** 1,280 ****
- /// $Id$
- 
  /*
!  *  Copyright (c) 2004-2005 Crossbow Technology, Inc.
!  *  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 (updated) modification history and the author appear in
!  *  all copies of this source code.
   *
!  *  Permission is also granted to distribute this software under the
!  *  standard BSD license as contained in the TinyOS distribution.
   *
!  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
!  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
!  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
!  *  ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS 
!  *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
!  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, 
!  *  OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
!  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
!  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
!  *  THE POSSIBILITY OF SUCH DAMAGE.
   */
  
- #include "Atm128I2C.h"
- 
  /**
!  * This driver implements an interupt driven I2C Master controller 
!  * Hardware Abstraction Layer (HAL) to the ATmega128 
!  * two-wire-interface (TWI) hardware subsystem.
   *
!  * @author Martin Turon <mturon at xbow.com>
   * @author Philip Levis
-  *
-  * @version $Id$
   */
- generic module Atm128I2CMasterP() {
-   provides interface AsyncStdControl;
-   provides interface I2CPacket;
-   
-   uses interface HplAtm128I2CBus as I2C;
-   uses interface Leds as ReadLeds;
-   uses interface Leds as WriteLeds;
- }
- implementation {
-   task void readDoneTask();
-   task void writeDoneTask();
- 
-   enum {
-     I2C_OFF     = 0,
-     I2C_IDLE    = 1,
-     I2C_READING = 2,
-     I2C_WRITING = 3,
-     I2C_SPINOUT = 10000,
-   } atm128_i2c_state_t;
  
!   uint8_t state = I2C_OFF;
!   
!   uint8_t packetAddr;
!   uint8_t* packetPtr;
!   uint8_t packetLen;
! 
!   async command error_t AsyncStdControl.start() {
!     atomic {
!       if (state == I2C_OFF) {
! 	call I2C.init(FALSE);
! 	call I2C.enable(TRUE);
! 	call I2C.enableAck(TRUE);
! 	state = I2C_IDLE;
! 	return SUCCESS;
!       }
!       else {
! 	return FAIL;
!       }
!     }
!   }
  
-   async command error_t AsyncStdControl.stop() {
-     atomic {
-       if (state == I2C_IDLE) {
- 	call I2C.enable(FALSE);
- 	call I2C.enableInterrupt(FALSE);
- 	call I2C.clearInterruptPending();
- 	call I2C.off();
- 	state = I2C_OFF;
- 	return SUCCESS;
-       }
-       else {
- 	return FAIL;
-       }
-     }
-   }
  
-   error_t i2c_abort() {
-     call I2C.enableInterrupt(FALSE);
-     call I2C.stop();
-     call I2C.clearInterruptPending();
-     return FAIL;
-   }
  
!   bool i2c_wait() {
!     uint16_t i;
!     for (i = 0; i < I2C_SPINOUT; i++) {
!       if (call I2C.isInterruptPending()) {
! 	return TRUE;
!       }
!     }
!     return FALSE;
!   }
    
!   async command error_t I2CPacket.read(uint8_t addr, uint8_t* data, uint8_t len) {
!     uint8_t localLen;
!     bool waitSuccess;
!     atomic {
!       if (state == I2C_IDLE) {
! 	state = I2C_READING;
!       }
!       else if (state == I2C_OFF) {
! 	return EOFF;
!       }
!       else {
! 	return EBUSY;
!       }
!     }
!     /* This follows the procedure described on page 209 of the atmega128L
!      * data sheet. It is synchronous (does not handle interrupts).*/
!     atomic {
!       packetAddr = addr;
!       packetPtr = data;
!       packetLen = len;
!       localLen = len;
!     }
!     /* Clear interrupt pending, send the I2C start command and abort
!        if we're not in the start state.*/
!     call I2C.enableInterrupt(FALSE);
!     call I2C.start();
!     waitSuccess = i2c_wait();
!     if (!waitSuccess || call I2C.status() != ATM128_I2C_START) {
!       call ReadLeds.led1On();
!       return i2c_abort();
!     }
!     
!     /* Clear the start bit, write the address and abort if we're not in
!        the right state. */
!     call I2C.write(addr | ATM128_I2C_SLA_READ);
!     /* We don't need to clear the interrupt pending bit because
!        clearing the start bit will do so automatically (it reads TWINT
!        to be 1, then writes that back). */
!     call I2C.clearStart();
!     waitSuccess = i2c_wait();
!     if (!waitSuccess) {
!       call ReadLeds.led1On();
!       return i2c_abort();
!     }
!     else if (call I2C.status() != ATM128_I2C_MR_SLA_ACK) {
!       call ReadLeds.led2On();
!       return i2c_abort();
!     }
!     
!     /* Read in the data bytes. */
!     for (len = 0; len < localLen; len++) {
!       call I2C.clearInterruptPending();
!       data[len] = call I2C.read();
!       waitSuccess = i2c_wait();
!       if (!waitSuccess) {
! 	call ReadLeds.led2On();	
! 	return i2c_abort();
!       }
!       else if (call I2C.status() != ATM128_I2C_MR_DATA_ACK) {
! 	call ReadLeds.led2On();
! 	return i2c_abort();
!       }
!     }
!     /* Send a stop condition and clear TWINT to send it. */
!     call I2C.stop();
!     post readDoneTask();
!     return SUCCESS;
!   }
! 
!   async command error_t I2CPacket.write(uint8_t addr, uint8_t* data, uint8_t len) {
!     uint8_t localLen;
!     bool waitSuccess;
!     atomic {
!       if (state == I2C_IDLE) {
! 	state = I2C_READING;
!       }
!       else if (state == I2C_OFF) {
! 	return EOFF;
!       }
!       else {
! 	return EBUSY;
!       }
!     }
!     /* This follows the procedure described on page 209 of the atmega128L
!      * data sheet. It is synchronous (does not handle interrupts).*/
!     atomic {
!       packetAddr = addr;
!       packetPtr = data;
!       packetLen = len;
!       localLen = len;
!     }
!     /* Clear interrupt pending, send the I2C start command and abort
!        if we're not in the start state.*/
!     call I2C.enableInterrupt(FALSE);
!     call I2C.start();
!     waitSuccess = i2c_wait();
!     if (!waitSuccess || call I2C.status() != ATM128_I2C_START) {
!       call WriteLeds.led0On();
!       return i2c_abort();
!     }
!     
!     /* Clear the start bit, write the address and abort if we're not in
!        the right state. */
!     call I2C.write(addr | ATM128_I2C_SLA_WRITE);
!     /* We don't need to clear the interrupt pending bit because
!        clearing the start bit will do so automatically (it reads TWINT
!        to be 1, then writes that back). */
!     call I2C.clearStart();
!     waitSuccess = i2c_wait();
!     if (!waitSuccess || call I2C.status() != ATM128_I2C_MW_SLA_ACK) {
!       call WriteLeds.led1On();
!       return i2c_abort();
!     }
      
!     /* Read in the data bytes. */
!     for (len = 0; len < localLen; len++) {
!       call I2C.write(data[len]);
!       call I2C.clearInterruptPending();
!       waitSuccess = i2c_wait();
!       if (!waitSuccess) {
! 	call WriteLeds.led1On();	
! 	return i2c_abort();
!       }
!       else if (call I2C.status() != ATM128_I2C_MW_DATA_ACK) {
! 	call WriteLeds.led2On();
! 	return i2c_abort();
!       }
!     }
! 
!     /* Send a stop condition and clear TWINT to send it. */
!     call I2C.stop();
!     post writeDoneTask();
!     return SUCCESS;
!   }
    
!   task void readDoneTask() {
!     uint8_t addr;
!     uint8_t len;
!     uint8_t* ptr;
! 
!     atomic {
!       addr = packetAddr;
!       len = packetLen;
!       ptr = packetPtr;
!       state = I2C_IDLE;
!     }
!     
!     signal I2CPacket.readDone(addr, ptr, len, SUCCESS);
!   }
    
!   task void writeDoneTask() {
!     uint8_t addr;
!     uint8_t len;
!     uint8_t* ptr;
! 
!     atomic {
!       addr = packetAddr;
!       len = packetLen;
!       ptr = packetPtr;
!       state = I2C_IDLE;
!     }
!     
!     signal I2CPacket.writeDone(addr, ptr, len, SUCCESS);
!   }
  
!   async event void I2C.symbolSent() {}
  }
--- 1,79 ----
  /*
!  * Copyright (c) 2006 Stanford University.
!  * All rights reserved.
   *
!  * Redistribution and use in source and binary forms, with or without
!  * modification, are permitted provided that the following conditions
!  * are met:
!  * - Redistributions of source code must retain the above copyright
!  *   notice, this list of conditions and the following disclaimer.
!  * - Redistributions in binary form must reproduce the above copyright
!  *   notice, this list of conditions and the following disclaimer in the
!  *   documentation and/or other materials provided with the
!  *   distribution.
!  * - Neither the name of the Stanford University nor the names of
!  *   its contributors may be used to endorse or promote products derived
!  *   from this software without specific prior written permission.
   *
!  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
!  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
!  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
!  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
!  * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
!  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
!  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
!  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
!  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
!  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
!  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
!  * OF THE POSSIBILITY OF SUCH DAMAGE.
   */
  
  /**
!  * The configuration that takes the underlying I2C driver on the 
!  * Atmega128 and turns it into a shared abstraction.
   *
!  * @date May 28 2006
   * @author Philip Levis
   */
  
! #include "Atm128I2C.h"
  
  
  
! configuration Atm128I2CMasterP {
!   provides interface Resource[uint8_t client];
!   provides interface I2CPacket<TI2CBasicAddr>[uint8_t client];
! }
! implementation {
!   enum {
!     ATM128_I2C_CLIENT_COUNT = uniqueCount(UQ_ATM128_I2CMASTER),
!   };
    
!   components new FcfsArbiterC(UQ_ATM128_I2CMASTER) as Arbiter;
!   components new AsyncPowerManagerP() as Power;
!   components new Atm128I2CMasterImplP() as I2C;
!   components new Atm128I2CMasterPacketP() as Master;
!   components HplAtm128I2CBusC;
!   components LedsC, NoLedsC, MainC;
      
!   Resource  = I2C;
!   I2CPacket = I2C;
!   MainC.SoftwareInit -> Power;
    
!   I2C.SubResource -> Arbiter;
!   I2C.SubPacket   -> Master;
!   I2C.Atm128I2C -> Master;
!   Power.Leds -> NoLedsC;
!   Arbiter.Leds -> NoLedsC;
    
!   Power.AsyncStdControl -> Master;
!   Power.ResourceController -> Arbiter;
!   Power.ArbiterInit -> Arbiter;
  
!   Master.I2C -> HplAtm128I2CBusC;
!   Master.ReadDebugLeds -> NoLedsC;
!   Master.WriteDebugLeds -> NoLedsC;
!   
  }
+ 

Index: HplAtm128I2CBus.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c/Attic/HplAtm128I2CBus.nc,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -C2 -d -r1.1.2.2 -r1.1.2.3
*** HplAtm128I2CBus.nc	1 May 2006 21:50:50 -0000	1.1.2.2
--- HplAtm128I2CBus.nc	8 Jun 2006 03:22:03 -0000	1.1.2.3
***************
*** 44,73 ****
    
    async command uint8_t status();
-   
-   // Transaction interface
-   async command void start();   //!< Start bus transaction (send start symbol)
-   async command bool isStarting();
-   async command void clearStart();
-   
-   async command void stop();    //!< End bus transaction
-   async command bool isStopping();
  
!   // Data interface
!   async command void write(uint8_t data);
!   async command uint8_t read();
  
    async command void enableAck(bool enable);
!   async command bool isAckEnabled();
    async command void enableInterrupt(bool enable);
    async command bool isInterruptEnabled();
!   async command bool isInterruptPending();
!   async command void clearInterruptPending();
!   
!   async event void symbolSent();
    
!   async command void enable(bool enable);
!   async command bool isEnabled();
  
    async command bool hasWriteCollided();
  
  }
--- 44,86 ----
    
    async command uint8_t status();
  
!   async command void readCurrent();
!   async command void sendCommand();
!   async event void commandComplete();
  
+   
+   // Transaction interface
+   async command void setStart(bool on);
+   async command bool hasStart();
+   async command void setStop(bool on);   
+   async command bool hasStop();
    async command void enableAck(bool enable);
!   async command bool hasAcks();
!   
    async command void enableInterrupt(bool enable);
    async command bool isInterruptEnabled();
! 
!   // Examines actual register. Included so that code which needs
!   // to spin in TWINT does not have to read out cached copies.
!   async command bool isRealInterruptPending();
! 
!   // Operates on cached copy (from readCurrent)
!   async command bool isInterruptPending(); 
    
!   // NOTE: writing a 1 in the interrupt pending bit (TWINT) of the
!   // atm128 I2C control register (TWCR) will *clear* the bit if it
!   // is set. This is how you tell the I2C to take the next action,
!   // as when the bit is cleared it starts the next operation.
!   async command void setInterruptPending(bool on);
  
+   async command void enable(bool on);
+   async command bool isEnabled();
    async command bool hasWriteCollided();
+   
+   // Data interface to TWDR
+   async command void write(uint8_t data);
+   async command uint8_t read();
+   
+   
  
  }

Index: HplAtm128I2CBusP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c/Attic/HplAtm128I2CBusP.nc,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -C2 -d -r1.1.2.2 -r1.1.2.3
*** HplAtm128I2CBusP.nc	1 May 2006 21:50:50 -0000	1.1.2.2
--- HplAtm128I2CBusP.nc	8 Jun 2006 03:22:03 -0000	1.1.2.3
***************
*** 26,30 ****
   */
  
- #define I2C_TIMEOUT 30000
  #define F_CPU       7372800
  
--- 26,29 ----
***************
*** 50,54 ****
  }
  implementation {
! 
    async command void I2C.init(bool hasExternalPulldown) {
      // Set the internal pullup resisters
--- 49,54 ----
  }
  implementation {
!   uint8_t current;
!   
    async command void I2C.init(bool hasExternalPulldown) {
      // Set the internal pullup resisters
***************
*** 76,101 ****
      return TWSR & 0xf8;
    }
    
    /** Send START symbol and begin I2C bus transaction. */
!   async command void I2C.start() {
!     SET_BIT(TWCR, TWSTA);
!   }
!   async command bool I2C.isStarting() {
!     return READ_BIT(TWCR, TWSTA);
    }
!   async command void I2C.clearStart() {
!     CLR_BIT(TWCR, TWSTA);
    }
!   
!   /** Signal STOP and end I2C bus transaction. */
!   async command void I2C.stop() {
!     uint8_t tmp = TWCR;
!     tmp |= (1 << TWSTO);
!     tmp &= ~(1 << TWEA);
!     TWCR = tmp;
!     //SET_BIT(TWCR, TWSTO);
    }
!   async command bool I2C.isStopping() {
!     return READ_BIT(TWCR, TWSTO);
    }
    
--- 76,111 ----
      return TWSR & 0xf8;
    }
+ 
+   async command void I2C.sendCommand() {
+     atomic TWCR = current;
+   }
+ 
+   async command void I2C.readCurrent() {
+     atomic current = TWCR;
+   }
    
    /** Send START symbol and begin I2C bus transaction. */
!   async command void I2C.setStart(bool on) {
!     if (on) {
!       atomic SET_BIT(current, TWSTA);
!     }
!     else {
!       atomic CLR_BIT(current, TWSTA);
!     }
    }
!   async command bool I2C.hasStart() {
!     return READ_BIT(current, TWSTA);
    }
! 
!   async command void I2C.setStop(bool on) {
!     if (on) {
!       atomic SET_BIT(current, TWSTO);
!     }
!     else {
!       atomic CLR_BIT(current, TWSTO);
!     }
    }
!   async command bool I2C.hasStop() {
!     return READ_BIT(current, TWSTO);
    }
    
***************
*** 111,166 ****
    async command void I2C.enableAck(bool enable) {
      if (enable) {
!       SET_BIT(TWCR, TWEA);
      }
      else {
!       CLR_BIT(TWCR, TWEA);
      }
    }
    
!   async command bool I2C.isAckEnabled() {
!     return READ_BIT(TWCR, TWEA);
    }
    
    async command void I2C.enableInterrupt(bool enable) {
      if (enable) {
!       SET_BIT(TWCR, TWIE);
      }
      else {
!       CLR_BIT(TWCR, TWIE);
      }
    }
  
    async command bool I2C.isInterruptEnabled() {
!     return READ_BIT(TWCR, TWIE);
    }
    
!   async command bool I2C.isInterruptPending() {
      return READ_BIT(TWCR, TWINT);
    }
!   
!   async command void I2C.clearInterruptPending() {
!     SET_BIT(TWCR, TWINT);
    }
    
    async command void I2C.enable(bool enable) {
      if (enable) {
!       SET_BIT(TWCR, TWEN);
      }
      else {
!       CLR_BIT(TWCR, TWEN);
      }
    }
  
    async command bool I2C.isEnabled() {
!     return READ_BIT(TWCR, TWEN);
    }
  
    async command bool I2C.hasWriteCollided() {
!     return READ_BIT(TWCR, TWWC);
    }
  
!   default async event void I2C.symbolSent() { }
!   AVR_NONATOMIC_HANDLER(SIG_2WIRE_SERIAL) {
!     signal I2C.symbolSent();
    }
  }
--- 121,185 ----
    async command void I2C.enableAck(bool enable) {
      if (enable) {
!       atomic SET_BIT(current, TWEA);
      }
      else {
!       atomic CLR_BIT(current, TWEA);
      }
    }
    
!   async command bool I2C.hasAcks() {
!     return READ_BIT(current, TWEA);
    }
    
    async command void I2C.enableInterrupt(bool enable) {
      if (enable) {
!       atomic SET_BIT(current, TWIE);
      }
      else {
!       atomic CLR_BIT(current, TWIE);
      }
    }
  
    async command bool I2C.isInterruptEnabled() {
!     return READ_BIT(current, TWIE);
    }
    
!   async command bool I2C.isRealInterruptPending() {
      return READ_BIT(TWCR, TWINT);
    }
! 
!   async command bool I2C.isInterruptPending() {
!     return READ_BIT(current, TWINT);
!   }
! 
!   async command void I2C.setInterruptPending(bool on) {
!     if (on) {
!       atomic SET_BIT(current, TWINT);
!     }
!     else {
!       atomic CLR_BIT(current, TWINT);
!     }
    }
    
    async command void I2C.enable(bool enable) {
      if (enable) {
!       atomic SET_BIT(current, TWEN);
      }
      else {
!       atomic CLR_BIT(current, TWEN);
      }
    }
  
    async command bool I2C.isEnabled() {
!     return READ_BIT(current, TWEN);
    }
  
    async command bool I2C.hasWriteCollided() {
!     return READ_BIT(current, TWWC);
    }
  
!   default async event void I2C.commandComplete() { }
!   AVR_ATOMIC_HANDLER(SIG_2WIRE_SERIAL) {
!     signal I2C.commandComplete();
    }
  }



More information about the Tinyos-2-commits mailing list