[Tinyos-commits] CVS: tinyos-1.x/tos/platform/msp430 HPLI2CInterrupt.nc, NONE, 1.1 MSP430I2C.nc, NONE, 1.1 MSP430I2CC.nc, NONE, 1.1 MSP430I2CEvents.nc, NONE, 1.1 MSP430I2CM.nc, NONE, 1.1 MSP430I2CPacket.nc, NONE, 1.1 msp430usart.h, NONE, 1.1 HPLUSART0M.nc, 1.8, 1.9 HPLUSART1M.nc, 1.7, 1.8 HPLUSARTControl.nc, 1.3, 1.4 msp430hardware.h, 1.20, 1.21

Joe Polastre jpolastre at users.sourceforge.net
Sun Jan 23 18:33:07 PST 2005


Update of /cvsroot/tinyos/tinyos-1.x/tos/platform/msp430
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25144

Modified Files:
	HPLUSART0M.nc HPLUSART1M.nc HPLUSARTControl.nc 
	msp430hardware.h 
Added Files:
	HPLI2CInterrupt.nc MSP430I2C.nc MSP430I2CC.nc 
	MSP430I2CEvents.nc MSP430I2CM.nc MSP430I2CPacket.nc 
	msp430usart.h 
Log Message:
initial checkin of hardware i2c module driver for msp430 microcontrollers
supports the f15x and f16x series of microcontrollers as well as any others
that have the built in hardware i2c module.  it does not support the f14x
series of devices, such as the f149, which much implement i2c in software.

The main logic for the I2C module is in MSP430I2CM, which uses the
underlying HPLUSART0M to set USART0 to I2C mode when necessary.
MSP430I2CM also exposes the MSP430I2CPacket interface, which is the
easiest way to send and receive data from a slave device where the MSP430
is the master on the i2c bus.  MSP430I2CM also exposes a number of other
primitives to build slave I2C implementations above the HAL provided by
MSP430I2CM.  

Developers should wire to MSP430I2CC, which performs the underlying
wiring for MSP430I2CM.

The implementation committed here has been tested for both reading and
writing to the Analog Devices AD5242 digital potentiometer.  Please report
bugs to tinyos-help at millennium.berkeley.edu





--- NEW FILE: HPLI2CInterrupt.nc ---
/*
 * Copyright (c) 2004, Technische Universitat Berlin
 * 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 Technische Universitat Berlin 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 THE COPYRIGHT 
 * OWNER OR 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.
 *
 * - Description ----------------------------------------------------------
 * Feedback from the USART. 
 * - Revision -------------------------------------------------------------
 * $Revision: 1.1 $
 * $Date: 2005/01/24 02:33:04 $
 * @author: Jan Hauer (hauer at tkn.tu-berlin.de)
 * ========================================================================
 */
 
interface HPLI2CInterrupt {

  /**
   * Signals that an I2C Interrupt has occurred.
   */
  async event void fired();

}


--- NEW FILE: MSP430I2C.nc ---
// $Id: MSP430I2C.nc,v 1.1 2005/01/24 02:33:04 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
 * Revision:  $Revision: 1.1 $
 *
 */
interface MSP430I2C {
  /**
   * Enable the I2C module (set the I2CEN bit)
   */
  async command result_t enable();
  /**
   * Disable the I2C module (clear the I2CEN bit)
   */
  async command result_t disable();

  /**
   * Set Master I2C mode
   */
  async command result_t setModeMaster();
  /**
   * Set Slave I2C mode
   */
  async command result_t setModeSlave();

  /**
   * Use 7-bit addressing mode
   */
  async command result_t setAddr7bit();
  /**
   * Use 10-bit addressing mode
   */
  async command result_t setAddr10bit();

  /**
   * Set the MSP430's own address
   */
  async command result_t setOwnAddr(uint16_t addr);
  /**
   * Set the slave address of the device for the next i2c bus transaction
   */
  async command result_t setSlaveAddr(uint16_t addr);

  /**
   * Only valid in Master mode.  Set the next i2c bus transaction to
   * transmit to a slave device.
   */
  async command result_t setTx();
  /**
   * Only valid in Master mode.  Set the next i2c bus transaction to
   * receive from a slave device.
   */
  async command result_t setRx();

  /**
   * Set the data to transmit in the I2C data register.
   */
  async command result_t setData(uint16_t value);
  /**
   * Get data from the I2C data register when in receive mode.
   */
  async command uint16_t getData();

  /**
   * Set the number of bytes to transmit or receive in master mode.
   */
  async command result_t setByteCount(uint8_t value);
  /**
   * Number of bytes to transmit or receive remaining in master mode.
   */
  async command uint8_t  getByteCount();

  async command result_t isArbitrationLostPending();
  async command result_t isNoAckPending();
  async command result_t isOwnAddrPending();
  async command result_t isReadyRegAccessPending();
  async command result_t isReadyRxDataPending();
  async command result_t isReadyTxDataPending();
  async command result_t isGeneralCallPending();
  async command result_t isStartRecvPending();

  async command void enableArbitrationLost();
  async command void disableArbitrationLost();

  async command void enableNoAck();
  async command void disableNoAck();

  async command void enableOwnAddr();
  async command void disableOwnAddr();

  async command void enableReadyRegAccess();
  async command void disableReadyRegAccess();

