--- /dev/null
+/*
+ * Copyright (c) 2008, Titanium Mirror, Inc.
+ * 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 Universität 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.
+ */
+
+/**
+ * This configuration provides the interface for using USCI_B0 in its I2C
+ * mode.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#if !defined(__MSP430_HAS_USCI_AB0__)
+#error "Target does not have a USCI_B0 peripheral (I2C)"
+#endif
+
+#include "I2C.h"
+#include "Msp430Usci.h"
+
+generic configuration Msp430I2CB0C() {
+ provides {
+ interface Resource;
+ interface ResourceRequested;
+ /* interface SomethingToSetOwnAddress */
+ /* interface SomethingToDenoteMode */
+ interface I2CPacket<TI2CBasicAddr> as I2CBasicPacket;
+ interface I2CPacket<TI2CExtdAddr> as I2CExtdPacket;
+ interface ArbiterInfo; /* ??? */
+ }
+ uses interface AsyncConfigure<const msp430_usci_i2c_t*> as Configure;
+}
+implementation {
+ enum {
+ CLIENT_ID = unique(MSP430_USCIB0_RESOURCE)
+ };
+
+ components new Msp430I2CP() as I2CP;
+ I2CBasicPacket = I2CP;
+ I2CExtdPacket = I2CP;
+ Configure = I2CP;
+
+ components Msp430UsciB0C as UsciC;
+ Resource = UsciC.Resource[CLIENT_ID];
+ ResourceRequested = UsciC.ResourceRequested[CLIENT_ID];
+ ArbiterInfo = UsciC.ArbiterInfo;
+ I2CP -> UsciC.Registers;
+ I2CP -> UsciC.Interrupts[CLIENT_ID];
+ I2CP -> UsciC.ArbiterInfo;
+ UsciC.ResourceConfigure[CLIENT_ID] -> I2CP;
+
+ components HplMsp430GeneralIOC as IOC;
+ I2CP.SCL -> IOC.UCB0SCL;
+ I2CP.SDA -> IOC.UCB0SDA;
+
+#if 0 /* FIXME: no virtualized alarm for msp430 */
+ comonents new SomeVirtualizedAlarmClientC() as AlarmC;
+ I2CP.Alarm -> AlarmC;
+#endif
+
+ components BusyWaitMicroC;
+ I2CP.BusyWait -> BusyWaitMicroC;
+
+ components Msp430CounterMicroC;
+ I2CP.Counter -> Msp430CounterMicroC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2008, Titanium Mirror, Inc.
+ * 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 Universität 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.
+ */
+
+/**
+ * This configuration provides the interface for using USCI_B1 in its I2C
+ * mode.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#if !defined(__MSP430_HAS_USCI_AB1__)
+#error "Target does not have a USCI_B1 peripheral (I2C)"
+#endif
+
+#include "I2C.h"
+#include "Msp430Usci.h"
+
+generic configuration Msp430I2CB1C() {
+ provides {
+ interface Resource;
+ interface ResourceRequested;
+ /* interface SomethingToSetOwnAddress */
+ /* interface SomethingToDenoteMode */
+ interface I2CPacket<TI2CBasicAddr> as I2CBasicPacket;
+ interface I2CPacket<TI2CExtdAddr> as I2CExtdPacket;
+ interface ArbiterInfo; /* ??? */
+ }
+ uses interface AsyncConfigure<const msp430_usci_i2c_t*> as Configure;
+}
+implementation {
+ enum {
+ CLIENT_ID = unique(MSP430_USCIB1_RESOURCE)
+ };
+
+ components new Msp430I2CP() as I2CP;
+ I2CBasicPacket = I2CP;
+ I2CExtdPacket = I2CP;
+ Configure = I2CP;
+
+ components Msp430UsciB1C as UsciC;
+ Resource = UsciC.Resource[CLIENT_ID];
+ ResourceRequested = UsciC.ResourceRequested[CLIENT_ID];
+ ArbiterInfo = UsciC.ArbiterInfo;
+ I2CP -> UsciC.Registers;
+ I2CP -> UsciC.Interrupts[CLIENT_ID];
+ I2CP -> UsciC.ArbiterInfo;
+ UsciC.ResourceConfigure[CLIENT_ID] -> I2CP;
+
+ components HplMsp430GeneralIOC as IOC;
+ I2CP.SCL -> IOC.UCB1SCL;
+ I2CP.SDA -> IOC.UCB1SDA;
+
+#if 0 /* FIXME: no virtualized alarm for msp430 */
+ comonents new SomeVirtualizedAlarmClientC() as AlarmC;
+ I2CP.Alarm -> AlarmC;
+#endif
+
+ components BusyWaitMicroC;
+ I2CP.BusyWait -> BusyWaitMicroC;
+
+ components Msp430CounterMicroC;
+ I2CP.Counter -> Msp430CounterMicroC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2008, Titanium Mirror, Inc.
+ * 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 Universität 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.
+ */
+
+/**
+ * USCI I2C implementation. Currently supports only single master operation.
+ * Repeated start operations are supported, as are using multiple I2CPacket
+ * read or write commands to satisfy a single I2C read or write transaction.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+generic module Msp430I2CP() {
+ provides {
+ interface I2CPacket<TI2CBasicAddr> as I2CBasicPacket;
+ interface I2CPacket<TI2CExtdAddr> as I2CExtdPacket;
+ interface ResourceConfigure;
+ }
+ uses {
+ interface HplMsp430UsciReg as Registers;
+ interface HplMsp430UsciInt as Interrupts;
+ interface HplMsp430GeneralIO as SDA;
+ interface HplMsp430GeneralIO as SCL;
+ interface AsyncConfigure<const msp430_usci_i2c_t*> as Configure;
+ interface ArbiterInfo;
+ interface BusyWait<TMicro, uint16_t>;
+ interface Counter<TMicro, uint16_t>;
+ }
+}
+implementation {
+ enum {
+ /* Activity timing */
+ SCL_WAIT_TIME = 1024, /* micros */
+ BUSY_CHECK_TIME = 1024, /* micros */
+ START_CHECK_TIME = 102, /* micros */
+ STOP_CHECK_TIME = 102, /* micros */
+
+ /* Setting new I2C flags is dangerous; manually ensure the bit definitions
+ * below do not overlap with those defined in tos/types/I2C.h.
+ */
+ I2C_EXTENDED = 0x10,
+ };
+
+ i2c_flags_t m_flags;
+ uint8_t* m_buf;
+ uint16_t m_len;
+ uint16_t m_pos;
+
+ inline void setSDA()
+ {
+ call SDA.makeInput();
+ }
+
+ inline void clrSDA()
+ {
+ call SDA.makeOutput();
+ }
+
+ inline void setSCL()
+ {
+ call SCL.makeInput();
+ }
+
+ inline void clrSCL()
+ {
+ call SCL.makeOutput();
+ }
+
+ bool idleBus()
+ {
+ /* Look for bus idle when the I2C pins are in IO mode. */
+ return (call SDA.get() && call SCL.get());
+ }
+
+ bool resetBus()
+ {
+ /* When the I2C pins are in IO mode, verify the I2C bus is idle or attempt
+ * to get the bus into an idle state. This code is only valid if we are
+ * the only master on the I2C bus and is not suitable for multi-master
+ * setups.
+ *
+ * Return TRUE if the bus was idle or was successfully brought to idle.
+ * Return FALSE if the bus could not be made idle in a reasonable time.
+ */
+ if (idleBus())
+ return TRUE;
+ else {
+ uint16_t i;
+
+ /* Wait a bit if SCL is low. A save might be clock stretching. */
+ i = call Counter.get();
+ while (call Counter.get() - i <= SCL_WAIT_TIME) {
+ if (!(call SCL.get()))
+ return FALSE;
+ }
+
+ /* If SDA is low, clock SCL in an attempt to release it. */
+ for (i = 0; i < 10 && !call SDA.get(); i++) {
+ clrSCL();
+ call BusyWait.wait(10);
+ setSCL();
+ call BusyWait.wait(10);
+ }
+ if (!idleBus())
+ return FALSE;
+
+ /* Drive a stop condition on the bus to stop any active slaves. */
+ clrSCL();
+ clrSDA();
+ call BusyWait.wait(10);
+ setSCL();
+ call BusyWait.wait(10);
+ setSDA();
+ call BusyWait.wait(10);
+ return idleBus();
+ }
+ }
+
+ bool isConfigured()
+ {
+ return !(call Registers.getCtl1(UCSWRST));
+ }
+
+ /* TRUE if a transaction (we initiated, single master) is in progress. */
+ bool isBusy()
+ {
+ return m_len;
+ }
+
+ /* Wait for an I2C start, if in progress, to complete. Return FALSE if a
+ * start is pending and did not finish within the allotted time. Return TRUE
+ * if no start was pending, or it finished within the allotted time.
+ */
+ bool waitStart()
+ {
+ uint16_t t0 = call Counter.get();
+
+ do {
+ if (!(call Registers.getCtl1(UCTXSTT)))
+ return TRUE;
+ } while (call Counter.get() - t0 <= START_CHECK_TIME);
+ return FALSE;
+ }
+
+ /* Wait for an I2C stop, if in progress, to complete. Return FALSE if a
+ * stop is pending and did not finish within the allotted time. Return TRUE
+ * if no stop was pending, or it finished within the allotted time.
+ */
+ bool waitStop()
+ {
+ uint16_t t0 = call Counter.get();
+
+ do {
+ if (!(call Registers.getCtl1(UCTXSTP)))
+ return TRUE;
+ } while (call Counter.get() - t0 <= STOP_CHECK_TIME);
+ return FALSE;
+ }
+
+ async command void ResourceConfigure.configure()
+ {
+ atomic {
+ const msp430_usci_i2c_t* config = call Configure.get();
+
+ call Registers.setCtl1(UCSWRST);
+
+ /* Several conditions might find a slave driving the bus at this point.
+ * One such condition is a badly timed PUC of this slave. Use resetBus()
+ * to attempt rectification of such conditions.
+ */
+ if (!resetBus())
+ return;
+
+ /* Configure USCI registers. I2C requires UCMODE_3 and UCSYNC */
+ call Registers.assignCtl0(config->ctl0 | UCMODE_3 | UCSYNC);
+ call Registers.assignCtl1(config->ctl1 | UCSWRST);
+ call Registers.assignBr0(config->brx & 0xff);
+ call Registers.assignBr1(config->brx >> 8);
+ call Registers.assignMctl(0);
+ call Registers.assignI2Coa(config->i2coa);
+ call Registers.assignI2Csa(0);
+
+ /* Configure pins for I2C */
+ call SDA.selectModuleFunc();
+ call SCL.selectModuleFunc();
+
+ /* Clear interrupts; we'll add them as needed */
+ call Registers.assignI2Cie(0);
+ call Registers.clrIeRx();
+ call Registers.clrIeTx();
+
+ /* Enable the device */
+ call Registers.clrCtl1(UCSWRST);
+ }
+ }
+
+ void signalDone()
+ {
+ error_t error = (m_pos == m_len) ? SUCCESS : FAIL;
+ uint16_t len = m_len;
+ uint16_t addr;
+
+ /* No more I2C interrupts until the next I2C request arrives */
+ call Registers.assignI2Cie(0);
+ call Registers.clrIeTx();
+ call Registers.clrIeRx();
+
+ /* Wait for stop to finish, if it is in progress. */
+ if (!waitStop())
+ error = FAIL;
+
+ m_len = 0;
+ addr = call Registers.readI2Csa();
+ switch ((call Registers.getCtl0(UCSLA10) ? 2 : 0) + /* extended addr */
+ (call Registers.getCtl1(UCTR) ? 1 : 0)) { /* write */
+ case 0:
+ atomic signal I2CBasicPacket.readDone(error, addr, len, m_buf);
+ break;
+ case 1:
+ atomic signal I2CBasicPacket.writeDone(error, addr, len, m_buf);
+ break;
+ case 2:
+ atomic signal I2CExtdPacket.readDone(error, addr, len, m_buf);
+ break;
+ case 3:
+ atomic signal I2CExtdPacket.writeDone(error, addr, len, m_buf);
+ break;
+ }
+ }
+
+ async command void ResourceConfigure.unconfigure()
+ {
+ atomic {
+ /* Signal done if a pending operation */
+ if (isBusy())
+ signalDone();
+
+ /* Disable the device */
+ call Registers.setCtl1(UCSWRST);
+
+ /* Clear interrupts and interrupt flags. */
+ call Registers.assignI2Cie(0);
+ call Registers.clrIeRx();
+ call Registers.clrIfgRx();
+
+ /* Restore I2C pins to IO function */
+ call SDA.selectIOFunc();
+ call SCL.selectIOFunc();
+ }
+ }
+
+ error_t read(i2c_flags_t flags, uint16_t addr, uint8_t len, uint8_t* rxBuf)
+ {
+ /* From the TI family guide SDAU144D, page 17-17:
+ * "Data is received from the slave as long as UCTXSTP or UCTXSTT is not
+ * set. If UCBxRXBUF is not read the master holds the bus during reception
+ * of the last data bit and until the UCBxRXBUF is read."
+ *
+ * Since the I2C bus can only be suspended during read by *not* reading a
+ * byte out of RXBUF, the only reasonable command after a read() that
+ * did not include I2C_STOP is a read that does not include I2C_START. A
+ * read that includes I2C_START, or a write (which by definition must
+ * include I2C_START) will effectively create the situation where the
+ * prior read caused the slave to send one more byte than was delivered via
+ * readDone() to the user code. In many cases, this won't be a problem, as
+ * triggering the slave to read an extra byte will do no harm. But this
+ * may not always be the case, if for example the slave maintains state
+ * that is changed upon the read of that final byte the user code never
+ * sees.
+ */
+ if (!isConfigured() || isBusy() || len == 0 || !rxBuf)
+ return FAIL;
+
+ m_flags = flags;
+ m_len = len;
+ m_buf = rxBuf;
+ m_pos = 0;
+
+#if 0 /* FIXME: No virtualized alarm for msp430 */
+ /* We require an alarm because we aren't looking at UCALIFG, arbitration
+ * lost. If this were to happen, the state machine hangs.
+ */
+ call Alarm.start(I2C_TIMEOUT);
+#endif
+ if (m_flags & I2C_EXTENDED)
+ call Registers.setCtl0(UCSLA10);
+ else
+ call Registers.clrCtl0(UCSLA10);
+ call Registers.assignI2Csa(addr);
+ call Registers.clrCtl1(UCTR);
+ if (m_flags & I2C_START) {
+ call Registers.clrIfgRx(); /* see above re: suspending reads */
+ call Registers.setCtl1(UCTXSTT);
+ }
+ if (m_len == 1 && (m_flags & I2C_STOP)) {
+ /* UCTXSTP must assert before hw finishes clocking in the last byte.
+ * FIXME: in reading a single I2C trx using multiple I2C...read() calls,
+ * too much time spent by the user processing the readDone() can cause
+ * the I2C hardware to clock an extra byte's worth of clocks, thereby
+ * issuing 1 byte more of read with the slave, before the stop event.
+ */
+ waitStart();
+ call Registers.setCtl1(UCTXSTP);
+ }
+ call Registers.setI2Cie(UCNACKIE);
+ call Registers.setIeRx();
+ return SUCCESS;
+ }
+
+ async command error_t I2CBasicPacket.read(i2c_flags_t flags, uint16_t addr,
+ uint8_t length, uint8_t* data)
+ {
+ atomic return read(flags & ~I2C_EXTENDED, addr, length, data);
+ }
+
+ async command error_t I2CExtdPacket.read(i2c_flags_t flags, uint16_t addr,
+ uint8_t length, uint8_t* data)
+ {
+ atomic return read(flags | I2C_EXTENDED, addr, length, data);
+ }
+
+ error_t write(i2c_flags_t flags, uint16_t addr, uint8_t len, uint8_t* txBuf)
+ {
+ if (!isConfigured() || isBusy() || len == 0 || !txBuf)
+ return FAIL;
+
+ m_flags = flags;
+ m_len = len;
+ m_buf = txBuf;
+ m_pos = 0;
+
+#if 0 /* FIXME: No virtualized alarm for msp430 */
+ /* We require an alarm because we aren't looking at UCALIFG, arbitration
+ * lost. If this were to happen, the state machine hangs.
+ */
+ call Alarm.start(I2C_TIMEOUT);
+#endif
+ if (m_flags & I2C_EXTENDED)
+ call Registers.setCtl0(UCSLA10);
+ else
+ call Registers.clrCtl0(UCSLA10);
+ call Registers.assignI2Csa(addr);
+ call Registers.setCtl1((m_flags & I2C_START) ? UCTR + UCTXSTT : UCTR);
+ call Registers.setI2Cie(UCNACKIE);
+ call Registers.setIeTx();
+ return SUCCESS;
+ }
+
+ async command error_t I2CBasicPacket.write(i2c_flags_t flags, uint16_t addr,
+ uint8_t length, uint8_t* data)
+ {
+ atomic return write(flags & ~I2C_EXTENDED, addr, length, data);
+ }
+
+ async command error_t I2CExtdPacket.write(i2c_flags_t flags, uint16_t addr,
+ uint8_t length, uint8_t* data)
+ {
+ atomic return write(flags | I2C_EXTENDED, addr, length, data);
+ }
+
+#if 0 /* FIXME: need a virtualized alarm for msp430 */
+ event void Alarm.fired()
+ {
+ if (m_flags & I2C_STOP) {
+ call Registers.setCtl1(UCTXSTP);
+ call Registers.clrIfgTx();
+ }
+ signalDone();
+ }
+#endif
+
+ async event void Interrupts.tx()
+ {
+ if (m_pos == m_len) {
+ if (m_flags & I2C_STOP) {
+ call Registers.setCtl1(UCTXSTP);
+ call Registers.clrIfgTx();
+ }
+ signalDone();
+ } else
+ call Registers.setTxbuf(m_buf[m_pos++]);
+ }
+
+ async event void Interrupts.rx(uint8_t nobyte)
+ {
+ if (m_len - m_pos == 2 && (m_flags & I2C_STOP)) {
+ /* As soon as we read RXBUF, the hw will begin clocking in the next byte.
+ * To guarantee that a slow uC can still set UCTXSTP before the last
+ * byte is fully clocked, we set it before the second to last byte is
+ * read from RXBUF, when the hw has I2C communications suspended.
+ */
+ call Registers.setCtl1(UCTXSTP);
+ }
+ m_buf[m_pos++] = call Registers.getRxbuf();
+ if (m_pos == m_len)
+ signalDone();
+ }
+
+ async event void Interrupts.i2cNack()
+ {
+ call Registers.setCtl1(UCTXSTP);
+ call Registers.clrStat(UCNACKIFG);
+ signalDone();
+ }
+
+ default async event void I2CBasicPacket.readDone(error_t error, uint16_t addr,
+ uint8_t length, uint8_t* data) {}
+ default async event void I2CBasicPacket.writeDone(error_t error,
+ uint16_t addr, uint8_t length, uint8_t* data) {}
+ default async event void I2CExtdPacket.readDone(error_t error, uint16_t addr,
+ uint8_t length, uint8_t* data) {}
+ default async event void I2CExtdPacket.writeDone(error_t error, uint16_t addr,
+ uint8_t length, uint8_t* data) {}
+
+ default async command const msp430_usci_i2c_t* Configure.get()
+ {
+ const static msp430_usci_i2c_t def = {
+ ctl0: UCSYNC | UCMODE_3 | UCMST, /* I2C master */
+ ctl1: UCSWRST | UCSSEL_3, /* I2C clock source is SMCLK */
+ brx: 10, /* I2C clock=SMCLK/10; ~95KHz if SMCLK=2^20Hz */
+ ren: USCI_REN_NONE
+ };
+
+ return &def;
+ }
+
+ async event void Interrupts.i2cStart() {}
+ async event void Interrupts.i2cStop() {}
+ async event void Interrupts.i2cCal() {}
+ async event void Interrupts.brk() {}
+ async event void Counter.overflow() {}
+}