--- /dev/null
+#-*-Makefile-*- vim:syntax=make
+# olimexp169.target
+
+PLATFORM ?= olimexp169
+
+#MSP_MCU = msp430x169
+
+# Disable MSP430 hardware multiply because it makes MSPGCC die
+PFLAGS += -mdisable-hwmul
+OPTFLAGS += -O
+
+# Olimex P169 doesn't support bsl
+MSP_BSL ?= false
+MSP_BSL_FLAGS = --device=none
+
+#VOLUME_FILE = volumes-stm25p.xml
+#VOLUME_ALLOCATOR ?= tos-storage-stm25p
+
+#ifdef CC2420_CHANNEL
+#PFLAGS += -DCC2420_DEF_CHANNEL=$(CC2420_CHANNEL)
+#endif
+
+$(call TOSMake_include_platform,msp)
+
+$(PLATFORM): $(BUILD_DEPS)
+ @:
$(call TOSMake_include_platform,msp)
-tmicore: $(BUILD_DEPS)
+$(PLATFORM): $(BUILD_DEPS)
@:
$(call TOSMake_include_platform,msp)
-tmirws: $(BUILD_DEPS)
+$(PLATFORM): $(BUILD_DEPS)
@:
# concepts of inversion and assertion. Reviewed slaa089d and slaa096d;
# no changes required due to updated documentation.
#
-# Important conventions used in this code
-# =======================================
+#
+# Set and clear of digital signals
+# ================================
+#
# All functions that can set or clear a digital pin or signal state do so
-# relative to the assertion state of its signal. That is, SetXXX(1) asserts
-# signal XXX and SetXXX(0) unasserts signal XXX. Asserting a signal means its
+# relative to the assertion state of its signal. That is, setXXX(1) asserts
+# signal XXX and setXXX(0) unasserts signal XXX. Asserting a signal means its
# logic value is set to that value that asserts, or activates, its condition.
# Signals may be either active high or active low, as shown in the chart below.
#
# active --- value --- --- value ---
# state logic voltage logic voltage
# ----------------------------------------
-# high 1 Vcc 0 GND
-# low 0 GND 1 VCC
+# high 1 Vcc 0 GND
+# low 0 GND 1 VCC
+#
+# It is the responsibility of the setXXX functions to properly convert the
+# set request into the proper output value. This provides a consistency for
+# applications using the set functions, since they no longer care the manner
+# in which an asserted or unasserted signal are actually represented in the
+# transmission medium.
#
#
# Important information about RS-232C signals
# ===========================================
#
-# Setting RS-232 signals, like DTR and RTS, from a host using Python using the
-# convention defined above:
-# A signal is asserted by calling serial.setXXX(1) [Ex: setDSR(1)]
-# A signal is unasserted by calling serial.setXXX(0) [Ex: setRTS(0)]
+# RS-232C signals are active low. Confusingly, however, RS-232C physical
+# drivers effectively invert the value, such that a high value, or MARK, is
+# delivered over the wire as a negative voltage while a low value, or SPACE, is
+# delivered as a positive voltage. By looking at an RS-232C signal on an
+# oscilloscope, one might conclude that the RS-232C signals are active high for
+# this reason. Here is how RS-232 breaks down:
#
-# RS-232C signal output mechanics:
-# An asserted RS-232C DTR or RTS signal is simultaneously:
-# logic 0
-# A SPACE condition
-# Has a voltage between +3v and +15v per the RS-232C specification
-# TTL level RS-232C pins use Vcc to indicate the logic 0 / SPACE condition
-# An unasserted DTR or RTS signal is simultaneously:
-# logic 1
-# A MARK condition
-# Has a voltage between -3v and -15v per the RS-232C specification
+# signal logical RS-232C RS-232C TTL RS-232
+# state value value name output voltage output voltage
+# ---------------------------------------------------------------
+# asserted 0/low SPACE +3v...+15v GND (0V)
+# unasserted 1/high MARK -3v...-15v VCC
#
-# PC serial ports often break the spec and use 0v to indicate logic 1/MARK
+# Note that some RS-232 signals, notably TxD (transmit data) and RxD (receive
+# data), can be idle. An idle signal is always unasserted.
#
-# TTL level RS-232C pins use GND to indicate the logic 0/SPACE and Vcc to
-# indicate logic 1/MARK
+# Using this guidance, an asserted DTR signal is logic low, is 0V in TTL RS-232
+# and +3V..15V in RS-232C.
#
-# RS-232C signal lines are active low, in that the asserted signal is
-# represented by a logic zero (0).
+# PC serial ports often break the spec and treat 0v as a logic 1/MARK instead
+# of an invalid value.
#
#
# Important MSP430 signals
# The BSL protocol is entered by manipulating the RST and TCK pins on MSP430
# uC's with dedicated JTAG pins, and by manipulating RST and TEST pins on
# MSP430 uC's with shared JTAG pins. The assertion state of TEST and TCK
-# are always equal, so we use the term TTCK to imply either or both of them
+# are the same, so we use the term TTCK to imply either or both of them
# simultaneously.
#
# RST and TCK are active low signals. TEST is active high.
# An MSP430 is reset by simplying asserting RST for a short period then
# unasserting it.
#
-# The BSL mode is entered by performing this sequence of events:
+# The BSL mode is entered by performing this sequence of events, subject to
+# timing constraints documented by TI:
# Assert RST
# Assert TTCK
# Unssert TTCK
# that can vary significantly from the TI schematic.
#
# The code presented in the TI document does not use a consistent methodology
-# to indicate what is happening when a SetXXX(n) function is called. In some
+# to indicate what is happening when a setXXX(n) function is called. In some
# cases, 'n' represents the assertion state, where 1=asserted and 0=unasserted.
# In other cases, 'n' represents the inverse of the assertion state. In yet
# other cases, 'n' represents the logic value of the signal on a given pin, or
# the inverse of the logic value.
#
-# To improve readability, this code explicitly defines all SetXXX(n) functions
-# where 'n' represents the assertion state of the signal. In other words, when
-# n==1 the signal is asserted and when n==0 the signal is unasserted. One can
-# trivially determine the logic state of any signal pin by applying the current
-# assertion state to the signal's active state (see the chart above).
+# To improve readability and allow for modular, pluggable BSL handling, this
+# code explicitly defines all setXXX(n) functions where 'n' represents the
+# assertion state of the signal. In other words, when n==1 the signal is
+# asserted and when n==0 the signal is unasserted. One can trivially determine
+# the logic state of any signal pin by applying the current assertion state to
+# the signal's active state (see the charts above).
#
# Device support
# ==============
# @author Jonathan Hui <jhui@archedrock.com>
# @author David Gay
# @author Kevin Klues <klueska@cs.stanford.edu>
+# @author R. Steve McKown <rsmckown@gmail.com>
#
# $Revision$
# $Date$
#
+from __future__ import with_statement # Does this require too new a python?
+
+import os
+import re
from re import match
from sys import *
from xml.dom import *
return path
-NUM_SECTORS = 16
-SECTOR_SIZE = 65536
+HEADER_FILE = 'Stm25p.h'
+NUM_SECTORS = 0
+SECTOR_SIZE = 0
+
+def parseHeader( dotplatform ):
+ """ Return an ordered list of paths from the dotplatform file """
+ paths = []
+ inArray = False
+ p = re.compile('push\s*\(\s*@includes,\s*qw\s*\(');
+ q = re.compile('\)\s*\)\s*;');
+ try:
+ with open(dotplatform, 'r') as file:
+ for line in file:
+ path = line.strip()
+ if path:
+ if p.match(path):
+ inArray = True
+ elif q.match(path):
+ inArray = False
+ elif inArray == True:
+ paths.append(path)
+ return paths
+ except:
+ return None
+
+def findFile( paths, filename ):
+ """ Find the first occurrence of 'filename' in the list of paths given. """
+ for path in paths:
+ rpath = expand_path(path)
+ try:
+ for file in os.listdir(rpath):
+ if file == filename:
+ return rpath + '/' + filename
+ except OSError:
+ None
+ return None
+
+def findVars( path, vars ):
+ """ Finds values for the variables already present in vars from path """
+ inEnum = False
+ p = re.compile('enum\s.*{');
+ q = re.compile('}s*;');
+ r = re.compile('^\s*([A-Z0-9_]*)\s*=\s*([^,]*)');
+ with open(path, 'r') as file:
+ for line in file:
+ line = line.strip()
+ if line:
+ if p.match(line):
+ inEnum = True
+ elif q.match(line):
+ inEnum = False
+ elif inEnum == True:
+ m = r.search(line)
+ if vars.has_key(m.group(1)):
+ vars[m.group(1)] = m.group(2)
+
+paths = parseHeader(platformdir + '/.platform')
+if paths:
+ path = findFile(paths, HEADER_FILE)
+ if path:
+ enums = {}
+ enums["STM25P_NUM_SECTORS"] = 0
+ enums["STM25P_SECTOR_SIZE_LOG2"] = 0
+ findVars(path, enums)
+ NUM_SECTORS = int(enums["STM25P_NUM_SECTORS"])
+ SECTOR_SIZE = 2**int(enums["STM25P_SECTOR_SIZE_LOG2"])
+if NUM_SECTORS == 0 or SECTOR_SIZE == 0:
+ stderr.write( "tos-storage-stm25p: no valid Stm25p.h found.\n\t"
+ "Check @includes in the platform's .platform file\n" )
+ exit(2)
volumes = {}
#endif
/**
- * CC2420 header. An I-frame (interoperability frame) header has an
- * extra network byte specified by 6LowPAN
+ * CC2420 header definition.
+ *
+ * An I-frame (interoperability frame) header has an extra network
+ * byte specified by 6LowPAN
+ *
+ * Length = length of the header + payload of the packet, minus the size
+ * of the length byte itself (1). This is what allows for variable
+ * length packets.
+ *
+ * FCF = Frame Control Field, defined in the 802.15.4 specs and the
+ * CC2420 datasheet.
+ *
+ * DSN = Data Sequence Number, a number incremented for each packet sent
+ * by a particular node. This is used in acknowledging that packet,
+ * and also filtering out duplicate packets.
+ *
+ * DestPan = The destination PAN (personal area network) ID, so your
+ * network can sit side by side with another TinyOS network and not
+ * interfere.
+ *
+ * Dest = The destination address of this packet. 0xFFFF is the broadcast
+ * address.
+ *
+ * Src = The local node ID that generated the message.
+ *
+ * Network = The TinyOS network ID, for interoperability with other types
+ * of 802.15.4 networks.
+ *
+ * Type = TinyOS AM type. When you create a new AMSenderC(AM_MYMSG),
+ * the AM_MYMSG definition is the type of packet.
+ *
+ * TOSH_DATA_LENGTH defaults to 28, it represents the maximum size of
+ * the payload portion of the packet, and is specified in the
+ * tos/types/message.h file.
+ *
+ * All of these fields will be filled in automatically by the radio stack
+ * when you attempt to send a message.
*/
typedef nx_struct cc2420_header_t {
nxle_uint8_t length;
message_t* msg,
uint8_t len) {
cc2420_header_t* header = call CC2420PacketBody.getHeader( msg );
+
+ if (len > call Packet.maxPayloadLength()) {
+ return ESIZE;
+ }
+
header->type = id;
header->dest = addr;
header->destpan = call CC2420Config.getPanAddr();
TimeSyncPacketMilli = CC2420TimeSyncMessageP;
Packet = CC2420TimeSyncMessageP;
- CC2420TimeSyncMessageP.SubSend -> CC2420ActiveMessageC.AMSend;
- CC2420TimeSyncMessageP.SubPacket -> CC2420ActiveMessageC.Packet;
+ // use the AMSenderC infrastructure to avoid concurrent send clashes
+ components AMQueueP, ActiveMessageC;
+ CC2420TimeSyncMessageP.SubSend -> AMQueueP.Send[unique(UQ_AMQUEUE_SEND)];
+ CC2420TimeSyncMessageP.AMPacket -> ActiveMessageC;
+ CC2420TimeSyncMessageP.SubPacket -> ActiveMessageC;
CC2420TimeSyncMessageP.PacketTimeStamp32khz -> CC2420PacketC;
CC2420TimeSyncMessageP.PacketTimeStampMilli -> CC2420PacketC;
uses
{
- interface AMSend as SubSend[uint8_t id];
+ interface Send as SubSend;
+ interface AMPacket;
interface Packet as SubPacket;
interface PacketTimeStamp<T32khz,uint32_t> as PacketTimeStamp32khz;
void * timesync = msg->data + len;
*(timesync_radio_t*)timesync = event_time;
- err = call SubSend.send[id](addr, msg, len + sizeof(timesync_radio_t));
+ call AMPacket.setDestination(msg, addr);
+ call AMPacket.setType(msg, id);
+ err = call SubSend.send(msg, len + sizeof(timesync_radio_t));
call PacketTimeSyncOffset.set(msg);
return err;
}
command error_t TimeSyncAMSend32khz.cancel[am_id_t id](message_t* msg)
{
call PacketTimeSyncOffset.cancel(msg);
- return call SubSend.cancel[id](msg);
+ return call SubSend.cancel(msg);
}
default event void TimeSyncAMSend32khz.sendDone[am_id_t id](message_t* msg, error_t error) {}
command uint8_t TimeSyncAMSend32khz.maxPayloadLength[am_id_t id]()
{
- return call SubSend.maxPayloadLength[id]() - sizeof(timesync_radio_t);
+ return call SubSend.maxPayloadLength() - sizeof(timesync_radio_t);
}
command void* TimeSyncAMSend32khz.getPayload[am_id_t id](message_t* msg, uint8_t len)
{
- return call SubSend.getPayload[id](msg, len + sizeof(timesync_radio_t));
+ return call SubSend.getPayload(msg, len + sizeof(timesync_radio_t));
}
/*----------------- TimeSyncAMSendMilli -----------------*/
}
/*----------------- SubSend.sendDone -------------------*/
- event void SubSend.sendDone[am_id_t id](message_t* msg, error_t error)
+ event void SubSend.sendDone(message_t* msg, error_t error)
{
+ am_id_t id = call AMPacket.type(msg);
signal TimeSyncAMSend32khz.sendDone[id](msg, error);
signal TimeSyncAMSendMilli.sendDone[id](msg, error);
}
/****************** Prototypes ****************/
task void startDone_task();
- task void startDone_task();
task void stopDone_task();
task void sendDone_task();
metadata->ack = FALSE;
metadata->rssi = 0;
metadata->lqi = 0;
- metadata->timesync = FALSE;
+ //metadata->timesync = FALSE;
metadata->timestamp = CC2420_INVALID_TIMESTAMP;
ccaOn = TRUE;
return 0;
}
- return (DUTY_ON_TIME * (10000 - dutyCycle)) / dutyCycle;
+ return ((uint32_t)DUTY_ON_TIME * (10000 - dutyCycle)) / dutyCycle;
}
/**
return 10000;
}
- return getActualDutyCycle((DUTY_ON_TIME * 10000)
+ return getActualDutyCycle(((uint32_t)DUTY_ON_TIME * 10000)
/ (sleepInterval + DUTY_ON_TIME));
}
reset_state();
m_state = S_STARTED;
atomic receivingPacket = FALSE;
+ /* Note:
+ We use the falling edge because the FIFOP polarity is reversed.
+ This is done in CC2420Power.startOscillator from CC2420ControlP.nc.
+ */
call InterruptFIFOP.enableFallingEdge();
}
return SUCCESS;
call SpiResource.release();
}
- if ( m_timestamp_size ) {
- if ( rxFrameLength > 10 ) {
- call PacketTimeStamp.set(m_p_rx_buf, m_timestamp_queue[ m_timestamp_head ]);
+ //new packet is buffered up, or we don't have timestamp in fifo, or ack
+ if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get()
+ || !m_timestamp_size
+ || rxFrameLength <= 10) {
+ call PacketTimeStamp.clear(m_p_rx_buf);
+ }
+ else {
+ if (m_timestamp_size==1)
+ call PacketTimeStamp.set(m_p_rx_buf, m_timestamp_queue[ m_timestamp_head ]);
m_timestamp_head = ( m_timestamp_head + 1 ) % TIMESTAMP_QUEUE_SIZE;
m_timestamp_size--;
- }
- } else {
- call PacketTimeStamp.clear(m_p_rx_buf);
+
+ if (m_timestamp_size>0) {
+ call PacketTimeStamp.clear(m_p_rx_buf);
+ m_timestamp_head = 0;
+ m_timestamp_size = 0;
+ }
}
-
+
// We may have received an ack that should be processed by Transmit
// buf[rxFrameLength] >> 7 checks the CRC
if ( ( buf[ rxFrameLength ] >> 7 ) && rx_buf ) {
provides interface CC2420Register as MANAND;
provides interface CC2420Register as MANOR;
provides interface CC2420Register as AGCCTRL;
+ provides interface CC2420Register as RXFIFO_REGISTER;
// ram
provides interface CC2420Ram as IEEEADR;
MANAND = Spi.Reg[ CC2420_MANAND ];
MANOR = Spi.Reg[ CC2420_MANOR ];
AGCCTRL = Spi.Reg[ CC2420_AGCCTRL ];
+ RXFIFO_REGISTER = Spi.Reg[ CC2420_RXFIFO ];
// ram
IEEEADR = Spi.Ram[ CC2420_RAM_IEEEADR ];
}
- inline uint32_t time16to32(uint16_t time, uint32_t recent_time)
+ inline uint32_t getTime32(uint16_t time)
{
- if ((recent_time&0xFFFF)<time)
- return ((recent_time-0x10000UL)&0xFFFF0000UL)|time;
- else
- return (recent_time&0xFFFF0000UL)|time;
+ uint32_t recent_time = call BackoffTimer.getNow();
+
+ return recent_time - (uint16_t)(recent_time - time);
}
/**
* would have picked up and executed had our microcontroller been fast enough.
*/
async event void CaptureSFD.captured( uint16_t time ) {
- uint32_t time32 = time16to32(time, call BackoffTimer.getNow());
+ uint32_t time32;
+ uint8_t sfd_state = 0;
atomic {
+ time32 = getTime32(time);
switch( m_state ) {
case S_SFD:
m_state = S_EFD;
sfdHigh = TRUE;
+ // in case we got stuck in the receive SFD interrupts, we can reset
+ // the state here since we know that we are not receiving anymore
+ m_receiving = FALSE;
call CaptureSFD.captureFallingEdge();
call PacketTimeStamp.set(m_msg, time32);
if (call PacketTimeSyncOffset.isSet(m_msg)) {
- nx_uint8_t *taddr = m_msg->data + (call PacketTimeSyncOffset.get(m_msg) - sizeof(cc2420_header_t));
- timesync_radio_t *timesync = (timesync_radio_t*)taddr;
+ uint8_t absOffset = sizeof(message_header_t)-sizeof(cc2420_header_t)+call PacketTimeSyncOffset.get(m_msg);
+ timesync_radio_t *timesync = (timesync_radio_t *)((nx_uint8_t*)m_msg+absOffset);
// set timesync event time as the offset between the event time and the SFD interrupt time (TEP 133)
*timesync -= time32;
call CSN.clr();
- call TXFIFO_RAM.write( call PacketTimeSyncOffset.get(m_msg), (uint8_t*)timesync, sizeof(timesync_radio_t) );
+ call TXFIFO_RAM.write( absOffset, (uint8_t*)timesync, sizeof(timesync_radio_t) );
call CSN.set();
+ //restoring the event time to the original value
+ *timesync += time32;
}
if ( (call CC2420PacketBody.getHeader( m_msg ))->fcf & ( 1 << IEEE154_FCF_ACK_REQ ) ) {
releaseSpiResource();
call BackoffTimer.stop();
-
- if ( ( ( (call CC2420PacketBody.getHeader( m_msg ))->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7 ) == IEEE154_TYPE_DATA ) {
- call PacketTimeStamp.set(m_msg, time32);
- }
-
if ( call SFD.get() ) {
break;
}
/** Fall Through because the next interrupt was already received */
-
+
case S_EFD:
sfdHigh = FALSE;
call CaptureSFD.captureRisingEdge();
/** Fall Through because the next interrupt was already received */
default:
- if ( !m_receiving ) {
+ /* this is the SFD for received messages */
+ if ( !m_receiving && sfdHigh == FALSE ) {
sfdHigh = TRUE;
call CaptureSFD.captureFallingEdge();
+ // safe the SFD pin status for later use
+ sfd_state = call SFD.get();
call CC2420Receive.sfd( time32 );
m_receiving = TRUE;
m_prev_time = time;
// wait for the next interrupt before moving on
return;
}
+ // if SFD.get() = 0, then an other interrupt happened since we
+ // reconfigured CaptureSFD! Fall through
}
- sfdHigh = FALSE;
- call CaptureSFD.captureRisingEdge();
- m_receiving = FALSE;
- if ( time - m_prev_time < 10 ) {
- call CC2420Receive.sfd_dropped();
- if (m_msg)
- call PacketTimeStamp.clear(m_msg);
+ if ( sfdHigh == TRUE ) {
+ sfdHigh = FALSE;
+ call CaptureSFD.captureRisingEdge();
+ m_receiving = FALSE;
+ /* if sfd_state is 1, then we fell through, but at the time of
+ * saving the time stamp the SFD was still high. Thus, the timestamp
+ * is valid.
+ * if the sfd_state is 0, then either we fell through and SFD
+ * was low while we safed the time stamp, or we didn't fall through.
+ * Thus, we check for the time between the two interrupts.
+ * FIXME: Why 10 tics? Seams like some magic number...
+ */
+ if ((sfd_state == 0) && (time - m_prev_time < 10) ) {
+ call CC2420Receive.sfd_dropped();
+ if (m_msg)
+ call PacketTimeStamp.clear(m_msg);
+ }
+ break;
}
- break;
-
}
}
}
;
BusyWait = BusyWaitCounterC;
- BusyWaitCounter.Counter -> Msp430Counter32khzC;
+ BusyWaitCounterC.Counter -> Msp430Counter32khzC;
}
}
}
implementation {
-#if defined(__MSP430_HAS_USCI_AB0__)
- components new HplMsp430UsciRegP(UCA0CTL0_, UCA0CTL1_, UCA0BR0_, UCA0BR1_,
- UCA0MCTL_, 0/*UCA0I2CIE_*/, UCA0STAT_, UCA0RXBUF_, UCA0TXBUF_, UCA0ABCTL_,
- UCA0IRTCTL_, UCA0IRRCTL_, 0/*UCA0I2COA_*/, 0/*UCA0I2CSA_*/, IE2_, IFG2_,
- UCA0RXIFG, UCA0TXIFG)
- as RegA0P;
- RegA0 = RegA0P.Registers;
-
- components new HplMsp430UsciRegP(UCB0CTL0_, UCB0CTL1_, UCB0BR0_, UCB0BR1_,
- 0/*UCB0MCTL_*/, UCB0I2CIE_, UCB0STAT_, UCB0RXBUF_, UCB0TXBUF_,
- 0/*UCB0ABCTL_*/, 0/*UCB0IRTCTL_*/, 0/*UCB0IRRCTL_*/, UCB0I2COA_,
- UCB0I2CSA_, IE2_, IFG2_, UCB0RXIFG, UCB0TXIFG) as RegB0P;
- RegB0 = RegB0P.Registers;
-
- components HplMsp430UsciInt0P as Int0P;
- IntA0 = Int0P.IntA;
- IntB0 = Int0P.IntB;
-#elif defined(__MSP430_HAS_USCI__)
+#if defined(__MSP430_HAS_USCI_AB0__) || defined(__MSP430_HAS_USCI__)
components new HplMsp430UsciRegP(UCA0CTL0_, UCA0CTL1_, UCA0BR0_, UCA0BR1_,
UCA0MCTL_, 0/*UCA0I2CIE_*/, UCA0STAT_, UCA0RXBUF_, UCA0TXBUF_, UCA0ABCTL_,
UCA0IRTCTL_, UCA0IRRCTL_, 0/*UCA0I2COA_*/, 0/*UCA0I2CSA_*/, IE2_, IFG2_,
MSP430REG_NORACE(UCB0RXBUF);
#endif
- /* This USCI_Ax and USCI_Bx interrupt vector signals receive events for UART
- * and SPI modes, and status events for I2C modes. Only Bx can do I2C.
+ /* This interrupt vector signals receive events. USCI_A0 can receive events
+ * for UART and SPI modes, while USCI_B0 can receive events for I2C and SPI
+ * modes.
*/
TOSH_SIGNAL(USCIAB0RX_VECTOR) {
- if (READ_FLAG(UC0IFG, UCA0RXIFG)) {
+ if (READ_FLAG(UC0IFG & UC0IE, UCA0RXIE)) {
volatile uint8_t c = UCA0RXBUF; /* read to clear UCA0RXIFG */
if (READ_FLAG(UCA0CTL1, UCBRK)) {
- UCA0CTL1 &= ~UCBRK;
+ CLR_FLAG(UCA0CTL1, UCBRK);
if (READ_FLAG(UCA0CTL0, UCMODE_3) == UCMODE_3)
- UCA0CTL1 &= ~UCDORM;
+ CLR_FLAG(UCA0CTL1, UCDORM);
signal IntA.brk();
} else
signal IntA.rx(c);
- } else if (READ_FLAG(UC0IFG, UCB0RXIFG))
+ } else if (READ_FLAG(UC0IFG & UC0IE, UCB0RXIE)) {
signal IntB.rx(UCB0RXBUF); /* read clears UCB0RXIFG */
- else if (READ_FLAG(UCB0STAT, UCALIFG))
+
+ /* FIXME: the arbitration of I2C interrupts are not vetted. If, for example
+ * the UCALIFG bit gets set and neither it nor the corresponding interrupt
+ * enable bit is never unset, then an ISR configured for UCSTTIFG or
+ * UCSTPIFG will never be signalled.
+ */
+
+ } else if (READ_FLAG(UCB0STAT, UCALIFG)) {
+ CLR_FLAG(UCB0STAT, UCALIFG);
signal IntB.i2cCal();
- else if (READ_FLAG(UCB0STAT, UCNACKIFG))
+ } else if (READ_FLAG(UCB0STAT, UCNACKIFG)) {
+ CLR_FLAG(UCB0STAT, UCNACKIFG);
+ CLR_FLAG(UC0IFG, UCB0TXIFG); /* Errata USCI25; 'reset' means clear? */
signal IntB.i2cNak();
- else if (READ_FLAG(UCB0STAT, UCSTTIFG))
+ } else if (READ_FLAG(UCB0STAT, UCSTTIFG)) {
+ CLR_FLAG(UCB0STAT, UCSTTIFG);
signal IntB.i2cStart();
- else if (READ_FLAG(UCB0STAT, UCSTPIFG))
+ } else if (READ_FLAG(UCB0STAT, UCSTPIFG)) {
+ CLR_FLAG(UCB0STAT, UCSTPIFG);
signal IntB.i2cStop();
+ }
}
- /* This USCI_Ax and USCI_Bx interrupt vector signals transmit events for UART
- * and SPI modes, and rx/tx events for I2C modes. Only Bx can do I2C.
+ /* This interrupt vector signals transmit events. USCI_A0 can receive events
+ * for UART and SPI modes, while USCI_B0 can receive events for I2C and SPI
+ * modes.
*/
TOSH_SIGNAL(USCIAB0TX_VECTOR) {
- if (READ_FLAG(UC0IFG, UCB0RXIFG))
+ if (READ_FLAG(UC0IFG & UC0IE, UCB0RXIE))
signal IntB.rx(UCB0RXBUF); /* I2C receive */
- else if (READ_FLAG(UC0IFG, UCA0TXIFG))
+ else if (READ_FLAG(UC0IFG & UC0IE, UCA0TXIFG))
signal IntA.tx();
- else if (READ_FLAG(UC0IFG, UCB0TXIFG))
+ else if (READ_FLAG(UC0IFG & UC0IE, UCB0TXIFG))
signal IntB.tx();
}
default async event void IntA.i2cStart() {}
default async event void IntA.i2cStop() {}
+ /* UART is not available for B devices, so IntB.brk() is never sitnalled */
default async event void IntB.brk() {}
default async event void IntB.rx(uint8_t byte) {}
default async event void IntB.tx() {}
MSP430REG_NORACE(UCB1RXBUF);
#endif
- /* This USCI_Ax and USCI_Bx interrupt vector signals receive events for UART
- * and SPI modes, and status events for I2C modes. Only Bx can do I2C.
+ /* This interrupt vector signals receive events. USCI_A1 can receive events
+ * for UART and SPI modes, while USCI_B1 can receive events for I2C and SPI
+ * modes.
*/
TOSH_SIGNAL(USCIAB1RX_VECTOR) {
- if (READ_FLAG(UC1IFG, UCA1RXIFG)) {
+ if (READ_FLAG(UC1IFG & UC1IE, UCA1RXIE)) {
volatile uint8_t c = UCA1RXBUF; /* read to clear UCA1RXIFG */
if (READ_FLAG(UCA1CTL1, UCBRK)) {
- UCA1CTL1 &= ~UCBRK;
+ CLR_FLAG(UCA1CTL1, UCBRK);
if (READ_FLAG(UCA1CTL0, UCMODE_3) == UCMODE_3)
- UCA1CTL1 &= ~UCDORM;
+ CLR_FLAG(UCA1CTL1, UCDORM);
signal IntA.brk();
} else
signal IntA.rx(c);
- } else if (READ_FLAG(UC1IFG, UCB1RXIFG))
+ } else if (READ_FLAG(UC1IFG & UC1IE, UCB1RXIE)) {
signal IntB.rx(UCB1RXBUF); /* read clears UCB1RXIFG */
- else if (READ_FLAG(UCB1STAT, UCALIFG))
+
+ /* FIXME: the arbitration of I2C interrupts are not vetted. If, for example
+ * the UCALIFG bit gets set and neither it nor the corresponding interrupt
+ * enable bit is never unset, then an ISR configured for UCSTTIFG or
+ * UCSTPIFG will never be signalled.
+ */
+
+ } else if (READ_FLAG(UCB1STAT, UCALIFG)) {
+ CLR_FLAG(UCB1STAT, UCALIFG);
signal IntB.i2cCal();
- else if (READ_FLAG(UCB1STAT, UCNACKIFG))
+ } else if (READ_FLAG(UCB1STAT, UCNACKIFG)) {
+ CLR_FLAG(UCB1STAT, UCNACKIFG);
+ CLR_FLAG(UC1IFG, UCB1TXIFG); /* Errata USCI25; 'reset' means clear? */
signal IntB.i2cNak();
- else if (READ_FLAG(UCB1STAT, UCSTTIFG))
+ } else if (READ_FLAG(UCB1STAT, UCSTTIFG)) {
+ CLR_FLAG(UCB1STAT, UCSTTIFG);
signal IntB.i2cStart();
- else if (READ_FLAG(UCB1STAT, UCSTPIFG))
+ } else if (READ_FLAG(UCB1STAT, UCSTPIFG)) {
+ CLR_FLAG(UCB1STAT, UCSTPIFG);
signal IntB.i2cStop();
+ }
}
- /* This USCI_Ax and USCI_Bx interrupt vector signals transmit events for UART
- * and SPI modes, and rx/tx events for I2C modes. Only Bx can do I2C.
+ /* This interrupt vector signals transmit events. USCI_A1 can receive events
+ * for UART and SPI modes, while USCI_B1 can receive events for I2C and SPI
+ * modes.
*/
TOSH_SIGNAL(USCIAB1TX_VECTOR) {
- if (READ_FLAG(UC1IFG, UCB1RXIFG))
+ if (READ_FLAG(UC1IFG & UC1IE, UCB1RXIE))
signal IntB.rx(UCB1RXBUF); /* I2C receive */
- else if (READ_FLAG(UC1IFG, UCA1TXIFG))
+ else if (READ_FLAG(UC1IFG & UC1IE, UCA1TXIFG))
signal IntA.tx();
- else if (READ_FLAG(UC1IFG, UCB1TXIFG))
+ else if (READ_FLAG(UC1IFG & UC1IE, UCB1TXIFG))
signal IntB.tx();
}
default async event void IntA.i2cStart() {}
default async event void IntA.i2cStop() {}
+ /* UART is not available for B devices, so IntB.brk() is never sitnalled */
default async event void IntB.brk() {}
default async event void IntB.rx(uint8_t byte) {}
default async event void IntB.tx() {}
* UCxxCTL0 for more information.
*/
async command bool getIfgRx();
- async command void setIfgRx();
async command void clrIfgRx();
async command bool getIfgTx();
- async command void setIfgTx();
- async command void clrIfgTx();
-
}
return READ_FLAG(UCxxIfg, UCxxRXIFG);
}
- async command void Registers.setIfgRx()
- {
- SET_FLAG(UCxxIfg, UCxxRXIFG);
- }
-
async command void Registers.clrIfgRx()
{
CLR_FLAG(UCxxIfg, UCxxRXIFG);
{
return READ_FLAG(UCxxIfg, UCxxTXIFG);
}
-
- async command void Registers.setIfgTx()
- {
- SET_FLAG(UCxxIfg, UCxxTXIFG);
- }
-
- async command void Registers.clrIfgTx()
- {
- CLR_FLAG(UCxxIfg, UCxxTXIFG);
- }
}
async command uint8_t SpiByte.write(uint8_t byte)
{
- if (isBusy())
- return 0;
- else {
- waitOnTx();
- call Registers.setTxbuf(byte);
- waitOnRx();
- return call Registers.getRxbuf();
+ atomic {
+ if (isBusy())
+ return 0;
+ else {
+ waitOnTx();
+ call Registers.setTxbuf(byte);
+ waitOnRx();
+ return call Registers.getRxbuf();
+ }
}
}
if (end > m_len)
end = m_len;
+ waitOnTx(); /* Don't assume that the last tx is done already */
call Registers.setTxbuf(m_txBuf ? m_txBuf[m_pos] : 0);
while (++m_pos < end) {
waitOnRx();
uint8_t m_pins;
uint8_t* m_sobuf; /* Original buffer ptr from UartStream.send() */
- uint8_t m_solen; /* Original buffer len from UartStream.send() */
+ uint16_t m_solen; /* Original buffer len from UartStream.send() */
uint8_t* m_sbuf; /* Position of next char to send */
- uint8_t m_slen; /* Len of chars in m_sbuf to send */
+ uint16_t m_slen; /* Len of chars in m_sbuf to send */
bool m_rxie; /* Set if rxie has been enabled to UartStream.receive() */
uint8_t* m_robuf; /* Original receive buffer */
- uint8_t m_rolen; /* Original (maximum) receive len */
+ uint16_t m_rolen; /* Original (maximum) receive len */
uint8_t* m_rbuf; /* Position of next byte in which to receive a char */
- uint8_t m_rlen; /* Remaining length in receive buffer */
+ uint16_t m_rlen; /* Remaining length in receive buffer */
sfrb(MYBRX, 219U);
call Registers.clrIeRx();
call Registers.clrIeTx();
call Registers.clrIfgRx();
- call Registers.clrIfgTx();
/* Restore pins to their pre-configure state */
if (m_pins & PINS_RXD)
async command error_t UartByte.send(uint8_t byte)
{
- /* FIXME: race with UartStream.send() */
atomic {
- if (m_sobuf)
- return FAIL;
while (!call Registers.getIfgTx());
call Registers.setTxbuf(byte);
return SUCCESS;
atomic {
if (m_sobuf || !buf || !len)
return FAIL;
- m_sobuf = buf;
- m_solen = len;
+ m_sbuf = m_sobuf = buf;
+ m_slen = m_solen = len;
call Registers.setIeTx();
- call Registers.setTxbuf(*m_sobuf);
- m_slen = m_solen - 1;
- if (m_slen)
- m_sbuf = m_sobuf + 1;
return SUCCESS;
}
}
async event void Interrupts.tx()
{
+ /* FIXME: this can cause an arbitrarily long ISR, if m_slen is large.
+ * But depending on timing, we may always only write 1 byte.
+ */
+ while (!call Registers.getIfgTx()); /* in case interleaved UB.send */
while (m_slen && call Registers.getIfgTx()) {
call Registers.setTxbuf(*m_sbuf);
if (--m_slen)
m_sbuf++;
}
- if (m_slen == 0 && m_sobuf) {
+ if (m_slen == 0) {
call Registers.clrIeTx();
- call Registers.clrIfgTx();
m_sobuf = 0;
signal UartStream.sendDone(m_sobuf, m_solen, SUCCESS);
}
async event void Interrupts.rx(uint8_t byte)
{
- atomic {
- if (m_robuf) {
- /* receive() takes precedence if active */
- while (m_rlen && call Registers.getIfgRx()) {
- *m_rbuf = byte;
- if (--m_rlen)
- m_rbuf++;
- }
- if (m_rlen == 0 && m_robuf) {
- if (m_rxie) {
- call Registers.clrIeRx();
- call Registers.clrIfgRx();
- }
- m_robuf = 0;
- signal UartStream.receiveDone(m_robuf, m_rolen, SUCCESS);
+ if (m_robuf) {
+ /* receive() takes precedence if active */
+ /* FIXME: an arbitrarily long ISR may occur if m_rlen is large.
+ * But depending on timing, we may always only read 1 byte.
+ */
+ while (m_rlen && call Registers.getIfgRx()) {
+ *m_rbuf = byte;
+ if (--m_rlen)
+ m_rbuf++;
+ }
+ if (m_rlen == 0 && m_robuf) {
+ if (m_rxie) {
+ call Registers.clrIeRx();
+ call Registers.clrIfgRx();
}
- } else
- signal UartStream.receivedByte(byte);
- }
+ m_robuf = 0;
+ signal UartStream.receiveDone(m_robuf, m_rolen, SUCCESS);
+ }
+ } else
+ signal UartStream.receivedByte(byte);
}
default async command const msp430_usci_uart_t* Configure.get()
--- /dev/null
+/*
+ * Copyright (c) 2002, Vanderbilt University
+ * 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 VANDERBILT UNIVERSITY 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 VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY 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 VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti, Brano Kusy, Janos Sallai
+ * Date last modified: 3/17/03
+ * Ported to T2: 3/17/08 by Brano Kusy (branislav.kusy@gmail.com)
+ * Adapted for 32kHz and LPL: 6/16/09 by Thomas Schmid (thomas.schmid@ucla.edu)
+ */
+
+#include "TimeSyncMsg.h"
+
+configuration TimeSync32kC
+{
+ uses interface Boot;
+ provides interface Init;
+ provides interface StdControl;
+ provides interface GlobalTime<T32khz>;
+
+ //interfaces for extra fcionality: need not to be wired
+ provides interface TimeSyncInfo;
+ provides interface TimeSyncMode;
+ provides interface TimeSyncNotify;
+}
+
+implementation
+{
+ components new TimeSyncP(T32khz) as TimeSyncP;
+
+ GlobalTime = TimeSyncP;
+ StdControl = TimeSyncP;
+ Init = TimeSyncP;
+ Boot = TimeSyncP;
+ TimeSyncInfo = TimeSyncP;
+ TimeSyncMode = TimeSyncP;
+ TimeSyncNotify = TimeSyncP;
+
+ components TimeSyncMessageC as ActiveMessageC;
+ TimeSyncP.RadioControl -> ActiveMessageC;
+ TimeSyncP.Send -> ActiveMessageC.TimeSyncAMSend32khz[AM_TIMESYNCMSG];
+ TimeSyncP.Receive -> ActiveMessageC.Receive[AM_TIMESYNCMSG];
+ TimeSyncP.TimeSyncPacket -> ActiveMessageC;
+
+ components Counter32khz32C, new CounterToLocalTimeC(T32khz) as LocalTime32khzC;
+ LocalTime32khzC.Counter -> Counter32khz32C;
+ TimeSyncP.LocalTime -> LocalTime32khzC;
+
+ components new TimerMilliC() as TimerC;
+ TimeSyncP.Timer -> TimerC;
+
+#if defined(TIMESYNC_LEDS)
+ components LedsC;
+#else
+ components NoLedsC as LedsC;
+#endif
+ TimeSyncP.Leds -> LedsC;
+
+#ifdef LOW_POWER_LISTENING
+ components CC2420ActiveMessageC;
+ TimeSyncP.LowPowerListening -> CC2420ActiveMessageC;
+#endif
+
+
+}
#endif
TimeSyncP.Leds -> LedsC;
+#ifdef LOW_POWER_LISTENING
+ components CC2420ActiveMessageC;
+ TimeSyncP.LowPowerListening -> CC2420ActiveMessageC;
+#endif
+
}
nx_uint16_t nodeID; // the node if of the sender
nx_uint8_t seqNum; // sequence number for the root
- /* This field is initially set to the offset between global time and local
- * time. The TimeStamping component will add the current local time when the
- * message is actually transmitted. Thus the receiver will receive the
- * global time of the sender when the message is actually sent. */
+ /*
+ * After TEP 133, the message timestamp contains the difference between
+ * event time and the time the message was actually sent out. TimeSyncP
+ * sends the local time associated with this globalTime to the
+ * TimeStamping mechanism, which then calculates the difference.
+ *
+ * On the receiving side, the difference is applied to the local
+ * timestamp. The receiving timestamp thus represents the time on the
+ * receiving clock when the remote globalTime was taken.
+ */
nx_uint32_t globalTime;
//just for convenience
interface Leds;
interface TimeSyncPacket<precision_tag,uint32_t>;
interface LocalTime<precision_tag> as LocalTime;
+
+
+#ifdef LOW_POWER_LISTENING
+ interface LowPowerListening;
+#endif
+
}
}
implementation
IGNORE_ROOT_MSG = 4, // after becoming the root ignore other roots messages (in send period)
ENTRY_VALID_LIMIT = 4, // number of entries to become synchronized
ENTRY_SEND_LIMIT = 3, // number of entries to send sync messages
- ENTRY_THROWOUT_LIMIT = 100, // if time sync error is bigger than this clear the table
+ ENTRY_THROWOUT_LIMIT = 500, // if time sync error is bigger than this clear the table
};
typedef struct TableItem
float newSkew = skew;
uint32_t newLocalAverage;
int32_t newOffsetAverage;
+ int32_t localAverageRest;
+ int32_t offsetAverageRest;
int64_t localSum;
int64_t offsetSum;
newOffsetAverage = table[i].timeOffset;
localSum = 0;
+ localAverageRest = 0;
offsetSum = 0;
+ offsetAverageRest = 0;
while( ++i < MAX_ENTRIES )
if( table[i].state == ENTRY_FULL ) {
+ /*
+ This only works because C ISO 1999 defines the signe for modulo the same as for the Dividend!
+ */
localSum += (int32_t)(table[i].localTime - newLocalAverage) / tableEntries;
+ localAverageRest += (table[i].localTime - newLocalAverage) % tableEntries;
offsetSum += (int32_t)(table[i].timeOffset - newOffsetAverage) / tableEntries;
+ offsetAverageRest += (table[i].timeOffset - newOffsetAverage) % tableEntries;
}
- newLocalAverage += localSum;
- newOffsetAverage += offsetSum;
+ newLocalAverage += localSum + localAverageRest / tableEntries;
+ newOffsetAverage += offsetSum + offsetAverageRest / tableEntries;
localSum = offsetSum = 0;
for(i = 0; i < MAX_ENTRIES; ++i)
uint32_t age, oldestTime = 0;
int32_t timeError;
- tableEntries = 0;
-
// clear table if the received entry's been inconsistent for some time
timeError = msg->localTime;
call GlobalTime.local2Global((uint32_t*)(&timeError));
{
if (++numErrors>3)
clearTable();
+ return; // don't incorporate a bad reading
}
- else
- numErrors = 0;
+ tableEntries = 0; // don't reset table size unless you're recounting
+ numErrors = 0;
for(i = 0; i < MAX_ENTRIES; ++i) {
age = msg->localTime - table[i].localTime;
if( diff < -16 || diff > 16 )
return msg;
#endif
- if( (state & STATE_PROCESSING) == 0 ) {
+ if( (state & STATE_PROCESSING) == 0
+ && call TimeSyncPacket.isValid(msg)) {
message_t* old = processedMsg;
processedMsg = msg;
outgoingMsg->globalTime = globalTime;
+#ifdef LOW_POWER_LISTENING
+ call LowPowerListening.setRxSleepInterval(&outgoingMsgBuffer, LPL_INTERVAL);
+#endif
// we don't send time sync msg, if we don't have enough data
if( numEntries < ENTRY_SEND_LIMIT && outgoingMsg->rootID != TOS_NODE_ID ){
++heartBeats;
if (mode == mode_)
return SUCCESS;
- if (mode_ == TS_USER_MODE){
+ if (mode_ == TS_TIMER_MODE){
call Timer.startPeriodic((uint32_t)1000 * BEACON_RATE);
}
else
--- /dev/null
+# Includes that should take precedence come first. Platforms come before
+# chips because they may override files. These must be specified as
+# @includes instead of -I's to @opts, otherwise the %T won't be processed
+# by ncc.
+
+push( @includes, qw(
+ %T/platforms/olimexp168
+ %T/platforms/telosa
+ %T/chips/msp430
+ %T/chips/msp430/adc12
+ %T/chips/msp430/dma
+ %T/chips/msp430/pins
+ %T/chips/msp430/timer
+ %T/chips/msp430/usart
+ %T/chips/msp430/sensors
+ %T/lib/timer
+ %T/lib/serial
+ %T/lib/adc
+ %T/lib/power
+) );
+
+@opts = qw(
+ -gcc=msp430-gcc
+ -mmcu=msp430x169
+ -fnesc-target=msp430
+ -fnesc-no-debug
+);
+
+push @opts, "-fnesc-scheduler=TinySchedulerC,TinySchedulerC.TaskBasic,TaskBasic,TaskBasic,runTask,postTask" if !$with_scheduler_flag;
+push @opts, "-mingw-gcc" if $cygwin;
+
+$ENV{'CIL_MACHINE'} =
+ "version_major=3 " .
+ "version_minor=2 " .
+ "version=msp430-3.2.3 " .
+ "short=2,2 " .
+ "int=2,2 " .
+ "long=4,2 " .
+ "long_long=8,2 " .
+ "pointer=2,2 " .
+ "enum=2,2 " .
+ "float=4,2 " .
+ "double=4,2 " .
+ "long_double=4,2 " .
+ "void=1,1 " .
+ "fun=1,2 " .
+ "wchar_size_size=2,2 " .
+ "alignof_string=1 " .
+ "max_alignment=1 " .
+ "char_wchar_signed=true,true " .
+ "const_string_literals=true " .
+ "big_endian=false " .
+ "underscore_name=false " .
+ "__builtin_va_list=true " .
+ "__thread_is_keyword=true";
+
--- /dev/null
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * 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 Arch Rock Corporation 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
+ * ARCHED ROCK 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
+ */
+
+/**
+ * DemoSensorC is a generic sensor device that provides a 16-bit
+ * value. The platform author chooses which sensor actually sits
+ * behind DemoSensorC, and though it's probably Voltage, Light, or
+ * Temperature, there are no guarantees.
+ *
+ * This particular DemoSensorC on the telosb platform provides a
+ * voltage reading, using VoltageC.
+ *
+ * To convert from ADC counts to actual voltage, divide this reading
+ * by 4096 and multiply by 3.
+ *
+ * @author Gilman Tolle <gtolle@archrock.com>
+ * @version $Revision: 1.4 $ $Date: 2006/12/12 18:23:45 $
+ *
+ */
+
+generic configuration DemoSensorC()
+{
+ provides interface Read<uint16_t>;
+}
+implementation
+{
+ components new VoltageC() as DemoSensor;
+ Read = DemoSensor;
+}
--- /dev/null
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * 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 Arch Rock Corporation 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
+ * ARCHED ROCK 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
+ */
+
+/**
+ * DemoSensorNowC is a generic sensor device that provides a 16-bit
+ * value that can be read from async context. The platform author
+ * chooses which sensor actually sits behind DemoSensorNowC, and
+ * though it's probably Voltage, Light, or Temperature, there are no
+ * guarantees.
+ *
+ * This particular DemoSensorNowC on the telosb platform provides a
+ * voltage reading, using VoltageC.
+ *
+ * To convert from ADC counts to actual voltage, divide this reading
+ * by 4096 and multiply by 3.
+ *
+ * @author Gilman Tolle <gtolle@archrock.com>
+ * @version $Revision: 1.4 $ $Date: 2006/12/12 18:23:45 $
+ *
+ */
+
+generic configuration DemoSensorNowC()
+{
+ provides interface Resource;
+ provides interface ReadNow<uint16_t>;
+}
+implementation
+{
+ components new Msp430InternalVoltageC() as DemoSensorNow;
+
+ Resource = DemoSensorNow;
+ ReadNow = DemoSensorNow;
+}
--- /dev/null
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * 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 Arch Rock Corporation 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
+ * ARCHED ROCK 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
+ */
+
+/**
+ * DemoSensorStreamC is a generic sensor device that provides a 16-bit
+ * value. The platform author chooses which sensor actually sits
+ * behind DemoSensorStreamC, and though it's probably Voltage, Light, or
+ * Temperature, there are no guarantees.
+ *
+ * This particular DemoSensorStreamC on the telosb platform provides a
+ * voltage reading, using VoltageStreamC.
+ *
+ * To convert from ADC counts to actual voltage, divide this reading
+ * by 4096 and multiply by 3.
+ *
+ * @author Gilman Tolle <gtolle@archrock.com>
+ * @version $Revision: 1.4 $ $Date: 2006/12/12 18:23:45 $
+ *
+ */
+
+generic configuration DemoSensorStreamC()
+{
+ provides interface ReadStream<uint16_t>;
+}
+implementation
+{
+ components new VoltageStreamC() as DemoSensor;
+ ReadStream = DemoSensor;
+}
--- /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.
+ */
+
+ /**
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+configuration HplUserButtonC {
+ provides interface GeneralIO;
+ provides interface GpioInterrupt;
+}
+implementation {
+ components HplMsp430GeneralIOC as GeneralIOC;
+ components HplMsp430InterruptC as InterruptC;
+
+ components new Msp430GpioC() as UserButtonC;
+ UserButtonC -> GeneralIOC.Port61;
+ GeneralIO = UserButtonC;
+
+ components new Msp430InterruptC() as InterruptUserButtonC;
+ InterruptUserButtonC.HplInterrupt -> InterruptC.Port61;
+ GpioInterrupt = InterruptUserButtonC.Interrupt;
+}
--- /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.
+ */
+
+/**
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+configuration MoteClockC {
+ provides interface Init as MoteClockInit;
+}
+implementation {
+ components new Msp430ClockC(4096, 32);
+ MoteClockInit = Msp430ClockC.Init;
+}
--- /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.
+ */
+
+ /**
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+module MotePlatformC @safe() {
+ provides interface Init;
+}
+implementation {
+ command error_t Init.init() {
+ /* reset all of the ports to be input and using i/o functionality */
+ atomic
+ {
+#ifdef __MSP430_HAS_WDT__
+ /* Stop the watchdog, if running. Should be somewhere in chips/msp430... */
+ WDTCTL = WDTPW + WDTHOLD;
+#endif
+
+ /* Port 1: 7-0:- */
+ P1SEL = 0; /* 0 0 0 0 0 0 0 0 */
+ P1OUT = 0; /* 0 0 0 0 0 0 0 0 */
+ P1DIR = 0; /* 0 0 0 0 0 0 0 0 */
+
+ /* Port 2: 7-0:- */
+ P2SEL = 0; /* 0 0 0 0 0 0 0 0 */
+ P2OUT = 0; /* 0 0 0 0 0 0 0 0 */
+ P2DIR = 0; /* 0 0 0 0 0 0 0 0 */
+
+ /* Port 3: 7-6:- , 5:RXD0, 4:TXD0, 3-0:- */
+ P3SEL = 0; /* 0 0 0 0 0 0 0 0 */
+ P3OUT = 0; /* 0 0 0 0 0 0 0 0 */
+ P3DIR = 0x10; /* 0 0 0 1 0 0 0 0 */
+
+ /* Port 4: 7-0:- */
+ P4SEL = 0; /* 0 0 0 0 0 0 0 0 */
+ P4OUT = 0; /* 0 0 0 0 0 0 0 0 */
+ P4DIR = 0; /* 0 0 0 0 0 0 0 0 */
+
+ /* Port 5: 7-0:- */
+ P5SEL = 0; /* 0 0 0 0 0 0 0 0 */
+ P5OUT = 0; /* 0 0 0 0 0 0 0 0 */
+ P5DIR = 0; /* 0 0 0 0 0 0 0 0 */
+
+ /* Port 6: 7-2:-, 1:BUT, 0:LED */
+ P6SEL = 0; /* 0 0 0 0 0 0 0 0 */
+ P6OUT = 0x01; /* 0 0 0 0 0 0 0 1 */
+ P6DIR = 0x01; /* 0 0 0 0 0 0 0 1 */
+
+ P1IE = 0;
+ P2IE = 0;
+ }
+ return SUCCESS;
+ }
+}
--- /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.
+ */
+
+ /**
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "hardware.h"
+
+configuration PlatformLedsC {
+ provides {
+ interface GeneralIO as Led0;
+ interface GeneralIO as Led1;
+ interface GeneralIO as Led2;
+ }
+ uses interface Init;
+}
+implementation
+{
+ components PlatformP;
+ Init = PlatformP.LedsInit;
+
+ components HplMsp430GeneralIOC as GeneralIOC;
+
+ components new Msp430GpioC() as Led0Impl;
+ Led0 = Led0Impl;
+ Led0Impl -> GeneralIOC.Port60;
+
+ components new NoPinC() as Led2Impl;
+ Led1 = Led2Impl;
+ Led2 = Led2Impl;
+}
+
--- /dev/null
+
+configuration PlatformSerialC {
+
+ provides interface StdControl;
+ provides interface UartStream;
+ provides interface UartByte;
+
+}
+
+implementation {
+
+ components new Msp430Uart0C() as UartC;
+ UartStream = UartC;
+ UartByte = UartC;
+
+ components TelosSerialP;
+ StdControl = TelosSerialP;
+ TelosSerialP.Msp430UartConfigure <- UartC.Msp430UartConfigure;
+ TelosSerialP.Resource -> UartC.Resource;
+
+}
--- /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.
+ */
+
+ /**
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+module PlatformSerialP {
+ provides interface StdControl;
+ uses interface Resource;
+}
+implementation {
+ command error_t StdControl.start()
+ {
+ return call Resource.immediateRequest();
+ }
+
+ command error_t StdControl.stop()
+ {
+ call Resource.release();
+ return SUCCESS;
+ }
+
+ event void Resource.granted() {}
+}
--- /dev/null
+/**
+ * Copyright (c) 2007 Arch Rock Corporation
+ * 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 Arch Rock Corporation 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
+ * ARCHED ROCK 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
+ */
+
+/**
+ * Generic layer to translate a GIO into a toggle switch
+ *
+ * @author Gilman Tolle <gtolle@archrock.com>
+ * @version $Revision: 1.1 $
+ */
+
+#include <UserButton.h>
+
+generic module SwitchToggleC() {
+ provides interface Get<bool>;
+ provides interface Notify<bool>;
+
+ uses interface GeneralIO;
+ uses interface GpioInterrupt;
+}
+implementation {
+ norace bool m_pinHigh;
+
+ task void sendEvent();
+
+ command bool Get.get() { return call GeneralIO.get(); }
+
+ command error_t Notify.enable() {
+ call GeneralIO.makeInput();
+
+ if ( call GeneralIO.get() ) {
+ m_pinHigh = TRUE;
+ return call GpioInterrupt.enableFallingEdge();
+ } else {
+ m_pinHigh = FALSE;
+ return call GpioInterrupt.enableRisingEdge();
+ }
+ }
+
+ command error_t Notify.disable() {
+ return call GpioInterrupt.disable();
+ }
+
+ async event void GpioInterrupt.fired() {
+ call GpioInterrupt.disable();
+
+ m_pinHigh = !m_pinHigh;
+
+ post sendEvent();
+ }
+
+ task void sendEvent() {
+ bool pinHigh;
+ pinHigh = m_pinHigh;
+
+ signal Notify.notify( pinHigh );
+
+ if ( pinHigh ) {
+ call GpioInterrupt.enableFallingEdge();
+ } else {
+ call GpioInterrupt.enableRisingEdge();
+ }
+ }
+}
--- /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.
+ */
+
+ /**
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#ifndef USERBUTTON_H
+#define USERBUTTON_H
+
+typedef enum { BUTTON_RELEASED = 0, BUTTON_PRESSED = 1 } button_state_t;
+
+#endif
--- /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.
+ */
+
+ /**
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include <UserButton.h>
+
+configuration UserButtonC {
+ provides interface Get<button_state_t>;
+ provides interface Notify<button_state_t>;
+}
+implementation {
+ components HplUserButtonC;
+ components new SwitchToggleC();
+ SwitchToggleC.GpioInterrupt -> HplUserButtonC.GpioInterrupt;
+ SwitchToggleC.GeneralIO -> HplUserButtonC.GeneralIO;
+
+ components UserButtonP;
+ Get = UserButtonP;
+ Notify = UserButtonP;
+
+ UserButtonP.GetLower -> SwitchToggleC.Get;
+ UserButtonP.NotifyLower -> SwitchToggleC.Notify;
+}
--- /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.
+ */
+
+ /**
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include <UserButton.h>
+
+module UserButtonP {
+ provides interface Get<button_state_t>;
+ provides interface Notify<button_state_t>;
+
+ uses interface Get<bool> as GetLower;
+ uses interface Notify<bool> as NotifyLower;
+}
+implementation {
+
+ command button_state_t Get.get() {
+ /* Olimex P169 user button pin is high when released - active low */
+ if ( call GetLower.get() ) {
+ return BUTTON_RELEASED;
+ } else {
+ return BUTTON_PRESSED;
+ }
+ }
+
+ command error_t Notify.enable() {
+ return call NotifyLower.enable();
+ }
+
+ command error_t Notify.disable() {
+ return call NotifyLower.disable();
+ }
+
+ event void NotifyLower.notify( bool val ) {
+ /* tmirws user button pin is high when released - active low */
+ if ( val ) {
+ signal Notify.notify( BUTTON_RELEASED );
+ } else {
+ signal Notify.notify( BUTTON_PRESSED );
+ }
+ }
+
+ default event void Notify.notify( button_state_t val ) { }
+}
--- /dev/null
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * 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 Arch Rock Corporation 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
+ * ARCHED ROCK 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
+ */
+
+/**
+ * VoltageC is a common name for the Msp430InternalVoltageC voltage
+ * sensor available on the telosb platform.
+ *
+ * To convert from ADC counts to actual voltage, divide by 4096 and
+ * multiply by 3.
+ *
+ * @author Gilman Tolle <gtolle@archrock.com>
+ * @version $Revision: 1.4 $ $Date: 2006/12/12 18:23:45 $
+ */
+
+generic configuration VoltageC() {
+ provides interface Read<uint16_t>;
+}
+implementation {
+ components new Msp430InternalVoltageC();
+ Read = Msp430InternalVoltageC.Read;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * 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 Arch Rock Corporation 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
+ * ARCHED ROCK 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
+ */
+
+/**
+ * VoltageC is a common name for the Msp430InternalVoltageC voltage
+ * sensor available on the telosb platform.
+ *
+ * To convert from ADC counts to actual voltage, divide by 4096 and
+ * multiply by 3.
+ *
+ * @author Gilman Tolle <gtolle@archrock.com>
+ * @version $Revision: 1.4 $ $Date: 2006/12/12 18:23:45 $
+ */
+
+generic configuration VoltageStreamC() {
+ provides interface ReadStream<uint16_t>;
+}
+implementation {
+ components new Msp430InternalVoltageC();
+ ReadStream = Msp430InternalVoltageC.ReadStream;
+}
+
--- /dev/null
+#ifndef _H_hardware_h
+#define _H_hardware_h
+
+#include "msp430hardware.h"
+//#include "MSP430ADC12.h"
+//#include "CC2420Const.h"
+//#include "AM.h"
+
+// need to undef atomic inside header files or nesC ignores the directive
+#undef atomic
+
+#endif // _H_hardware_h
components new Msp430ClockC(8192, 32);
MoteClockP.SubInit -> Msp430ClockC.Init;
- MoteClockP.Msp430ClockInit -> Msp430ClockC;
}
module MoteClockP {
provides interface Init;
- uses {
- interface Init as SubInit;
- interface Msp430ClockInit;
- }
+ uses interface Init as SubInit;
}
implementation {
for (i = 0; i < 0xfffe; i++); /* ensure LFXT1 is stable */
return call SubInit.init();
}
-
- event void Msp430ClockInit.setupDcoCalibrate()
- {
- call Msp430ClockInit.defaultSetupDcoCalibrate();
- }
-
- event void Msp430ClockInit.initClocks()
- {
- call Msp430ClockInit.defaultInitClocks();
- }
-
- event void Msp430ClockInit.initTimerA()
- {
- call Msp430ClockInit.defaultInitTimerA();
- }
-
- event void Msp430ClockInit.initTimerB()
- {
- call Msp430ClockInit.defaultInitTimerB();
- }
}
/***************** Init Commands ****************/
command error_t Init.init() {
- int i;
- for(i = 0; i < uniqueCount(UQ_STATE); i++) {
- state[i] = S_IDLE;
- }
return SUCCESS;
}