  async command void enableReadyRxData();
  async command void disableReadyRxData();

  async command void enableReadyTxData();
  async command void disableReadyTxData();

  async command void enableGeneralCall();
  async command void disableGeneralCall();

  async command void enableStartRecv();
  async command void disableStartRecv();

}

--- NEW FILE: MSP430I2CC.nc ---
// $Id: MSP430I2CC.nc,v 1.1 2005/01/24 02:33:04 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
 * Revision:  $Revision: 1.1 $
 *
 * Primitives for accessing the hardware I2C module on MSP430 microcontrollers.
 * This configuration assumes that the bus is available and reserved 
 * prior to use; aka Bus Arbitration occurs before start() is called.
 * Once the bus is acquired, call start() and then the commands in this module
 * may be used.  Likewise, stop() should be called before releasing the bus.
 */

configuration MSP430I2CC
{
  provides {
    interface StdControl;
    interface MSP430I2C;
    interface MSP430I2CPacket;
    interface MSP430I2CEvents;
  }
}
implementation
{
  components HPLUSART0M, MSP430I2CM as I2CM;

  StdControl = I2CM;
  MSP430I2C = I2CM;
  MSP430I2CPacket = I2CM;
  MSP430I2CEvents = I2CM;

  I2CM.USARTControl -> HPLUSART0M;
  I2CM.HPLI2CInterrupt -> HPLUSART0M;
}

--- NEW FILE: MSP430I2CEvents.nc ---
// $Id: MSP430I2CEvents.nc,v 1.1 2005/01/24 02:33:04 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
 * Revision:  $Revision: 1.1 $
 *
 */
 
interface MSP430I2CEvents
{
  async event void arbitrationLost();
  async event void noAck();
  async event void ownAddr();
  async event void readyRegAccess();
  async event void readyRxData();
  async event void readyTxData();
  async event void generalCall();
  async event void startRecv();
}


--- NEW FILE: MSP430I2CM.nc ---
// $Id: MSP430I2CM.nc,v 1.1 2005/01/24 02:33:04 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
 * Revision:  $Revision: 1.1 $
 * 
 * Primitives for accessing the hardware I2C module on MSP430 microcontrollers.
 * This module assumes that the bus is available and reserved prior to the
 * commands in this module being invoked.  Most applications will use the
 * readPacket and writePacket interfaces as they provide the master-mode
 * read and write operations from/to a slave device.  An I2C slave
 * implementation may be built above the primitives provided in this module.
 */

includes msp430usart;

