[Tinyos-2-commits]
CVS: tinyos-2.x/tos/chips/atm128/i2c Atm128I2C.h, 1.1.2.3,
1.1.2.4 Atm128I2CMasterC.nc, 1.1.2.1,
1.1.2.2 Atm128I2CMasterP.nc, 1.1.2.1,
1.1.2.2 HplAtm128I2CBus.nc, 1.1.2.1,
1.1.2.2 HplAtm128I2CBusC.nc, 1.1.2.1,
1.1.2.2 HplAtm128I2CBusP.nc, 1.1.2.1, 1.1.2.2
Phil Levis
scipio at users.sourceforge.net
Mon May 1 14:50:52 PDT 2006
Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9424
Modified Files:
Tag: tinyos-2_0_devel-BRANCH
Atm128I2C.h Atm128I2CMasterC.nc Atm128I2CMasterP.nc
HplAtm128I2CBus.nc HplAtm128I2CBusC.nc HplAtm128I2CBusP.nc
Log Message:
Rewrite of the I2C code. It's fully synchronous now. Future work includes
making it async in the same way as SPI.
The low-level I2C interface needs work; the way that the TWINT bit of
the TSCR works is problematic, in that you cannot write bits without
also twiddling TWINT.
Index: Atm128I2C.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c/Attic/Atm128I2C.h,v
retrieving revision 1.1.2.3
retrieving revision 1.1.2.4
diff -C2 -d -r1.1.2.3 -r1.1.2.4
*** Atm128I2C.h 27 Jan 2006 23:13:22 -0000 1.1.2.3
--- Atm128I2C.h 1 May 2006 21:50:50 -0000 1.1.2.4
***************
*** 28,33 ****
#define _H_Atm128I2C_h
! #define ATM128_I2C_SLA_W 0x00
! #define ATM128_I2C_SLA_R 0x01
typedef uint8_t Atm128_TWBR_t; //!< Two Wire Bit Rate Register
--- 28,33 ----
#define _H_Atm128I2C_h
! #define ATM128_I2C_SLA_WRITE 0x00
! #define ATM128_I2C_SLA_READ 0x01
typedef uint8_t Atm128_TWBR_t; //!< Two Wire Bit Rate Register
Index: Atm128I2CMasterC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c/Attic/Atm128I2CMasterC.nc,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -C2 -d -r1.1.2.1 -r1.1.2.2
*** Atm128I2CMasterC.nc 27 Jan 2006 22:19:36 -0000 1.1.2.1
--- Atm128I2CMasterC.nc 1 May 2006 21:50:50 -0000 1.1.2.2
***************
*** 1,5 ****
/// $Id$
! /**
* Copyright (c) 2004-2005 Crossbow Technology, Inc. All rights reserved.
*
--- 1,5 ----
/// $Id$
! /*
* Copyright (c) 2004-2005 Crossbow Technology, Inc. All rights reserved.
*
***************
*** 23,36 ****
*/
! /// @author Martin Turon <mturon at xbow.com>
! generic configuration HalI2CMasterC (uint8_t device)
! {
! provides interface HalI2CMaster as I2CDevice;
}
implementation {
! components HplI2CBusC, new HalI2CMasterP(device);
!
! I2CDevice = HalI2CMasterP;
! HalI2CMasterP.I2C -> HplI2CBusC;
}
--- 23,43 ----
*/
! /**
! * @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;
}
Index: Atm128I2CMasterP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c/Attic/Atm128I2CMasterP.nc,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -C2 -d -r1.1.2.1 -r1.1.2.2
*** Atm128I2CMasterP.nc 27 Jan 2006 22:19:36 -0000 1.1.2.1
--- Atm128I2CMasterP.nc 1 May 2006 21:50:50 -0000 1.1.2.2
***************
*** 34,196 ****
*
* @author Martin Turon <mturon at xbow.com>
*
! * @version 2005/9/11 mturon Initial version
*/
! generic module HalI2CMasterP (uint8_t device)
! {
! provides {
! interface HalI2CMaster as I2CDevice;
! }
! uses {
! interface HplI2CBus as I2C;
! }
}
implementation {
! enum {
! I2C_READY,
! I2C_PING,
! I2C_READ,
! I2C_WRITE,
! };
!
! uint8_t i2cMode; //!< What type of transaction are we working on?
! uint8_t i2cOffset; //!< Offset address into device memmap to read/write
! int8_t i2cLength; //!< Length of data to read/write
!
! norace uint8_t *i2cData; //!< Pointer to next data byte
!
! /**
! * An efficient I2C engine for the ATmega128. This task handles state
! * transitions triggered by the .symbolDone() interrupt of the hardware
! * I2C subsystem. The hardware stores actual subtransaction state in
! * the status register. The type of user transaction (i2cMode) drives
! * this engine at a higher level.
! *
! * @author Martin Turon
! *
! * @version 2005/9/10 mturon Initial version
! */
! void task i2cEngine() {
! uint8_t state = call I2C.status();
!
! switch (i2cMode) {
! case I2C_PING:
! case I2C_READ:
! switch (state) {
! case ATM128_I2C_START:
! call I2C.deviceRead(device); // talk in read mode
! call I2C.send();
! break;
!
! case ATM128_I2C_MR_SLA_ACK:
! case ATM128_I2C_MR_DATA_ACK:
! if (i2cLength-- > 0) {
! // if data left, read next byte
! call I2C.send();
! } else {
! // otherwise, complete with success
! call I2C.end();
!
! if (i2cMode == I2C_PING) {
! signal I2CDevice.pingDone(SUCCESS);
! } else {
!
! signal I2CDevice.readDone();
! }
!
! i2cMode = I2C_READY;
! }
! break;
!
! default:
! call I2C.end();
! i2cMode = I2C_READY;
! // signal error
! }
! break;
!
! case I2C_WRITE:
! switch (state) {
! case ATM128_I2C_START:
! call I2C.deviceWrite(device); // talk in write mode
! call I2C.send();
! break;
!
! case ATM128_I2C_MW_SLA_ACK:
! case ATM128_I2C_MW_DATA_ACK:
! if (i2cLength-- > 0) {
! // if data left, write next byte
! call I2C.set(*i2cData);
! call I2C.send();
! } else {
! // otherwise, clean exit
! call I2C.end();
! i2cMode = I2C_READY;
! signal I2CDevice.writeDone();
! }
! break;
! default:
! call I2C.end();
! i2cMode = I2C_READY;
! // signal error
! }
! break;
! }
! if (i2cMode == I2C_READY) return;
! // start timeout timer
}
! /** Ping a I2C slave device to see if it exists. */
! command error_t I2CDevice.ping() {
! if (i2cMode != I2C_READY)
! return FAIL;
!
! i2cMode = I2C_PING;
! i2cData = NULL;
! i2cLength = 0;
! call I2C.begin();
! return SUCCESS;
}
! /** Write a byte sequence to an I2C slave device. */
! command error_t I2CDevice.write(uint8_t *data, uint8_t length) {
! if (i2cMode != I2C_READY)
! return FAIL;
! i2cMode = I2C_WRITE;
! i2cData = data;
! i2cLength = length;
! call I2C.begin();
! return SUCCESS;
}
! /** Read a byte sequence from an I2C slave device. */
! command error_t I2CDevice.read(uint8_t *data, uint8_t length) {
! if (i2cMode != I2C_READY)
! return FAIL;
! i2cMode = I2C_READ;
! i2cData = data;
! i2cLength = length;
! call I2C.begin();
! return SUCCESS;
}
! default event void I2CDevice.pingDone (error_t result) {}
! default event void I2CDevice.readDone () {}
! default event void I2CDevice.writeDone () {}
! /** Intercept interrupt signal when pending symbol completes. */
! async event void I2C.symbolSent() {
! if (call I2C.status() == ATM128_I2C_MW_DATA_ACK) {
! // If reading, grab the next data byte.
! if (i2cData != NULL)
! *i2cData++ = call I2C.get();
! }
! // Queue up handling for next symbol
! post i2cEngine();
}
}
--- 34,280 ----
*
* @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() {}
}
Index: HplAtm128I2CBus.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c/Attic/HplAtm128I2CBus.nc,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -C2 -d -r1.1.2.1 -r1.1.2.2
*** HplAtm128I2CBus.nc 27 Jan 2006 22:19:36 -0000 1.1.2.1
--- HplAtm128I2CBus.nc 1 May 2006 21:50:50 -0000 1.1.2.2
***************
*** 34,76 ****
*
* @author Martin Turon <mturon at xbow.com>
*
! * @version 2005/9/11 mturon Initial version
*/
! interface HplI2CBus {
!
! command void init(); //!< Initialize i2c clock speed
!
! // Transaction interface
! command void begin(); //!< Start bus transaction (send start symbol)
! command void end(); //!< End bus transaction
! command void send(); //!< Send next byte of transaction
!
! // Data interface
! command error_t ping (uint8_t dev); //!< Ping device
! command error_t write(uint8_t dev, uint8_t data); //!< Write to device
! command error_t read (uint8_t dev, uint8_t *data); //!< Read from device
!
! command error_t writeBuffer(uint8_t dev, uint8_t *data, int8_t len);
! command error_t readBuffer (uint8_t dev, uint8_t *data, int8_t len);
!
! async command uint8_t get(); //!< Get data register
! async command void set(uint8_t data); //!< Set data register
! async command void deviceRead (uint8_t addr); //!< Set device to read
! async command void deviceWrite(uint8_t addr); //!< Set device to write
! async command Atm128I2CControl_t getControl();
! async command Atm128I2CStatus_t getStatus();
! async command void setControl( Atm128I2CControl_t x );
! async command void setStatus ( Atm128I2CStatus_t x );
!
! async command uint8_t status();
! async command bool isDone();
! async command error_t waitDone();
! // async command void enable();
! // async command void disable();
- async event void symbolSent();
}
--- 34,73 ----
*
* @author Martin Turon <mturon at xbow.com>
+ * @author Philip Levis
*
! * @version $Id$
*/
! interface HplAtm128I2CBus {
! async command void init(bool hasExternalPulldown);
! async command void off();
!
! 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();
}
Index: HplAtm128I2CBusC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c/Attic/HplAtm128I2CBusC.nc,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -C2 -d -r1.1.2.1 -r1.1.2.2
*** HplAtm128I2CBusC.nc 27 Jan 2006 22:19:36 -0000 1.1.2.1
--- HplAtm128I2CBusC.nc 1 May 2006 21:50:50 -0000 1.1.2.2
***************
*** 32,55 ****
*
* @author Martin Turon <mturon at xbow.com>
*
! * @version 2005/9/11 mturon Initial version
*/
! configuration HplI2CBusC
! {
! provides interface HplI2CBus as I2C;
}
implementation {
! components LedsC
! , HplAtm128GeneralIOC
! , BusyWaitMicroC
! , HplI2CBusP
! ;
! I2C = HplI2CBusP.I2C;
!
! HplI2CBusP.Leds -> LedsC;
! HplI2CBusP.uWait -> BusyWaitMicroC;
! HplI2CBusP.I2CClk -> HplAtm128GeneralIOC.PortD0;
! HplI2CBusP.I2CData -> HplAtm128GeneralIOC.PortD1;
}
--- 32,49 ----
*
* @author Martin Turon <mturon at xbow.com>
+ * @author Philip Levis
*
! * @version $Id$
*/
!
! configuration HplAtm128I2CBusC {
! provides interface HplAtm128I2CBus as I2C;
}
implementation {
! components HplAtm128GeneralIOC as IO, HplAtm128I2CBusP as Bus;
! I2C = Bus.I2C;
! Bus.I2CClk -> IO.PortD0;
! Bus.I2CData -> IO.PortD1;
}
Index: HplAtm128I2CBusP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/i2c/Attic/HplAtm128I2CBusP.nc,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -C2 -d -r1.1.2.1 -r1.1.2.2
*** HplAtm128I2CBusP.nc 27 Jan 2006 22:19:36 -0000 1.1.2.1
--- HplAtm128I2CBusP.nc 1 May 2006 21:50:50 -0000 1.1.2.2
***************
*** 37,269 ****
*
* @author Martin Turon <mturon at xbow.com>
*
! * @version 2005/9/11 mturon Initial version
*/
! module HplI2CBusP
! {
! provides interface HplI2CBus as I2C;
! uses {
! interface Leds;
! interface BusyWait<TMicro,uint16_t> as uWait;
! interface GeneralIO as I2CClk;
! interface GeneralIO as I2CData;
! }
}
implementation {
! command void I2C.init() {
! // Set the internal pullup resisters
! call I2CClk.makeOutput();
! call I2CData.makeOutput();
call I2CClk.set();
call I2CData.set();
!
! TWSR = 0; // set prescaler == 0
! TWBR = (F_CPU / 100000UL - 16) / 2; // set I2C baud rate
! // TWBR = 50;
}
/** Send START symbol and begin I2C bus transaction. */
! command void I2C.begin() {
! //TWCR = 1<<TWIE | 1<<TWEN | 1<<TWSTA | 1<<TWINT ;
! Atm128I2CControl_t ctrl;
! ctrl.bits = (Atm128I2CControl_s) { twen : 1, twint : 1, twsta : 1, twie : 1 };
! call I2C.setControl(ctrl);
}
!
! /** Signal STOP and end I2C bus transaction. */
! command void I2C.end() {
! Atm128I2CControl_t ctrl;
! ctrl.bits = (Atm128I2CControl_s) { twen : 1, twint : 1, twsto : 1, twie: 0 };
! call I2C.setControl(ctrl);
}
!
! /** Send next byte of I2C bus transaction. */
! command void I2C.send() {
! Atm128I2CControl_t ctrl;
! ctrl.bits = (Atm128I2CControl_s) { twen : 1, twint : 1, twie : 1 };
! call I2C.setControl(ctrl);
}
!
! error_t i2c_quit() {
! call I2C.end();
! return FAIL;
}
!
! /** Ping a I2C slave device to see if it exists. */
! command error_t I2C.ping(uint8_t addr) {
!
! // call Leds.set(call I2C.isDone());
!
! // avr_i2c_enable();
! // avr_i2c_start();
! // avr_i2c_wait();
!
! call I2C.begin();
! call I2C.waitDone();
!
! call Leds.set(call I2C.status()>>3 & 0x7);
! //(call I2C.getStatus()).bits.tws);
!
! // confirm start sent status
! if (!(call I2C.status() == ATM128_I2C_START)) return i2c_quit();
!
!
! call I2C.deviceRead(addr);
! call I2C.send();
! call I2C.waitDone();
! // confirm slave ack status
! if (!(call I2C.status() == ATM128_I2C_MR_SLA_ACK)) return i2c_quit();
!
! call I2C.end();
!
! return SUCCESS;
}
!
/** Write a byte to an I2C slave device. */
! command error_t I2C.write(uint8_t addr, uint8_t data) {
! call I2C.begin();
! call I2C.waitDone();
! // confirm start sent status
! if (!(call I2C.status() == ATM128_I2C_START)) return i2c_quit();
!
! call I2C.deviceWrite(addr);
! call I2C.send();
! call I2C.waitDone();
! // confirm slave ack status
! if (!(call I2C.status() == ATM128_I2C_MW_SLA_ACK)) return i2c_quit();
!
! call I2C.set(data);
! call I2C.send();
! call I2C.waitDone();
! // confirm data ack status
! if (!(call I2C.status() == ATM128_I2C_MW_DATA_ACK)) return i2c_quit();
!
! call I2C.end();
!
! return SUCCESS;
}
! /** Read a byte from an I2C slave device. */
! command error_t I2C.read(uint8_t addr, uint8_t *data) {
! call I2C.begin();
! call I2C.waitDone();
! // confirm start sent status
! if (!(call I2C.status() == ATM128_I2C_START)) return i2c_quit();
!
! call I2C.deviceRead(addr);
! call I2C.send();
! call I2C.waitDone();
! // confirm slave ack status
! if (!(call I2C.status() == ATM128_I2C_MR_SLA_ACK)) return i2c_quit();
!
! call I2C.send();
! call I2C.waitDone();
! *data = call I2C.get();
! // confirm data ack status
! if (!(call I2C.status() == ATM128_I2C_MR_DATA_ACK)) return i2c_quit();
!
! call I2C.end();
!
! return SUCCESS;
}
! /** Write one data byte to a given offset on a I2C slave device. */
! command error_t I2C.writeBuffer(uint8_t device, uint8_t *data, int8_t len) {
! call I2C.begin();
! call I2C.waitDone();
! // confirm start sent status
! if (!(call I2C.status() == ATM128_I2C_START)) return i2c_quit();
!
! call I2C.deviceWrite(device);
! call I2C.send();
! call I2C.waitDone();
! // confirm slave ack status
! if (!(call I2C.status() == ATM128_I2C_MW_SLA_ACK)) return i2c_quit();
!
! while (len-- > 0) {
! call I2C.set(*data++);
! call I2C.send();
! call I2C.waitDone();
! // confirm data ack status
! if (!(call I2C.status() == ATM128_I2C_MW_DATA_ACK)) return i2c_quit();
! }
!
! call I2C.end();
!
! return SUCCESS;
}
!
! /** Read one data byte to a given offset on a I2C slave device. */
! command error_t I2C.readBuffer(uint8_t device, uint8_t *data, int8_t len) {
! call I2C.begin();
! call I2C.waitDone();
! // confirm start sent status
! if (!(call I2C.status() == ATM128_I2C_START)) return i2c_quit();
!
! call I2C.deviceRead(device);
! call I2C.send();
! call I2C.waitDone();
! // confirm slave ack status
! if (!(call I2C.status() == ATM128_I2C_MR_SLA_ACK)) return i2c_quit();
!
! while (len-- > 0) {
! call I2C.send();
! call I2C.waitDone();
! *data++ = call I2C.get();
! // confirm data ack status
! if (!(call I2C.status() == ATM128_I2C_MR_DATA_ACK)) return i2c_quit();
! }
!
! call I2C.end();
!
! return SUCCESS;
}
! //=== Read the data registers. ========================================
! async command uint8_t I2C.get() { return TWDR; }
!
! //=== Write the data registers. =======================================
! async command void I2C.set(uint8_t data) { TWDR = data; }
!
! async command void I2C.deviceRead (uint8_t addr) { TWDR = addr | 0x01; }
! async command void I2C.deviceWrite (uint8_t addr) { TWDR = addr; }
!
! //=== Read the control registers. =====================================
! async command Atm128I2CControl_t I2C.getControl() {
! return *(Atm128I2CControl_t*)&TWCR;
}
! async command Atm128I2CStatus_t I2C.getStatus() {
! return *(Atm128I2CStatus_t*)&TWSR;
}
!
! //=== Write the control registers. ====================================
! async command void I2C.setControl( Atm128I2CControl_t x ) {TWCR = x.flat;}
! async command void I2C.setStatus ( Atm128I2CStatus_t x ) {TWSR = x.flat;}
!
! async command uint8_t I2C.status() { return TWSR & 0xF8; }
!
! //=== Utility routines ===============================================
!
! async command bool I2C.isDone() {
! return (call I2C.getControl()).bits.twint;
}
! async command error_t I2C.waitDone() {
! int i = 0;
! while (!call I2C.isDone()) {
! call uWait.wait(100);
! if (i++ > I2C_TIMEOUT) return FAIL; // timeout
! }
! return SUCCESS;
}
! // async command void I2C.enable() { SET_BIT(TWCR,TWE); }
! // async command void I2C.disable() { CLR_BIT(TWCR,TWE); }
default async event void I2C.symbolSent() { }
AVR_NONATOMIC_HANDLER(SIG_2WIRE_SERIAL) {
! atomic signal I2C.symbolSent();
}
}
--- 37,166 ----
*
* @author Martin Turon <mturon at xbow.com>
+ * @author Philip Levis
*
! * @version $Id$
*/
! module HplAtm128I2CBusP {
! provides interface HplAtm128I2CBus as I2C;
! uses {
! interface GeneralIO as I2CClk;
! interface GeneralIO as I2CData;
! }
}
implementation {
! async command void I2C.init(bool hasExternalPulldown) {
! // Set the internal pullup resisters
! if (hasExternalPulldown) {
! //call I2CClk.makeOutput();
! //call I2CData.makeOutput();
call I2CClk.set();
call I2CData.set();
! }
! call I2CClk.makeInput();
! call I2CData.makeInput();
! TWSR = 0; // set prescaler == 0
! TWBR = (F_CPU / 50000UL - 16) / 2; // set I2C baud rate
! //TWBR = 50;
! TWAR = 0;
! TWCR = 0;
}
+ async command void I2C.off() {
+ call I2CClk.clr();
+ call I2CData.clr();
+ }
+
+ async command uint8_t I2C.status() {
+ 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);
}
!
/** Write a byte to an I2C slave device. */
! async command void I2C.write(uint8_t data) {
! TWDR = data;
}
! async command uint8_t I2C.read() {
! return TWDR;
}
! 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();
}
}
More information about the Tinyos-2-commits
mailing list