module MSP430I2CM
{
  provides {
    interface StdControl;
    interface MSP430I2C;
    interface MSP430I2CPacket;
    interface MSP430I2CEvents;
  }
  uses {
    interface HPLUSARTControl as USARTControl;
    interface HPLI2CInterrupt;
  }
}
implementation
{
  // 16-bit writes are atomic
  MSP430REG_NORACE(I2COA);
  MSP430REG_NORACE(I2CSA);
  MSP430REG_NORACE(I2CNDAT);
  MSP430REG_NORACE(I2CDR);
  MSP430REG_NORACE(I2CTCTL);

#ifndef __msp430_have_usart0_with_i2c
#error MSP430I2C: Compiling with hardware I2C support, but MCU does not support I2C
#endif

  // init() command causes nesC to complain about a race condition
  // other variables protected by only being modified when the stateI2C
  // variable allows modification (ie stateI2C != IDLE)
  norace uint8_t stateI2C;
  uint8_t length;
  uint8_t ptr;
  norace result_t result;
  uint8_t* data;
  msp430_usartmode_t usart_mode;

  enum {
    OFF = 1,
    IDLE,
    PACKET_WRITE,
    PACKET_READ
  };

  task void readDone() {
    // variables protected from change by the stateI2C state machine
    result_t _result;
    uint8_t _length;
    uint8_t* _data;
    uint16_t _addr;

    _result = result;
    _length = length;
    _data = data;
    _addr = I2CSA;

    atomic stateI2C = IDLE;
    signal MSP430I2CPacket.readPacketDone(_addr, _length, _data, _result);
  }

  task void writeDone() {
    // variables protected from change by the stateI2C state machine
    result_t _result;
    uint8_t _length;
    uint8_t* _data;
    uint16_t _addr;

    _result = result;
    _length = length;
    _data = data;
    _addr = I2CSA;

    // wait for the module to finish its transmission
    // spin only lasts ~4bit times == 4us.
    while (I2CDCTL & I2CBUSY) ;

    atomic stateI2C = IDLE;
    signal MSP430I2CPacket.writePacketDone(_addr, _length, _data, _result);
  }

  command result_t StdControl.init() {
    // init does not apply to "non-atomic access to shared variable"
    stateI2C = OFF;
    return SUCCESS;
  }

  command result_t StdControl.start() {
    uint8_t _state = 0;
    
    atomic {
      _state = stateI2C;
      if (_state == OFF) 
	stateI2C = IDLE;
    }

    if (_state == OFF) {
      usart_mode = call USARTControl.getMode();
      if (usart_mode != USART_I2C)
	call USARTControl.setModeI2C();
      return SUCCESS;
    }
    else if (_state == IDLE)
      return SUCCESS;

    return FAIL;
  }

  command result_t StdControl.stop() {
    atomic {
      stateI2C = OFF;
      call MSP430I2C.disable();
    }
    call USARTControl.setMode(usart_mode);
    return SUCCESS;
  }

  async command result_t MSP430I2C.isArbitrationLostPending() {
    if (I2CIFG & ALIFG){
      I2CIFG &= ~ALIFG;
      return SUCCESS;
    }
    return FAIL;
  }

  async command result_t MSP430I2C.isNoAckPending() {
    if (I2CIFG & NACKIFG){
      I2CIFG &= ~NACKIFG;
      return SUCCESS;
    }
    return FAIL;
  }

  async command result_t MSP430I2C.isOwnAddrPending() {
    if (I2CIFG & OAIFG){
      I2CIFG &= ~OAIFG;
      return SUCCESS;
    }
    return FAIL;
  }

  async command result_t MSP430I2C.isReadyRegAccessPending() {
    if (I2CIFG & ARDYIFG){
      I2CIFG &= ~ARDYIFG;
      return SUCCESS;
    }
    return FAIL;
  }

  async command result_t MSP430I2C.isReadyRxDataPending() {
    if (I2CIFG & RXRDYIFG){
      I2CIFG &= ~RXRDYIFG;
      return SUCCESS;
    }
    return FAIL;
  }

  async command result_t MSP430I2C.isReadyTxDataPending() {
    if (I2CIFG & TXRDYIFG){
      I2CIFG &= ~TXRDYIFG;
      return SUCCESS;
    }
    return FAIL;
  }

  async command result_t MSP430I2C.isGeneralCallPending() {
    if (I2CIFG & GCIFG){
      I2CIFG &= ~GCIFG;
      return SUCCESS;
    }
    return FAIL;
  }

  async command result_t MSP430I2C.isStartRecvPending() {
    if (I2CIFG & STTIFG){
      I2CIFG &= ~STTIFG;
      return SUCCESS;
    }
    return FAIL;
  }

  async command void MSP430I2C.enableArbitrationLost() {
    atomic I2CIE |= ALIE;
  }
  async command void MSP430I2C.enableNoAck() {
    atomic I2CIE |= NACKIE;
  }
  async command void MSP430I2C.enableOwnAddr() {
    atomic I2CIE |= OAIE;
  }
  async command void MSP430I2C.enableReadyRegAccess() {
    atomic I2CIE |= ARDYIE;
  }
  async command void MSP430I2C.enableReadyRxData() {
    atomic I2CIE |= RXRDYIE;
  }
  async command void MSP430I2C.enableReadyTxData() {
    atomic I2CIE |= TXRDYIE;
  }
  async command void MSP430I2C.enableGeneralCall() {
    atomic I2CIE |= GCIE;
  }
  async command void MSP430I2C.enableStartRecv() {
    atomic I2CIE |= STTIE;
  }

  async command void MSP430I2C.disableArbitrationLost() {
    atomic I2CIE &= ~ALIE;
  }
  async command void MSP430I2C.disableNoAck() {
    atomic I2CIE &= ~NACKIE;
  }
  async command void MSP430I2C.disableOwnAddr() {
    atomic I2CIE &= ~OAIE;
  }
  async command void MSP430I2C.disableReadyRegAccess() {
    atomic I2CIE &= ~ARDYIE;
  }
  async command void MSP430I2C.disableReadyRxData() {
    atomic I2CIE &= ~RXRDYIE;
  }
  async command void MSP430I2C.disableReadyTxData() {
    atomic I2CIE &= ~TXRDYIE;
  }
  async command void MSP430I2C.disableGeneralCall() {
    atomic I2CIE &= ~GCIE;
  }
  async command void MSP430I2C.disableStartRecv() {
    atomic I2CIE &= ~STTIE;
  }

  async command result_t MSP430I2C.setModeMaster() {
    bool _res = FAIL;
    atomic {
      if (call USARTControl.isI2C()) {
	U0CTL |= MST;
	_res = SUCCESS;
      }
    }
    return _res;
  }

  async command result_t MSP430I2C.setModeSlave() {
    bool _res = FAIL;
    atomic {
      if (call USARTControl.isI2C()) {
	U0CTL &= ~MST;
	_res = SUCCESS;
      }
    }
    return _res;
  }

  async command result_t MSP430I2C.setAddr7bit() {
    bool _res = FAIL;
    atomic {
      if (call USARTControl.isI2C()) {
	U0CTL &= ~XA;
	_res = SUCCESS;
      }
    }
    return _res;
  }

  async command result_t MSP430I2C.setAddr10bit() {
    bool _res = FAIL;
    atomic {
      if (call USARTControl.isI2C()) {
	U0CTL |= XA;
	_res = SUCCESS;
      }
    }
    return _res;
  }

  async command result_t MSP430I2C.setOwnAddr(uint16_t _addr) {
    bool _res = FAIL;
    atomic {
      if (call USARTControl.isI2C()) {
	U0CTL &= ~I2CEN;
	I2COA = _addr;
	U0CTL |= I2CEN;
	_res = SUCCESS;
      }
    }
    return _res;
  }

  async command result_t MSP430I2C.setSlaveAddr(uint16_t _addr) {
    I2CSA = _addr;
  }

  // only valid in master mode
  async command result_t MSP430I2C.setTx() {
    bool _res = FAIL;
    atomic {
      if ((call USARTControl.isI2C()) && (U0CTL & MST)) {
	I2CTCTL |= I2CTRX;
	_res = SUCCESS;
      }
    }
    return _res;
  }

  // only valid in master mode
  async command result_t MSP430I2C.setRx() {
    bool _res = FAIL;
    atomic {
      if ((call USARTControl.isI2C()) && (U0CTL & MST)) {
	I2CTCTL &= ~I2CTRX;
	_res = SUCCESS;
      }
    }
    return _res;
  }

  async command result_t MSP430I2C.setData(uint16_t value) {
    bool _res = FAIL;
    if (call USARTControl.isI2C()) {
      I2CDR = value;
      _res = SUCCESS;
    }
    return _res;
  }

  async command uint16_t MSP430I2C.getData() {
    return I2CDR;
  }

  async command result_t MSP430I2C.setByteCount(uint8_t value) {
    if (call USARTControl.isI2C()) {
      I2CNDAT = value;
      return SUCCESS;
    }
    return FAIL;
  }

  async command uint8_t MSP430I2C.getByteCount() {
    return I2CNDAT;
  }

  async command result_t MSP430I2C.enable() {
    result_t _res = FAIL;
    atomic {
      if (call USARTControl.isI2C()) {
	U0CTL |= I2CEN;
	_res = SUCCESS;
      }
    }
    return _res;
  }

  async command result_t MSP430I2C.disable() {
    result_t _res = FAIL;
    atomic {
      if (call USARTControl.isI2C()) {
	U0CTL &= ~I2CEN;
	_res = SUCCESS;
      }
    }
    return _res;
  }

  command result_t MSP430I2CPacket.readPacket(uint16_t _addr, uint8_t _length, uint8_t* _data) {
    uint8_t _state;

    atomic {
      _state = stateI2C;
      if (_state == IDLE) {
	stateI2C = PACKET_READ;
      }
    }

    if (_state == IDLE) {
      // perform register modifications with interrupts disabled
      // to maintain consistent state
      atomic {
	result = FAIL;

	// disable I2C to set the registers
	U0CTL &= ~I2CEN;

	I2CSA = _addr;

	length = _length;
	data = _data;
	ptr = 0;

	U0CTL |= MST;

	// enable I2C module
	U0CTL |= I2CEN;
	
	I2CNDAT = _length;

	// set transmit mode
	I2CTCTL &= ~I2CTRX;

	// get an event if the receiver does not ACK
	I2CIE = RXRDYIE | NACKIE;
	I2CIFG = 0;

	// start condition and stop condition need to be sent
	I2CTCTL |= (I2CSTP | I2CSTT);
      }

      return SUCCESS;
    }

    return FAIL;
  }

  // handle the interrupt within this component
  void localRxData() {
    uint16_t* _data16 = (uint16_t*)data;

    if (stateI2C != PACKET_READ)
      return;

    // figure out where we are in the transmission
    // should only occur when I2CNDAT > 0
    if (I2CTCTL & I2CWORD) {
      _data16[(int)ptr] = I2CDR;
      ptr = ptr + 2;
    }
    else {
      data[(int)ptr] = I2CDR & 0xFF;
      ptr++;
    }

    I2CIFG = 0;
    
    if (ptr == length) {
      I2CIE &= ~RXRDYIE;
      result = SUCCESS;
      if (!post readDone())
	stateI2C = IDLE;
    }
  }

  command result_t MSP430I2CPacket.writePacket(uint16_t _addr, uint8_t _length, uint8_t* _data) {
    uint8_t _state;

    atomic {
      _state = stateI2C;
      if (_state == IDLE) {
	stateI2C = PACKET_WRITE;
      }
    }

    if (_state == IDLE) {
      // perform register modifications with interrupts disabled
      atomic {
	// disable I2C to set the registers
	result = FAIL;

	U0CTL &= ~I2CEN;

	I2CSA = _addr;
	
	length = _length;
	data = _data;
	ptr = 0;

	U0CTL |= MST;
	
	// enable I2C module
	U0CTL |= I2CEN;
	
	I2CNDAT = _length;

	// set transmit mode
	I2CTCTL |= I2CTRX;

	// get an event if the receiver does not ACK
	I2CIE = TXRDYIE | NACKIE;
	I2CIFG = 0;

	// start condition and stop condition need to be sent
	I2CTCTL |= (I2CSTP | I2CSTT);
      }

      return SUCCESS;
    }

    return FAIL;
  }

  // handle the interrupt within this component
  void localTxData() {
    uint16_t* _data16 = (uint16_t*)data;

    if (stateI2C != PACKET_WRITE)
      return;

    // figure out where we are in the transmission
    // should only occur when I2CNDAT > 0
    if (I2CTCTL & I2CWORD) {
      I2CDR = _data16[(int)ptr];
      ptr = ptr + 2;
    }
    else {
      I2CDR = data[(int)ptr];
      ptr++;
    }

    I2CIFG = 0;
    
    if (ptr == length) {
      I2CIE &= ~TXRDYIE;
      result = SUCCESS;
      if (!post writeDone())
	stateI2C = IDLE;
    }
  }

  // handle the interrupt within this component
  void localNoAck() {
    if ((stateI2C != PACKET_WRITE) || (stateI2C != PACKET_READ))
      return;

    I2CNDAT = 0;

    // issue a stop command to clear the bus if it has not been stopped
    if (I2CDCTL & I2CBB)
      I2CTCTL |= I2CSTP;

    if (stateI2C == PACKET_WRITE) {
      if (!post writeDone())
	stateI2C = IDLE;
    }
    else if (stateI2C == PACKET_READ) {
      if (!post readDone())
	stateI2C = IDLE;
    }
  }

  async event void HPLI2CInterrupt.fired() {
    volatile uint16_t value = I2CIV;
    switch (value) {
    case 0x0000:
      break;
    case 0x0002:
      signal MSP430I2CEvents.arbitrationLost();
      break;
    case 0x0004:
      localNoAck();
      signal MSP430I2CEvents.noAck();
      break;
    case 0x0006:
      signal MSP430I2CEvents.ownAddr();
      break;
    case 0x0008:
      signal MSP430I2CEvents.readyRegAccess();
      break;
    case 0x000A:
      localRxData();
      signal MSP430I2CEvents.readyRxData();
      break;
    case 0x000C:
      localTxData();
      signal MSP430I2CEvents.readyTxData();
      break;
    case 0x000E:
      signal MSP430I2CEvents.generalCall();
      break;
    case 0x0010:
      signal MSP430I2CEvents.startRecv();
      break;
    }
  }

  default event void MSP430I2CPacket.readPacketDone(uint16_t _addr, uint8_t _length, uint8_t* _data, result_t _success) { }
  default event void MSP430I2CPacket.writePacketDone(uint16_t _addr, uint8_t _length, uint8_t* _data, result_t _success) { }

  default async event void MSP430I2CEvents.arbitrationLost() { }
  default async event void MSP430I2CEvents.noAck() { }
  default async event void MSP430I2CEvents.ownAddr() { }
  default async event void MSP430I2CEvents.readyRegAccess() { }
  default async event void MSP430I2CEvents.readyRxData() { }
  default async event void MSP430I2CEvents.readyTxData() { }
  default async event void MSP430I2CEvents.generalCall() { }
  default async event void MSP430I2CEvents.startRecv() { }

}

--- NEW FILE: MSP430I2CPacket.nc ---
interface MSP430I2CPacket {
  command result_t readPacket(uint16_t _addr, uint8_t _length, uint8_t* _data);
  command result_t writePacket(uint16_t _addr, uint8_t _length, uint8_t* _data);

  event void readPacketDone(uint16_t addr, uint8_t length, uint8_t* data, result_t success);
  event void writePacketDone(uint16_t addr, uint8_t length, uint8_t* data, result_t success);
}

--- NEW FILE: msp430usart.h ---
// $Id: msp430usart.h,v 1.1 2005/01/24 02:33:04 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
 * Revision:  $Revision: 1.1 $
 */

#ifndef MSP430USART_H
#define MSP430USART_H

typedef enum
{
  USART_NONE = 0,
  USART_UART = 1,
  USART_UART_TX = 2,
  USART_UART_RX = 3,
  USART_SPI = 4,
  USART_I2C = 5
} msp430_usartmode_t;

#endif

Index: HPLUSART0M.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/tos/platform/msp430/HPLUSART0M.nc,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** HPLUSART0M.nc	26 Jun 2004 02:33:40 -0000	1.8
--- HPLUSART0M.nc	24 Jan 2005 02:33:04 -0000	1.9
***************
*** 1,4 ****
  /*
!  * Copyright (c) 2004, Technische Universitat Berlin
   * All rights reserved.
   *
--- 1,4 ----
  /*
!  * Copyright (c) 2004-2005, Technische Universitat Berlin
   * All rights reserved.
   *
***************
*** 41,44 ****
--- 41,45 ----
    provides interface HPLUSARTControl as USARTControl;
    provides interface HPLUSARTFeedback as USARTData;
+   provides interface HPLI2CInterrupt;
  }
  implementation
***************
*** 58,64 ****
    
    TOSH_SIGNAL(UART0TX_VECTOR) {
!     signal USARTData.txDone();
    }
    
    async command void USARTControl.enableUART() {
        ME1 |= (UTXE0 | URXE0);   // USART0 UART module enable
--- 59,158 ----
    
    TOSH_SIGNAL(UART0TX_VECTOR) {
!     if (call USARTControl.isI2C())
!       signal HPLI2CInterrupt.fired();
!     else
!       signal USARTData.txDone();
!   }
! 
!   default async event void HPLI2CInterrupt.fired() { }
!   
!   async command bool USARTControl.isSPI() {
!     bool _ret = FALSE;
!     atomic{
!       if (ME1 & USPIE0)
! 	_ret = TRUE;
!     }
!     return _ret;
    }
    
+   async command bool USARTControl.isUART() {
+     bool _ret = FALSE;
+     atomic {
+       if ((ME1 & UTXE0) && (ME1 & URXE0))
+ 	_ret = TRUE;
+     }
+     return _ret;
+   }
+ 
+   async command bool USARTControl.isUARTtx() {
+     bool _ret = FALSE;
+     atomic {
+       if (ME1 & UTXE0)
+ 	_ret = TRUE;
+     }
+     return _ret;
+   }
+ 
+   async command bool USARTControl.isUARTrx() {
+     bool _ret = FALSE;
+     atomic {
+       if (ME1 & UTXE0)
+ 	_ret = TRUE;
+     }
+     return _ret;
+   }
+   
+   async command bool USARTControl.isI2C() {
+     bool _ret = FALSE;
+ #ifdef __msp430_have_usart0_with_i2c
+     atomic {
+       if ((U0CTL & I2C) && (U0CTL & SYNC))
+ 	_ret = TRUE;
+     }
+ #endif
+     return _ret;
+   }
+ 
+   async command msp430_usartmode_t USARTControl.getMode() {
+     if (call USARTControl.isUART())
+       return USART_UART;
+     else if (call USARTControl.isUARTrx())
+       return USART_UART_RX;
+     else if (call USARTControl.isUARTtx())
+       return USART_UART_TX;
+     else if (call USARTControl.isSPI())
+       return USART_SPI;
+     else if (call USARTControl.isI2C())
+       return USART_I2C;
+     else
+       return USART_NONE;
+   }
+ 
+   /**
+    * Sets the USART mode to one of the options from msp430_usartmode_t
+    * defined in MSP430USART.h
+    */
+   async command void USARTControl.setMode(msp430_usartmode_t _mode) {
+     switch (_mode) {
+     case USART_UART:
+       call USARTControl.setModeUART();
+       break;
+     case USART_UART_RX:
+       call USARTControl.setModeUART_RX();
+       break;
+     case USART_UART_TX:
+       call USARTControl.setModeUART_TX();
+       break;
+     case USART_SPI:
+       call USARTControl.setModeSPI();
+       break;
+     case USART_I2C:
+       call USARTControl.setModeI2C();
+       break;
+     default:
+       break;
+     }
+   }
+ 
    async command void USARTControl.enableUART() {
        ME1 |= (UTXE0 | URXE0);   // USART0 UART module enable
***************
*** 70,74 ****
        TOSH_SEL_URXD0_IOFUNC();
    }
!   
    async command void USARTControl.enableUARTTx() {
        ME1 |= UTXE0;   // USART0 UART Tx module enable
--- 164,168 ----
        TOSH_SEL_URXD0_IOFUNC();
    }
! 
    async command void USARTControl.enableUARTTx() {
        ME1 |= UTXE0;   // USART0 UART Tx module enable
***************
*** 88,92 ****
        TOSH_SEL_URXD0_IOFUNC();
    }
!   
    async command void USARTControl.enableSPI() {
        ME1 |= USPIE0;   // USART0 SPI module enable
--- 182,186 ----
        TOSH_SEL_URXD0_IOFUNC();
    }
! 
    async command void USARTControl.enableSPI() {
        ME1 |= USPIE0;   // USART0 SPI module enable
***************
*** 108,112 ****
        IE1 &= ~(UTXIE0 | URXIE0);  // interrupt disable    
  
!       U0CTL |= SWRST;
        U0CTL |= CHAR | SYNC | MM;  // 8-bit char, SPI-mode, USART as master
        U0CTL &= ~(0x20); 
--- 202,206 ----
        IE1 &= ~(UTXIE0 | URXIE0);  // interrupt disable    
  
!       U0CTL = SWRST;
        U0CTL |= CHAR | SYNC | MM;  // 8-bit char, SPI-mode, USART as master
        U0CTL &= ~(0x20); 
***************
*** 136,140 ****
        ME1 &= ~(UTXE0 | URXE0); //USART UART module disable
        ME1 |= USPIE0;   // USART SPI module enable
!       UCTL0 &= ~SWRST;  
  
        IFG1 &= ~(UTXIFG0 | URXIFG0);
--- 230,234 ----
        ME1 &= ~(UTXE0 | URXE0); //USART UART module disable
        ME1 |= USPIE0;   // USART SPI module enable
!       U0CTL &= ~SWRST;  
  
        IFG1 &= ~(UTXIFG0 | URXIFG0);
***************
*** 146,156 ****
    void setUARTModeCommon() {
      atomic {
!       UCTL0 = SWRST;  
!       UCTL0 |= CHAR;  // 8-bit char, UART-mode
  
        U0RCTL &= ~URXEIE;  // even erroneous characters trigger interrupts
  
!       UCTL0 = SWRST;
!       UCTL0 |= CHAR;  // 8-bit char, UART-mode
  
        if (l_ssel & 0x80) {
--- 240,251 ----
    void setUARTModeCommon() {
      atomic {
!       U0CTL = SWRST;  
!       U0CTL |= CHAR;  // 8-bit char, UART-mode
  
        U0RCTL &= ~URXEIE;  // even erroneous characters trigger interrupts
  
!       
!       U0CTL = SWRST;
!       U0CTL |= CHAR;  // 8-bit char, UART-mode
  
        if (l_ssel & 0x80) {
***************
*** 211,214 ****
--- 306,339 ----
      return;
    }
+ 
+   // i2c enable bit is not set by default
+   async command void USARTControl.setModeI2C() {
+ #ifdef __msp430_have_usart0_with_i2c
+     atomic {
+       TOSH_MAKE_SIMO0_INPUT();
+       TOSH_MAKE_UCLK0_INPUT();
+       TOSH_SEL_SIMO0_MODFUNC();
+       TOSH_SEL_UCLK0_MODFUNC();
+ 
+       IE1 &= ~(UTXIE0 | URXIE0);  // interrupt disable    
+ 
+       U0CTL = SWRST;
+       U0CTL |= SYNC | I2C;  // 7-bit addr, I2C-mode, USART as master
+       U0CTL &= ~I2CEN;
+ 
+       U0CTL |= MST;
+ 
+       I2CTCTL = I2CSSEL_2;        // use 1MHz SMCLK as the I2C reference
+ 
+       I2CPSC = 0x00;              // I2C CLK runs at 1MHz/10 = 100kHz
+       I2CSCLH = 0x03;
+       I2CSCLL = 0x03;
+       
+       I2CIE = 0;                 // clear all I2C interrupt enables
+       I2CIFG = 0;                // clear all I2C interrupt flags
+     }
+ #endif
+     return;
+   }
   
    async command void USARTControl.setClockSource(uint8_t source) {

Index: HPLUSART1M.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/tos/platform/msp430/HPLUSART1M.nc,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** HPLUSART1M.nc	26 Jun 2004 02:33:40 -0000	1.7
--- HPLUSART1M.nc	24 Jan 2005 02:33:04 -0000	1.8
***************
*** 1,4 ****
  /*
!  * Copyright (c) 2004, Technische Universitat Berlin
   * All rights reserved.
   *
--- 1,4 ----
  /*
!  * Copyright (c) 2004-2005, Technische Universitat Berlin
   * All rights reserved.
   *
***************
*** 61,64 ****
--- 61,146 ----
    }
   
+   async command bool USARTControl.isSPI() {
+     bool _ret = FALSE;
+     atomic{
+       if (ME2 & USPIE1)
+ 	_ret = TRUE;
+     }
+     return _ret;
+   }
+   
+   async command bool USARTControl.isUART() {
+     bool _ret = FALSE;
+     atomic {
+       if ((ME2 & UTXE1) && (ME2 & URXE1))
+ 	_ret = TRUE;
+     }
+     return _ret;
+   }
+ 
+   async command bool USARTControl.isUARTtx() {
+     bool _ret = FALSE;
+     atomic {
+       if (ME2 & UTXE1)
+ 	_ret = TRUE;
+     }
+     return _ret;
+   }
+ 
+   async command bool USARTControl.isUARTrx() {
+     bool _ret = FALSE;
+     atomic {
+       if (ME2 & UTXE1)
+ 	_ret = TRUE;
+     }
+     return _ret;
+   }
+   
+   // i2c not supported on USART1
+   async command bool USARTControl.isI2C() {
+     return FALSE;
+   }
+ 
+   async command msp430_usartmode_t USARTControl.getMode() {
+     if (call USARTControl.isUART())
+       return USART_UART;
+     else if (call USARTControl.isUARTrx())
+       return USART_UART_RX;
+     else if (call USARTControl.isUARTtx())
+       return USART_UART_TX;
+     else if (call USARTControl.isSPI())
+       return USART_SPI;
+     else if (call USARTControl.isI2C())
+       return USART_I2C;
+     else
+       return USART_NONE;
+   }
+ 
+   /**
+    * Sets the USART mode to one of the options from msp430_usartmode_t
+    * defined in MSP430USART.h
+    */
+   async command void USARTControl.setMode(msp430_usartmode_t _mode) {
+     switch (_mode) {
+     case USART_UART:
+       call USARTControl.setModeUART();
+       break;
+     case USART_UART_RX:
+       call USARTControl.setModeUART_RX();
+       break;
+     case USART_UART_TX:
+       call USARTControl.setModeUART_TX();
+       break;
+     case USART_SPI:
+       call USARTControl.setModeSPI();
+       break;
+     default:
+       break;
+     }
+   }
+ 
+   // i2c is not available on USART1
+   async command void USARTControl.setModeI2C() { }
+     
    async command void USARTControl.enableUART() {
        ME2 |= (UTXE1 | URXE1);   // USART1 UART module enable
***************
*** 136,140 ****
        ME2 &= ~(UTXE1 | URXE1); //USART UART module disable
        ME2 |= USPIE1;  // USART SPI module enable
!       UCTL1 &= ~SWRST;  
  
        IFG2 &= ~(UTXIFG1 | URXIFG1);
--- 218,222 ----
        ME2 &= ~(UTXE1 | URXE1); //USART UART module disable
        ME2 |= USPIE1;  // USART SPI module enable
!       U1CTL &= ~SWRST;  
  
        IFG2 &= ~(UTXIFG1 | URXIFG1);
***************
*** 146,156 ****
    void setUARTModeCommon() {
      atomic {
!       UCTL1 = SWRST;  
!       UCTL1 |= CHAR;  // 8-bit char, UART-mode
  
        U1RCTL &= ~URXEIE;  // even erroneous characters trigger interrupts
  
!       UCTL1 = SWRST;
!       UCTL1 |= CHAR;  // 8-bit char, UART-mode
  
        if (l_ssel & 0x80) {
--- 228,238 ----
    void setUARTModeCommon() {
      atomic {
!       U1CTL = SWRST;  
!       U1CTL |= CHAR;  // 8-bit char, UART-mode
  
        U1RCTL &= ~URXEIE;  // even erroneous characters trigger interrupts
  
!       U1CTL = SWRST;
!       U1CTL |= CHAR;  // 8-bit char, UART-mode
  
        if (l_ssel & 0x80) {

Index: HPLUSARTControl.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/tos/platform/msp430/HPLUSARTControl.nc,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** HPLUSARTControl.nc	10 Jun 2004 15:04:48 -0000	1.3
--- HPLUSARTControl.nc	24 Jan 2005 02:33:04 -0000	1.4
***************
*** 1,4 ****
  /*
!  * Copyright (c) 2004, Technische Universität Berlin
   * All rights reserved.
   *
--- 1,4 ----
  /*
!  * Copyright (c) 2004-2005, Technische Universität Berlin
   * All rights reserved.
   *
***************
*** 36,45 ****
   * $Revision$
   * $Date$
!  * @author: Jan Hauer (hauer at tkn.tu-berlin.de)
   * ========================================================================
   */
   
  interface HPLUSARTControl {
  
   /**
     * Enables both the Rx and the Tx UART modules.
--- 36,78 ----
   * $Revision$
   * $Date$
!  * @author Jan Hauer (hauer at tkn.tu-berlin.de)
!  * @author Joe Polastre
   * ========================================================================
   */
   
+ includes msp430usart;
+ 
  interface HPLUSARTControl {
  
+   /**
+    * Returns an enum value corresponding to the current mode of the USART
+    * module.  Allows one to read the module mode, change it, and then
+    * reset it back to its original state after use.
+    */
+   async command msp430_usartmode_t getMode();
+ 
+   /**
+    * Sets the USART mode to one of the options from msp430_usartmode_t
+    * defined in MSP430USART.h
+    *
+    * @return SUCCESS if the mode was changed
+    */
+   async command void setMode(msp430_usartmode_t mode);
+ 
+   /**
+    * Returns TRUE if the USART has UART TX mode enabled
+    */
+   async command bool isUARTtx();
+ 
+   /**
+    * Returns TRUE if the USART has UART RX mode enabled
+    */
+   async command bool isUARTrx();
+ 
+   /**
+    * Returns TRUE if the USART is set to UART mode (both RX and TX)
+    */
+   async command bool isUART();
+ 
   /**
     * Enables both the Rx and the Tx UART modules.
***************
*** 82,85 ****
--- 115,124 ----
    async command void disableSPI();
    
+ 
+   /**
+    * Returns TRUE if the USART is set to SPI mode
+    */
+   async command bool isSPI();
+ 
   /**
     * Switches USART to SPI mode.
***************
*** 104,107 ****
--- 143,158 ----
     */	
    async command void setModeUART();
+ 
+   /**
+    * Returns TRUE if the module is set to I2C mode for MSP430 parts that
+    * support hardware I2C.
+    */
+   async command bool isI2C();
+ 
+   /**
+    * Switches USART to I2C mode for MSP430 parts that support
+    * hardware I2C. Interrupts disabled by default.
+    */
+   async command void setModeI2C();
   
    async command void setClockSource(uint8_t source);

Index: msp430hardware.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/tos/platform/msp430/msp430hardware.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** msp430hardware.h	10 Jan 2005 12:08:58 -0000	1.20
--- msp430hardware.h	24 Jan 2005 02:33:04 -0000	1.21
***************
*** 125,128 ****
--- 125,136 ----
  #endif
  
+ // I2CBusy flag is not defined by current MSP430-GCC
+ #ifdef __msp430_have_usart0_with_i2c
+ #define I2CBUSY   (0x01 << 5)
+ MSP430REG_NORACE2(U0CTLnr,U0CTL);
+ MSP430REG_NORACE2(I2CTCTLnr,I2CTCTL);
+ MSP430REG_NORACE2(I2CDCTLnr,I2CDCTL);
+ #endif
+ 
  // The signal attribute has opposite meaning in msp430-gcc than in avr-gcc
  #define TOSH_SIGNAL(signame) \
***************
*** 217,221 ****
    // use MCLK or SMCLK and switch to the lowest LPM that keeps 
    // the required clock(s) running. 
-   
    extern uint8_t TOSH_sched_full;
    extern volatile uint8_t TOSH_sched_free;
--- 225,228 ----
***************
*** 234,238 ****
           && ((TACTL & TASSEL_3) == TASSEL_2))
        || ((ME1 & (UTXE0 | URXE0)) && (U0TCTL & SSEL1))
!       || ((ME2 & (UTXE1 | URXE1)) && (U1TCTL & SSEL1)) )
        LPMode_bits = LPM1_bits;
      // ADC12 check  
--- 241,251 ----
           && ((TACTL & TASSEL_3) == TASSEL_2))
        || ((ME1 & (UTXE0 | URXE0)) && (U0TCTL & SSEL1))
!       || ((ME2 & (UTXE1 | URXE1)) && (U1TCTL & SSEL1)) 
! #ifdef __msp430_have_usart0_with_i2c
!       // registers end in "nr" to prevent nesC race condition detection
!       || ((U0CTLnr & I2CEN) && (I2CTCTLnr & SSEL1) &&
! 	  (I2CDCTLnr & I2CBUSY) && (U0CTLnr & SYNC) && (U0CTLnr & I2C))
! #endif	
!       )
        LPMode_bits = LPM1_bits;
      // ADC12 check  
***************
*** 249,253 ****
      __asm__ __volatile__( "bis  %0, r2" : : "m" ((uint16_t)LPMode_bits) );
    }
-   
  }
  
--- 262,265 ----



More information about the Tinyos-commits mailing list